4次のルンゲクッタ法が、4次のテイラー展開と同精度になる理由

 投稿者:SECOND  投稿日:2013年 9月27日(金)15時26分37秒
  !最も簡単な微分方程式 dy/dx=f'(x) の解 f(x)の曲線描画 …不定積分と同、について、

!4次のルンゲクッタ法が、4次のテイラー展開と同精度になる理由。
!------------------------------------------------------------

!区間 h 直接のテイラー展開式
!f(x+h)= f(x) + f'(x)*h + f''(x)/2!*h^2 + f'''(x)/3!*h^3 + f''''(x)/4!*h^4 + ...

!4階微分を要する4次のテイラー展開の出力が、
!区間 h を細分化した位置 (a1,a2,a3,a4) での、1階微分だけの重み付き (b1,b2,b3,b4) 加算でも、
!同じになると仮定し、次の様に置く。

!f(x+h)= f(x)+
!        +b1*f'(x+a1*h)*h
!        +b2*f'(x+a2*h)*h
!        +b3*f'(x+a3*h)*h
!        +b4*f'(x+a4*h)*h

!この式を更にテイラー展開し、直接のテイラー展開式と、同じになれるか a1,a2,, b1,b2,, を調べる。

!f(x+h)= f(x)+
!        +b1*{f'(x) +f''(x)/1!*(a1*h) +f'''(x)/2!*(a1*h)^2 +f''''(x)/3!*(a1*h)^3 +?*h^4}*h
!        +b2*{f'(x) +f''(x)/1!*(a2*h) +f'''(x)/2!*(a2*h)^2 +f''''(x)/3!*(a2*h)^3 +?*h^4}*h
!        +b3*{f'(x) +f''(x)/1!*(a3*h) +f'''(x)/2!*(a3*h)^2 +f''''(x)/3!*(a3*h)^3 +?*h^4}*h
!        +b4*{f'(x) +f''(x)/1!*(a4*h) +f'''(x)/2!*(a4*h)^2 +f''''(x)/3!*(a4*h)^3 +?*h^4}*h

!各 階微分ごとに係数を整理。

!       +(b1+b2+b3+b4)                      *f'(x)*h
!       +(b1*a1  +b2*a2  +b3*a3  +b4*a4  )  *f''(x)*h^2
!       +(b1*a1^2+b2*a2^2+b3*a3^2+b4*a4^2)/2*f'''(x)*h^3
!       +(b1*a1^3+b2*a2^3+b3*a3^3+b4*a4^3)/6*f''''(x)*h^4
!       +?*h^5

!係数比較により、以下の式を満たせば同じになる。

!        b1     +b2     +b3     +b4        =1
!       (b1*a1  +b2*a2  +b3*a3  +b4*a4  )  =1/2!
!       (b1*a1^2+b2*a2^2+b3*a3^2+b4*a4^2)/2=1/3!
!       (b1*a1^3+b2*a2^3+b3*a3^3+b4*a4^3)/6=1/4!

!       |  1  ,  1  ,  1  ,  1  ||b1| =|1  |
!       | a1  , a2  , a3  , a4  ||b2| =|1/2|
!       | a1^2, a2^2, a3^2, a4^2||b3| =|1/3|
!       | a1^3, a2^3, a3^3, a4^3||b4| =|1/4|

!ルンゲクッタ4は通常、
!a1..a4=   0, 1/2, 1/2, 1   で、逆行列が、求まらないけれども、(特異行列エラー)
!b1..b4= 1/6, 1/3, 1/3, 1/6 は、上式を満たしているのが分る。

! a1,a2,, を適宜に決めると、b1,b2,, が決まる式になっているので、
!逆行列の求まる範囲で、他の a1,a2,, で試しに、グラフの重ね書きをしてみる。
!a1,a2,a3,a4 と、b1,b2,b3,b4 の組合せが無数にあるのが判る。

DIM A_(4,4), I_(4,4), B_(4,1), C_(4,1)
!-----
SET DRAW mode mask
SET COLOR MIX(15) .4,.4,.4
SET WINDOW -2, 9, -5, 3
DRAW grid( EXP(1), 1)
!----
LET xs= EXP(-4)                             !開始x
LET xe= EXP( 2)                             !終了x
LET h=.01                                   !計算間隔
!------------------------------
! 原始関数(比較用)                        !原始関数、サンプル1、サンプル2
!------------------------------             !3曲線を、減法混色3原色で
SET LINE COLOR "cyan"                       !重ねるので、一致していれば
FOR x=xs TO xe STEP h                       !黒線になる。
   PLOT LINES: x,f(x);
NEXT x
PLOT LINES
WAIT DELAY .5
!------------------------------
! ルンゲクッタ a1..a4 サンプル1
!------------------------------
CALL a1a4_b1b4( 0, 1/2-.001, 1/2+.001, 1)   !a1,a2,a3,a4 から b1,b2,b3,b4 を計算
SET LINE COLOR "yellow"
CALL GRAPH
WAIT DELAY .5
!------------------------------
! ルンゲクッタ a1..a4 サンプル2
!------------------------------
CALL a1a4_b1b4( 0, 1/3, 2/3, 1)             !a1,a2,a3,a4 から b1,b2,b3,b4 を計算
SET LINE COLOR "magenta"
CALL GRAPH


SUB a1a4_b1b4( a1,a2,a3,a4 )
   CALL A_row(1,  1  ,  1  ,  1  ,  1   )
   CALL A_row(2, a1  , a2  , a3  , a4   )
   CALL A_row(3, a1^2, a2^2, a3^2, a4^2 )
   CALL A_row(4, a1^3, a2^3, a3^3, a4^3 )
   MAT I_=INV(A_)
   LET C_(1,1)=1
   LET C_(2,1)=1/2
   LET C_(3,1)=1/3
   LET C_(4,1)=1/4
   MAT B_=I_*C_
   PRINT "b1,b2,b3,b4 の値"
   MAT PRINT B_;
END SUB

SUB A_row(r, a,b,c,d)
   LET A_(r,1)=a
   LET A_(r,2)=b
   LET A_(r,3)=c
   LET A_(r,4)=d
END SUB

!------------------------------
! 原始関数を使わないで、初期値から、その積分曲線を、ルンゲクッタで、描く。
!------------------------------
SUB GRAPH
   LET y=f(xs)                 !出力初期値
   FOR x=xs TO xe STEP h
      PLOT LINES: x,y;
      CALL RungeKutta
   NEXT x
   PLOT LINES
END SUB

!-----------------------------
!f(x+h)= f(x)+
!        +b1*f'(x+a1*h)*h
!        +b2*f'(x+a2*h)*h
!        +b3*f'(x+a3*h)*h
!        +b4*f'(x+a4*h)*h
!-----------------------------
SUB RungeKutta
   CALL Diff( k1, x+A_(2,1)*h)
   CALL Diff( k2, x+A_(2,2)*h)
   CALL Diff( k3, x+A_(2,3)*h)
   CALL Diff( k4, x+A_(2,4)*h)
   LET  y=y+(B_(1,1)*k1 +B_(2,1)*k2 +B_(3,1)*k3 +B_(4,1)*k4)*h
END SUB

!********* サンプル関数 *********  DEF f()= 、LET k= は、同時交換。

DEF f(x)=LOG(x)               !原始関数:f(x)=log(x)          1階微分:f'(x)=1/x
!DEF f(x)=SIN(x^2)-COS(x)      !原始関数:f(x)=SIN(x^2)-COS(x) 1階微分:f'(x)=COS(x^2)*2*x+SIN(x)
!DEF f(x)=x^3-3*x^2+x-1        !原始関数:f(x)=x^3-3*x^2+x-1   1階微分:f'(x)=3*x^2-6*x+1

SUB Diff( k, x)
   LET k=1/x                  !k= dy/dx= f'(x) 最も簡単な微分方程式
   !LET k=COS(x^2)*2*x+SIN(x)  !k= dy/dx= f'(x) 最も簡単な微分方程式
   !LET k=3*x^2-6*x+1          !k= dy/dx= f'(x) 最も簡単な微分方程式
END SUB

END
 

戻る