|
|
K. Taubert, W. Wiedl: Matlab Differentialgleichungen |
|
|
|
die im einfachsten Falle alle durch:
[t,y] = Integrator(M-Function, t-Intervall, Anfangswerte);aufgerufen werden. Dabei sind:
function dy = Funktionsname(t,y)
y1'(t) = y2(t)und erhalten für µ=2 damit:
y1' = y2 y2' = 2*(1-y12) * y2 - y1;Bedingt durch die Forderung, daß der Funktionswert als Spaltenmatrix geliefert werden muß, formulieren wir die M-Function also:
function dy = VDP(t,y) dy(1,1) = y(2); dy(2,1) = 2*(1 - y(1)^2)*y(2) - y(1);Der Aufruf des Integrators und die graphische Ausgabe der Lösung erfolgen dann z.B. durch:
[t,y] = ode23('VDP',[0 20],[2; 0]);
plot(t,y)
Beispiel 1.2
Ein weiteres Standardbeispiel besteht aus den
Eulerschen Gleichungen für eine festen Körper ohne externe Kräfte.
Die M-Function lautet:
function dy=RIGID(t,y)
dy = [ y(2)*y(3);
-y(1)*y(3);
-0.51*y(1)*y(2)];
Der Funktionswert wird hier als ganzes erzeugt und nicht elementweise wie
in Beispiel 1.1. Der Aufruf und die graphische Darstellung erfogt dann in der Form:
[t,y] = ode45('RIGID',[0;12],[0 1 1]);
In den neuesten Versionen von Matlab (seit Release 11) ist die möglich, die obigen Integratoren auch für Probleme zu nutzen, die in der Form:
M(t) y'(t) = F(t,y); y(0) = y0
Wenn ein Problem mit Massenmatrix formuliert ist, muß dies den Integratoren mitgeteilt werden. Man benutzt dazu beim Aufruf der Integratoren einen 4. Stellungsparameter, dessen Werte man mit Hilfe einer zusätzlichen odeset-Anweisung besetzt:
opt = odeset(...Eigenschaften festlegen...);
[t,y] = integrator('M-File',Integrationsintervall,Anfangswerte,opt);
plot(t,y)
Um zu signalisieren, daß das Problem mit Massenmatrix formuliert wurde,
muß man der Eigenschaft Mass in der odeset-Anweisung einen geeigneten
Wert zuweisen. Mögliche Werte von Mass sind:
'none' | 'M' | 'M(t)' | 'M(t,y)'wobei 'none' der voreingestellte Wert ist und signalisiert, daß keine Massenmatrix benötigt wird. Die drei anderen Werte signalisieren dagegen, daß eine solche Matrix benötigt wird und von welchen Parametern die Massenmatrix abhängt.
Die Massenmatrix selbst fragt der Integrator vom M-File ab, das zu diesem Zwecke mit einem dritten Stellungsparameter formuliert werden m&uszlig;:
function dy=name(t,y,flag)Der 3. Stellungsparameter, hier flag genannt, hat von Aufruf zu Aufruf verschiedene Werte, abhängig davon, welche Daten der Integrator vom M-File abfragt. Falls die Ableitungen abgefragt werden, den Wert '', also einen leeren String, falls die Massenmatrix abgefragt wird, den Wert 'mass'. Das M-File muß die dementsprechenden Werte zurückgeben.
Beispiel 1.3
Wir behandeln hier noch einmal das Problem aus Beispiel 1.2, formulieren
diesmal das Problem aber mit der Einheitsmatrix als Massenmatrix. Das M-File kann dann z.B. wie
folgt lauten:
function wert=DRIGID(t,y,flag)
switch flag
case ''
wert = [ y(2)*y(3);
-y(1)*y(3);
-0.51*y(1)*y(2)];
case 'mass'
wert = [ 1 0; 0 1];
end
Man beachte, daß der Funktionswert einmal der Vektor der Ableitungen, einmal die Einheitsmatrix
ist.
Der Aufruf erfolgt jetzt durch:
opt = odeset('Mass','M');
[t,y] = ode113('DRIGID',[0;12],[0 1 1]);
plot(t,y);
Der Eigenschaft Mass wird hier der Wert 'M' zugewiesen, da die Einheitsmatrix eine konstante
Matrix ist.
Bemerkung: In früheren Matlab-Versionen wurden die Eigenschaften der Massenmatrix anders beschrieben. Die hier gegebene Darstellung ist ab Version 5.2 gültig.
Was abgeschätzt wird, ist also nicht der globale Fehler, die Differenz
zwischen exakter Lösung y(tn+1) und berechneter Lösung yn+1,
der die Anwender eigentlich interessiert. Brauchbare Abschätzungen des globalen Fehlers
sind allerdings schwierig zu implementieren. Die lokale Fehlerabschätzung der Matlab
Integratoren liefert in der Regel aber Lösungen mit globalen Fehlern, die grob den
angegebenen lokalen Fehlerschranken entsprechen.
Bei schwierigen (für die Fehlerkontrolle) Problemen, kann es erforderlich sein, das
Problem mit höherer Genauigkeit zu rechnen um überhaupt brauchbare Ergebnisse
zu erhalten. Die Genauigkeitsanforderungen hängen also nicht nur von den Wünschen
der Anwendenden, sondern auch vom zu lösenden Problem ab.
Die Schranken für den lokalen Fehler werden komponentenweise in der Form:
Anzumerken ist, daß die flops-Angaben von Matlab für den Fall,
daß man die Voreinstellungen und den Fall, daß man die voreingestellten Werte
für 'AbsTol' und 'RelTol' benutzt differieren.
Über den Wert von InitialStep kann von Anwenderseite eine obere Schranke für
die Größe des 1. Integrationsschrittes vorgegeben werden, die Schrittweite ist
immer ein skalarer Wert. Intern benutzten die
Integratoren ein Verfahren, das die Weite des 1. Integrationsschrittes anhand der Ableitungen
zum Startzeitpunkt abschätzt. Falls dort alle Ableitungen den Wert 0 haben, fehlt
dieser Anhaltspunkt und die Integratoren können einen viel zu großen Anfangsschritt
wählen, der dann zeitaufwendig korrigiert werden muß.
Die Vorgabe eines Wertes für die maximale Schrittweite erfolgt über den Wert
von MaxStep und ist immer eine positive skalare Zahl. Sinnvoll ist
eine Vorgabe z.B. dann, wenn man die Periode einer Lösung kennt und
sicher sein will, daß die Schwingung
Listen mit Ausgabezeitpunkten
Statistiken zur Arbeit der Integrators
Eigene Ausgabefunktionen
Der Rückgabewert einer Ausgabefunktion muß ein Skalar mit dem
Wert 0 oder 1 sein. Er bestimmt, ob die Integration abgebrochen wird (1)
oder fortgesetzt wird (0).
Der Integrator ruft die Ausgabefunktion auf:
1.2 Fehlerkontrolle.
Die Matlab Integratoren benutzen eine Standardtechnik zur Fehlerkontrolle.
In jedem Schritt wird der lokale Fehler abgeschätzt und mit
einer vom Benutzer vorgegebenen Schranke verglichen.
Lokale Fehlerkontrolle bedeutet, daß der Fehler, der im aktuellen
Integrationsschritt entstanden ist, unter der Voraussetzung kontrolliert
wird, daß alle benutzten Ausgangswerte exakt waren.
Wenn also der n+1. Integrationsschritt in (tn,yn)
beginnt und eventuell noch die Ergebnisse (tn-1,yn-1) bis (tn-k,yn-k)
früherer Integrationsschritte benutzt und selbst als Ergebnis
(tn+1,yn+1) liefert, so wird der Fehler, der im Schritt
von tn nach tn+1 entsteht unter der Annahme, daß
alle Werte (tn,yn) bis (tn-k,yn-k) exakt waren,
abgeschätzt und mit der vorgegebenen Fehlerschranke verglichen.
Je länger das Integrationsintervall allerdings wird, desto weiter kann der globale
Fehler vom lokalen Fehler abweichen.
Größere Abweichungen können sind bei instabilen Problemen zu erwarten.
Eine Lösung eines Anfangswertproblems nennen wir dabei stabil, wenn eine kleine
Störung des Anfangswertes sich bei den Lösungskurven auch nur durch kleine
Abweichungen bemerkbar machen. Falls die kleinen Störungen im Laufe der Zeit sogar
herausgedämpft werden, nennen wir die Lösung asymptotisch stabil.
abs(LokalerFehleri) <= max(RelTol*abs(yi),AbsTol(i))
Bei der absoluten Fehlertoleranz ist die Skalierung der einzelnen Lösungskomponenten von
Bedeutung. Wenn eine Lösungskomponente abs(yi) kleiner als AbsTol(i) ausfällt,
wird der Integrator nicht veranlasst, auch nur eine genaue Stelle für diese Komponente
zu berechnen. Dies bedeutet, daß man eigentlich schon vor der Integration wissen muß,
in welcher Größenordnung sich die Lösungskomponenten eines Problems bewegen.
In vielen Fällen wird man eine Integration mehrfach durchführen müssen, bis
man eine geeignete Besetzung von AbsTol gefunden hat.
Beispiel 1.4:
Wir betrachten das Anfangswertproblem:
y'(t) = µ ( y(t) - sin(t) ) + cos(t), y(0) = 1
y(t) = sin(t) + exp( µt )
y'(t) = µ ( y(t) - sin(t) ) + cos(t), y(0) = 1+d
y(t) = sin(t) + (1+d) exp( µt )
Die zugehörigen Tabellen geben die aufgetretenen globalen relativen Fehler, die benötigten Gleitkommaoperationen
und die (systemabhängigen) Laufzeiten bei der numerischen Integration an:
1.3 Schrittweitenkontrolle.
Die Schrittweiten der Integratoren wird über die Fehlerkontrolle und damit im
wesentlichen über die Vorgaben der Werte von RelTol und AbsTol gesteuert.
Darüber hinaus kann noch die maximale Schrittweite über den
Wert von MaxStep vorgegeben und eine Anfangsschrittweite über den Wert von
InitialStep vorgeschlagen werden.
Die Vorgabe eines Wertes von InitialStep empfiehlt sich also:
Die Wahl eines geeigneten Wertes von InitialStep setzt natürlich voraus, daß man
entsprechende Informationen über das Lösungsverhalten hat.
1.5 Integrator Ausgabe
Refine-Eigenschaft
Die Refine-Eigenschaft bestimmt, wieviele Ausgabewerte pro Integrationsschritt
ausgegeben werden. Der Wert dieser Eigenschaft muß eine ganze Zahl
sein. Bei ode45 ist der Default-Wert 4, bei allen anderen Integratoren 1.
Mit dem Refine-Wert 1 erhält man bei n Integrationsschritten also n+1
Ausgabewerte, der zusätzliche Wert ist der Wert zum Anfangszeitpunkt.
Wenn Sie für eine Graphik glattere Verläufe benötigen, müssen
Sie den Refine-Wert erhöhen, das ist weit weniger aufwendig, als die
Reduzierung der Fehlertoleranzen. Der
'Refine'-Wert hat keinen Einfluß auf die Schrittweitensteuerung,
eventuelle (äquidistante) Zwischenpunkte werden durch Interpolation
gewonnen. Der genaue Algorithmus dafür ist nicht veröffentlicht, die
Matlab-Literatur gibt jedoch an, daß die zusätzlichen Ausgabewerte
von vergleichbarer Genauigkeit wie die Endpunkte der Integrationsschritte sind.
Die Refine-Eigenschaft ist nur wirksam, wenn das Integrationsintervall
lediglich durch Anfangs- und Endzeitpunkt beschrieben wird.
Beispiel 1.5
Wir integrieren noch einmal die van der Pol-Gleichung aus Beispiel 1.1.
Die Integration erfolgt einmal mit ode45 ein anderes mal mit ode23. Da der Refine-Wert 1 ist,
kann man die verwendeten Schrittweiten als Differenz der Ausgabezeitpunkte ermitteln.
Graphisch dargestellt
wird die Lösung und die Schrittweiten der Integratoren, man sieht die wesentlich kleineren
Schrittweiten von ode23.
opt = odeset('Refine',1,'AbsTol',1.0e-9,'RelTol',1.0e-6);
[t1,y1] = ode45('VDP',[0 20],[2 0],opt);
[t2,y2] = ode23('VDP',[0 20],[2 0],opt);
subplot(2,1,1)
plot(t2,y2)
title('Lösung der VDP-Gleichung mit µ=2')
subplot(2,1,2)
n1 = length(t1);
h1 = t1(2:n1) - t1(1:n1-1);
n2 = length(t2)
h2 = t2(2:n2) -t2(1:n2-1);
plot(t1(1:n1-1),h1,t2(1:n2-1),h2)
xlabel('ode45/ode23-Schrittweite bei Fehlertoleranz 1.0e-9/1.0e-6')
Das Integrationsintervall haben wir bisher immer in der Form [Anfangswert Endwert]
angegeben. Die Ausgabewerte werden dann gesteuert durch:
Alternativ dazu kann man eine Liste von Ausgabezeitpunkten angeben [t0, t1, ... , tn].
Die Zeitpunkte müssen streng monoton steigend oder fallend angeordnet sein. Sobald
mehr als 2 Listenelemente angegeben werden, liefern die Integratoren die Ausgabewerte
nur zu diesen Zeitpunkten. Der erste Zeitpunkt wird als Startzeitpunkt, der letzte als
Endpunkt des Integrationsintervalles interpretiert. Wiederum haben diese Ausgabezeitpunkte,
abgesehen vom 1. und letzten, keinen Einfluß auf die Wahl der Integrationsschritte.
Es ist mit dieser Technik nicht möglich nur die Werte am Ende des Integrationsintervalles
zu erhalten, es muß immer mindestens 3 Ausgabezeitpunkte geben.
[t,y] = ode45('VDP',pi*(0:-1:-4),[2; 0]);
Mit Hilfe der Stats Eigenschaft kann jeder Matlab Integrator dazu veranlaßt;
werden, genauere Angaben zu seiner Arbeit auszugeben, dies sind im Einzelnen:
Die Angaben beziehen sich immer auf das gesamte Integrationsintervall,
nicht auf einzelne Integrationsschritte. Die Angaben zu 3 bis 6 werden
allerdings nur von den steifen Integratoren ausgegeben, die wir hier
noch nicht behandeln.
Die statistischen Ausgaben erfolgen in einen dritten Ausgabewert. Der Default-Wert
zur 'Stats'-Eigenschaft ist 'off', der andere mögliche Wert ist 'on'.
Beispiel 1.6:
Wir betrachten noch einmal das Problem von Beispiel 1.3,
benutzen jetzt aber den Aufruf:
opt = odeset('Mass','M','Stats','on');
[t,y,S] = ode45('DYRIGID2',Intv,Ynull,opt);
Auf dem Bildschirm erhalten wir die Ausgabe:
19 successful steps
2 failed attempts
127 function evaluations
Im Vektor S sind die Werte [ 19 2 127 0 0 0 ] abgelegt.
Matlab bietet die Möglichkeit, nach jedem Integrationssschritt
eine eigene Ausgabefunktion aufzurufen, der Name dieser Funktion,
genauer, der Name des M-Files, muß als Wert der Eigenschaft
OutputFcn angegeben werden.
opt = odeset('OutputFcn','Eigenw','Refine',1);
[t,y] = ode45('VDP',[0 20],[2 0],opt);
Betont sei, daß mit einer eigenen Ausgabefunktion nicht die
Funktionswerte des Integrators beeinflußt werden, im obigen Aufruf
also nicht die Werte von t und y.
Beispiel 1.7:
Wir integrieren die van der Pol-Gleichung aus Beispiel 1.1
und wollen die Integration abbrechen, sobald die Jacobi-Matrix des Systems komplexe
Eigenwerte aufweist. Wir benutzen dazu eine M-Funktion, die je nach Aufruf, die
Ableitungen dy = F(t,y) oder die Jacobi-Matrix dF/dy liefert.
function dy = DOUTFUN(t,y,flag)
global my;
switch flag
case ''
dy = [ y(2);
my*(1 - y(1)^2)*y(2) - y(1) ];
case 'Jacobian'
dy = [ 0.0 1.0;
-my*2*y(1)*y(2)-1 my*(1-y(1).^2) ];
end
Die Ausgabefunktion berechnet die Eigenwerte der Jacobi-Matrix und gibt
als Funktionswert 1 (abbrechen) zuück, sobald ein komplexer
Eigenwert auftritt, anderenfalls wird als Funktionswert 0 (weiter integrieren) geliefert.
function out = OUTOUT2(t,y,flag)
if nargin == 2 | flag == 'init'
eiw = eig(DOUTFUN(t,y,'Jacobian'))';
if imag(eiw(1)) ~= 0
out = 1;
else
out = 0;
end
end
Das aufrufende Skript lautet:
global my eiw;
my = 5.0;
opt = odeset('Refine',1,'OutputFcn','Outout2', ...
'AbsTol',1.0e-9,'RelTol',1.0e-6);
[t,y] =ode45('VDP',[0 20],[2 0],opt);
plot(t,y)
title('Lösung der van der Pol-Gleichung für µ=5')
xlabel('t-Intervall mit realen Eigenwerten')
Zu beachten ist, da&szLig; im Falle eines Refine-Wertes > 1, der Wert des 1. Stellungsoperanden
der Ausgabefunktion ein entsprechend langer Vektor ist.
Beispiel 1.8:
In diesem Beispiel sollen die Lösungskurven der van der Pol Gleichung zusammen mit
den zugehörigen Eigenwerten der Jacobi-Matrix dargestellt
werden. Wir benutzen dasselbe M-File DOUTFUN wie in Beispiel 1.7, die Ausgabefunktion lautet jetzt jedoch:
function out = OUTOUTF(t,y,flag)
global my eiw;
if nargin == 2 | flag == 'init'
[n1,n2] = size(eiw);
eiw(n1+1,:) = eig(DOUTFUN(t,y,'Jacobian'))';
out = 0;
else
out = 1;
end
Das aufrufende Skript ist:
clear all
global my eiw;
my = 5.0;
opt = odeset('Refine',1,'OutputFcn','Outoutf', ...
'AbsTol',1.0e-9,'RelTol',1.0e-6);
[t,y] =ode45('VDP',[0 20],[2 0],opt);
subplot(3,1,1)
plot(t,y)
title('Lösung der van der Pol-Gleichung mit µ=5');
subplot(3,1,2)
plot(t,real(eiw))
subplot(3,1,3)
plot(t,imag(eiw))
xlabel('Eigenwerte der Jacobi-Matrix')