C++で微分を実装してみたので忘備録として記録しておきます。
f′(x)=f(x+Δx)−f(x)Δx
まずは典型的な上記の式の前進差分近似を使った方法で微分をしてみます。
多少は誤差があるものの微分ができました。
関数ポインタを使ってnumericalDiffに微分したい関数を渡しているため、他の式に対しても微分を行うことが可能です。
また、引数epsの値を小さくすることでより精度の高い微分を多なうことができます。
前進差分近似を使うよりも中心差分近似を使った微分の方が誤差が少なくなるみたいですのでそちらも実装していきます。
先ほどのコードからnumericalDiff関数だけ以下の式に合わせて変更していきます。
f′(x)=f(x+Δx)−f(x - Δx)2Δx
中心差分近似を使うことで上記のサンプルに対しては誤差なく微分を行うことができました。
数値微分を実装する
f′(x)=f(x+Δx)−f(x)Δx
まずは典型的な上記の式の前進差分近似を使った方法で微分をしてみます。
#include <iostream>
double func(double x){ return x*x;}
double numericalDiff(double (*f)(double), double x, double eps=0.001){ return (f(x + eps) - f(x)) / eps;}
int main(void){ double (*pfunc)(double); pfunc = func; printf("%lf", numericalDiff(pfunc, 2)); return 0;}
4.001000
多少は誤差があるものの微分ができました。
関数ポインタを使ってnumericalDiffに微分したい関数を渡しているため、他の式に対しても微分を行うことが可能です。
また、引数epsの値を小さくすることでより精度の高い微分を多なうことができます。
誤差の少ない数値微分
前進差分近似を使うよりも中心差分近似を使った微分の方が誤差が少なくなるみたいですのでそちらも実装していきます。
先ほどのコードからnumericalDiff関数だけ以下の式に合わせて変更していきます。
f′(x)=f(x+Δx)−f(x - Δx)2Δx
double numericalDiff(double (*f)(double), double x, double eps=0.001){ return (f(x + eps) - f(x - eps)) / (2*eps);}
4.000000
中心差分近似を使うことで上記のサンプルに対しては誤差なく微分を行うことができました。