無意味なブログ

勉強のこと、趣味のこと、日記など適当に

MENU

微分方程式をプログラムで解こう!(3):差分法[2]「差分法の精度」

前回(第2回)
微分方程式をプログラムで解こう!(2):差分法[1]「sin(x)を微分する」 - 無意味なブログ

前回は関数sin(x)を、3つの差分法を使って微分しました。
今回は分割数nを変化させた時、結果がどう変わるのかみてみます。

差分法の精度

差分法は近似的に解を求める手法です。
そのため、必ず誤差が生まれます。

差分法によって生まれる誤差のオーダーは、テイラー展開を用いることによって調べることができます。
詳しくは以下の記事を参考に。
d.hatena.ne.jp

前回用いた3つの差分法がそれぞれ持つ誤差のオーダー(桁数)は刻み幅hを用いて以下のように書けます。

前進差分の誤差: \mathcal{O}(h)
後退差分の誤差: \mathcal{O}(h)
中心差分の誤差: \mathcal{O}(h^2)

(ここで、 \mathcal{O}() は、式の表す数値の大きさをオーダー(桁数)で表したものです。
例えば上にある \mathcal{O}(h) は、hと同じ桁ぐらいの数であることを示します。)

ここで重要なのが、"中心差分を使った方が、前進差分を使うより、刻み幅を小さくした時、誤差の減少具合が大きい"ということです。
例えば刻み幅hを \frac{1}{2} 倍すると、前進差分による誤差はおよそ \frac{1}{2} 倍され、中心差分による誤差はおよそ \frac{1}{4} 倍されます。

以下の図は関数f(x)=sin(x)を、刻み幅を変えて微分した場合のイメージ図になります。
f:id:kouya17:20170201072715j:plain

図中の"forward"は前進差分の結果、"central"は中心差分の結果を示してます。うん。イメージ図が描きたかっただけです。

差分法の精度を実際に確かめてみる

前回(微分方程式をプログラムで解こう!(2):差分法[1]「sin(x)を微分する」 - 無意味なブログ)
で作成した、sin(x)を微分するプログラムをちょっと変えて、前進差分・後退差分・中心差分の精度を確かめてみます。

今回誤差の評価に用いたプログラムは以下の通りです。

関数f(x)=sin(x)を分割数n=10,20,40,80,160,320,640で微分した時の最大誤差を計算します。
出力ファイルにはlog(刻み幅h)とlog(最大誤差)が出力されます。

結果

横軸にlog(刻み幅h)、縦軸にlog(最大誤差)をとり、結果をプロットします。

f:id:kouya17:20170204045259p:plain

log(刻み幅h)が小さくなるほど、log(最大誤差)が小さくなっています。
また、log(刻み幅h)とlog(最大誤差)は比例の関係にあることがわかります。

結果について線形近似を行うと、近似直線の傾きはそれぞれ以下のようになりました。
前進差分=0.997
後退差分=0.997
中心差分=1.996
この結果から
 ●前進差分・後退差分による最大誤差は刻み幅hにおおよそ比例する。
 ●中心差分による最大誤差は刻み幅hのおおよそ2乗に比例する。
ということがわかります。

今回の結果は先ほど説明した"差分法の誤差のオーダー"を実際に確かめることができた、ということになりますね。
前進差分・後退差分は \mathcal{O}(h) の誤差を持つことから"1次精度"、中心差分は \mathcal{O}(h^2) の誤差を持つことから"2次精度"といいます。
簡単にいうと、中心差分は前進差分や後退差分と比べて誤差を減らしやすい手法なんです。

今回グラフのx軸y軸共にlogを用いていますが、両対数グラフの説明は以下のサイトがわかりやすいです。
mathtrain.jp

まとめ

●差分によって生まれる誤差について説明しました。
●分割数nを変えてsin(x)を微分してみました。その結果、以下のことがわかりました。
 ・前進差分・後退差分による最大誤差は刻み幅hにおおよそ比例する。
 ・中心差分による最大誤差は刻み幅hのおおよそ2乗に比例する。

シリーズ第3回「差分法[2]差分法の精度」は以上です。
次回はより様々な差分法を紹介していきます。