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

Berechnen von DGL mit zeitabhängigem Parameter

 

bjoern_r.
Forum-Newbie

Forum-Newbie


Beiträge: 4
Anmeldedatum: 20.04.17
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 20.04.2017, 15:00     Titel: Berechnen von DGL mit zeitabhängigem Parameter
  Antworten mit Zitat      
Ich bin neu hier (jedenfalls als Fragesteller - sonst habe ich hier fast immer eine gute Antwort gefunden ohne die Frage nochmal zu stellen. Diesmal leider nicht)

Ich muss eine DGL lösen die eine zeitabhängige Variable enthält. Hierzu habe ich zwei Ansätze probiert und somit zwei Fragen.

1. Ansatz: Interpolieren der zeitabhängigen Variable mit interp1 und lösen der DGL mit ode45
--> Frage: kann man das zeitlich noch verbessern?

2. Ansatz: inkrementelle Lösung über for-Schleift
--> Frage: Die Geschwindigkeit ist zwar schon gut, aber das Beispiel ist auch stark vereinfacht. Kann man diese for-Schleife irgendwie durch eine sinnvolle Vektor/ Matrix-Operation ersetzen um die Performance noch weiter zu steigern

Vielen Dank im Voraus!

Code:

t = 0:60*60*10;
y0 = 1;
a = 1 * 10^-5;

% Zeitabhängiger Parameter A
dt = 1/60/60;
A(1,:) = [0; 1; 1+dt; 2; 2+dt; 3; 3+dt; 4; 4+dt; 5; 5+dt; 6; 6+dt; 7; 7+dt; 8; 8+dt; 9; 9+dt; 10] *60*60; % Zeit
A(2,:) = [1; 1;   0;  0;  1;   1;  0;   0;  1;   1;  0;   0;  1;   1;  0;   0;  1 ;  1 ;0    ;0 ] + 0.1; % Werte

%% Ansatz 1: lösen der Differentialgleichung mit ODE45
tic
dydt =@(t, y) a * interp1(A(1,:), A(2,:), t, 'lienar') * y;
[tout,yout] = ode45(dydt, t, y0);
Rechenzeit = toc;

figure
plot(tout,yout, '.', 'DisplayName', ['ode45, Rechenzeit: ',num2str(Rechenzeit),'s'])
hold on


%% Ansatz 2: Inkrementelle Berechnung mittels for-Schleife
tic
dt = t(2) - t(1);
Ainterp = interp1(A(1,:), A(2,:), t, 'linear');

yout = ones(size(t));
tout = t;

for i=2:length(t)
   
    yout(i) = yout(i-1) + a * Ainterp(i) * yout(i-1) * dt;
   
end
Rechenzeit = toc;

plot(t,yout, '.', 'DisplayName', ['for-loop, Rechenzeit: ',num2str(Rechenzeit),'s'])
legend show
hold off
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 20.04.2017, 19:55     Titel:
  Antworten mit Zitat      
Hallo,

der erste Ansatz ist sicher der genauere. Die Rechenzeit beträgt bei mir 0,4 Sekunden. Das sollte doch nicht wirklich ein Problem sein?

Grüße,
Harald
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: 25.04.2017, 13:15     Titel: Re: Berechnen von DGL mit zeitabhängigem Parameter
  Antworten mit Zitat      
Hallo bjoern_r.,

Code:
dydt =@(t, y) a * interp1(A(1,:), A(2,:), t, 'lienar') * y;

Gibt das keine Fehlermeldung wegen des "lienar"?
interp1 ist überraschend ineffizient geschrieben. Eine hand-kodierte lineare Interpolation wird da deutlich schneller sein. Allerdings sind lineare Interpolationen nicht stetig differenzierbar und deshalb stören sie die Schrittweiten-Kontrolle von ODE45. Man kann nicht vorhersagen, welche Auswirkungen das hat: Vielleicht bricht ODE45 mit einem Fehlermeldung ab, oder die Eregebnisse werden von Rundungsfehlern dominiert, da die Schrittweite solange runtergefahren wird, bis der Knick wegen der begrenzten Precision nicht mehr erkannt wird.

Ich habe viele Codes gesehen, in denen Forscher unstetige Funktionen mit Standard-Integratoren behandelt haben. Man bekommt tatsächlich eine Zahl heraus, aber aus wissenschaftlicher Sicht ist das kein "Ergebnis", da die Einflüsse zufälliger Rundungs-Effekte nicht abgeschätzt werden. Wenn soetwas in Doktor-Arbeiten auftaucht, bezeichne ich es als "Pfuschen".

Eine Vereinfachung bleibt: Eine lineare Interpolation besteht doch aus abschnittweisen Polynomen. Die zu integrieren ist trivial, da das doch Trapez-Summen sind. Wozu benötigst Du dann überhaupt ODE45?

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

Forum-Newbie

Forum-Newbie


Beiträge: 4
Anmeldedatum: 20.04.17
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.06.2017, 14:48     Titel:
  Antworten mit Zitat      
Zitat:
Gibt das keine Fehlermeldung wegen des "lienar"?

Doch, natürlich gibt das eine Fehlermeldung. Da habe ich wohl beim Kopieren einen Fehler gemacht.

Zitat:
Eine lineare Interpolation besteht doch aus abschnittweisen Polynomen. Die zu integrieren ist trivial, da das doch Trapez-Summen sind. Wozu benötigst Du dann überhaupt ODE45?

Meinst Du das so oder schwebt dir noch eine "bessere" Lösung vor?

Code:
Adt = cumtrapz(A(1,:), A(2,:)); % Integral von A

Adt_interp = interp1(A(1,:), Adt, t, 'linear');

yout = y0 * exp( a * Adt_interp );
 
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.