How to optimize a function?

This example illustrates how the minimum of a quadratic function of the form \(f(x)=ax^2+bx+c\) can be determined using the GammaLib optimizer.

The source code is in examples/cpp/optimize/optimize.cpp.

First, the function to be optimized has to be implemented as a class derived from GOptimizerFunction:

C++

 1class parabola : public GOptimizerFunction {
 2public:
 3    parabola(void) : m_value(0), m_gradient(1), m_curvature(1,1) {}
 4    void           eval(const GOptimizerPars& pars);
 5    double         value(void) const { return m_value; }
 6    GVector*       gradient(void) { return &m_gradient; }
 7    GMatrixSparse* curvature(void) { return &m_curvature; }
 8protected:
 9    double        m_value;     //!< Function value
10    GVector       m_gradient;  //!< Function gradient vector
11    GMatrixSparse m_curvature; //!< Curvature matrix
12};
13void parabola::eval(const GOptimizerPars& pars)
14{
15    const double a   =  2.0;
16    const double b   = -4.0;
17    const double c   =  2.0;
18    double x         = pars[0]->value();
19    m_value          = a*x*x + b*x + c;
20    m_gradient[0]    = 2.0*a*x + b;
21    m_curvature(0,0) = m_gradient[0] * m_gradient[0];
22};

Lines 1-12 define the parabola class that requires implementing the eval, value, gradient and curvature methods. The eval method, implement in lines 13-22, performs the computation of the function value, the gradient and the products of the gradients.

The optimization is then done using the following code:

C++

1GOptimizerLM opt;
2parabola fct;
3GOptimizerPars pars(1);
4pars[0]->value(1.5);
5opt.optimize(fct, pars);
6std::cout << "Function value .....: " << fct.value() << std::endl;
7std::cout << "Parameter value ....: " << pars[0]->value() << std::endl;

Line 1 allocates an Levenberg-Marquardt optimizer, line 2 creates an instance of the function to optimize. In line 3, a parameter container with a single parameter is allocated, and the value of the single parameter is set to 1.5 in line 4. In line 5, the optimizer is called, and the resulting function value and best fitted parameter is logged in to console in lines 6-7.

Here’s the output:

$ ./optimize
Function value .....: 4.99001e-07
Parameter value ....: 1.0005