📄 alg055.txt
字号:
> restart;
> # ADAMS VARIABLE STEP-SIZE PREDICTOR-CORRECTOR ALGORITHM 5.5
> #
> # To approximate the solution of the initial value problem
> # y' = f( t, y ), a <= t <= b, y(a) = ALPHA,
> #
> # with local truncation error within a given tolerance:
> #
> # INPUT: endpoints a, b; initial condition ALPHA; tolerance TOL;
> # maximum step size HMAX; minimum step size HMIN.
> #
> # OUTPUT: I, T(I), W(I), H where at the Ith step W(I) approximates
> # y(T(I)) and step size H was used or a message that the
> # minimum step size was exceeded.
> alg055 := proc() local RK4, OK, A, B, ALPHA, TOL, HMIN, HMAX, FLAG, NAME, OUP, H, DONE, KK, NFLAG, I, TT, WP, WC, SIG, K, J, Q; global W,T,F,Part1,Part2;
> # Step 1
> RK4 := proc(H,X,Y,KK) local K1, K2, K3, K4; global W,T;
> K1 := H*F(X,Y);
> K2 := H*F(X+0.5*H,Y+0.5*K1);
> K3 := H*F(X+0.5*H,Y+0.5*K2);
> K4 := H*F(X+H,Y+K3);
> W[KK] := Y+(K1+2.0*(K2+K3)+K4)/6.0;
> T[KK] := X+H;
> end;
> printf(`This is the Adams Variable Step-size Predictor-Corrector Method\n`);
> printf(`Input the function F(t,y) in terms of t and y\n`);
> printf(`For example: y-t^2+1\n`);
> F := scanf(`%a`)[1];
> F := unapply(F,t,y);
> OK := FALSE;
> while OK = FALSE do
> printf(`Input left and right endpoints separated by blank.\n`);
> A := scanf(`%f`)[1];
> B := scanf(`%f`)[1];
> if A >= B then
> printf(`Left endpoint must be less than right endpoint.\n`);
> else
> OK := TRUE;
> fi;
> od;
> OK := FALSE;
> printf(`Input the initial condition.\n`);
> ALPHA := scanf(`%f`)[1];
> while OK = FALSE do
> printf(`Input tolerance.\n`);
> TOL := scanf(`%f`)[1];
> if TOL <= 0 then
> printf(`Tolerance must be positive.\n`);
> else
> OK := TRUE;
> fi;
> od;
> OK := FALSE;
> while OK = FALSE do
> printf(`Input minimum and maximum mesh spacing `);
> printf(`separated by a blank.\n`);
> HMIN := scanf(`%f`)[1];
> HMAX := scanf(`%f`)[1];
> if HMIN < HMAX and HMIN > 0 then
> OK := TRUE;
> else
> printf(`Minimum mesh spacing must be a `);
> printf(`positive real number and less than\n`);
> printf(`the maximum mesh spacing.\n`);
> fi;
> od;
> if OK = TRUE then
> printf(`Choice of output method:\n`);
> printf(`1. Output to screen\n`);
> printf(`2. Output to text file\n`);
> printf(`Please enter 1 or 2\n`);
> FLAG := scanf(`%d`)[1];
> if FLAG = 2 then
> printf(`Input the file name in the form - drive:\\name.ext\n`);
> printf(`For example A:\\OUTPUT.DTA\n`);
> NAME := scanf(`%s`)[1];
> OUP := fopen(NAME,WRITE,TEXT);
> else
> OUP := default;
> fi;
> fprintf(OUP, `ADAMS VARIABLE STEP-SIZE PREDICTOR CORRECTOR METHOD\n\n`);
> fprintf(OUP, ` t w h sigma\n`);
> # Step 2
> T[0] := A;
> W[0] := ALPHA;
> H := HMAX;
> # OK is used in place of FLAG to exit the loop in Step 4
> OK := TRUE;
> # DONE is used in place of LAST to indicate when the last
> # value is calculated
> DONE := FALSE;
> # Step 3
> for KK from 1 to 3 do
> RK4(H,T[KK-1],W[KK-1],KK);
> od;
> # NFLAG indicates calculation from RK4
> NFLAG := 1;
> I := 5;
> # Use TT in place of t
> TT := T[3] + H;
> # Step 4
> while DONE = FALSE do
> # Step 5
> # Predict W(I)
> Part1 := 55.0*F(T[I-2],W[I-2])-59.0*F(T[I-3],W[I-3]);
> Part2 := 37.0*F(T[I-4],W[I-4])-9.0*F(T[I-5],W[I-5]);
> WP := W[I-2]+H*(Part1+Part2)/24.0;
> # Correct W(I)
> Part1 := 9.0*F(TT,WP)+19.0*F(T[I-2],W[I-2])-5.0*F(T[I-3],W[I-3]);
> Part2 := F(T[I-4],W[I-4]);
> WC := W[I-2]+H*(Part1+Part2)/24.0;
> SIG := 19.0*abs(WC-WP)/(270.0*H);
> # Step 6
> if SIG <= TOL then
> # Step 7
> # Result accepted
> W[I-1] := WC;
> T[I-1] := TT;
> # Step 8
> if NFLAG = 1 then
> K := I-3;
> KK := I-1;
> # Previous results are also accepted
> for J from K to KK do
> fprintf(OUP, `%12.8f %11.8f %11.8f %11.8f\n`, T[J-1], W[J-1], H, SIG);
> od;
> fprintf(OUP, `%12.8f %11.8f %11.8f %11.8f\n`, T[I-1], W[I-1], H, SIG);
> else
> # Previous results were already accepted
> fprintf(OUP, `%12.8f %11.8f %11.8f %11.8f\n`, T[I-1], W[I-1], H, SIG);
> fi;
> # Step 9
> if OK = FALSE then
> DONE := TRUE;
> else
> # Step 10
> I := I+1;
> NFLAG := 0;
> # Step 11
> if SIG <= 0.1*TOL or T[I-2]+H > B then
> # Increase H if more accuracy has been obtained than is required, or
> # decrease H to include B as a mesh point
> # Step 12
> # To avoid underflow
> if SIG <= 1.0e-20 then
> Q := 4.0;
> else
> Q := (0.5*TOL/SIG)^(1/4);
> fi;
> # Step 13
> if Q > 4.0 then
> H := 4.0*H;
> else
> H := Q * H;
> fi;
> # Step 14
> if H > HMAX then
> H := HMAX;
> fi;
> # Step 15
> if T[I-2]+4.0*H > B then
> H := 0.25*(B-T[I-2]);
> if H < TOL then
> DONE := TRUE;
> fi;
> OK := FALSE;
> fi;
> # Step 16
> for KK from I-1 to I+2 do
> RK4(H,T[KK-1],W[KK-1],KK);
> od;
> NFLAG := 1;
> I := I+3;
> fi;
> fi;
> else
> # FALSE branch for Step 6 - result rejected
> # Step 17
> Q := (0.5*TOL/SIG)^(1/4);
> # Step 18
> if Q < 0.1 then
> H := 0.1 * H;
> else
> H := Q * H;
> fi;
> # Step 19
> if H < HMIN then
> fprintf(OUP, `HMIN exceeded\n`);
> DONE := TRUE;
> else
> if T[I-2]+4.0*H > B then
> H := 0.25*(B-T[I-2]);
> fi;
> if NFLAG = 1 then
> I := I-3;
> fi;
> for KK from I-1 to I+2 do
> RK4(H,T[KK-1],W[KK-1],KK);
> od;
> I := I+3;
> NFLAG := 1;
> fi;
> fi;
> # Step 20
> TT := T[I-2] + H;
> od;
> # Step 21
> if OUP <> default then
> fclose(OUP):
> printf(`Output file %s created successfully`,NAME);
> fi;
> fi;
> RETURN(0);
> end;
> alg055();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -