読者です 読者をやめる 読者になる 読者になる

猫尾製作所

あまりアテにしないでね

数値微分(その3)

数学 数値計算

数値微分について、いちばん簡単に見える手法を示させていただきます。

今、仮にいたるところで連続である関数  f(x) を想定します。

そもそも、 f(x) x = a における微分係数  f'(a) は数学的に次のように定義されるところでした。

 f'(a) = \lim_{h \to 0} \frac{f(a+h) - f(a)}{h}

極限をとっているので、 h は限りなく 0 に近づくのですが 0 にはならないということで、なかなか理解が難しいところではないかと思われます。ここで、 h = 0 としてしまっては、分母も分子も 0 になってしまうのですが、では限りなく 0 とは何かと問いかけたくもなります。

これを説明するのは難儀です。しかし、今回は数値計算のはなしをしているのです。計算機上で数値として記録されている実数は、実数といえど数学的にみれば有理数の真部分集合に過ぎず、離散的なものなのです。計算機上で表現可能な実数の集合の大きさは有限なのです。ですので、0 ではないが 0 にいちばん近い実数というのは、数学的には存在しないのですが、計算機上では存在するのです。いくらでも小さい実数を作り出すことは計算機上では不可能なのです。

さて、 f(x) が与えられているとします。これは数式の形でもよいのですが、プログラミング言語において引数及び戻り値がいずれも実数型の形であたえられる関数やメソッドでもかまいません。

この  f(x) x = a における微分係数  f'(a) を求めたいのですが、次のような操作でかなり精密な微分係数の値を与えることが可能になります。

微小量  \Delta x に対して  \Delta f = f(x + \Delta x) - f(x) として、 \frac{\Delta f}{\Delta x} の値を求めることです。これは先ほど述べた導関数の計算式と対応しております。ただし、 \Delta は 0.1 だとか 0.01 だとか(関数のスケールにもよりますが)具体的な微小量を代入して求めます。

では、具体的に その1 で使った関数  f(x) = \ln (x^2 + 1) - \exp (\sin x) を例に  f'(0) の値を数値計算してみましょう。精密な値は  f(0) = -1,  f'(0) = -1 でしたが、今回は計算機のたとえばプログラムの中にこの関数の数式が定義されている、すなわちコンピュータ上の実数からコンピュータ上の実数への関数値の近似計算の形として与えられているものとします。

Δx f(0 + Δx) f(0 + Δx) - f(0) 求められる微分係数
1 -1.62662964415591 -0.626629644155908 -0.626629644155908
1 / 4 -1.22007173562774 -0.220071735627740 -0.880286942510960
1 / 16 -1.06055251345172 -0.060552513451716 -0.968840215227463
1 / 64 -1.01550295197225 -0.015502951972245 -0.992188926223733
1 / 256 -1.00389862069272 -0.003898620692718 -0.998046897335939
1 / 1024 -1.00097608566318 -0.000976085663182 -0.999511719099246
1 / 4096 -1.00024411082268 -0.000244110822678 -0.999877929692957
1 / 16384 -1.00006103329360 -0.000061033293604 -0.999969482421875
1 / 65536 -1.00001525867265 -0.000015258672647 -0.999992370605469
1 / 262144 -1.00000381468999 -0.000003814689989 -0.999998092651367
1 / 1048576 -1.00000095367386 -0.000000953673861 -0.999999523162842
1 / 4194304 -1.00000023841855 -0.000000238418550 -0.999999880790710
1 / 16777216 -1.00000005960464 -0.000000059604642 -0.999999970197678
1 / 67108864 -1.00000001490116 -0.000000014901160 -0.999999985098839
1 / 268435456 -1.00000000372529 -0.000000003725290 -1.000000000000000
1 / 1073741824 -1.00000000093132 -0.000000000931322 -1.000000000000000
1 / 4294967296 -1.00000000023283 -0.000000000232830 -1.000000000000000

より正確に求めたければ、(右からの極限)と(左からの極限)の平均をとるという方法があります。すなわち、

 \Delta f_{+} = f(x + \Delta x) - f(x)
 \Delta f_{-} = f(x) - f(x - \Delta x)

として、

 \frac{\frac{\Delta f_{+}}{\Delta x} + \frac{\Delta f_{-}}{\Delta x}}{2}
 = \frac{\Delta f_{+} - \Delta f_{-}}{2 \Delta x}
 = \frac{f(x + \Delta x) - f(x) + f(x) - f(x - \Delta x)}{2 \Delta x}
 = \frac{f(x + \Delta x) - f(x - \Delta x)}{2 \Delta x}

とします。

次回はプログラミング言語でもって、これを記述・実装してみます。