Simpson公式(Simpson's rule,シンプソン法)

直感的な考え方

区分求積法,台形公式からの類推で「より次数の高い関数で近似できた方が誤差が減少する可能性があるのではないか?」と考えられる.つまり,一定(区分求積法),そして直線(台形公式)の次は,2次関数である.以下の図に示すように2次関数を表現する場合には3点を利用する必要があり,2つの区分を利用する必要がありそうである.

ここで,3点をx0,x1,x2,その関数値をf0,f1,f2として考えよう.まず2次関数がx0f0を通ることから,2次関数の係数をa,b,c(=f0)とするとまずは以下のような式を立てることができる.

(1)f(x)=a(xx0)2+b(xx0)+f0 また,同時に他の2点を通るということから,以下の二つの式が得られる. (2)f1=a(x1x0)2+b(x1x0)+f0 (3)f2=a(x2x0)2+b(x2x0)+f0

ここで,x1x0=h, x2x0=2hを考慮して整理すると以下のようなabに関する連立方程式となり,通常の方法で解くと.a,bは以下のように求められる.

(4)a=f02f1+f22h2,b=3f0+4f1f22h

さて,ここで式(1)で示した関数を積分してみる.

I=x0x2(a(xx0)2+b(xx0)+f0)dx=[13a(xx0)3+12b(xx0)2+f0x]x0x2=13a(x2x0)3+12b(x2x0)2+f0(x2x0)=13f02f1+f22h28h3+123f0+4f1f22h4h2+2f0h(5)=h3(f0+4f1+f2)

Newton-Cotes法からの誘導

ニュートン・コーツ(Newton-Cotes)法の定義は以下のとおりである.

(6)I=abf(x)dxabi=0nfilidx=i=0nfiablidx=i=0nαifi

ここでαi=ablidxである.また一般的にliは以下のように定義されている.

(7)li(x)=j=0n,jixxjxixj

ここで3点,つまりシンプソン則はn=2の場合に対応するので,3つの係数は以下のようになる.

(8)l0=(xx1)(xx2)(x0x1)(x0x2),l1=(xx0)(xx2)(x1x1)(x1x2),l2=(xx0)(xx1)(x2x0)(x2x1)

例えばα0は以下のような積分になる.

(9)α0=x0x2(xx1)(xx2)(x0x1)(x0x2)dx=h3 (10)α1=4h3,α2=h3

ここでx1x0=h,x2x0=2h,x2x1=hであることを利用している(上記のα0,α1,α2を実際に積分して求めることを課題にする).

最終的に,区間内の積分は,2次関数の近似で求めた積分と同じになる

(11)I=h3(f0+4f1+f2)

精度の評価

区分求積法や台形公式と同様に,シンプソン公式にもテイラー展開による評価を行おう.

まず例によって,元の関数をテイラー展開後に積分した積分値Iを考える. I=02h(f(xi)+t1!f(xi)+t22!f(xi)+t33!f(xi)+)dt(12)=2f(xi)h+4h22f(x)+8h36f(xi)+16h424f(x)+32h5120f(x)+ 次にシンプソン公式の括弧内の係数を除いた各項を計算する(テイラー展開する). (13)f(xi)=f(xi)(14)f(xi+h)=f(xi)+hf(x)+h22f(x)+h36f(x)+h424f(x)+(15)f(xi+2h)=f(xi)+2hf(x)+4h22f(x)+8h36f(x)+16h424f(x)+

これらを係数を合わせて総合すると以下のようになる

(16)I=2hf(xi)+4h22f(x)+8h36f(xi)+16h424f(x)+20h572f(x)+ これらの引き算して誤差を評価すると以下のようになる. (17)II=h590f(x)+

区分の誤差はh5に比例することがわかった.これまでと同様な議論をすれば,全区間の誤差はh4に比例する.つまり,Simpson公式は4次精度のスキームであることがわかる.まずは,これまでと同様にy=3x2の積分で誤差を評価してみよう.

プログラムを確認すると,区分求積法や台形公式との違いは,14-17行の4行である(別途f2などの定義は加えているが).このプログラムも積分区分が両端が重複するので,より効率的にプログラムを作成できる.興味のある学生さんは効率化を試みてみると良い.

    
program simpson_rule
implicit none
integer i, j, n
double precision a, b, h, s, s_exact, x, f0, f1, f2
a = 0.0
b = 5.0
s_exact = 125.0
do i=1,6
x = 0.0
s = 0.0
n = 2**i
h = (b-a)/n
do j=0,n/2-1
f0 = 3.0*x**2
f1 = 3.0*(x+h)**2
f2 = 3.0*(x+2*h)**2
s = s+h/3.d0*(f0+4*f1+f2)
x = x+2*h
end do
print *, n, abs((s-s_exact)/s_exact)
end do
end program

実行結果を以下に示す.驚くことに全ての分割数で誤差がゼロである.これはシンプソン公式自身が2次関数を構築するようにできており,積分対象が2次関数の場合は数値解と解析解は一致する(さらに驚くことに3次関数でも誤差はゼロとなる.解析解と数値解の誤差か中点xi+1で点対象になっている).

2 0.0000000000000000
4 0.0000000000000000
8 0.0000000000000000
16 0.0000000000000000
32 0.0000000000000000
64 0.0000000000000000
これでは面白くないので,4次関数であるy=5x4x軸に囲まれる範囲x=05の面積で試してみる(厳密解はS=3125.0である).
2 4.1666666666666713E-002
4 2.6041666666667151E-003
8 1.6276041666671518E-004
16 1.0172526041715172E-005
32 6.3578287779819223E-007
64 3.9736429898766802E-008

これまでと同様にGnuplotによって誤差と分割数の関係を見てみよう.新たにy=1/x4という4次精度のラインも加えた結果を示す.計算結果(紫線)は4次精度のスキームであることがわかる.これまで学んだ他のスキームよりも圧倒的に高精度であることがわかる.