我有一个数值分析程序,为简单起见计算类似于以下算法:
y = ax^3 + bx^2 + cx + d;
我在运行时计算a,b,c,d的值,并希望将以下等价物作为Func<double, double>
传递。我可以在哪里设置X的值,并获得Y.
y = 12x^3 + 13x^2 + 14x + 15;
其中12,13,14,15是在运行时计算的数字。
我意识到这可以通过传入双数组来完成,如下所示:Func<double[], double>
但我试图避免传递常数(可能很多)。
有没有办法在运行时在func中设置这些数字?
(优选不计算func&lt;&gt;本身的a,b,c,d部分?a,b,c,d的计算是工作的80%)
E.g:
a = ...
b = ...
c = ...
Func<x, double> {
((const)a) * x^3 + ((const)b) * x^2 + ((const)c) * x + 15;
}`
对于ABCD的每次评估 - 我将评估10 x。
答案 0 :(得分:11)
我不确定我是否理解你的要求,但你可以尝试这样的事情吗?
Func<double, double> CreateCalculationFunc()
{
double a = heavy calculation;
double b = heavy calculation;
double c = heavy calculation;
double d = heavy calculation;
Func<double, double> calculation = (x) =>
{
// You can use the constants in here without passing them as parameters
return x * (a * b / c - d);
};
return calculation;
}
在这种情况下,您只需调用CreateCalculationFunc()
,这将进行一次繁重的计算,并返回可重复使用的Func<double,double>
进行变量计算。
当然,这可以扩展到任何数量的预先计算的常量和多个变量。
答案 1 :(得分:2)
无法创建包含计算(Func<double,double>
)方法的类,该方法具有“常量”的属性。然后设置属性并使用Calculate
方法的引用作为Func<double,double>
委托:
public class Calculator
{
public double A { get; set; };
public double B { get; set; };
public double C { get; set; };
public double D { get; set; };
public double Calculate(double x)
{
return A*x*x*x + B*x*x + C*x + D;
}
}
答案 2 :(得分:2)
这听起来像你想要的功能语言叫做“currying”或“部分应用”。
给定Func<a, b, c, d, x, result>
,您将逐个应用这些值并减少参数集。
Func<a, b, c, d, x, result>(valueOfA)
将导致带有签名的函数
Func<b, c, d, x, result>
你可以传递。
C#中的currying / partial应用程序的相关链接:
或 - 试试F#;)
编辑:从上面的参考站点创建的短代码示例:
Boilerplate代码:
public static Func<B, R> Partial<A, B, R>(this Func<A, B, R> f, A a) {
return b => f(a, b);
}
public static Func<B, C, R> Partial<A, B, C, R>(this Func<A, B, C, R> f, A a) {
return (b, c) => f(a, b, c);
}
public static Func<B, C, D, R> Partial<A, B, C, D, R>(this Func<A, B, C, D, R> f, A a) {
return (b, c, d) => f(a, b, c, d);
}
您的密码:
Func<double, double, double, double, double> yourCalculation = (a, b, c, x) => a*Math.Pow(x, 3) + b*Math.Pow(x, 2) + c*x;
var aDefined = yourCalculation.Partial(12);
var bDefined = aDefined.Partial(13);
var cDefined = bDefined.Partial(14);
cDefined现在是一个新的Func,它“知道”预先应用的值,并且可以随意传递。我找不到具有4个以上参数的代表的现成解决方案(即那些不适合Func&lt; ...&gt;的东西),但这也应该是可能的。
通过这种方式,您可以预先计算一次,就像今天的方式一样,但是您可以将功能范围缩小到每个消费者的最后一部分。
答案 3 :(得分:0)
有几种不同的Func&lt;&gt;重载,您可以使用一个with 5 generic parameters,第一个是KeyValuePair:
Func<KeyValuePair<double,double>,double,double,double,double>
所以你传递a和b作为kvp和c,d和x作为其他参数。
答案 4 :(得分:0)
事后我真的可以这样做;
Class {
a = ...
b = ...
Func Algorithm = (x) => {
return x*a + x*b;
}
return Algorithm;
}
但Func&lt;&gt;只是有点困惑。和行动&lt;&gt;因为这是我第一次使用它们!谢谢你的帮助。