WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Besserer Algorithmus ohne Schleife?

 

StV0l
Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 06.06.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.06.2013, 09:49     Titel: Besserer Algorithmus ohne Schleife?
  Antworten mit Zitat      
Hallo zusammen,
für eine Matlab-Übungsaufgabe im Studium sollen wir eine Textdatei einlesen und und die Häufigkeit der Buchstaben angeben (nur a-z, Groß-klein egal). Im Prinzip alles kein Problem. Folgende Lösung habe ich:
Code:

fileId = fopen('Text.txt');
charArray =  double(lower(fread(fileId,'*char')));
verteilung = zeros(2,26);
verteilung(1,1:26) = 'a':'z';

for kk=1:26
    sprachverteilung(2,kk) = length(find(firstword == sprachverteilung(1,kk)));
end
 

Unser Prof. weist uns immer darauf hin, dass es bei Matlab wichtig ist "vektoriell" zu denken und Schleifen so weit wie möglich zu vermeiden. Deswegen meine Frage: lässt sich diese for-Schleife noch irgendwie eliminieren?
Bin gespannt auf eure Ideen!

Stephanus
Private Nachricht senden Benutzer-Profile anzeigen


Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 06.06.2013, 10:11     Titel: Re: Besserer Algorithmus ohne Schleife?
  Antworten mit Zitat      
Hallo StV0l,

Ein paar Tipps:
Code:
% charArray =  double(lower(fread(fileId,'*char')));
charArray = lower(fread(fileId, 'char'));  % Kein "double()" nötig mit "char"
verteilung = zeros(1, 26);

for kk = 1:26
    verteilung(kk) = sum(charArray == verteilung(kk));
end

Es gab in Deinem Code "verteilung" und "sprachverteilung", sowie "charArray" und "firstword". Ich vermute hier ist estwas mit den Namen durcheinander gekommen.

Schaue Dir mal an: "help histc".

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
StV0l
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 06.06.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.06.2013, 10:20     Titel:
  Antworten mit Zitat      
Danke für die Schnelle Antwort.
Sorry für die Namensdreher. Die sind erst hier beim Einfügen entstanden, als ich versucht habe den Variablen bessere "telling-names" zu geben. Da hab ich wohl einige übersehen.
Danke für den Hinweis mit double.

Die Mehrzeilige Ergebnismatrix hatte ich gewählt, weil es später die Möglichkeit geben soll auch mehret Dateien zu analysieren und diese dann miteinander zu vergleichen. Jede Datei sollte dann in einer eigenen Zeile stehen. Mir leuchtet aber ein, dass ich mir die "Kopfzeile" sparen kann.

Ich geh nun aber davon aus, dass sich die for-Schleife aber nicht vermeiden lässt!?

Vielen Dank!
Stephanus
Private Nachricht senden Benutzer-Profile anzeigen
 
Titus
Forum-Meister

Forum-Meister


Beiträge: 871
Anmeldedatum: 19.07.07
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 06.06.2013, 10:27     Titel:
  Antworten mit Zitat      
Hallo,

ja und nein: es könnte sein, dass sich die Schleife durch ein unlesbares Konstrukt ersetzen lässt.
Auch wenn Dein Prof. vollkommen recht hat, Operationen z.B. auf Matrizen möglichst ohne Schleifen sondern in vektorieller Form durchzuführen, ist dies einer der Fälle, wo definitiv eine saubere, gut lesbare Schleife vorzuziehen ist. Insbesondere, da wir es ja doch mit einer überschaubaren Anzahl Iterationen zu tun haben Wink.

Titus
Private Nachricht senden Benutzer-Profile anzeigen
 
StV0l
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 06.06.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.06.2013, 10:30     Titel: Lösung von Jan funktioniert nicht
  Antworten mit Zitat      
Hallo nochmal,
leider funktioniert die Lösung von Jan doch nicht. Und zwar stehen nach
Code:
charArray = lower(fread(fileId, 'char'));

in diesem Vektor ja die Ascii-Werte. also von 97 bis 122. Die sind dann natürlich nicht mit meiner Laufvariablen vereinbar. Meine Idee wäre das charArray einfach elementweise -96 zu rechnen. Wäre das performant?

Stephanus
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 06.06.2013, 10:43     Titel: Re: Lösung von Jan funktioniert nicht
  Antworten mit Zitat      
Hallo StV0l,

Die Orginalzeile "double(lower(fread(fileId,'*char')))" wandelt allerdings auch in die ASCII-Werte um.
Das Lesen von der Platte benötigt etwas in der Größen-Ordnung von zehntel Sekunden, die Subtraktion von 96 für mittelgroße Vektoren von einer Millionen Zeichen eher tausendstel Sekunden.

Am effizientesten wäre es, wenn FREAD gleich in das Format konvertiert, mit dem Du später arbeitest.

Es geht ohne Schleifen mit dem bereits erwähnten HISTC-Befehl, der genau solche Histogramme extrem effizient erstellt.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
StV0l
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 06.06.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.06.2013, 10:56     Titel: Zeitmessung zwei Varianten
  Antworten mit Zitat      
Hallo,

Hab jetzt mal beide Varianten mit und ohne Schleife ausprobiert:
Code:

tic;
fileId = fopen('Deutsch.txt');
charArray = lower(fread(fileId, 'char'))-96;
verteilung = zeros(1, 26);

%Variante 1: tic-toc ergibt ca. 0.016 sekunden
bar(histc(charArray,[1:26]))

%Variante 2: tic-toc ergibt ca. 0.018 Sekunden
for kk = 1:26
    verteilung(kk) = sum(charArray == kk);
end
bar(verteilung)
toc;
 


Das Textdokument hat 12206 Zeichen. Schleife und histc nehmen sich fast nix. Danke für die guten Ideen.
Auch wenn es hier gar nicht auf Performance ankam ist es spannend zu sehen, was so geht und ich bin begeistert von den schnellen Antworten. Werd mich jetzt wohl öfter hier melden... Wink

Gruß,
Stephanus
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 06.06.2013, 12:39     Titel: Re: Zeitmessung zwei Varianten
  Antworten mit Zitat      
HAllo StV0l,

Man benötigt bei "1:26" übrigens keine zusätzlichen eckigen Klammern: Da ist bereits ein Vektor.

Die fast gleiche Laufzeit liegt wohl daran, dass BAR die meiste Zeit benötigt.
Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
StV0l
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 06.06.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.06.2013, 12:42     Titel: Laufzeit
  Antworten mit Zitat      
Hallo Jan,

genau, das mit der Laufzeit stimmt. Ohne bar() ist histc() wesentlich schneller. Deswegen habe ich auch diese Variante genommen.

Stephanus
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.