ich verwende ode23 oder ode45 um ein AWP zu lösen. Leider muss ich diesen Schritt sehr häufig wiederholen, da eine Optimierung (fminunc) darüber läuft. ICh sehe eine Möglichkeit einer wesentlichen Einsparung wenn ich an ode23() diskrete Punkte übergeben anstatt innerhalb der Funktion ausrechnen zu lassen.
Dies scheitern jedoch daran, dass matlab bei ode23 oder ode45 intern die Schrittweiten anpasst und ändert, auch wenn die zurückgegebenen Ergebnisspunkt mit tspan sich steuern lassen.
Mein Code:
Code:
%
E ist 4x4 MAtrix, mit einer 1 und Rest 0
A2 ist Vektor Länge 24
function dPhi=rSeite3b(t,Phi,E,A2)
A=reshape(A2(9:24),4,4);%11);
Z0=(A2(1:4)*expmdemo1(A*t)+A2(5:8)*integral(@(t1) expmdemo1((t-t1)*A),0,t,'ArrayValued',true))*E;% %Kann man hier durch Übergabe etwas sparen? % Vorbereitung DGL
dPhi=zeros(4,1);
% System der DGL
dPhi(1)=Phi(1)*A(1,1)+Phi(2)*A(2,1)+Phi(3)*A(3,1)+Phi(4)*A(4,1)+Z0(1);
dPhi(2)=Phi(1)*A(1,2)+Phi(2)*A(2,2)+Phi(3)*A(3,2)+Phi(4)*A(4,2)+Z0(2);
dPhi(3)=Phi(1)*A(1,3)+Phi(2)*A(2,3)+Phi(3)*A(3,3)+Phi(4)*A(4,3)+Z0(3);
dPhi(4)=Phi(1)*A(1,4)+Phi(2)*A(2,4)+Phi(3)*A(3,4)+Phi(4)*A(4,4)+Z0(4);
vielleicht kann man über die Effizienz der Zielfunktion einiges herausholen.
Was macht denn expmdemo1? Falls es die Exponentialmatrix einer Funktion berechnet: warum nutzt du nicht expm? Lässt sich das Integral dann nicht auch relativ leicht über die Stammfunktion auswerten?
Der weitere Teil sieht mir nach einer Matrix-Vektor-Multiplikation aus und sollte für bessere Effizienz dann auch als solche implementiert werden.
für die 4 Zeilen der MAtrixmultiplikation schreiben. Macht aber in Sachen BErechnung leider keine Unterschiede.
Bezüglich expmdemo1 welches eine Alternative zu expm ist:
Man kann die beiden austauschen, es tut sich nicht viel. Hatte den Eindruck, dass man mit expmdemo1 etwas schneller wird.
Die Kosten/Dauer entstehen eher weil rSeite3b so häufig berechnet werden muss und expm oder expmdemo1 sehr kostspielig sind '(über profiler nachgeprüft). Wenn ich die interne Schrittweite steuern kann, dann kann ich die Aufrufe wesentlich verrringern.
Es ist notwendig, weil übergeprdnet noch eine fminunc Optimierung geschaltet wird, die über die MAtrix A bzw A2 insgesamt optimiert. (24 Variablen also)
die einzige Möglichkeit, die ich theoretisch sehe, ist minStep und maxStep gleich zu wählen. Allerdings wird so die Einhaltung der Fehlertoleranz ausgehebelt. Das bedeutet wiederum, dass die in fminunc geschätzten Gradienten stark fehlerbehaftet sind und die Konvergenz unter Umständen dementsprechend schlecht.
Wenn man also an der Anzahl der Funktionsaufrufe nichts drehen kann, dann vielleicht an der Effizienz? Für die Berechnung des Integrals muss ja der Integrand auch mehrfach ausgewertet werden. Wenn ich nicht ganz auf dem Holzweg bin, kann man das doch explizit integrieren und sich so die numerische Auswertung des Integrals schenken?
Noch ein wichtiger Punkt: wenn E nur eine 1 enthält und ansonsten Nullen, dann werden jede Menge Einträge des Integrals umsonst berechnet. Das kann man vielleicht verhindern?
Der Integrand lässt sich nur für den Fall A regulär angeben, da inv(A) nur dann existiert. Dies ist
1) nicht gegeben, da A beliebig sein kann.
2) wenn A nur regulär, eingeschränkt wird, dann die theoretische Lösung des AWP zusammenbricht, die alle A voraussetzt.
Ja, an E anzusetzen wäre eine Idee, sehe bisher leider nicht wie man da was machen kann.
minStep klingt sehr gut, würde es gerne ausprobieren. LEider lässt odeset in meiner Version ein minStep nicht zu. Vielleicht liegt es an meiner Version: R2012a
sorry, Irrtum auf meiner Seite. In Simulink gibt es eine minimale und eine maximale Schrittweite, da dachte ich, dass es das in MATLAB wohl auch gäbe, gibt es aber nicht. Es ist ja auch nicht im Sinne des Erfinders, da so die Fehlertoleranzen nicht eingehalten werden.
Was du noch versuchen könntest: Datenpunkte berechnen und Integration mit trapz.
Was E angeht: im Zweifelsfall zunächst per Fallunterscheidung. Dann sollte man sehen, wie sich das wieder zurückvereinfachen lässt.
habe versucht trapz() oder quadv() zu nehmen anstatt integral().
Brauche jedoch die Datenpunkte eben fixiert, wenn ode23 aufgerufen wird, also feste (interne) Stepsize, sonst gibt es die Fehlermeldung, dass Werte nicht berechnet werden können.
Es scheint so zu sein, als wäre bei ode23 bzw ode45 dies nicht möglich, da variable stpsize benutzt werden soll. Vielleicht gibt es einen anderen odesolver der dies nicht macht und feste stepsize zulässt.
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.