Question

I have a mathematical function -exp{-(x - 1)²} - exp{-0.5*(y - 2)²} which is passed into an BFGS algorithm using the function and its derivatives

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)
};

Now, the algorithm has been coded to minimise the function passed to it and this works great. However, I want to add the ability to maximise a function. To do this I will merely wrap the minimise code by negating the function and the derivatives and pass the result to the minimise code.

The ctor for the algo. is

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;
}

Which initialises the Function/Gradient. This class has a Minimize method and now I have added

public double Maximize()
{
     // Negate the function.
     Func<double[], double> f;
     f = (x) => -this.Function(x);
     this.Function = f;

     // Negate the derivatives.
     ...
}

My question is how can I merely negate the this.Function/this.Gradient objects? What I have done above throws a StackOverflowException.

Thanks for your time.


Edit. with function declaration

[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();
    ...
Was it helpful?

Solution

Yes, it will:

f = (x) => -this.Function(x);
this.Function = f;

Assuming that Function is a Funct<double[],double> at the class level, you are basically writing:

this.Function = (x) => -this.Function(x);

so yeah, that will explode. This is because this.Function is deferred via captured scope. I suspect what you mean is:

Func<double[], double> oldFunc = this.Function;
this.Function = (x) => -oldFunc(x);

Now we're capturing the old function into a delegate, and using that captured delegate rather than call recursively.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top