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

while-Schleife zu langsam: Alternativen?

 

zab
Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 14.01.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.01.2009, 12:10     Titel: while-Schleife zu langsam: Alternativen?
  Antworten mit Zitat      
Hallo,

bin ein ziemlicher Neueinsteiger was MatLab angeht, muss mich aber für die Datenauswertung eines Studienprojektes damit beschäftigen. Hänge nun an einem kleinen Problem. Meine Lösung funktioniert zwar, aber dauert *ewig* lange, bis die Berechnung fertig ist. Vielleicht hat ja jemand eine Idee, wie man das Beschleunigen kann (vielleicht andere/bessere MatLab-Befehle)?

Hier jedenfalls mal, was ich vor habe:

Ich habe eine Matrix A, in der Nullen und einsen vorkommen (z. B. A = [0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 1 0 0 1])

Am Ende brauche ich eine Matrix B (soll die gleiche Länge und Dimension haben wie A) die durch einen aus der Anzahl der Nullen berechnete Werte enthält.

Die Rechnung hierfür sei 6/AnzahlDerNullen (bis zur vorangegangenen 1)

B sieht also am Ende so aus B = [0 0 0 2 2 2 3 3 3 3 2 2 2 2 2 1.5 1.5 1.5 3]

Die ersten drei Nullen entstehen also, weil es keine vorangegangene "1" gibt. Dann beim ersten Auftreten der "1" (in A), werden die vorangegangenen Nullen gezählt und die Rechnung durchgeführt. Bis zum nächsten Auftreten einer "1" (in A), wird das Ergebnis in B geschrieben. Dann kommt wieder eine "1" in A, die vorangegangenen Nullen werden gezählt (hier "3"), Rechnung durchgeführt und in B geschrieben ...


Mein Code, mit dem ich das realisiere sieht momentan so aus (der Code funktionkiert auch soweit, nur die Ausführung dauert ewig):

Code:

i = 1
calculation = 0
while(i<max(size(A)))
    if (A(i) == 0)
        zeros = zeros+1;
    else
        calculation = 6/zeros;
        zeros = 1;
    end
   
    B(i) = calculation;
    i = i + 1;
end
 


Problem ist, dass meine A-Matrix ca. 1.000.000 Einträge hat, die Rechnung mit der while-Schleife dauert also mehrere Minuten. Vielleicht gibt es aber einen anderen Weg, den ich gehen könnte?


Bin für wirklich jede Hilfe dankbar!
Private Nachricht senden Benutzer-Profile anzeigen


Epfi
Forum-Meister

Forum-Meister



Beiträge: 1.134
Anmeldedatum: 08.01.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.01.2009, 14:25     Titel:
  Antworten mit Zitat      
1. Vorsicht! zeros ist ein Matlab-Befehl. Einen solchen als Variablennamen zu benutzen ist zwar möglich, aber nicht unbedingt empfehlenswert.

2. Matlab und Schleifen sind nicht befreundet. Überhaupt nicht! Warum, hast Du ja auch schon gemerkt. Es gibt für alles Vektor bzw. Matrizenoptimierte Befehle.

3. Die Hilfe und Dokumentation (F1) sind wirklich sehr ausführlich und hilfreich, manche Funktionsnamen sind einfach nicht offensichtlich, da kommt man ohne Hilfe nicht drauf. Und wenn man nichtmal weiß, was für eine Funktion man überhaupt sucht, dann fragt man hier ;)

Für dein Problem sollte es eine recht einfache und schnelle Lösung geben: den Befehl find. Um alle nullen in einer Matrix A zu finden benutzt man den so:
Code:
null_indizes = find(A == 0)
Als Rückgabe erhälst Du einen Vektor null_indizes in dem die Indizes der Nullen in aufgelistet sind. Bei deinem A-Vektor kommt dabei [1 2 3 5 6 8 9 10 12 13 14 15 17 18] raus. Mit diesen Zahlen sollte es dann möglich sein, weiterzurechnen...

Zuletzt bearbeitet von Epfi am 14.01.2009, 17:31, insgesamt einmal bearbeitet
Private Nachricht senden Benutzer-Profile anzeigen
 
zab
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 14.01.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.01.2009, 17:28     Titel:
  Antworten mit Zitat      
Habs jetzt gelöst. Zwar etwas anders, wie ursprünglich gedacht, aber in meinen Fall funktioniert das auch so.

Hier jedenfalls mein Code:
Code:

OneIndices = find(A > 0); % Indizes aller einsen finden

j = [0;OneIndices];  % Vektor um 0 erweitern
j(end) = [];       % letztes Element wegwerfen (nun haben wir wieder gleiche Dimensionen)


B = 6 ./ (OneIndices - j - 1); % Abstand zwischen den Nullen berechnen, Rechenoperation wie gewuenscht (6/Abstand) durchfuehren

clear j;  % j wegwerfen
 


Zwar ist nun die Dimension von A und B nicht mehr gleich, aber darauf kann ich verzichten ...

Nochmals vielen Dank für die Mühen!
Private Nachricht senden Benutzer-Profile anzeigen
 
Epfi
Forum-Meister

Forum-Meister



Beiträge: 1.134
Anmeldedatum: 08.01.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.01.2009, 17:36     Titel:
  Antworten mit Zitat      
Nochmal Vorsicht ;)

j und i haben in Matlab normalerweise den Wert der komplexen Einheit, i*i = j*j = i*j = j*i = -1.
Es gilt das gleiche wie für Variablennamen. Es geht zwar, kann aber schnell mal zu Verwirrungen führen, weil das Programm damit zwar läuft, aber komische Ergebnisse liefert.

Das beste Beispiel hast Du schon selbst geliefert: solltest Du in deinem Programm nach dem clear j nochmal aus versehen auf j zugreifen, wird dir Matlab sehr wahrscheinlich keine Fehlermeldung geben, weil viele Operationen auch für imaginäre Zahlen zulässig sind.
Private Nachricht senden Benutzer-Profile anzeigen
 
zab
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 14.01.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.01.2009, 17:39     Titel:
  Antworten mit Zitat      
UiUiUi. Komme aus der Programmierecke (wie man sicherlich schon gemerkt hat) und bewege mich in MatLab noch recht ungeschickt.

Vielen Dank für den Hinweis! Da muss ich meinen Kopf erst auf "Mathe" umstellen Smile
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 - 2024 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.