动态定义函数

时间:2014-03-21 08:52:41

标签: c# function dynamic

我正在测试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)的电路。方程由许多变量组成,这些变量取决于网格中节点的数量,用户可以指定,方程式如下:

enter image description here

所以基本上我每个节点有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包含变量,而这个循环公式没有多大意义。

提前致谢。

1 个答案:

答案 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 ,否则你显然可以预先计算价值 - 但这几乎没有帮助:)

鉴于此,我不知道这是不是你要追求的。你必须指定什么应该被认为是常量,传递给函数的是什么等。