「ルンゲ=クッタ法」の版間の差分

次数の説明、ルンゲ゠クッタ゠ギル法、細部の修正
m (脱字修正・重複除去・文法的修正・英単語補足)
(次数の説明、ルンゲ゠クッタ゠ギル法、細部の修正)
{{出典の明記|date=2015年11月}}
'''ルンゲ=クッタ法'''({{lang-en-short|Runge–Kutta method}})とは、[[数値解析]]において[[微分方程式]]の初期値問題に対して近似解を求め与える一連の方法である。この技法は1900年頃に数学者[[カール・ルンゲ]]と{{日本語版にない記事リンク|マルティン・ヴィルヘルム・クッタ|en|Martin Wilhelm Kutta}}によって発展された。
 
== 古典的ルンゲ=クッタ法 ==
 
== ルンゲ゠クッタ法 ==
前述の RK4 の一般化として、以下の形式を持つ ''s'' 段のルンゲ゠クッタ法を構成することができる。整数 ''s'' をそのルンゲ゠クッタ法の'''段数''' (stage) という
 
:<math> y_{n+1} = y_n + h\sum_{i=1}^s b_i k_i, </math>
:(文献によって、等価であるが上と異なる定義の仕方をしているものがあることに注意する。)
 
具体的なルンゲ゠クッタ公式は、目的の次数 ''p'' を解ができるだけ高い精度持つように適切に選ばれた係数 ''a''<sub>''ij''</sub> ('''ルンゲ゠クッタ行列''')、''b''<sub>''i''</sub> ('''重み''')、''c''<sub>''i''</sub> ('''節点''') で指定される (但し、1 ≤ ''ji'' <, ''ij'' ≤ ''s'')。特に ''i'' ≤ ''j'' に対して ''a''<sub>''ij''</sub>=0 満たされている方法が広く用いられ、総称して '''陽的ルンゲ゠クッタ法''' (ERK、{{lang-en-short|explicit Runge&ndash;Kutta methods}}) と呼ぶ。そうでないものを '''陰的ルンゲ゠クッタ法''' (IRK、{{lang-en-short|implicit Runge&ndash;Kutta methods}}) と呼ぶ。
 
ルンゲ゠クッタ法が次数近似値 ''py''<sub>''n''</sub> の精度持つため ''y''<sub>''n''+1</sub> から計算するときは、切断発生する誤差の大きさが ''O''(''h''<sup>''p''+1</sup>) なるき、そのルンゲ゠クッタ公式は ''p'' 次精度を持つといい、''p'' を '''次数''' (まめに係は '''位''') と呼ぶ。''p'' 次のルンゲ゠クッタ公式は、誤差の大きさの条件が課される。切断誤差自体定義から具体的な表式を代入し、係数の条件を求めることによって得られる。例えば、2 段の陽的方法が2次精度を持つための係数に対する条件は、''b''<sub>1</sub> + ''b''<sub>2</sub> = 1, ''b''<sub>2</sub>''c''<sub>2</sub> = 1/2, かつ ''b''<sub>2</sub>''a''<sub>21</sub> = 1/2 である。この条件を満たす範囲内で様々な方法を考え得る。
 
これらの係数を分かりやすく表記する方法として、以下のような形式の'''ブッチャー配列''' (''Butcher tableau'') が知られている:
\end{align}</math>
 
実際には、それぞれのルンゲ゠クッタ法に対しついて各要素に具体的な値を入れて用いる。陽的な方法ではルンゲ゠クッタ行列の上三角成分は常に 0 になるので表記を省略する。例えば RK4 はブッチャー配列を用いて以下のように表現される。
 
:<math>\begin{align}
 
:<math>\sum_{j=1}^{s} a_{ij} = c_i\ \mathrm{for}\ i=1, \ldots, s.</math>
 
