C# と F# の間で自動微分を機能させるのに問題があります。
C# には、double を受け取って double を返す関数があります。
private double Price(double yield)
{
double price;
price = 0;
for (int index = 1; index <= _maturity * _frequency; index++)
{
price += (_coupon / _frequency) * _nominal / Math.Pow(1 + (yield / _frequency), index);
}
price += _nominal / Math.Pow(1 + (yield / _frequency), _maturity * _frequency);
return price;
}
Math.pow は非常に厳しく、そのパラメーターには double または int のみを許可するため、この関数を具体的に選択しました。
この関数を自動微分で微分したいと思います。このためのメソッドを F# で記述しました。
type Diff(d : double, df : Lazy<Diff>) = class
member x.d = d
member x.df = df
static member (+) (x : Diff, y : Diff) =
Diff(x.d + y.d, lazy (x.df.Value + y.df.Value))
static member (-) (x : Diff, y : Diff) =
Diff(x.d - y.d, lazy (x.df.Value - y.df.Value))
static member (*) (x : Diff, a : double) =
Diff(x.d * a, lazy (x.df.Value * a))
static member (*) (x : Diff, y : Diff) =
Diff(x.d * y.d, lazy ((x.df.Value * y) + (y.df.Value * x)))
override x.ToString() =
x.d.ToString()
end
let rec dZero = Diff(0.0, lazy dZero)
let dConst x = Diff(x, lazy dZero)
let dId x = Diff(x, lazy dConst 1.0)
let Differentiate (x:Diff) = x.df.Value
// Example function
let f (x:Diff) = x*x*x;
// Example usage:
// (f (dId 5)).ToString = "125"
// (Differentiate (f (dId 5))).ToString = "75"
// (Differentiate (Differentate (f (dId 5)))).ToString = "30"
残念ながら、タイプ Diff を Price(..) 関数に入力してタイプ Diff を生成する必要があります。次に、このタイプを Differente(..) 関数に入力して、別のタイプ Diff を返します。
ただし、私の C# 関数は double でのみ機能します (C# プログラムの他の場所で使用されているため、このままにしておきたいと思います)。
これを解決するために考えることができる唯一の方法は、すべての関数を 2 回記述することです。これは明らかにひどいものです。
1) 毎回差別化されたバージョンを書いたほうがいいかもしれません 2) これはあまり拡張可能なモデルではありません
これを回避する方法、または double 関数を Diff 関数 (できれば F#) に強制する方法はありますか。理想的には、(double -> double) 関数をスローして Diff.ToString() を取得したいだけです。
これが完全に曖昧であるか、理解できない場合は申し訳ありません。不明な点があればコメントで質問にお答えします。
これに対する解決策があることを願っています!前もって感謝します、
アシュリー