C#和F中的自动微分#
我遇到了一个问题,无法在C和F之间进行自动区分 在C#中,我有一个函数,它接受一个double并返回一个double,比如:C#和F中的自动微分#,c#,f#,automatic-differentiation,C#,F#,Automatic Differentiation,我遇到了一个问题,无法在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)
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;
}
私人双价(双收益)
{
双倍价格;
价格=0;
对于(int index=1;index无法使用现有的C#函数,也没有任何简单的方法将其提升到可以在Diff
类型的成员上操作的函数。一旦编译了函数,它就不透明,内部结构不可用;您所能做的就是使用双参数调用该函数并获得一个doubl此外,您的Price
方法使用了您甚至没有在Diff
类中定义的操作((\)
和Pow
)
我不确定它是否符合您的目的,但一种可能的替代方法是在F#中编写Price
函数的通用内联版本,然后可以在double或Diff
s上运行(假设您添加(\)
和Pow
操作符).没有办法使用现有的C#函数,也没有任何简单的方法将其提升到可以在Diff
类型的成员上操作的函数。一旦编译了该函数,它是不透明的,并且内部结构不可用;您所能做的就是使用双参数调用该函数并获得双结果。此外更重要的是,您的Price
方法使用了您甚至没有在Diff
类中定义的操作((\)
和Pow
)
我不确定它是否符合您的目的,但一种可能的替代方法是在F#中编写Price
函数的通用内联版本,然后可以在double或Diff
s上运行(假设您添加(\)
和Pow
操作符).您可以重新发明Haskell类型的类:
interface Eq<T>
{
bool Equal(T a, T b);
bool NotEqual(T a, T b);
}
interface Num<T> : Eq<T>
{
T Zero { get; }
T Add(T a, T b);
T Subtract(T a, T b);
T Multiply(T a, T b);
T Negate(T a);
}
sealed class Int : Num<int>
{
public static readonly Int Instance = new Int();
private Int() { }
public bool Equal(int a, int b) { return a == b; }
public bool NotEqual(int a, int b) { return a != b; }
public int Zero { get { return 0; } }
public int Add(int a, int b) { return a + b; }
public int Subtract(int a, int b) { return a - b; }
public int Multiply(int a, int b) { return a * b; }
public int Negate(int a) { return -a; }
}
接口均衡
{
布尔相等(ta,tb);
bool-NotEqual(ta,tb);
}
接口编号:Eq
{
T零{get;}
T添加(T a,T b);
T减去(ta,tb);
T乘(ta,tb);
T否定(ta);
}
密封类Int:Num
{
public static readonly Int Instance=new Int();
私有Int(){}
公共布尔等于(inta,intb){返回a==b;}
公共bool NotEqual(inta,intb){返回a!=b;}
public int Zero{get{return 0;}}
公共整数加法(整数a,整数b){返回a+b;}
公共整数减法(整数a,整数b){返回a-b;}
公共整数乘法(整数a,整数b){返回a*b;}
公共int否定(int a){return-a;}
}
然后你可以做:
static T F<M, T>(M m, T x) where M : Num<T>
{
return m.Multiply(x, m.Multiply(x, x));
}
static void Main(string[] args)
{
Console.WriteLine(F(Int.Instance, 5)); // prints "125"
}
静态tf(M,tx),其中M:Num
{
返回m.Multiply(x,m.Multiply(x,x));
}
静态void Main(字符串[]参数)
{
Console.WriteLine(F(Int.Instance,5));//打印“125”
}
然后是:
class Diff
{
public readonly double d;
public readonly Lazy<Diff> df;
public Diff(double d, Lazy<Diff> df)
{
this.d = d;
this.df = df;
}
}
class DiffClass : Floating<Diff>
{
public static readonly DiffClass Instance = new DiffClass();
private static readonly Diff zero = new Diff(0.0, new Lazy<Diff>(() => DiffClass.zero));
private DiffClass() { }
public Diff Zero { get { return zero; } }
public Diff Add(Diff a, Diff b) { return new Diff(a.d + b.d, new Lazy<Diff>(() => Add(a.df.Value, b.df.Value))); }
public Diff Subtract(Diff a, Diff b) { return new Diff(a.d - b.d, new Lazy<Diff>(() => Subtract(a.df.Value, b.df.Value))); }
public Diff Multiply(Diff a, Diff b) { return new Diff(a.d * b.d, new Lazy<Diff>(() => Add(Multiply(a.df.Value, b), Multiply(b.df.Value, a)))); }
...
}
类差异
{
公共只读双d;
公共只读文件;
公共差异(双d,延迟df)
{
这个。d=d;
this.df=df;
}
}
类别:浮动
{
公共静态只读DiffClass实例=新建DiffClass();
private static readonly Diff zero=new Diff(0.0,new Lazy(()=>DiffClass.zero));
私有DiffClass(){}
public Diff Zero{get{return Zero;}}
public Diff Add(Diff a,Diff b){返回新的Diff(a.d+b.d,new Lazy(()=>Add(a.df.Value,b.df.Value));}
public Diff Subtract(Diff a,Diff b){返回新的Diff(a.d-b.d,new Lazy(()=>Subtract(a.df.Value,b.df.Value));}
public Diff Multiply(Diff a,Diff b){返回新的Diff(a.d*b.d,new Lazy(()=>Add(Multiply(a.df.Value,b),Multiply(b.df.Value,a));}
...
}
您可以这样做:
static T Price<M, T>(M m, T _maturity, T _frequency, T _coupon, T _nominal, T yield) where M : Floating<T>
{
T price;
price = m.Zero;
for (T index = m.Succ(m.Zero); m.Compare(index, m.Multiply(_maturity, _frequency)) <= 0; index = m.Succ(index))
{
price = m.Add(price, m.Divide(m.Multiply(m.Divide(_coupon, _frequency), _nominal), m.Power(m.Add(m.Succ(m.Zero), m.Divide(yield, _frequency)), index)));
}
price = m.Add(price, m.Divide(_nominal, m.Power(m.Add(m.Succ(m.Zero), m.Divide(yield, _frequency)), m.Multiply(_maturity, _frequency))));
return price;
}
静态T价格(M M,T U到期日,T U频率,T U息票,T U名义,T收益率),其中M:浮动
{
T价格;
价格=零米;
对于(T index=m.Succ(m.Zero);m.Compare(index,m.Multiply(_-maturity,_-frequency))您可以重新创建Haskell类型的类:
interface Eq<T>
{
bool Equal(T a, T b);
bool NotEqual(T a, T b);
}
interface Num<T> : Eq<T>
{
T Zero { get; }
T Add(T a, T b);
T Subtract(T a, T b);
T Multiply(T a, T b);
T Negate(T a);
}
sealed class Int : Num<int>
{
public static readonly Int Instance = new Int();
private Int() { }
public bool Equal(int a, int b) { return a == b; }
public bool NotEqual(int a, int b) { return a != b; }
public int Zero { get { return 0; } }
public int Add(int a, int b) { return a + b; }
public int Subtract(int a, int b) { return a - b; }
public int Multiply(int a, int b) { return a * b; }
public int Negate(int a) { return -a; }
}
接口均衡
{
布尔相等(ta,tb);
bool-NotEqual(ta,tb);
}
接口编号:Eq
{
T零{get;}
T添加(T a,T b);
T减去(ta,tb);
T乘(ta,tb);
T否定(ta);
}
密封类Int:Num
{
public static readonly Int Instance=new Int();
私有Int(){}
公共布尔等于(inta,intb){返回a==b;}
公共bool NotEqual(inta,intb){返回a!=b;}
public int Zero{get{return 0;}}
公共整数加法(整数a,整数b){返回a+b;}
公共整数减法(整数a,整数b){返回a-b;}
公共整数乘法(整数a,整数b){返回a*b;}
公共int否定(int a){return-a;}
}
然后你可以做:
static T F<M, T>(M m, T x) where M : Num<T>
{
return m.Multiply(x, m.Multiply(x, x));
}
static void Main(string[] args)
{
Console.WriteLine(F(Int.Instance, 5)); // prints "125"
}
静态tf(M,tx),其中M:Num
{
返回m.Multiply(x,m.Multiply(x,x));
}
静态void Main(字符串[]参数)
{
Console.WriteLine(F(Int.Instance,5));//打印“125”
}
然后是:
class Diff
{
public readonly double d;
public readonly Lazy<Diff> df;
public Diff(double d, Lazy<Diff> df)
{
this.d = d;
this.df = df;
}
}
class DiffClass : Floating<Diff>
{
public static readonly DiffClass Instance = new DiffClass();
private static readonly Diff zero = new Diff(0.0, new Lazy<Diff>(() => DiffClass.zero));
private DiffClass() { }
public Diff Zero { get { return zero; } }
public Diff Add(Diff a, Diff b) { return new Diff(a.d + b.d, new Lazy<Diff>(() => Add(a.df.Value, b.df.Value))); }
public Diff Subtract(Diff a, Diff b) { return new Diff(a.d - b.d, new Lazy<Diff>(() => Subtract(a.df.Value, b.df.Value))); }
public Diff Multiply(Diff a, Diff b) { return new Diff(a.d * b.d, new Lazy<Diff>(() => Add(Multiply(a.df.Value, b), Multiply(b.df.Value, a)))); }
...
}
类差异
{
公共只读双d;
公共只读文件;
公共差异(双d,延迟df)
{
这个。d=d;
this.df=df;
}
}
类别:浮动
{
公共静态只读DiffClass实例=新建DiffClass();
private static readonly Diff zero=new Diff(0.0,new Lazy(()=>DiffClass.zero));
私有DiffClass(){}
public Diff Zero{get{return Zero;}}
public Diff Add(Diff a,Diff b){返回新的Diff(a.d+b.d,new Lazy(()=>Add(a.df.Value,b.df.Value));}
public Diff Subtract(Diff a,Diff b){返回新的Diff(a.d-b.d,new Lazy(()=>Subtract(a.df.Value,b.df.Value));}
public Diff Multiply(Diff a,Diff b){返回新的Diff(a.d*b.d,new Lazy(()=>Add(Multiply(a.df.Value,b),Multiply(b.df.Value,a));}
...
}
您可以这样做:
static T Price<M, T>(M m, T _maturity, T _frequency, T _coupon, T _nominal, T yield) where M : Floating<T>
{
T price;
price = m.Zero;
for (T index = m.Succ(m.Zero); m.Compare(index, m.Multiply(_maturity, _frequency)) <= 0; index = m.Succ(index))
{
price = m.Add(price, m.Divide(m.Multiply(m.Divide(_coupon, _frequency), _nominal), m.Power(m.Add(m.Succ(m.Zero), m.Divide(yield, _frequency)), index)));
}
price = m.Add(price, m.Divide(_nominal, m.Power(m.Add(m.Succ(m.Zero), m.Divide(yield, _frequency)), m.Multiply(_maturity, _frequency))));
return price;
}
静态T价格(M M,T U到期日,T U频率,T U息票,T U名义,T收益率),其中M:浮动
{
T价格;
价格=零米;
对于(T指数=m