右辺の積分を既知の値だけで表現する陽解法,未知数
この陽解法のメリットと陰解法のメリットを組み合わせる(ある意味の妥協としての)アイディアが,予測子・修正子法である.つまり,陽解法によって
ここで,何か既にやったことがあるような・・・となると思う.この方法は既にHeun法で利用している(Heun法はもっとも低次の予測子・修正子法である).ここでは,Adams-Bashforth系の方法とAdams-Moulton系の方法を組み合わせた予測子・修正子法,つまり,より高次のAdams-Bashforth-Moulton法を紹介する.と言っても組み合わせるだけであるので特に難しいことはない.
組み合わせは何通りもあるので,3次のAdams-Bashforth法と4次のAdams-Moulton法 を組み合わせた方法を紹介する(同じステップ数なので,記憶しておく値が共通している).
まず,3次のAdams-Bashforth法で
次に,この
これらの手順に基づいて,分割数に対する誤差の変化を計算するFortranプログラムは以下のようになる.(多少雑であるが) 3次の予測子・修正子法が利用できるまでの初期ステップにおいては,Heun法を利用している.
program error_pc implicit none real*8 :: x, y, y_p1, x_end=1.d0, h, f_i, f_m1, f_m2, f_p1 integer :: i, n, n_max do i=1,6 n_max = 2**i h = x_end/n_max x=0.d0 y=1.0d0 do n=1, n_max f_i = f(x,y) if (n < 3) then y_p1 = y+f_i*h f_p1 = f(x+h, y_p1) y = y+0.5*h*(f_i+f_p1) ! Heun method else y_p1 = y+h/12.d0*(5*f_m2-16.d0*f_m1+23.d0*f_i) ! 3rd-order AB f_p1 = f(x+h, y_p1) y = y+h/24.d0*(f_m2-5.d0*f_m1+19.d0*f_i+9.d0*f_p1) ! 4th-order AM end if f_m2 = f_m1 f_m1 = f_i x = x+h end do write(*,*)n_max, abs(y-exp(1.d0))/exp(1.d0) end do stop contains function f(x,y) implicit none double precision, intent(in) :: x, y double precision :: f f = 3.d0*x**2*y end function f end program error_pc
Gnuplotのスクリプト
reset set log xy set title 'Error by Predictor-Corrector method' set xlabel 'n' set ylabel 'E_{total}' set format y "%.2e" set title font "Arial,20" set xlabel font "Arial,20" set ylabel font "Arial,20" set key font "Arial,12" plot 'error_pc.txt' with linespoints linewidth 3, 1/x, 1/x**2, 1/x**3 set terminal png set output 'error_pc.png' replot
3次の予測子・修正子法に関する数値誤差の分割数依存性を以下に示す.分割数が増大するにつれて3次精度の傾きに近くなっていることがわかる.