Verfasst am: 09.07.2012, 23:36
Titel: Was macht Matlab so langsam?
Guten Abend,
leider arbeite ich sehr selten mit Matlab und habe nun ein Programm geschrieben, dass zwar mir die gewünschten Ergebnisse ausgibt aber sehr sehr lange dafür rechnet. Von daher würde es mir sehr helfen, wenn ihr mir sagt, welcher Befehl mein Programm so langsam macht und was eine Alternative wäre. Da ich stark vermute dass das string einlesen mein Programm so langsam macht, möchte ich euch hier nicht mit code erschlagen und zeige erstmal einen Ausschnitt. Sollte euch was aus der Beschreibung auffallen bitte gebt bescheid, dann schreibe ich gerne den Code.
Ich habe eine Differentialgleichung 2. Ordnung 3x3. Diese wird mir in einem extra Programm in Abhängigkeit von Symbolen berechnet und mittels eines globalen Strangs ausgegeben. Ist diese Gleichung einmal generiert (was nicht sehr Lange dauert) möchte ich diese nun integrieren.
Dazu benutzte ich eine Eingabedatei in der man die Variablen (Längen, Massen etc) einstellen kann und diese dann via Funktion an den Integrator übergeben werden. Mein Integrator sieht dann folgendermaßen aus:
Es gibt in Matlab den sogenannten "Profiler". Im Editor unter Tools/Open Profiler zu sehen. Dieser Zeigt dir an wie lange die einzelnen Abschnitte im Code brauchen und was am längsten dauert.
Vielleicht hilft dir dies mal weiter.
Warum übergibst du denn die Variablen als String? Du kannst sie doch vorher mit str2num (besser als eval) umwandeln und anschließend als double übergeben (hier könnte man noch die globale Definition der Variablen vermeiden).
Warum übergibst du denn die Variablen als String? Du kannst sie doch vorher mit str2num (besser als eval) umwandeln und anschließend als double übergeben (hier könnte man noch die globale Definition der Variablen vermeiden).
viele Grüße
Thomas
Ganz einfach, weil ich es nicht besser wusste Ich werde es aber auf jedenfalls mal so probieren! Danke!
wenn du weitere Unterstützung brauchst, bitte die gesamte Anwendung zur Verfügung stellen. Ein weiterer Aspekt könnte z.B. die Wahl des DGL-Lösers (odexy) sein.
Vlt noch eine kleine Erkaerung vornweg: Es handelt sich um eine Kurbelschwinge. Diese besteht aus einem Doppelpendel und einem einfachen Pendel. Beide Pendel bewegen sich wie sie sollen.
Jetzt möchte ich diese über Zwangsbedingungen jedoch verkoppeln. (Hier constraintforce) Und hier steigt mir das Programm aus, bzw rechnet sich zu Tode. Dass es funktioniert kann ganz einfach getestet werden, z.B. durch C = varalpha. Was bedeutet die Änderung des Winkels alpha ist 0.
Dieser Code baut mir meine Differentialgleichung (ich werde das mit num2string später testen)
ich hatte das am Anfang wohl etwas falsch verstanden. Ich denke hier ist es günstigsten die symbolischen Ausdrücke dx1,dx2,dx3 in ein Matlab-Funktionen umzuwandeln (z.B. mit Matlabfunction). Danach kann man die erzeugten Funktionen einfach in der integrator funktion aufrufen.
ich bekomme eine Fehlermeldung, wenn ich deine Code-Fragmente kopiere und versuche auszuführen.
??? Undefined function or method 'eval' for input arguments of type
'double'.
Error in ==> integrator at 15
dxe1 = eval(dx1);
[...]
Vorschläge:
Wenn du wenig Zeit reinstecken willst:
Profiler laufen lassen und an den angezeigten Stellen arbeiten.
Wenn du das ganze "richtig" machen willst:
- weg mit den globalen Variablen
- weg mit eval
- verschiedene Löser testen
Ich hab nur den Teil build_ode ausgeführt. Als Ergebnis erhält man die symbolischen Ausdrücke dx1, dx2 und dx3. Diese werden in ein string umgewandelt und dann mit eval ausgewertet. Eine Umwandlung in double kann ich eigentlich nirgends entdecken.
Wenn man die (meterlangen) symbolischen Ausdrücke durch Funktionen ersetzt fällt das eval schon mal weg.
Ich habe noch ein paar Fragen zum besseren Verständnis:
Mit verschiedenen Loesern meinst du ODE45, 15s usw?
Zum Thema eval und globale Variablen weg und lieber Funktionen benutzen habe ich noch folgendes Problem.
Build ODE baut mir meine Bewegungsgleichung die ja anschliessend integriert werden soll. Da ich aber am Ende die Lösung bei verschiedenen Eingangsparametern (Längen, Massen, Drehmomenten usw) haben moechte, muss meine Bewegungsgleichung nur ein einziges mal hergeleitet werden. Danach möchte ich diese einfach abspeichern und immer wieder benutzen. Geht dies denn ohne globale Variablen? Weil wenn ich die Gleichung via Funktion übergeben mag dann müsste ich die Funktion (hier also build ode) jedes mal ausführen oder?
wenn ich diese anonymous function benutze definiere ich über diese ja meine Bewegungsgleichung die mir in Build_ODE berechnet wird und übergebe diese an den Integrator. Wenn ich nun aber meine Eingabewerte, sagen wir mal die Masse, ändere und das Programm nochmal durchlaufen lassen möchte, dann wird ja auch nochmals BUILD_ODE durchlaufen oder?
Nochmals zum Verständnis, falls meine obige Annahme stimmt.
Der Optimalzustand im fertigen Programm sollte sein:
Starte Programm, generiere mir meine Bewegungsgleichung schreibe diese in eine Funktion, Variable was auch immer und berechne daraus meine Bewegung. Ändert man nun was checkt mein Programm ob diese Funktion bzw Variable in der die Bewegungsgleichung schon ist enthalten ist bereits vorhanden ist und benutzt ohne mein BUILD_ODE auszuführen diese Variable für andere Werte.
Sollte ich mit obiger Annahme falsch liegen, dann wäre es kurz nett mir zu sagen woher Matlab weis, dass es bei der Anonymous Function BUILD_ODE nur einmal durchlaufen muss.
erstellen. Danach kannst du die Parameter params ändern ohne das du build_ode erneut ausführen musst. Wenn du allerdings mehr als nur Parameter ändern willst, musst du build_ode anpassen und natürlich erneut ausführen.
ich habe mich jetzt länger zu der anonymous function eingelesen und bin dabei auf eine andere Idee gestossen, die meiner Meinung nach sogar besser (vor allem für den weiteren Verlauf) geeignet ist.
Ich speichere meine Variable in einer Datei mittels save und lade diese in den Integrator. Das einzige Problem das ich hier noch habe ist, dass ich ja einen symbolischen Ausdruck speichere und diesen via Format zu ASCI umwandeln kann. Ich vermute nur, dies ist sehr nahe an der von mir genutzten Methode mit eval, richtig?
Gibt es hier eine schöne Möglichkeit mit save und load das ganze sauber und schnell zu lösen, oder komme ich um die Anonymus Funktion nicht rum?
der Nachteil an save und load ist, dass du wohl wiederholt laden würdest und das Lesen von der Festplatte bekanntlich langsam ist. Da sollte man zumindest mit persistent Variablen arbeiten.
Zitat:
oder komme ich um die Anonymus Funktion nicht rum?
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
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.