logo

ミッドポイントメソッド 📂数値解析

ミッドポイントメソッド

メソッド

DR2D \subset \mathbb{R}^2で定義された連続関数に対し、初期値問題{y=f(x,y)(y(x0),y(x1))=(Y0,Y1)\begin{cases} y ' = f(x,y) \\ ( y( x_{0} ), y (x_{1}) ) = ( Y_{0} , Y_{1} ) \end{cases}ffに与えられている。区間(a,b)(a,b)ax0<x1<<xn<xNba \le x_{0} < x_{1} < \cdots < x_{n} < \cdots x_{N} \le bのようなノードポイントで分けたとする。特に十分に小さいh>0h > 0に対しxj=x0+jhx_{j} = x_{0} + j hとすると、初期値y0=Y0y_{0} = Y_{0}に対して yn+1:=yn1+2hf(xn,yn) y_{n+1} := y_{n-1} + 2 h f ( x_{n} , y_{n} )

導出 1

Y(t)Y’(t)xnx_{n}に対してテイラー展開すると Y(t)=y(xn)+(txn)Y’’(xn)+(txn)22Y(3)(ξn) Y’(t) = y ' ( x_{n} ) + ( t - x_{n} ) Y’’ (x_{n} ) + {{( t - x_{n} )^2} \over {2}} Y^{(3)} ( \xi_{n} ) を満たすξn[xn1,xn]\xi_{n} \in [ x_{n-1} , x_{n} ]が存在する。両辺にt=xn1t= x_{n-1}からxn+1x_{n+1}までの定積分を取ると xn1xn+1Y(t)dt=xn1xn+1[y(xn)+(txn)Y’’(xn)+(txn)22Y(3)(ξn)]dt \int_{x_{n-1} }^{ x_{n+1} } Y’(t) dt = \int_{x_{n-1} }^{ x_{n+1} } \left[ y ' ( x_{n} ) + ( t - x_{n} ) Y’’ (x_{n} ) + {{( t - x_{n} )^2} \over {2}} Y^{(3)} ( \xi_{n} ) \right] dt xn1=xnhx_{n-1} = x_{n} - hかつxn+1=xn+hx_{n+1} = x_{n} + hなので xn1xn+1Y(t)dt=(xn+h(xnh))y(xn)+h3(h3)6Y(3)(ξn) \int_{x_{n-1} }^{ x_{n+1} } Y’(t) dt = ( x_{n} + h - (x_{n} - h) ) y ' ( x_{n} ) + {{ h^3 - ( - h^3 ) } \over {6}} Y^{(3)} ( \xi_{n} ) 微積分学の基本定理により Y(xn+1)Y(xn1)=2hy(xn)+h33Y(3)(ξn) Y(x_{n+1}) - Y(x_{n-1})= 2h y ' ( x_{n} ) + {{ h^3 } \over {3}} Y^{(3)} ( \xi_{n} ) Y=fY’ = fと仮定し、h33Y(3)(ξn)\displaystyle {{ h^3 } \over {3}} Y^{(3)} ( \xi_{n} )を除外すると yn+1=yn1+2hf(xn,yn) y_{n+1} = y_{n-1} + 2 h f ( x_{n} , y_{n} )

オイラーメソッドとの比較

誤差分析

オイラーメソッドと比較すると、2個のデータを使う分、計算は増えるが誤差は小さくなると推測できる。オイラーメソッドの誤差は、多くの条件が与えられてもO(h)O (h)にバウンドされているだけだ。

一方、ミッドポイントメソッドはマルチポイントメソッドとして、その誤差を計算すると maxx0xnbY(xn)yh(xn)e2K(bx0)η(h)+[e2K(bx0)12K][13h2Y(3)] \max_{ x_{0} \le x_{n} \le b} | Y (x_{n} ) - y_{h} (x_{n} ) | \le e^{2K(b-x_{0})} \eta (h) + \left[ {{ e^{2K (b - x_{0} ) } - 1 } \over {2K}} \right] \left[ {{1} \over {3}} h^2 | Y^{(3)} |_{\infty} \right] ここで初期誤差はη(h)=max{Y0y0,Y(x1)yh(x1)}\displaystyle \eta (h) = \max \left\{ |Y_{0} - y_{0}| , | Y(x_{1}) - y_{h} (x_{1}) | \right\}で、y0=Y0y_{0} =Y_{0}だから実際にはη(h)=Y(x1)yh(x1) \eta (h) = | Y(x_{1}) - y_{h} (x_{1}) |になる。YYをテイラー展開すると Y(x1)=Y(x0)+hY(x0)+h22Y’’(ζ)=y0+hf(x0,y0)+h22Y’’(ζ) Y (x_{1}) = Y(x_{0}) + h Y(x_{0}) + {{h^{2} } \over {2}} Y’’ (\zeta) = y_{0} + h f(x_{0} , y_{0}) + {{h^{2} } \over {2}} Y’’ (\zeta) この時、オイラーメソッドによるとy0+hf(x0,y0)=y1 y_{0} + h f(x_{0} , y_{0}) = y_{1}であるから、 Y(x1)yh(x1)=h22Y’’(ζ)=O(h2) Y(x_{1}) - y_{h} (x_{1}) = {{h^{2} } \over {2}} Y’’ (\zeta) = O(h^{2} ) 結果としてミッドポイントメソッドはオイラーメソッドよりも精度面で優れていると言える。O(h2)O (h^2)にバウンドされているためだ。

安定性の問題

しかし、ミッドポイントメソッドには致命的な欠陥がある。以下はRでミッドポイントメソッドを実装したコードだ。

Midpoint<-function(f,Y\_0,Y\_1=NA,a,b,h=10^(-3))
{
  Y <- t(Y\_0)
  if(is.na(Y\_1))
  {
    Y<-rbind(Y,Y[1,]+h*f(a,Y[1,]))
  }
  else
  {
    Y<-rbind(Y,Y\_1)
  }
  node <- seq(a,b,by=h)
  
  for(x in node[-1])
  {
    Y<-rbind(Y,Y[length(Y[,1])-1,]+2*h*f(x,Y[length(Y[,1]),]))
  }
  
  return(Y)
}
 
f<-function(x,y) {1/(1+x^2) + - 2*(y^(2))}
out<-Midpoint(f,seq(0,0,len=1),0,2,h=0.1)
out[,1]
 
g<-function(x,y) {x-y^2}
out<-Midpoint(g,seq(0,0,len=1),0,3.25,h=0.25)
out[,1]

実行してみると、f()と違い、g()は適切に解が得られない。これはミッドポイントメソッドの安定性に問題があるという例を示している。

20190412\_165014.png


  1. Atkinson. (1989). An Introduction to Numerical Analysis(2nd Edition): p362. ↩︎