code 33061; procedure ARK (T, TE, M0, M, U, DERIVATIVE, DATA, OUT); integer M0, M; real T, TE; array U, DATA; procedure DERIVATIVE, OUT; begin integer P, N, Q; own real EC0, EC1, EC2, TAU0, TAU1, TAU2, TAUS, T2; real THETANM1, TAU, BETAN, QINV, ETA; array MU, LAMBDA[1:DATA[1]], THETHA[0:DATA[1]], RO, R[M0:M]; boolean START, STEP1, LAST; procedure INITIALIZE; begin integer I, J, K, L, N1; real S, THETA0; array ALFA[1:8, 1:DATA[1]+1], TH[1:8], AUX[1:3]; real procedure LABDA(I, J); value I, J; integer I, J; LABDA:= if P < 3 then (if J =I-1 then MUI(I) else 0) else if P =3 then (if I =N then (if J=0 then .25 else if J =N - 1 then .75 else 0) else if J =0 then (if I =1 then MUI(1) else .25) else if J =I - 1 then LAMBDA[I] else 0) else 0; real procedure MUI(I); value I; integer I; MUI:= if I =N then 1 else if I < 1 ! I > N then 0 else if P < 3 then LAMBDA[I] else if P =3 then LAMBDA[I] + .25 else 0; real procedure SUM(I, A, B, X); value B; integer I, A, B; real X; begin real S; S:= 0; for I:= A step 1 until B do S:= S + X; SUM:= S end SUM; N:= DATA[1]; P:= DATA[2]; EC1:= EC2 := 0; BETAN:= DATA[3]; THETANM1:= if P=3 then .75 else 1; THETA0:= 1 - THETANM1; S:= 1; for J:= N - 1 step - 1 until 1 do begin S:= - S * THETA0 + DATA[N + 10 - J]; MU[J]:= DATA[N + 11 - J] / S; LAMBDA[J]:= MU[J] - THETA0 end; for I:= 1 step 1 until 8 do for J:= 0 step 1 until N do ALFA[I, J + 1]:= if I = 1 then 1 else if J = 0 then 0 else if I = 2 ! I = 4 ! I = 8 then MUI(J) ** ENTIER((I + 2) / 3) else if (I = 3 ! I = 6) & J > 1 then SUM(L, 1, J-1, LABDA(J, L) * MUI(L) ** ENTIER(I / 3)) else if I = 5 & J > 2 then SUM(L, 2, J - 1, LABDA(J, L) * SUM(K, 1, L - 1, LABDA(L, K) * MUI(K))) else if I = 7 & J > 1 then SUM(L, 1, J - 1, LABDA(J, L) * MUI(L)) * MUI(J) else 0; N1:=if N < 4 then N + 1 else if N < 7 then 4 else 8; I:= 1; for S:= 1, .5, 1 / 6, 1 / 3, 1 / 24, 1 / 12, .125, .25 do begin TH[I]:= S; I:= I + 1 end; if P = 3 & N < 7 then TH[1]:= TH[2]:= 0; AUX[2]:= " - 14; DECSOL(ALFA, N1, AUX, TH); INIVEC(0, N, THETHA, 0); DUPVEC(0, N1 - 1, 1, THETHA, TH); if ^ (P = 3 & N < 7) then begin THETHA[0]:= THETHA[0] - THETA0; THETHA[N - 1]:= THETHA[N - 1] - THETANM1; Q:= P + 1 end else Q:= 3; QINV:= 1 / Q; START:= DATA[8] = 0; DATA[10]:= 0; LAST:= false; DUPVEC(M0, M, 0, R, U); DERIVATIVE(T, R) end INITIALIZE procedure LOCAL ERROR CONSTRUCTION(I); value I; integer I; begin if THETHA[I] ^= 0 then ELMVEC(M0, M, 0, RO, R, THETHA[I]); if I = N then begin DATA[9]:= SQRT(VECVEC(M0, M, 0, RO, RO))* TAU; EC0:= EC1; EC1:= EC2; EC2:= DATA[9] / TAU ** Q end end LEC; procedure STEPSIZE; begin real TAUACC, TAUSTAB, AA, BB, CC, EC; ETA:= SQRT(VECVEC(M0, M, 0, U, U)) * DATA[7] + DATA[6]; if ETA > 0 then begin if START then begin if DATA[8] = 0 then begin TAUACC:= DATA[5]; STEP1:= true end else if STEP1 then begin TAUACC:= (ETA / EC2) ** QINV; if TAUACC > 10 * TAU2 then TAUACC:= 10 * TAU2 else STEP1:= false end else begin BB:= (EC2 - EC1) / TAU1; CC:= - BB * T2 + EC2; EC:= BB * T + CC; TAUACC:= if EC < 0 then TAU2 else (ETA / EC) ** QINV; START:= false end end else begin AA:= ((EC0 - EC1) / TAU0 + (EC2 - EC1) / TAU1) / (TAU1 + TAU0); BB:= (EC2 - EC1) / TAU1 - (2 * T2 - TAU1) * AA; CC:= - (AA * T2 + BB) * T2 + EC2; EC:= (AA * T + BB) * T + CC; TAUACC:= if EC < 0 then TAUS else (ETA / EC) ** QINV; if TAUACC > 2 * TAUS then TAUACC:= 2 * TAUS; if TAUACC < TAUS / 2 then TAUACC:= TAUS / 2 end end else TAUACC:= DATA[5]; if TAUACC < DATA[5] then TAUACC:= DATA[5]; TAUSTAB:= BETAN / DATA[4]; if TAUSTAB < DATA[5] then begin DATA[10]:= 1; goto ENDARK end; TAU:= if TAUACC > TAUSTAB then TAUSTAB else TAUACC; TAUS:= TAU; if TAU >= TE - T then begin TAU:= TE - T; LAST:= true end; TAU0:= TAU1; TAU1:= TAU2; TAU2:= TAU end STEPSIZE procedure DIFFERENCE SCHEME; begin integer I, J; real MT, LT; MULVEC(M0, M, 0, RO, R, THETHA[0]); if P = 3 then ELMVEC(M0, M, 0, U, R, .25 * TAU); for I:= 1 step 1 until N - 1 do begin MT:= MU[I] * TAU; LT:= LAMBDA[I] * TAU; for J:= M0 step 1 until M do R[J]:= LT * R[J] + U[J]; DERIVATIVE(T + MT, R); LOCAL ERROR CONSTRUCTION(I) end; ELMVEC(M0, M, 0, U, R, THETANM1 * TAU); DUPVEC(M0, M, 0, R, U); DERIVATIVE(T + TAU, R); LOCAL ERROR CONSTRUCTION(N); T2:= T; if LAST then begin LAST:= false; T:= TE end else T:= T + TAU; DATA[8]:= DATA[8]+1 end DIFSCH; INITIALIZE; NEXT STEP: STEPSIZE; DIFFERENCE SCHEME; OUT; if T ^= TE then goto NEXT STEP; ENDARK: end ARK; eop