
f(a : double ) : double
{
a*a + 3 * a
}
df(a : double ) : double
{
2*a + 3
}
明らかに、少なくともコードfとdfは機能的に依存しており、おそらく機能の重複が見られます。 派生物の定義を思い出して、それに応じてdfコードを修正すれば、状況を修正できます。
df(a : double ) : double
{
def delta = 0.1;
(f(a+delta)-f(a))/delta
}
この場合、機能の重複を取り除きましたが、デルタパラメーターに最適な値がないため、プログラムの精度は支払われました。
真面目なエンジニアは、たとえばmatlabでプログラミングし、お気に入りのプログラミング言語にさらにコードを生成することで、この問題を解決できます。 しかし、コード生成は悪であるという意見があるため、別の方法について説明します。
虚数単位iは、方程式x 2 +1 = 0の解であると仮定されます。類推により、方程式x 2 = 0を解き、ゼロに等しくない別の虚数単位dを導入します。 次に、テイラー級数の関数の展開を思い出してください。

虚数単位をhに置き換え、d 2 = 0という事実を使用すると、次のようになります。

したがって、点xで関数fの導関数の値を見つけるには、数fの虚数部(x + d)の係数を取得すれば十分です。 現代の言語では、複素数を扱うクラスを定義することは問題ではありません。これらの拡張数を扱うクラスを簡単に定義できます。 次の例は、Nemerleに翻訳されています。
public class Dual
{
public this (real : double , imaginary : double )
{
this .real = real;
this .imaginary = imaginary;
}
real : double ;
imaginary : double ;
public Real : double { get { real } }
public Imaginary : double { get { imaginary } }
public static @+(a : Dual, b : Dual) : Dual
{
Dual(a.real + b.real, a.imaginary + b.imaginary)
}
public static @-(a : Dual, b : Dual) : Dual
{
Dual(a.real - b.real, a.imaginary - b.imaginary)
}
public static @*(a : Dual, b : Dual) : Dual
{
Dual(a.real * b.real, a.real * b.imaginary + a.imaginary * b.real)
}
public static @/(a : Dual, b : Dual) : Dual
{
a*Dual(1/b.real, - b.imaginary / (b.real*b.real))
}
public static @:(k : double ) : Dual
{
Dual(k,0)
}
}
これで、記事の冒頭から例を書き換えることができます。
f(a : Dual) : Dual
{
a*a + 3.0 * a
}
f(a : double ) : double
{
f(Dual(a,0)).Real
}
df(a : double ) : double
{
f(Dual(a,1)).Imaginary
}
もちろん、派生物のコードは無料で入手できます。 このアプローチの短所は、2進数を扱うために基本関数を再定義する必要があることですが、得られた式のおかげで難しくありません。正弦過負荷は以下のとおりです。
public Sin(a : Dual) : Dual
{
Dual( Math .Sin(a.Real), Math .Cos(a.Real)*a.Imaginary)
}
もっと欲しい:
自動差別化 | |
二重番号 | |
自動差別化 | |
![]() | 自動ディエンティフィケーション、C ++テンプレートおよび
写真測量 |
ネメルル |
コンピューターサイエンスのブログを作成して、この投稿を投稿したかったのですが、ハブで一時的に新しいブログを作成できないことを願っています。そのため、「異常なプログラミング」ブログに掲載しました。 Computer Scienceブログは、言い換え、翻訳、Computer Scienceの定義に該当する記事の注釈、pdfへのリンクなどを書くことができる場所になる予定でした。 このブログで記事を書きたい人は誰でも、そのオープンを待つのではなく、「コンピューターサイエンスへ」というタグを付けて「異常なプログラミング」で書くことをお勧めします。