ルンゲ゠クッタ法が次数 ''p'' の精度を持つためには、切断誤差が ''O''(''h''<sup>''p''+1</sup>) となるために係数に条件が課される。切断誤差自体の定義から具体的な条件が得られる。例えば、2 段の陽的方法が2次精度を持つための係数に対する条件は、''b''<sub>1</sub> + ''b''<sub>2</sub> = 1, ''b''<sub>2</sub>''c''<sub>2</sub> = 1/2, かつ ''b''<sub>2</sub>''a''<sub>21</sub> = 1/2 である。この条件を満たす範囲内で様々な方法を考え得る。
 
== 陽的ルンゲ゠クッタ法 ==
 
 
''α'' = 1/2 の場合が'''中点法''' ('''修正改良オイラー法''')
:<math> y_{n+1} = y_n + hf\left(t_n+\frac{h}{2},y_n+\frac{h}{2}f(t_n, y_n)\right)</math>
に対応し、以下のブッチャー配列で与えられる。
 
 
''α'' = 1 の場合は'''ホイン法''' ('''修正オイラー法''')として知られ、ブッチャー配列は以下の通りである。
{| cellpadding=3px cellspacing=0px
|width="20px"| || style="border-right:1px solid;" | 0
 
 
修正版として '''Kutta クッタの3/8公式''' ({{lang-en-short|Kutta's 8/3-rule}}) が知られている。
{| cellpadding=3px cellspacing=0px
|width="20px"| || style="border-right:1px solid;" | 0
||| style="border-right:1px solid;" | || 1/8 || 3/8 || 3/8 || 1/8
|}
 
 
対象の変数 ''y'' が多成分の巨大なベクトルの場合、計算機上で記憶するデータ量が最小で済むように構成された '''ルンゲ゠クッタ゠ギル法''' ({{lang-en-short|Runge&ndash;Kutta&ndash;Gill method}}) も用いられる。
{| cellpadding=3px cellspacing=0px
|width="20px"| || style="border-right:1px solid;" | 0
|-
||| style="border-right:1px solid;" | 1/2 || style="text-align:center;" | 1/2
|-
||| style="border-right:1px solid;" | 1/2 || style="text-align:center;" | 1/2 - ''α''<sub>-</sub> || style="text-align:center;"| ''α''<sub>-</sub>
|-
||| style="border-right:1px solid; border-bottom:1px solid;" | 1 || style="border-bottom:1px solid;text-align:center;" | 0
| style="border-bottom:1px solid;text-align:center;" | 1 - ''α''<sub>+</sub> || style="border-bottom:1px solid;" | ''α''<sub>+</sub>
| style="border-bottom:1px solid;" |
|-
||| style="border-right:1px solid;" | || style="text-align:center;" | 1/6 || style="text-align:center;" | ''α''<sub>-</sub>/3 || ''α''<sub>+</sub>/3 || 1/6
|}
但し、''α''<sub>±</sub> = 1 ± 1/√2 である。以下の手順で計算することにより、記録領域を3ベクトル (''y'', ''k'', ''q'') に収めることができる (RK4 や 3/8 公式では少なくとも4ベクトル必要になる)。但し、初期状態として ''y'' に ''y''<sub>n</sub> が保持されているとし、この手順により ''y'' に次の値 ''y''<sub>n+1</sub> が設定される。
# ''k'' ← ''h'' ''f'' (''x'', ''y''),
# (''y'', ''q'') ← (''y'' + ''k''/2, ''k''),
# ''k'' ← ''h'' ''f'' (''x'' + ''h''/2, ''y''),
# (''y'', ''q'') ← (''y'' + ''α''<sub>-</sub> (''k'' - ''q''), ''q'' + ''α''<sub>-</sub> (2 ''k'' - 3 ''q'')),
# ''k'' ← ''h'' ''f'' (''x'' + ''h''/2, ''y''),
# (''y'', ''q'') ← (''y'' + ''α''<sub>+</sub> (''k'' - ''q''), ''q'' + ''α''<sub>+</sub> (2 ''k'' - 3 ''q'')),
# ''k'' ← ''h'' ''f'' (''x'' + ''h'', ''y''),
# (''y'', ''q'') ← (''y'' + (1/6)(''k'' - 2 ''q''), 0).
 
== 誤差と収束性 ==
60

回編集