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

Ableitung und Integrationswert bei ode45 passen nicht zusamm

 

Steffi95

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 26.08.2015, 16:22     Titel: Ableitung und Integrationswert bei ode45 passen nicht zusamm
  Antworten mit Zitat      
Hallo liebes Forum,

ich habe ein Problem beim Lösen einer DGL mit ode45:

Mein y0 ist größer 0 und obwohl mein y' auch größer 0 ist, wird meine nächste Integrationsgröße y1 kleiner als die des vorherigen Zeitschritts y0.

Wie kann das sein, dass bei einer positiven Ableitung im nächsten Zeitschritt mein Integrationswert abnimmt?

Vielen Dank im Vorraus für eure Hilfe,

Liebe Grüße,
Steffi


Winkow
Moderator

Moderator



Beiträge: 3.842
Anmeldedatum: 04.11.11
Wohnort: Dresden
Version: R2014a 2015a
     Beitrag Verfasst am: 26.08.2015, 17:09     Titel:
  Antworten mit Zitat      
es wäre sicherlich einfacher sich da reinzudenken wenn du ein beispiel zur verfügung stellst das dieses verhalten reproduziert.
grüße
_________________

richtig Fragen
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 27.08.2015, 08:45     Titel:
  Antworten mit Zitat      
Hallo,

eine Möglichkeit ist ein Vorzeichenwechsel der Ableitung innerhalb des Integrationsschritt, eine weitere ein Fehler bei der Anwendung von ode45. Ansonsten siehe Winkow Beitrag.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Steffi95

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.08.2015, 09:51     Titel:
  Antworten mit Zitat      
Hallo,

vielen Dank für eure Antworten!

Ich habe das Problem gefunden. Ich habe für verschiedene Fälle zur Berechnung von y'. Ab einem bestimmten Zeitpunkt t, soll y' anders berechnet werden. Beim Debuggen ist mir aufgefallen, dass der Solver zwischen den beiden Fällen hin und her springt. Ich nehme an, dass der Solver damit nicht zurecht kommt. Durch Ändern der Fallbedingungen tritt das Problem nicht mehr auf.

Schöne Grüße,
Steffi
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 27.08.2015, 10:36     Titel:
  Antworten mit Zitat      
Hallo,

in solchen Fällen sollten Events oder separate ode45-Aufrufe verwendet werden.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Steffi95

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 28.08.2015, 11:01     Titel:
  Antworten mit Zitat      
Hallo Harald,

vielen Dank für den Tipp mit den Events. Ich versuche es nun darüber zu lösen.

So wie ich die Funktion bisher verstanden habe, bricht ode45 ab, sobald in meiner Event-Funktion der Variable value = 0 und iserminal = 1 ist.

Ich habe nun das Problem, dass meine Funktion je nachdem in welchem Wertebereich ein bestimmter Wert A liegt verschiedene Fälle zur Berechnung von y' verwendet (s. Code)

Code:

if A < B
y' = f1;
elseif A > B && A<C
y' = f2;
elseif A>C
y' = f3
else
errordlg ('error')
end
 


Mir fällt keine Möglichkeit ein, wie ich diese Bedingungen in die Event-Funktion einbinden kann. Die if-Bedingunen einfach zu übernehmen würde ja dazu führen, dass mein ode45 ständig abbrechen würde.
Ich möchte die verschiedenen Fälle zur Berechnung von y' gerne in einer Funktion beibehalten, also dass abhängig vom vorliegenden Event meine Funktion den richtigen Fall auswählt.

Hat da jemand eine Idee, wie man das umsetzen könnte?

Vielen Dank schon einmal für eure Hilfe!

Grüße,
Steffi
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 28.08.2015, 11:44     Titel:
  Antworten mit Zitat      
Hallo,

deine Funktion würdest du lassen, wie sie ist.

Wenn ich mich richtig erinnere, wäre eine Event-Funktion dann z.B.

Code:
function [value,isterminal,direction] = events(t,y)

value = t-B; % zur Zeit B soll gestoppt werden
isterminal = 0; % es soll weitergemacht werden
direction = 0;


Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Steffi95

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 28.08.2015, 13:03     Titel:
  Antworten mit Zitat      
Das Problem bei der Sache ist, dass meine Variablen A und C keine Zeitpunkte darstellen, sondern Werte die abhängig von t sind (A = f(t), C = f(t)). B ist eine Konstante.
Leider wird der Wert A allerdings nicht identisch B, sondern er überschreitet diesen ab einem bestimmten Zeitpunkt, sodass der Wert value mit dem nachfolgenden Code niemals 0 wird (sondern negativ).

Code:

function [value,isterminal,direction] = events(t,y)

value = B-A;
isterminal = 0;
direction = 0;
 


Noch eine allgemeine Frage zu der Event-Funktion:
Ich habe die Funktion so verstanden, dass bei value = 0 und isterminal = 1 der solver ode45 abbricht und bei isterminal = 0 weiterrechnet.
Überspringt der Solver bei isterminal = 0 somit den Zeitpunkt des Events (wenn value = 0)? Oder welchen Zweck hat die Event-Funktionen wenn isterminal = 0?
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 28.08.2015, 13:17     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Das Problem bei der Sache ist, dass meine Variablen A und C keine Zeitpunkte darstellen, sondern Werte die abhängig von t sind (A = f(t), C = f(t)).

