離散的で高速な方法を使用して導関数を計算する方法を探しています。方程式の種類がわからないので、オイラー法などの積分に類似した離散的な方法を探しています。
10 に答える
ポイントで計算された導関数を探していると思います。その場合、簡単な方法があります。点の導関数を知る必要があります。これは、h->0 の差分商の極限によって与えられます。
実際には limit 関数を実装する必要があります。だからあなた:
- イプシロンを定義し、より正確にするにはより小さく、より速くするにはより大きく設定します
- 開始 h の差分商を計算します。h=0.01 と仮定し、それをf1に格納します。
DO-WHILE ループでは、次のようになります。
1- h を 2 で割ります (または 10 で割る、重要なことはそれを小さくすることです)
2- h の新しい値で差分商を再度計算し、これをf2
に格納します 3- diff = abs(f2-f1) を
設定します 4 - 割り当てf1 = f2
5- ポイント 1 から繰り返す(diff>epsilon)- 最後に、f'(a) の値として f1 (または f2) を返すことができます。
覚えておいてください: 関数が a で微分可能であると仮定しています。コンピューターが処理できる有限の 10 進数のエラーのために、得られるすべての結果は間違っています。これから逃れることはできません。
Python での例:
def derive(f, a, h=0.01, epsilon = 1e-7):
f1 = (f(a+h)-f(a))/h
while True: # DO-WHILE
h /= 2.
f2 = (f(a+h)-f(a))/h
diff = abs(f2-f1)
f1 = f2
if diff<epsilon: break
return f2
print "derivatives in x=0"
print "x^2: \t\t %.6f" % derive(lambda x: x**2,0)
print "x:\t\t %.6f" % derive(lambda x: x,0)
print "(x-1)^2:\t %.6f" % derive(lambda x: (x-1)**2,0)
print "\n\nReal values:"
print derive(lambda x: x**2,0)
print derive(lambda x: x,0)
print derive(lambda x: (x-1)**2,0)
出力:
derivatives in x=0
x^2: 0.000000
x: 1.000000
(x-1)^2: -2.000000
Real values:
7.62939453125e-08
1.0
-1.99999992328
結果の最初の 6 桁のみを使用したため、「正確な」値を初めて取得したときは、イプシロンとして 1e-7 を使用したことに注意してください。その後、REAL の計算値が出力されますが、明らかに数学的に間違っています。どの程度小さいイプシロンを選択するかは、結果をどれだけ正確にしたいかによって異なります。
数値 (「有限」) 導関数の計算には、かなりの理論 (および確立された実践) があります。結果を信じられるように、すべての詳細を正しくすることは簡単ではありません。(ペンと紙、またはMaple、Mathematica、Sage、またはSymPyなどのコンピューター代数システムを使用して) 関数の解析的な導関数を取得できる方法がある場合、これが断然最良のオプションです。
解析形式を取得できない場合、または関数がわからない場合 (単に出力である場合)、数値推定が唯一の選択肢です。C での数値レシピのこの章は良い出発点です。
簡単な方法は、関心のある導関数の各点の小さな値に対する f の変化を計算することです。たとえば、∂f/∂x を計算するには、次のように使用できます。
epsilon = 1e-8
∂f/∂x(x, y, z) = (f(x+epsilon,y,z) - f(x-epsilon, y, z))/(epsilon * 2);
他のパーシャルは y と z で同様です。
イプシロンに選択される値は、f の内容、必要な精度、使用される浮動小数点型、およびおそらくその他の要素によって異なります。興味のある関数でその値を試してみることをお勧めします。
自動微分は、この種のことを行う最も正確で概念的に優れた方法です。もう少し複雑です。
Maple のような記号的な数学言語を使用しない限り、できる最善の方法は、さまざまな点で導関数を近似することです。(そして、関数が必要な場合は補間します。)
使用したい関数が既にある場合は、誤差を改善するために後方除算差分法とリチャードソン外挿法を使用する必要があります。
また、これらのメソッドは 1 つの変数の関数で機能することにも注意してください。ただし、各変数の偏導関数は、他の変数を定数として扱います。
正式には、いいえ。離散関数の (部分) 導関数を記述しているか、連続関数の (部分) 導関数を近似する数値法を求めています。
離散関数には導関数がありません。導関数のイプシロン デルタ定義を確認すると、導関数が必要なポイントに近い関数を評価できる必要があることがわかります。関数が x、y、z の整数値の値しか持たない場合、これは意味がありません。したがって、fast の任意の値に対して離散関数の導関数を見つける方法はありません。
数値法で連続関数の微分を正確に計算したい場合も、運が悪いです。導関数の数値的方法は、アルゴリズムではなくヒューリスティックです。正確な解を保証する数値的方法はありません。幸いなことに、多くの優れたヒューリスティックが存在します。Mathematica はデフォルトでブレントの主軸法の特別なバージョンを使用する.ブレントの方法を非常にうまく実装しているGNU Scientific Libraryを使用することをお勧めします。私は自分の数学コースの 1 つの成績をすべて GSL に負っています。それがあなたのものなら、ルビーバインディングはかなり良いです。必要に応じて、ほとんどの数値微分ライブラリには、いくつかの異なるメソッドが用意されています。
本当に必要な場合は、サンプル コードを作成できます。お知らせ下さい。
これが数値微分に役立つことを願っています。
あなたが示したように関数が線形である場合、導関数は自明です。「x」に関する導関数は「a」です。'y' に関する導関数は 'b' であり、'z' に関する導関数は 'c' です。方程式がより複雑な形式であり、経験的な解ではなく解を表す式が必要な場合は、より複雑な形式の方程式を提出してください。
よろしく