我正在测试Extreme Optimization C#库,正是非线性系统求解器。 作为一个例子,我发现我必须以下列形状传递求解器非线性系统:
Func<Vector, double>[] f = {
x => Math.Exp(x[0])*Math.Cos(x[1]) - x[0]*x[0] + x[1]*x[1],
x => Math.Exp(x[0])*Math.Sin(x[1]) - 2*x[0]*x[1]
};
问题是我尝试解决的系统无法在设计时指定。它是由负载流方程组成的非线性系统,用于求解交流电(AC)的电路。方程由许多变量组成,这些变量取决于网格中节点的数量,用户可以指定,方程式如下:
所以基本上我每个节点有2个方程,这是2 * n方程,由于它们依赖于i,j索引,因此不能在单行中组成,因此我必须有2个嵌套for循环来创建P和Q方程式。
有没有办法创建Func<Vector, double>[] f = { equation system of variable lenght };
?
我看过帖子Creating a function dynamically at run-time,但它没有回答我的问题(我相信)
// ************************ EDIT ******************** ******************
方程的创建是这样的:
For (int i=0; i< n; i++){
double A=0.0;
double B=0.0;
For (int j=0; j< n; j++){
A+= G[i,j]*Math.Cos(Theta[i,j]) + B[i,j]*Math.Sin(Theta[i,j])
B+= G[i,j]*Math.Sin(Theta[i,j]) + B[i,j]*Math.Cos(Theta[i,j])
}
P[i]=V[i]*A;
Q[i]=V[i]*B;
}
当然A和B包含变量,而这个循环公式没有多大意义。
提前致谢。
答案 0 :(得分:2)
你正在传递一个函数数组,所以你应该很容易做到你想做的事情:
Func<Vector, double>[] funcs = new Func<Vector, double>[howeverManyYouWant];
for (var i = 0; i < howeverManyYouWant; i++)
{
var someConstant = 0.1f * i; // You need to define "constants" in scope
funcs[i] = x => Math.Exp(x[0])*Math.Cos(x[1]) - x[0]*x[0] + x[1]*x[1];
}
然后您可以根据需要传递数组。
如果您无法提前确定数组的大小,可以使用List<Func<Vector, double>>
代替数组,然后在准备就绪时调用ToArray()
。
编辑:我刚刚意识到你并没有真正传递Expression<Func<...>>
- 这使得一切都变得更加简单,因为你可以在函数内使用for循环传:
List<Func<Vector, double>> funcs
= new List<Func<Vector, double>>(howeverManyYouWant * 2);
for (var i = 0; i < howeverManyYouWant; i++)
{
// P[i] equation
funcs.Add
(
x =>
{
var a = 0d;
for (var j = 0; j < howeverManyYouWant; j++)
{
a += G[i, j] * Math.Cos(Theta[i, j]) + B[i, j] * Math.Sin(Theta[i, j]);
}
return x[i] * a;
}
);
// Add your Q[i] equation here the same way.
funcs.Add(...);
}
你必须修改它才能真正适合你的情况,因为我不知道如何调用func数组,传递给函数的内容,你想要的常量或变量等等。(我'我刚刚在此示例中将V
替换为x
,但它确实显示了基本想法。
当然你想在某个地方引用x
,否则你显然可以预先计算价值 - 但这几乎没有帮助:)
鉴于此,我不知道这是不是你要追求的。你必须指定什么应该被认为是常量,传递给函数的是什么等。