Dann also f in der Event-Funktion aufrufen, genau so wie du das schreibst?

Zitat:
Leider wird der Wert A allerdings nicht identisch B, sondern er überschreitet diesen ab einem bestimmten Zeitpunkt, sodass der Wert value mit dem nachfolgenden Code niemals 0 wird (sondern negativ).

Kein Problem. Es wird ja nach Vorzeichenwechseln (Nulldurchgängen) von value gesucht.

Zitat:
welchen Zweck hat die Event-Funktionen wenn isterminal = 0?

Dass man den Zeitpunkt des Vorzeichenwechsels fein auflöst und ein Hin- und Herspringen zwischen den Zweigen vermeidet.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Steffi95

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 28.08.2015, 15:30     Titel:
  Antworten mit Zitat      
Hallo Harald,

noch einmal vielen Dank für deine bisherige Hilfe!

Ich habe deine angegebenen Änderungen der Event-Funktion umgesetzt.

Jetzt habe ich allerdings das Problem, dass ode45 die ode-Funktion innerhalb eines Zeitschritts mehrmals aufruft, ohne dazwischen die Event-Funktion abzufragen. Dadurch springt er bei der Berechnung von y' innerhalb eines Zeitschritts trotzdem zwischen den verschiedenen Fällen hin und her und liefert ein unrealistisches Ergebnis.

Hast du dafür eventuell auch einen Lösungsvorschlag?

Tausend Dank,
Steffi
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 28.08.2015, 15:56     Titel:
  Antworten mit Zitat      
Hallo,

an sich würde ich das nur bei internen Zwischenschritten erwarten.
Kannst du ein Beispiel zur Verfügung stellen, in dem das Problem auftritt?

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Steffi95

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 02.09.2015, 13:52     Titel:
  Antworten mit Zitat      
Hallo Harald,

leider habe ich das Problem immer noch nicht gelöst.

Innerhalb von ode45 wird die ODE-Funktion 'odeFcn' mehrmals aufgerufen, ohne dass die Event-Funktion aufgrufen wird (s. Ausschnitt ode45)

Code:
...
% LOOP FOR ADVANCING ONE STEP.
  nofailed = true;                      % no failed attempts
  while true
    hA = h * A;
    hB = h * B;
    f(:,2) = feval(odeFcn,t+hA(1),y+f*hB(:,1),odeArgs{:});
    f(:,3) = feval(odeFcn,t+hA(2),y+f*hB(:,2),odeArgs{:});
    f(:,4) = feval(odeFcn,t+hA(3),y+f*hB(:,3),odeArgs{:});
    f(:,5) = feval(odeFcn,t+hA(4),y+f*hB(:,4),odeArgs{:});
    f(:,6) = feval(odeFcn,t+hA(5),y+f*hB(:,5),odeArgs{:});
...
 


Sind das für dich interne Zwischenschritte?

Jedenfalls ist das Problem bei meiner Funktion, dass innerhalb meiner ODE-Funktion mein y' zwar stets postitiv oder 0 ist, jedoch mein integrierter Wert negativ werden kann. Dies führt in meiner Funktion zu Fehlern.

Das Problem trifft in folgendem Beispiel (y' = 0 oder positiv) ebenfalls auf.
Code:

function [T, Y] = test

ODEOptions = odeset('MaxStep',1,'InitialStep',0.5,...
    'RelTol',1e-06,'AbsTol',1e-12,'Events',@events);

y0 = 0;
tstart = 0;
tend = 10;

[T,Y] = ode45(@Test,tstart:tend, y0, ODEOptions);

    function dy = Test (t,y)
       
        if t<=4.4
            dy=0;
        else
            dy = 0.1;
        end
       
        if y < 0
            error ('Negative y')
        end
       
    end

    function[value, isterminal, direction] = events(t,y)
        value=y;
        isterminal=1;
        direction=0;
    end
end
 


Ich gehe davon aus, dass das Problem ist, dass mein y' (entpsricht f in ode45) innerhalb der ODE-Funktion von 0 auf einen positiven Wert springt. Durch Multiplikation mit einem negativen Koeffizienten aus Matrix B wird daraus ein negatives delta y und damit ein negatives y für y0 = 0.

Leider habe ich keine Ahnung, wie ich dem entgehen kann.
Hast du vielleicht eine Idee?

Vielen Dank und schöne Grüße,
Steffi95
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 02.09.2015, 20:17     Titel:
  Antworten mit Zitat      
Hallo,

Wie wäre es, wenn du am Anfang deiner Funktion
Code:
       if y < 0
            dy = 0;
        end

setzt?

In der Event-Funktion würde ich
Code:
isterminal=0;

setzen. Du willst ja keinen Abbruch.

Generell würde ich nested functions meiden. Das kann schnell zum unbeabsichtigten Überschreiben von Variablen führen. Stattdessen könnte man hier local functions verwenden.

Grüße,
Harald
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.