У меня возникла проблема с автоматическим дифференцированием для работы между C# и F #.Автоматическое дифференцирование в C# и F #
В C# У меня есть функция, которая принимает двойную и возвращает двойные, скажет:
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 очень запретительный, и только позволяет дубль или 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 в моей Цена функция (..) для получения типа Diff, которая затем подается в мой Differente (..), чтобы возвращать другой тип Diff.
Моя функция C#, однако, работает исключительно на двухместных (и я бы хотел, чтобы она оставалась таким образом, поскольку она используется в других местах моей программы на C#).
Единственный способ, которым я могу думать, чтобы решить эту проблему, чтобы написать каждую функцию в два раза, что, очевидно, ужасно, как:
1) Я могу также просто написать дифференцированной версию каждый раз 2) Это не очень расширяемая модель
Так можно ли обойти это, или, возможно, принудить мои двойные функции к функциям Diff (желательно в F #). В идеале я просто хотел бы бросить (double -> double) функцию и получить Diff.ToString().
Извините, если это полностью расплывчато или невозможно понять. Я отвечу на любые вопросы в комментариях, если это неясно.
Надеюсь, что есть решение! Спасибо заранее,
Эшли
Я не уверен, что понимаю, что вы просите здесь. Если я правильно прочитал ваш вопрос, кажется, вы хотите использовать свой метод «Цена» (немодифицированный), поскольку вы используете свою примерную функцию 'f'. Но 'f' использует ваши пользовательские операторы, а метод C#, работающий в двойных рядах, всегда будет использовать операторы' double'. – dtb
Заметим, что если вас интересует только численное значение производной и нет символьного термина, просто используйте формулу аппроксимации: 'f '(x) = (f (x + h) -f (x))/h' для небольшого 'h' – Dario
@dtb Да, вы точно верны. В идеале я хотел бы использовать transform/coerce для параметров функций, чтобы получить их от двойного до Diff. – Ash