Das Dormand-Prince-Verfahren ist ein Runge-Kutta-Verfahren fünfter Ordnung.
Als Probe können die Gleichungen
genommen werden.
program DormandPrince(input, output); {Integration der Gleichung y'(x) = 4*Exp(0.8x) - 0.5y(x) mittlels des Dormand-Prince-Verfahren} var x0, y0: double; {Anfangswerte} xf: double; {Endwert} h: double; {Schrittweite} eps: double; {Genauigkeit} x, y: double; uround: double; dy0, dy: double; y1, hneu: double; nenner, fehler, faktor: double; fail, accept: boolean; maxit, i, j: integer; b, c, k: array[1..7] of real; a: array[1..7,1..7] of real; function fxy(x, y: double): double; begin fxy := 4.0*Exp(0.8*x) - 0.5*y end; {fxy} procedure init; begin writeln('Darstellung der Loesung einer expliziten Differentialgleichung'); writeln('mittels des Verfahren nach Dormand-Prince am Beispiel'); writeln('y`(x) = 4*Exp(0.8x) - 0.5y(x)'); writeln; writeln('Geben Sie bitte die Anfangswerte ein'); readln(x0, y0); writeln('Geben Sie nun an, bis zu welchem x-Wert y(x) berechnet werden soll.'); readln(xf); writeln('Und in welcher Schrittweite sollen die x-Werte liegen?'); readln(h); while (xf - x0)*h < 0 do begin writeln('Von ', x0:1:3,' aus koennen Sie ', xf:1:3,' in Schritten von ', h:1:3,' nicht erreichen.'); writeln('Geben Sie noch einmal den Endwert und die Schrittweite ein.'); readln(xf, h) end; {while} writeln('Wie hoch soll die Toleranz fuer den lokalen Abschneidefehler sein?'); readln(eps); while eps <= 0 do begin writeln('Nur positive Genauigkeiten machen Sinn. Versuchen Sie es noch einmal.'); readln(eps) end; {while} uround := 1.0E-6; while (1+uround) > 1 do uround := uround*0.1; c[1]:=0.0; c[2]:=0.2; c[3]:=3/10; c[4]:=0.8; c[5]:=8/9; c[6]:=1.0; c[7]:=1.0; b[1]:=71/57600; b[2]:=0.0; b[3]:=-71/16695; b[4]:=71/1920; b[5]:=-17253/339200; b[6]:=22/525; b[7]:=-1/40; a[2,1]:=0.2; a[3,1]:=3/40; a[3,2]:=9/40; a[4,1]:=44/45; a[4,2]:=-56/15; a[4,3]:=32/9; a[5,1]:=19372/6561; a[5,2]:=-25360/2187; a[5,3]:=64448/6561; a[5,4]:=-212/729; a[6,1]:=9017/3168; a[6,2]:=-355/33; a[6,3]:=46732/5247; a[6,4]:=49/176; a[6,5]:=-5103/18656; a[7,1]:=35/384; a[7,2]:=0.0; a[7,3]:=500/1113; a[7,4]:=125/192; a[7,5]:=-2187/6784; a[7,6]:=11/84; x := x0; y := y0; fail := false; accept:= true; maxit :=0; writeln('x y') end; {init} procedure result; begin writeln( x:1:5,' ', y:1:5) end; {result} begin {Dormand-Prince} init; repeat dy := 0.0; for j:=1 to 7 do begin dy0 := 0.0; for i:=1 to j-1 do begin dy0 := dy0 + a[j,i]*k[i] end; {for} k[j] := fxy(x + c[j]*h, y + h*dy0); dy := dy + b[j]*k[j] end; {for} y1 := y + h*dy0; if 1.0E-5 > abs(y1) then begin nenner := 1.0E-5 end else begin {if} nenner := abs(y1) end; {if} if abs(y) > nenner then begin nenner := abs(y) end; {if} if (2*uround/eps) > nenner then begin nenner := 2*uround/eps end; {if} fehler := abs(h*dy/nenner); if 5.0 < (1.1*exp((1/5)*ln(fehler/eps))) then begin faktor := 5.0 end else begin {if} faktor := 1.1*exp((1/5)*ln(fehler/eps)) end; {if} if 1.0 > faktor then begin faktor := 1.0; end; {if} hneu := h/faktor; if fehler < eps then begin y := y1; x := x + h; result; if (not accept) then begin if h < hneu then begin hneu := h end {if} end; {if} accept:=true; maxit :=0; end else begin {if} accept := false; maxit := maxit + 1; fail := (maxit = 20) or (x + 0.1*h = x) end; {if} h := hneu; until (x > xf) or fail; end. {Dormand-Prince}