在Func <double []>

时间:2017-10-29 20:58:43

标签: c#

我使用Accord数学来解决非线性约束的非线性函数 问题是NonlinearObjectiveFunction函数接受function参数Func<double[], double> function在我的情况下它是

x =>
x[0] * (Matrix[0, 0] * x[0] + Matrix[1, 0] * x[1] + Matrix[2, 0] * x[2]) +
x[1] * (Matrix[0, 1] * x[0] + Matrix[1, 1] * x[1] + Matrix[2, 1] * x[2]) +
x[2] * (Matrix[0, 2] * x[0] + Matrix[1, 2] * x[1] + Matrix[2, 2] * x[2])

是否有可能以某种方式使用循环构建此function?因为输入矩阵的维度可以改变。

class Program
    {
        static void Main(string[] args)
        {
            double[,] Matrix = new double[3, 3];

            Matrix[0, 0] = 0.00234329;
            Matrix[0, 1] = 0.00118878;
            Matrix[0, 2] = 0.00152143;
            Matrix[1, 0] = 0.00118878;
            Matrix[1, 1] = 0.00206312;
            Matrix[1, 2] = 0.00124812;
            Matrix[2, 0] = 0.00152143;
            Matrix[2, 1] = 0.00124812;
            Matrix[2, 2] = 0.00194796;

            double x1 = 0.0107;
            double x2 = -0.00054;
            double x3 = -0.0034;

            var f = new NonlinearObjectiveFunction(3, x =>
            x[0] * (Matrix[0, 0] * x[0] + Matrix[1, 0] * x[1] + Matrix[2, 0] * x[2]) +
            x[1] * (Matrix[0, 1] * x[0] + Matrix[1, 1] * x[1] + Matrix[2, 1] * x[2]) +
            x[2] * (Matrix[0, 2] * x[0] + Matrix[1, 2] * x[1] + Matrix[2, 2] * x[2])
            );

            var constraints = new[]
            {
                new NonlinearConstraint(3, x => x1 * x[0] + x2 * x[1] + x3 * x[2] >= 0.01),
                new NonlinearConstraint(3, x=> x[0] + x[1] + x[2]>=1 ),
                new NonlinearConstraint(3, x=> x[0] + x[1] + x[2]<=1 ),
                new NonlinearConstraint(3, x=> x[0]>=0),
                new NonlinearConstraint(3, x=> x[1]>=0),
                new NonlinearConstraint(3, x=> x[2]>=0)
            };

            var cobyla = new Cobyla(f, constraints);
            bool success = cobyla.Minimize();
            double minimum = cobyla.Value;
            double[] solution = cobyla.Solution;
        }
    }

1 个答案:

答案 0 :(得分:4)

您在代码示例中显示的lambda表达式可以像这样重写:

double ApplyMatrix(double[,] matrix, double[] x)
{
    double sum = 0;

    for (int row = 0; row < matrix.GetLength(1); row++)
    {
        double rowSum = 0;

        for (int col = 0; col < matrix.GetLength(0); col++)
        {
            rowSum += matrix[col, row] * x[col];
        }

        sum += x[row] * rowSum;
    }

    return sum;
}

然后,您可以将lambda表达式传递给使用上述内容的NonlinearObjectiveFunction

var f = new NonlinearObjectiveFunction(3, x => ApplyMatrix(Matrix, x));

当然,这假设您传递给方法的用户定义的Matrixx数组的维度彼此一致。即用户定义的矩阵总是方形的,x数组的元素总是至少与用户定义矩阵中的行和列一样多。

如果这不是您所询问的内容,请通过更准确地描述您正在尝试完成的内容来改进您的问题,包括解释您的意思&#34;循环&#34;