我有一个数学函数-exp{-(x - 1)²} - exp{-0.5*(y - 2)²}
,使用该函数及其导数将其传递给BFGS算法
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)
};
现在,已经对该算法进行了编码,以最小化传递给它的函数,并且效果很好。但是,我想添加使功能最大化的功能。为此,我将仅通过对函数和导数取反来包装最小化代码,并将结果传递给最小化代码。
算法的ctor。是
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
方法,现在我添加了
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
。
谢谢你的时间。
编辑。带有函数声明
[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();
...
是的,它会的:
f = (x) => -this.Function(x);
this.Function = f;
假设这Function
是一个Funct<double[],double>
在班级上的语言,基本上就是在写:
this.Function = (x) => -this.Function(x);
是的,那将会爆炸。这是因为this.Function
是通过捕获的作用域延迟的。我怀疑您的意思是:
Func<double[], double> oldFunc = this.Function;
this.Function = (x) => -oldFunc(x);
现在,我们将旧函数捕获到委托中,并使用捕获的委托而不是递归调用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句