CD-8 SONY ICF-5900 分解・修理・調整・整備マ …本書は「CD-8 SONY ICF-5900 の分解・修理・調整・整備マニュアルぜ爰渰ź쬰憊괰罵尨抜粋版です。\爀
数値解析 - 奈良女子大学kako/teaching/na/chap6.pdf6. 定積分の計算(その2) 6...
Transcript of 数値解析 - 奈良女子大学kako/teaching/na/chap6.pdf6. 定積分の計算(その2) 6...
1
数値解析
加古富志雄
令和元年 5月 27日
目 次6 定積分の計算(その2) 1
6.1 ニュートン・コーツの公式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
6.1.1 オイラー・マクローリン展開 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
6.1.2 ニュートン・コーツ公式の誤差 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
6.2 チェビシェフの公式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
6.3 ガウスの公式 (ガウス・ルジャンドル公式) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
6.3.1 ガウス・ルジャンドル積分の分点および重み . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6.4 ガウス型積分公式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6.4.1 ガウス・ルジャンドル公式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
6.4.2 ガウス・ルジャンドル公式によるプログラム . . . . . . . . . . . . . . . . . . . . . . . . . . 11
6.4.3 ガウス・チェビシェフ公式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
6.4.4 ガウス・チェビシェフ公式によるプログラム . . . . . . . . . . . . . . . . . . . . . . . . . . 13
6.4.5 ガウス・ラゲール公式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
6.4.6 ガウス・ラゲール公式によるプログラム . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
6.4.7 ガウス・エルミート公式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
6.4.8 ガウス・エルミート公式によるプロウグラム . . . . . . . . . . . . . . . . . . . . . . . . . . 18
6.5 ロンバーグ積分法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
6.5.1 ロンバーグ積分のプログラム . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
6.6 課題 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
6 定積分の計算(その2)6.1 ニュートン・コーツの公式積分の計算で出てきた、台形公式やシンプソンの公式は、それぞれ、与えられた 2点を通る直線あるいは 3点を通る2次の多項式で関数 f(x)を近似(補間多項式)し、それによって積分を計算するというものである。∫ b
a
f(x)dx ≈∫ b
a
fn(x)dx
ただし、fn(x)は f(x)の n次の補間式で、与えられた n+ 1個の点 x = xi, 0 = 1, . . . , nで f(xi) = fn(xi)を満たす多項式である。
6. 定積分の計算(その2) 2
n次の (ラグランジェ)補間多項式は
fn(x) =
n∑k=0
Fn(x)
(x− xk)F ′n(xk)
f(xk)
で与えられる。ただしFn(x) = (x− x0)(x− x1) · · · (x− xn)
および xi = a+ b−an i である。
n = 1のとき、f1(x) =
x− x1
x0 − x1f(x0) +
x− x0
x1 − x0f(x1) =
(x− b)f(a)− (x− a)f(b)
b− a
より、これを積分すると ∫ b
a
f1(x)dx =b− a
2(f(b) + f(a))
となり、台形公式が得られる。同様に、n = 2 として、
f2(x) =(x− x1)(x− x2)
(x0 − x1)(x0 − x2)f(x0) +
(x− x2)(x− x0)
(x1 − x2)(x1 − x0)f(x1) +
(x− x0)(x− x1)
(x2 − x0)(x2 − x1)f(x2)
を積分して、x0 = a, x1 = a+b2 , x2 = bを代入すると、∫ b
a
f2(x)dx =b− a
6
{f(a) + 4f(
a+ b
2) + f(b)
}を得る。これはシンプソンの公式である。点の数を増やしていくことで、より高次の積分公式が得られる。n = 3のばあい、シンプソンの 8/3公式となる。
b− a
8
{f(a) + 3f(
2a+ b
3) + 3f(
a+ 2b
3) + f(b)
}n = 4のとき、ブールの公式が得られる。
b− a
90
{7f(a) + 32f(
3a+ b
4) + 12f(
a+ b
2) + 32f(
a+ 3b
4) + 7f(b)
}このような積分公式を (閉じた)ニュートン・コーツの公式という。補間多項式を作る時に、両端の x = a, x = bでの f(x)の値を使わないで補間式を作ると、
Gn(x) = (x− x1) · · · (x− xn−1)
として、
fn(x) =
n−1∑k=1
Gn(x)
(x− xk)G′n(xk)
f(xk)
これを x = aから x = bまで積分すると、n = 2のとき、(中点則)∫ b
a
f2(x)dx =
∫ b
a
f(x1)dx = (b− a)f(a+ b
2)
n = 3のとき、(台形則) ∫ b
a
f3(x)dx =b− a
2
{f(
2a+ b
3) + f(
a+ 2b
3)
}
6. 定積分の計算(その2) 3
n = 4のとき、(ミルンの公式)
b− a
3
{2f(
3a+ b
4)− f(
a+ b
2) + 2f(
a+ 3b
4)
}n = 5のとき、
b− a
24
{11f(
4a+ b
5) + f(
3a+ 2b
5) + f(
2a+ 3b
5) + 11f(
a+ 4b
5)
}がそれぞれ得られる。このような積分公式を (開いた)ニュートン・コーツの公式という。nを大きくすれば、高次の公式が得られるが、あまり nを大きくするとかえって誤差が大きくなる。実際には、区間 [a, b]を小さい部分区間に分劃し、各部分区間に対してニュートン・コーツの n 次公式を使って積分を計算して、結果を合計する方法が使われる。これを合成積分公式という。f(x) = 1/(1 + x2)について、区間 [−3, 3]を 5等分、7等分、9等分した点を標本点にとり、4次、6次、8次の補間多項式を求めると、
f5(x) = 0.0173418423973x4 − 0.235849056604 ∗ x2 + 0.81795227525
f7(x) = −0.00569464074813x6 + 0.0935548122907x4 − 0.472788001704x2 + 0.928545325176
f9(x) = 0.00184837728195x8 − 0.0357352941176x6 + 0.236044624746x4 − 0.674203853955x2
+0.972046146045
となる。これらの関数のグラフをプロットすると
となる。この図のように、標本点の数 nを大きくして補間式を作成したとき、グラフが激しく振動するようになる。これをルンゲ現象という。このため、nを大きく取りすぎると、得られる補間式と元の関数とのずれがかえって大きくなる。
6.1.1 オイラー・マクローリン展開
∫ b
a
f(x)dx =b− a
n{12f(a) + f(a+ h) + · · ·+ f(a+ (n− 1)h) +
1
2f(b)}
6. 定積分の計算(その2) 4
−B2
2!h2{f ′(b)− f ′a)} − B4
4!h4{f ′′′(b)− f ′′′(a)}
−B6
6!h6{f (5)(b)− f (5)(a)} − B8
8!h8{f (7)(b)− f (7)(a)} − · · ·
ただし、Bi はベルヌーイ数
B0 = 1, B1 = −1
2, B2 =
1
6, B4 = − 1
30, B6 =
1
42, B8 = − 1
30,
B10 =5
66, B12 = − 691
2703, B14 =
7
6, B16 = −3617
510, . . .
で、h = b−an である。
6.1.2 ニュートン・コーツ公式の誤差
オイラー・マクローリン展開式から、台形公式の誤差は、最初の項だけ取り出すと、
En =b− a
2{f(b) + f(a)} −
∫ b
a
f(x)dx ≈ − 1
12h2{f ′(b)− f ′(a)}
となる。シンプソン公式は、分割数を 2mとすると、
S2m =4
3T2m − 1
3Tm
と表すことが出来るので、これから、
S2m −∫ b
a
f(x)dx ≈ 4
3(− 1
12h2{f ′(b)− f ′(a)}+ 1
720h4{f ′′′(b)− f ′′′(a)})
−1
3(− 4
12h2{f ′(b)− f ′(a)}+ 16
720h4{f ′′′(b)− f ′′′(a)})
=1
180h4{f ′′′(b)− f ′′′(a)}
で与えられる。シンプソンの 8/3公式は、分割数を 6mと取ると、
S6m =9
8T6m − 1
8T2m
より、この公式の誤差は、
S6m −∫ b
a
f(x)dx ≈ − 1
80h4{f ′′′(b)− f ′′′(a)}
となる。ブールの公式は、分割数を 4mと取ると、
B4m =64
45T4m − 4
9T2m +
1
45Tm
と表すことができるので、これから、この公式の誤差は、
B4m −∫ b
a
f(x)dx ≈ − 2
945h6{f (5)(b)− f (5)(a)}
となる。
6. 定積分の計算(その2) 5
中点則は、2T2m − Tm に等しいから、誤差は、
1
6h2{f ′(b)− f ′(a)}.
台形則は、 32T6m − 1
2T2m に等しいから、誤差は
1
4h2{f ′(b)− f ′(a)}.
ミルンの公式は、 83T4m − 2T2m + 1
3Tm に等しいから、誤差は、
7
90h4{f ′′′(b)− f ′′′(a)}.
6.2 チェビシェフの公式台形公式から、シンプソン公式、高次のニュートン・コーツ公式に進むにつれて、係数が複雑になってくる。区間を等分して計算するという原則に従えば仕方がない。しかし、等分に分割するという原則を外せば、係数を揃えることができる。つまり、
Cn =b− a
n{f(x1) + f(x2) + · · ·+ f(xn)}
の形の積分公式を作ることができる。例えば、n = 3の場合には、
x1 =a+ b
2− b− a
2√2
≈ 0.5(a+ b)− 0.353553390593(b− a)
x2 =a+ b
2
x3 =a+ b
2+
b− a
2√2
≈ 0.5(a+ b) + 0.353553390593(b− a)
と選ぶ。f(x) = x2 として計算すると∫ 1
0
x2dx ≈ 1
3{f(0.146446609407) + f(0.5) + f(0.8353553390593)} =
1.0
3
とほぼ正しい結果が求められる。(3点で補間した多項式で近似しているので、2次式の積分は正確に得られる。)
n = 5に対しては、
x1 = 0.083751256499509062054
x2 = 0.31272929522320946721
x3 = 0.5
x4 = 0.68727070477679053279
x5 = 0.91624874350049093795
と取る。xi, i = 1, . . . , 5は、
2304x5 − 5760x4 + 5280x3 − 2160x2 + 374x− 19 = 0
の解である。この方程式は、y = 2x− 1と置くと、
72y5 − 60y3 + 7y = 0
6. 定積分の計算(その2) 6
と書ける。この方程式の解は
y = 0, y = ±√±√11 + 5
2√3
n = 7に対しては、
x1 = 0.058069149620975482148
x2 = 0.23517161235742159431
x3 = 0.33804409474004618124
x4 = 0.5
x5 = 0.66195590525995381876
x6 = 0.76482838764257840569
x7 = 0.94193085037902451785
となる。これは、
414720x7 − 1244160x6 + 1434240x5 − 794880x4 + 215928x3 − 25848x2 + 913x = 0
の解である。この方程式は、y = 2x− 1と置くと、
6480y7 − 7560y5 + 2142y3 − 149y = 0
となる。
6.3 ガウスの公式 (ガウス・ルジャンドル公式)
チェビシェフの公式を導き出す時に、係数が同じになるように決めた。このとき、xiの値はかなり複雑になっている。ここまでくれば、係数が複雑になったとしても、できるだけ精度の高い公式を導き出すことが考えられる。ガウス型の積分公式は
GN = (b− a) {A1f(x1) +A2f(x2) + · · ·+Anf(xn)}
となる。ここで、分点 x1, . . . , xn と係数 A1, . . . , An は n = 3のとき、
x1 = a+b2 − b−a
2
√35 , A1 = 5
18 ,
x2 = a+b2 , A2 = 8
18 ,
x3 = a+b2 + b−a
2
√35 , A1 = 5
18
n = 5のとき、x1 = a+b
2 − b−a2 × 0.9061798, A1 = 0.1184634,
x2 = a+b2 − b−a
2 × 0.5384693, A2 = 0.2393143,
x3 = a+b2 , A3 = 0.2844444,
x4 = a+b2 + b−a
2 × 0.5384693, A4 = 0.2393143,
x5 = a+b2 + b−a
2 × 0.9061798, A5 = 0.1184634,
6. 定積分の計算(その2) 7
6.3.1 ガウス・ルジャンドル積分の分点および重み
ガウス公式の分点はルジャンドル多項式 Pn(z)、Pn(z)は
P0(z) = 1
P1(z) = z
Pk(z) =2k − 1
kzPn−1(z)−
k − 1
kPn−2(z), k = 2, . . .
で定義される、の0点 zi, i = 1, 2, . . . , nから
xi =a+ b
2+
b− a
2zi
で与えられる。
P2(z) =1
2(3z2 − 1)
P3(z) =1
2(5z3 − 3z)
P4(z) =1
8(35z4 − 30z2 + 3)
P5(z) =1
8(63z5 − 70z3 + 15z)
...
ニュートン法を用いて、ルジャンドル多項式の零点を計算するには、初期値として、zi = cos( i+0.75n+0.5 π)を使い、
Pn(z)の微分はP ′n(z) =
n(Pn−1(z)− xPn(z))
1− z2
で計算すればよい。重み wi は
wi =1
2
∫ 1
−1
Pn(z)
(z − zi)P ′n(zi)
dz =1− z2i
(nPn−1(zi))2
で与えられる。n = 3の時,P3(z) =
12 (5z
3 − 3z) より、
w1 =1
2
∫ 1
−1
52x(
√5x−
√3)
3√5
dx =5
18
w2 =1
2
∫ 1
−1
5
2(x2 − 3
5)−2
3dx =
8
18
w3 =1
2
∫ 1
−1
52x(
√5x+
√3)
3√5
dx =5
18
6.4 ガウス型積分公式ガウス公式は、与えられた密度関数 w(x)について、積分∫ b
a
w(x)f(x)dx
を数値計算するための公式を与える。ガウス・ルジャンドル公式は w(x) = 1についての公式である。
6. 定積分の計算(その2) 8
密度関数 w(x)と積分区間 [a, b]について、∫ b
a
w(x)pi(x)pj(x)dx =
{λi, i = j
0, i = j
を満たす多項式 {pi(x), i = 0, 1, . . .}を直交多項式という。pi(x)の次数は i次である。与えられた、w(x)と区間 [a, b]およびλiに対して、上の関係式を満たす多項式列が存在することは、{1, x, x2, . . .}の多項式列に対してグラムシュミットの直交化の手続きを行なえば求められることから明らかである。よく知られた直交多項式としては、次の表に上げるルジャンドル多項式、チェビシェフ多項式、ラゲール多項式やエルミート多項式などがある。
名称 区間 w(x) λn
Pn(x) ルジャンドル多項式 [−1, 1] 1 2/(2n+ 1)
Tn(x) チェビシェフ多項式 [−1, 1] 1/√1− x2 π/2(ただし、λ0 = π)
Ln(x) ラゲール多項式 [0,∞) e−x 1
Hn(x) エルミート多項式 (−∞,∞) e−x2
2nn!√π
定理 6.1 多項式 pn(x), n ≥ 1の零点は全て相異なる実数で、区間 [a, b]の内部に存在する。
定理 6.2 多項式列 {pn(x)}は次の漸化式を満たす。
pk(x) = (αkx+ βk)pk−1(x)− γkpk−2(x)
ただし、
αk =µk
µk−1
βk = − αk
λk−1
∫ b
a
w(x)xp2k−1(x)dx =µk
µk−1
(νkµk
− νk−1
µk−1
)γk =
αk
λk−2
∫ b
a
w(x)xpk−1(x)pk−2(x)dx =µkµk−2λk−1
µ2k−1λk−2
ここで、µk は pk(x)の最高次の係数であり、νk は pk(x)の k − 1次の係数である。
定理 6.3 {pk(x)}を直交多項式とするとき x = yに対して、次の式が成り立つ。
n−1∑k=0
pk(x)pk(y)
λk=
µn−1
µnλn−1
pn(x)pn−1(y)− pn−1(x)pn(y)
x− y
この関係式をクリストッフェル・ダルブーの恒等式という。
直交多項式 pn(x)について、その零点を x0, · · · , xn−1とする。この xiを標本点とする、f(x)の n− 1次の補間多項式 fn(x)は
fn(x) =
n−1∑k=0
(x− x0) · · · (x− xk−1)(x− xk+1) · · · (x− xn−1)
(xk − x0) · · · (xk − xk−1)(xk − xk+1) · · · (xk − xn−1)f(xk)
となる。xi は pn(x)の零点であることからこれは
fn(x) =
n−1∑k=0
pn(x)
(x− xk)p′n(xk)f(xk)
となる。
6. 定積分の計算(その2) 9
f(x) = 1/(1 + x2)について、n = 5, 7, 9での Pn(x)の零点を標本点とする補間多項式 (区間 [−3, 3])を作ると
f5(x) = 0.0330188855304x4 − 0.363207724564x2 + 1
f7(x) = −0.00743552931257x6 + 0.115536670734x4 − 0.557768463968x2 + 1
f9(x) = 0.00170287072488x8 − 0.0341575611625x6 + 0.238621936447x4 − 0.710462223865x2 + 1
これをグラフに描くと次のようになる。左の図は、ルジャンドル多項式で補間した関数のグラフで、n = 5, 7, 9の場合を図示している。右の図は n = 11の場合で、ルジャンドル多項式で補間した関数と等間隔の標本点で補間した関数のグラフである。nを大きくすると振動が激しくなるが、ルジャンドル多項式で補間した場合は振動が押さえられている。
クリストッフェル・ダルブーの恒等式で y = xk を代入すると、n−1∑j=0
pj(x)pj(xk)
λj=
µn−1
µnλn−1
pn(x)pn−1(xk)− pn−1(x)pn(xk)
x− xk=
µn−1
µnλn−1
pn(x)pn−1(xk)
x− xk
が成り立つので、これを補間式 fn(x)に代入すると、
fn(x) =µnλn−1
µn−1
n−1∑k=0
1
pn−1(xk)p′n(xk)
n−1∑j=0
pj(x)pj(xk)
λjf(xk)
となる。
定理 6.4 f(x)は区間 [a, b]で n回連続微分可能であるとする。このとき、x ∈ [a, b]に対して次の式が成り立つ。
ϵn(x) = f(x)− fn(x) =1
n!λnpn(x)f
(n)(ξx), ξx ∈ J
J は x0, . . . , xn−1, xを含む区間である。
上で求めた、補間式から、次の積分を計算すると、∫ b
a
w(x)fn(x)dx =µnλn−1
µn−1
n−1∑k=0
f(xk)
pn−1(xk)p′n(xk)
n−1∑j=0
pj(xk)
λj
∫ b
a
w(x)pj(x)dx
pn(x)の直交性から、 ∫ b
a
w(x)pj(x)dx = λ0, (j = 0の時、それ以外は 0)
が成り立つので、これから、 ∫ b
a
w(x)fn(x)dx =µnλn−1
µn−1
n−1∑k=0
f(xk)
pn−1(xk)p′n(xk)
6. 定積分の計算(その2) 10
が得られる。これがガウス型の積分公式である。例えば、直交多項式としてルジャンドル多項式を取ると、λn = 2/(2n+ 1), µn =
∏nk=1
2k−1k より、
∫ 1
−1
f(x)dx =2
n
n−1∑k=0
1
Pn−1(xk)P ′n(xk)
f(xk)
ここで、wk =
2
nPn−1(xk)P ′n(xk)
=2(1− x2
k)
(nPn−1(xk))2
とおくと、 ∫ 1
−1
f(x)dx =
n−1∑k=0
wkf(xk)
の積分公式が得られる。
6.4.1 ガウス・ルジャンドル公式
分点は、n次ルジャンドル多項式 Pn(x)の零点とし、重みは
wi =2(1− x2
i )
(nPn−1(xi))2
となる。
∫ 1
−1
f(x)dx ≒n−1∑k=0
wif(xi)
ルジャンドル多項式は、
P0(x) = 1
P1(x) = x
Pn(x) =(2n− 1)xPn−1(x)− (n− 1)Pn−2(x)
n
の漸化式を満たす。ニュートン法でルジャンドル多項式の零点を求める場合の初期値としては、
xi = cos
(i+ 0.75
n+ 0.5π
), (i = 0, 1, 2, . . . , n− 1)
Pn(x)の微分はP ′n(x) =
n(Pn−1(x)− xPn(x))
1− x2
で計算できる。
6. 定積分の計算(その2) 11
N 分点 重み2 ± 0.57735026918962576451 1.0
3 0 0.88888888888888888889
± 0.77459666924148337704 0.55555555555555555552
4 ± 0.3399810435848562648 0.65214515486254614263
± 0.86113631159405257522 0.34785484513745385742
5 0 0.56888888888888888889
± 0.53846931010568309104 0.47862867049936646803
± 0.9061798459386639928 0.23692688505618908748
6 ± 0.23861918608319690863 0.46791393457269104739
± 0.66120938646626451366 0.36076157304813860758
± 0.93246951420315202781 0.17132449237917034508
7 0 0.41795918367346938776
± 0.40584515137739716691 0.38183005050511894494
± 0.74153118559939443986 0.27970539148927666793
± 0.94910791234275852453 0.1294849661688696932
6.4.2 ガウス・ルジャンドル公式によるプログラム
1 // gauss−legendre2 #include "pch.h"
3 #include <iostream>4 #include <stdlib.h>5 #define USE MATH DEFINES6 #include <math.h>7
8 double f(double x);9 double integral(double a, double b, int n);
10 double w2[] = {11 − 0.57735026918962576451 , 1.0 ,12 + 0.57735026918962576451 , 1.0 };13 double w3[] = {14 − 0.77459666924148337704 , 0.55555555555555555552 ,15 0 , 0.88888888888888888889 ,16 + 0.77459666924148337704 , 0.55555555555555555552 };17 double w4[] = {18 − 0.86113631159405257522 , 0.34785484513745385742 ,19 − 0.3399810435848562648 , 0.65214515486254614263 ,20 + 0.3399810435848562648 , 0.65214515486254614263 ,21 + 0.86113631159405257522 , 0.34785484513745385742 };22 double w5[] = {23 − 0.9061798459386639928 , 0.23692688505618908748 ,24 − 0.53846931010568309104 , 0.47862867049936646803 ,25 0 , 0.56888888888888888889 ,26 + 0.53846931010568309104 , 0.47862867049936646803 ,27 + 0.9061798459386639928 , 0.23692688505618908748 };28 double w6[] = {29 − 0.93246951420315202781 , 0.17132449237917034508 ,30 − 0.66120938646626451366 , 0.36076157304813860758 ,31 − 0.23861918608319690863 , 0.46791393457269104739 ,32 + 0.23861918608319690863 , 0.46791393457269104739 ,33 + 0.66120938646626451366 , 0.36076157304813860758 ,
6. 定積分の計算(その2) 12
34 + 0.93246951420315202781 , 0.17132449237917034508 };35 double w7[] = {36 − 0.94910791234275852453 , 0.1294849661688696932 ,37 − 0.74153118559939443986 , 0.27970539148927666793 ,38 − 0.40584515137739716691 , 0.38183005050511894494 ,39 0 , 0.41795918367346938776 ,40 + 0.40584515137739716691 , 0.38183005050511894494 ,41 + 0.74153118559939443986 , 0.27970539148927666793 ,42 + 0.94910791234275852453 , 0.1294849661688696932 };43
44 double ∗w[] = {NULL, NULL, w2, w3, w4, w5, w6, w7};45 int46 main(int ac, char ∗ av[])47 {48 double a, b, s;49 int i;50
51 a = 0;52 b = 1;53 for(i = 2; i <= 7; i++) {54 s = integral(a, b, i);55 printf("integral = %25.17f\n", s);56 }57 printf("pi / 4 = %25.17f\n", M PI/4);58 return 0;59 }60
61 double62 integral(double a, double b, int n)63 {64 double ∗x;65 double h = (b − a)/2 ;66 double p = (b + a)/2 ;67 double s = 0, y;68 int i;69
70 if(n >= 2 && n <= 7) {71 x = w[n];72 } else {73 printf("n should be 2 <= n <= 7\n");74 exit(1);75 }76 for (i = 0; i < n; i++) {77 y = p + h ∗ ∗x++;78 s = s + ∗x++ ∗f(y);79 }80 s = s ∗ h;81 return s;82 }83
84 double85 f(double x)86 {87 double r;88 r = 1/(1+x∗x);89 return r;90 }
6. 定積分の計算(その2) 13
6.4.3 ガウス・チェビシェフ公式
分点は、n次チェビシェフ多項式 Tn(x)の零点で、
xi = cos(1 + 2i
2nπ), (i = 0, 1, 2, . . . , n− 1)
である。重みはwi =
π
n
となる。
∫ 1
−1
f(x)√1− x2
dx ≒n∑
k=1
wif(xi)
チェビシェフ多項式は、
T0(x) = 1
T1(x) = x
Tn(x) = 2xTn−1(x)− Tn−2(x)
の漸化式を満たす。
6.4.4 ガウス・チェビシェフ公式によるプログラム
1 // gauss−chebyshev2 #include "pch.h"
3 #include <iostream>4 #include <stdlib.h>5 #define USE MATH DEFINES6 #include <math.h>7
8 double f(double x);9 double integral(int n);
10
11 int12 main(int ac, char ∗ av[])13 {14 double s;15 int i;16
17 for(i = 2; i < 10; i++) {18 s = integral(i);19 printf("integral = %25.17f\n", s);20 }21 return 0;22 }23
24 double25 integral(int n)26 {27 double s = 0, x, w;28 int i;29
30 if(n < 0) return 0;31 w = M PI/n;
6. 定積分の計算(その2) 14
32 for (i = 0; i < n; i++) {33 x = cos((1+2∗i)∗M PI/(2∗n));34 s = s + f(x);35 }36 s = s ∗ w;37 return s;38 }39
40 double41 f(double x)42 {43 double r;44 r = 1.0/(1.0+x∗x);45 return r;46 }
6.4.5 ガウス・ラゲール公式
分点は、n次ラゲール多項式 Ln(x)の零点とし、重みは
wi =(n!)2xi
(Ln+1(xi))2
となる。 ∫ ∞
0
f(x)e−xdx ≒n∑
k=1
wif(xi)
ラゲール多項式は、
L0(x) = 1
L1(x) = 1− x
Ln(x) = (2n− 1− x)Ln−1(x)− (n− 1)2Ln−2(x)
の漸化式を満たす。ニュートン法でラゲール多項式の零点を求める場合の初期値としては、
xi =π2(i+ 0.75)2
4n, (i = 0, 1, 2, . . . , n− 1)
Ln(x)の微分はxL′
n(x) = (x− n− 1)Ln(x) + Ln+1(x)
で計算できる。
6. 定積分の計算(その2) 15
N 分点 重み2 0.5857864376269049512 0.85355339059327376219
3.4142135623730950488 0.1464466094067262378
3 0.41577455678347908331 0.71109300992917301547
2.2942803602790417198 0.27851773356924084882
6.2899450829374791969 0.010389256501586135749
4 0.3225476896193923118 0.60315410434163360164
1.7457611011583465757 0.35741869243779968662
4.5366202969211279833 0.038887908515005384271
9.3950709123011331292 0.00053929470556132745012
5 0.2635603197181409102 0.52175561058280865254
1.4134030591065167922 0.39866681108317592751
3.5964257710407220812 0.075942449681707595393
7.0858100058588375569 0.0036117586799220484546
12.640800844275782659 0.0000233699723857762279
6 0.22284660417926068946 0.45896467394996359368
1.1889321016726230307 0.41700083077212099431
2.9927363260593140777 0.11337338207404497573
5.7751435691045105018 0.0103991974531490749
9.8374674183825899177 0.00026101720281493205948
15.982873980601701783 0.0000008985479064296212385
7 0.19304367656036241384 0.40931895170127390207
1.0266648953391919503 0.42183127786171978021
2.5678767449507462069 0.1471263486575052784
4.9003530845264845681 0.020633514468716939866
8.1821534445628607911 0.0010740101432807455221
12.734180291797813758 0.000015865464348564201269
19.395727862262540312 0.000000031703154789955805616
6.4.6 ガウス・ラゲール公式によるプログラム
1 // gauss−laguerre2 #include "pch.h"
3 #include <iostream>4 #include <stdlib.h>5 #include <math.h>6
7 double f(double x);8 double integral(int n);9
10 double w2[] = {11 0.5857864376269049512 , 0.85355339059327376219 ,12 3.4142135623730950488 , 0.1464466094067262378 };13 double w3[] = {14 0.41577455678347908331 , 0.71109300992917301547 ,15 2.2942803602790417198 , 0.27851773356924084882 ,16 6.2899450829374791969 , 0.010389256501586135749 };17 double w4[] = {
6. 定積分の計算(その2) 16
18 0.3225476896193923118 , 0.60315410434163360164 ,19 1.7457611011583465757 , 0.35741869243779968662 ,20 4.5366202969211279833 , 0.038887908515005384271 ,21 9.3950709123011331292 , 0.00053929470556132745012 };22 double w5[] = {23 0.2635603197181409102 , 0.52175561058280865254 ,24 1.4134030591065167922 , 0.39866681108317592751 ,25 3.5964257710407220812 , 0.075942449681707595393 ,26 7.0858100058588375569 , 0.0036117586799220484546 ,27 12.640800844275782659 , 0.0000233699723857762279 };28 double w6[] = {29 0.22284660417926068946 , 0.45896467394996359368 ,30 1.1889321016726230307 , 0.41700083077212099431 ,31 2.9927363260593140777 , 0.11337338207404497573 ,32 5.7751435691045105018 , 0.0103991974531490749 ,33 9.8374674183825899177 , 0.00026101720281493205948 ,34 15.982873980601701783 , 0.0000008985479064296212385 };35 double w7[] = {36 0.19304367656036241384 , 0.40931895170127390207 ,37 1.0266648953391919503 , 0.42183127786171978021 ,38 2.5678767449507462069 , 0.1471263486575052784 ,39 4.9003530845264845681 , 0.020633514468716939866 ,40 8.1821534445628607911 , 0.0010740101432807455221 ,41 12.734180291797813758 , 0.000015865464348564201269 ,42 19.395727862262540312 , 0.000000031703154789955805616 };43
44 double ∗w[] = {NULL, NULL, w2, w3, w4, w5, w6, w7};45
46 int47 main(int ac, char ∗ av[])48 {49 double s;50 int i;51
52 for(i = 2; i <= 7; i++) {53 s = integral(i);54 printf("integral = %25.17f\n", s);55 }56 return 0;57 }58
59 double60 integral(int n)61 {62 double ∗x;63 double s = 0, y;64 int i;65
66
67 if (n >= 2 && n <= 7) {68 x = w[n];69 } else {70 printf("n should be 2 <= n <= 7\n");71 exit(1);72 }73 for (i = 0; i < n; i++) {74 y = ∗x++;75 s = s + f(y) ∗ ∗x++;76 }77 return s;78 }
6. 定積分の計算(その2) 17
79
80 double81 f(double x)82 {83 double r;84 r = 1.0/(1.0+x∗x);85 return r;86 }
6.4.7 ガウス・エルミート公式
分点は、n次エルミート多項式Hn(x)の零点とし、重みは
wi =2n+1n!
√π
(Hn+1(xi))2
となる。
∫ ∞
−∞f(x)e−x2 ≒
n∑k=1
wif(xi)
エルミート多項式は、
H0(x) = 1
H1(x) = 2x
Hn(x) = 2xHn−1(x)− 2(n− 1)Hn−2
の漸化式を満たす。ニュートン法でエルミート多項式の零点を求める場合の初期値としては、
xi =
{1√
4n+12i−12 π, (i = 0, 2, . . . 2k)
1√4n+3
iπ, (i = 1, 3, . . . , 2k − 1)
Hn(x)の微分はH ′
n(x) = 2xHn(x)−Hn+1(x)
で計算できる。
6. 定積分の計算(その2) 18
N 分点 重み2 ± 0.7071067811865475244 0.8862269254527580136
3 0 1.181635900603677352
±1.224744871391589049 0.2954089751509193379
4 ± 0.52464762327529031788 0.80491409000551283651
±1.6506801238857845559 0.081312835447245177143
5 0 0.94530872048294188123
±0.95857246461381850711 0.39361932315224115983
±2.0201828704560856329 0.019953242059045913208
6 ±0.43607741192761650868 0.72462959522439252409
±1.3358490740136969497 0.15706732032285664392
±2.3506049736744922228 0.0045300099055088456409
7 0 0.81026461755680732676
±0.81628788285896466304 0.42560725261012780052
±1.673551628767471445 0.054515582819127030592
±2.6519613568352334924 0.00097178124509951915415
6.4.8 ガウス・エルミート公式によるプロウグラム
1 // gauss−hermit2 #include "pch.h"
3 #include <iostream>4 #include <stdlib.h>5 #include <math.h>6
7 double f(double x);8 double integral(int n);9
10 double w2[] = {11 − 0.7071067811865475244 , 0.8862269254527580136 ,12 + 0.7071067811865475244 , 0.8862269254527580136 };13 double w3[] = {14 − 1.224744871391589049 , 0.2954089751509193379 ,15 0 , 1.181635900603677352 ,16 + 1.224744871391589049 , 0.2954089751509193379 };17 double w4[] = {18 − 1.6506801238857845559 , 0.081312835447245177143 ,19 − 0.52464762327529031788 , 0.80491409000551283651 ,20 + 0.52464762327529031788 , 0.80491409000551283651 ,21 + 1.6506801238857845559 , 0.081312835447245177143 };22 double w5[] = {23 − 2.0201828704560856329 , 0.019953242059045913208 ,24 − 0.95857246461381850711 , 0.39361932315224115983 ,25 0 , 0.94530872048294188123 ,26 + 0.95857246461381850711 , 0.39361932315224115983 ,27 + 2.0201828704560856329 , 0.019953242059045913208 };28 double w6[] = {29 − 2.3506049736744922228 , 0.0045300099055088456409 ,30 − 1.3358490740136969497 , 0.15706732032285664392 ,31 − 0.43607741192761650868 , 0.72462959522439252409 ,32 + 0.43607741192761650868 , 0.72462959522439252409 ,33 + 1.3358490740136969497 , 0.15706732032285664392 ,
6. 定積分の計算(その2) 19
34 + 2.3506049736744922228 , 0.0045300099055088456409 };35 double w7[] = {36 − 2.6519613568352334924 , 0.00097178124509951915415 ,37 − 1.673551628767471445 , 0.054515582819127030592 ,38 − 0.81628788285896466304 , 0.42560725261012780052 ,39 0 , 0.81026461755680732676 ,40 + 0.81628788285896466304 , 0.42560725261012780052 ,41 + 1.673551628767471445 , 0.054515582819127030592 ,42 + 2.6519613568352334924 , 0.00097178124509951915415 };43
44 double ∗w[] = {NULL, NULL, w2, w3, w4, w5, w6, w7};45
46 int47 main(int ac, char ∗ av[])48 {49 double a, b, s;50 int i;51
52 for(i=2; i <= 7; i++) {53 s = integral(i);54 printf("integral = %25.17f\n", s);55 }56 return 0;57 }58
59 double60 integral(int n)61 {62 double ∗x;63 double s = 0, y;64 int i;65
66 if (n >= 2 && n <= 7) {67 x = w[n];68 } else {69 printf("n should be 2 <= n <= 7\n");70 exit(1);71 }72 for (i = 0; i < n; i++) {73 y = ∗x++;74 s = s + f(y) ∗ ∗x++;75 }76 return s;77 }78
79 double80 f(double x)81 {82 double r;83 r = 1.0/(1.0+x∗x);84 return r;85 }
6.5 ロンバーグ積分法オイラー・マクローリン展開∫ b
a
f(x)dx =b− a
n{12f(a) + f(a+ h) + · · ·+ f(a+ (n− 1)h) +
1
2f(b)}
6. 定積分の計算(その2) 20
−B2
2!h2{f ′(b)− f ′a)} − B4
4!h4{f ′′′(b)− f ′′′(a)}
−B6
6!h6{f (5)(b)− f (5)(a)} − B8
8!h8{f (7)(b)− f (7)(a)} − · · ·
から、積分 I =∫ b
af(x)dxを台形公式で計算した場合の誤差は、
ϵn = Tn − I
=B2
2!h2{f ′(b)− f ′a)}+ B4
4!h4{f ′′′(b)− f ′′′(a)}
+B6
6!h6{f (5)(b)− f (5)(a)}+ B8
8!h8{f (7)(b)− f (7)(a)}+ · · ·
となる。nを 2倍にした台形公式で計算した場合の誤差は、上の式で、h → h2 とおいて、
ϵ2n =B2
4 · 2!h2{f ′(b)− f ′a)}+ B4
16 · 4!h4{f ′′′(b)− f ′′′(a)}+ B6
64 · 6!h6{f (5)(b)− f (5)(a)}+ · · ·
これから4ϵ2n − ϵn = −3
4
B4
4!h4{f ′′′(b)− f ′′′(a)} − 15
16
B6
6!h6{f (5)(b)− f (5)(a)} − · · ·
すなわち、T (1)n =
4T2n − Tn
3
で計算した場合の誤差は、
T (1)n − I =
4ϵ2n − ϵn3
= −1
4
B4
4!h4{f ′′′(b)− f ′′′(a)} − 5
16
B6
6!h6{f (5)(b)− f (5)(a)} − · · ·
となり、Tn あるいは T2n で求めた場合の誤差よりも小さくなっている。さらに、
T (2)n =
16T(1)2n − T
(1)n
15
を求めると、T (2)n =
1
64
B6
6!h6{f (5)(b)− f (5)(a)}+ 21
1024
B8
8!h8{f (7)(b)− f (7)(a)}+ · · ·
と誤差が減少する。T
(0)n = Tn とし、
T (k)n =
4kT(k−1)2n − T
(k−1)n
4k − 1, k = 1, 2, . . .
により、T(k)n を求めることにより、積分 I が計算できる。この方法をロンバーグ積分法という。
6.5.1 ロンバーグ積分のプログラム
1 // romberg.c2 #include "pch.h"
3 #include <iostream>4 #include <stdlib.h>5 #define USE MATH DEFINES6 #include <math.h>7 #define N 108
9 double f(double x);10 double romberg(double a, double b, int n);11 int pow2[2 ∗ N + 1];
6. 定積分の計算(その2) 21
12
13 int14 main(int ac, char ∗ av[])15 {16 double a, b, s;17 int i, n;18
19 n = 1;20 for (i = 0; i <= 2 ∗ N; i++) {21 pow2[i] = n;22 n = 2 ∗ n;23 }24 a = 0;25 b = 1;26 for (i = 2; i <= 7; i++) {27 s = romberg(a, b, i);28 printf("integral = %25.17f\n", s);29 }30 printf("pi / 4 = %25.17f\n", M PI / 4);31 return 0;32 }33
34 double35 romberg(double a, double b, int n)36 {37 double r[N + 1][N + 1];38 double s, y, h;39 int i, j, k;40
41 h = (b − a);42
43 r[1][1] = h ∗ (f(a) + f(b)) / 2;44 for (k = 2; k <= n; k++) {45 s = 0;46 for (i = 1; i <= pow2[k − 2]; i++)47 s = s + f(a + (2 ∗ i − 1) ∗ h / pow2[k − 1]);48 r[k][1] = (r[k − 1][1] + h / pow2[k − 2] ∗ s) / 2;49 }50 for (k = 2; k <= n; k++)51 for (j = 2; j <= k; j++)52 r[k][j] = r[k][j − 1] + (r[k][j − 1] − r[k − 1][j − 1]) / (pow2[2 ∗ j − 2] − 1);53
54 return r[n][n];55 }56
57 double58 f(double x)59 {60 double r;61 r = 1 / (1 + x ∗ x);62 return r;63 }
6.6 課題問題 6.1 ガウス公式を用いて、次の積分の近似値を計算せよ。
(a)
∫ 1
0
1
1 + x2dx (b)
∫ ∞
−∞cos(x)e−x2
dx