首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >取Func<double[],double>的负数

取Func<double[],double>的负数
EN

Stack Overflow用户
提问于 2014-02-10 12:57:48
回答 1查看 171关注 0票数 1

我有一个数学函数-exp{-(x - 1)²} - exp{-0.5*(y - 2)²},它使用函数及其导数传递给BFGS算法。

代码语言:javascript
复制
Func<double[], double> f = (x) => 
    Math.Exp(-Math.Pow(x[0] - 1, 2)) + Math.Exp(-0.5 * Math.Pow(x[1] - 2, 2));

Func<double[], double[]> g = (x) => new double[] 
{
    // df/dx = -2 * e^(-(x - 1)²)(x - 1).
    -2 * Math.Exp(-Math.Pow(x[0] - 1, 2)) * (x[0] - 1),

    // df/dy = -e^(-1/2(y - 2)²) * (y - 2).
    -Math.Exp(-0.5 * Math.Pow(x[1] - 2, 2)) * (x[1] - 2)
};

现在,算法已经被编码,以最小化传递给它的函数,这是很好的工作。但是,我想增加一个函数最大化的能力。要做到这一点,我只需要通过否定函数和导数来包装最小化代码,并将结果传递给最小化代码。

阿尔戈的领奖者。是

代码语言:javascript
复制
public BroydenFletcherGoldfarbShanno(int numberOfVariables, 
    Func<double[], double> function, 
    Func<double[], double[]> gradient, 
    Random random = null)
        : this(numberOfVariables, random)
{
    if (function == null)
        throw new ArgumentNullException("function");
    if (gradient == null)
        throw new ArgumentNullException("gradient");
    this.Function = function;
    this.Gradient = gradient;
}

它初始化Function/Gradient。这个类有一个Minimize方法,现在我添加了

代码语言:javascript
复制
public double Maximize()
{
     // Negate the function.
     Func<double[], double> f;
     f = (x) => -this.Function(x);
     this.Function = f;

     // Negate the derivatives.
     ...
}

我的问题是,我如何仅仅否定this.Function/this.Gradient对象?我上面所做的会抛出一个StackOverflowException

耽误您时间,实在对不起。

编辑。有功能声明

代码语言:javascript
复制
[TestMethod]
public void LBFGSMaximisationTest()
{
    // Suppose we would like to find the maximum of the function:
    // f(x, y) = exp{-(x - 1)²} + exp{-(y - 2)²/2}.
    // First we need write down the function either as a named
    // method, an anonymous method or as a lambda function.
    Func<double[], double> f = (x) =>
    Math.Exp(-Math.Pow(x[0] - 1, 2)) + Math.Exp(-0.5 * Math.Pow(x[1] - 2, 2));

    // Now, we need to write its gradient, which is just the
    // vector of first partial derivatives del_f / del_x.
    // g(x, y) = { del f / del x, del f / del y }.
    Func<double[], double[]> g = (x) => new double[] 
    {
        // df/dx = -2 * e^(-(x - 1)²)(x - 1).
        -2 * Math.Exp(-Math.Pow(x[0] - 1, 2)) * (x[0] - 1),

        // df/dy = -e^(-1/2(y - 2)²) * (y - 2).
        -Math.Exp(-0.5 * Math.Pow(x[1] - 2, 2)) * (x[1] - 2)
    };

    // Finally, we can create the L-BFGS solver, passing the functions as arguments.
    Random r = new SystemRandomSource(0, true);
    BroydenFletcherGoldfarbShanno lbfgs = new BroydenFletcherGoldfarbShanno(
        numberOfVariables: 2, function: f, gradient: g, random: r);

    // And then minimize the function.
    double maxValue = lbfgs.Maximize();
    ...
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-10 13:03:23

是的,它将:

代码语言:javascript
复制
f = (x) => -this.Function(x);
this.Function = f;

假设Function是类级别的Funct<double[],double>,您基本上是在编写:

代码语言:javascript
复制
this.Function = (x) => -this.Function(x);

所以是的,会爆炸的。这是因为this.Function通过捕获的作用域被推迟。我怀疑你的意思是:

代码语言:javascript
复制
Func<double[], double> oldFunc = this.Function;
this.Function = (x) => -oldFunc(x);

现在,我们将旧函数捕获到委托中,并使用捕获的委托,而不是递归调用。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21677898

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档