Commit d74650b9 authored by Fabian Meyer's avatar Fabian Meyer
Browse files

Use ackely function as example

parent 3b4d55ea
Loading
Loading
Loading
Loading
+22 −20
Original line number Diff line number Diff line
@@ -41,25 +41,30 @@ There are three steps to use gradient-descent-cpp:
```cpp
#include <gdcpp.h>

// Implement an objective functor.
struct Paraboloid
struct Ackley
{
    double operator()(const Eigen::VectorXd &xval, Eigen::VectorXd &gradient)
    static double pi()
    { return 3.141592653589; }

    Ackley()
    { }

    double operator()(const Eigen::VectorXd &xval, Eigen::VectorXd &) const
    {
        // compute gradient explicitly
        // if gradient calculation is omitted, then the optimizer uses
        // finite differences to approximate the gradient numerically
        gradient.resize(2);
        gradient(0) = 2 * xval(0);
        gradient(1) = 2 * xval(1);

        return xval(0) * xval(0) + xval(1) * xval(1);
        assert(xval.size() == 2);
        double x = xval(0);
        double y = xval(1);
        // Calculate ackley function, but no gradient. Let gradien be estimated
        // numerically.
        return -20.0 * std::exp(-0.2 * std::sqrt(0.5 * (x * x + y * y))) -
            std::exp(0.5 * (std::cos(2 * pi() * x) + std::cos(2 * pi() * y))) +
            std::exp(1) + 20.0;
    }
};

int main()
{
    // Create optimizer object with Paraboloid functor as objective.
    // Create optimizer object with Ackley functor as objective.
    //
    // You can specify a StepSize functor as template parameter.
    // There are ConstantStepSize, LimitedChangeStep, BarzilaiBorweinStep and
@@ -70,12 +75,12 @@ int main()
    // You can additionally specify a FiniteDifferences functor as template
    // parameter. There are Forward-, Backward- and CentralDifferences
    // available. (Default is CentralDifferences)
    gdc::GradientDescent<double, Paraboloid,
        gdc::ConstantStepSize<double, Paraboloid>> optimizer;
    gdc::GradientDescent<double, Ackley,
        gdc::WolfeLineSearch<double, Ackley>> optimizer;

    // Set number of iterations as stop criterion.
    // Set it to 0 or negative for infinite iterations (default is 0).
    optimizer.setMaxIterations(100);
    optimizer.setMaxIterations(200);

    // Set the minimum length of the gradient.
    // The optimizer stops minimizing if the gradient length falls below this
@@ -87,12 +92,9 @@ int main()
    // value (default is 1e-9).
    optimizer.setMinStepLength(1e-6);

    // Set the the parametrized StepSize functor used for the step calculation.
    optimizer.setStepSize(gdc::ConstantStepSize<double, Paraboloid>(0.8));

    // Set the momentum rate used for the step calculation (default is 0.0).
    // Defines how much momentum is kept from previous iterations.
    optimizer.setMomentum(0.1);
    optimizer.setMomentum(0.4);

    // Turn verbosity on, so the optimizer prints status updates after each
    // iteration.
@@ -100,7 +102,7 @@ int main()

    // Set initial guess.
    Eigen::VectorXd initialGuess(2);
    initialGuess << 2, 2;
    initialGuess << -2.7, 2.2;

    // Start the optimization
    auto result = optimizer.minimize(initialGuess);
+1 −0
Original line number Diff line number Diff line
@@ -4,3 +4,4 @@
# Created On: 13 Jul 2019

add_executable(paraboloid "paraboloid.cpp")
add_executable(ackley "ackley.cpp")

examples/ackley.cpp

0 → 100644
+79 −0
Original line number Diff line number Diff line
#include <gdcpp.h>

struct Ackley
{
    static double pi()
    { return 3.141592653589; }

    Ackley()
    { }

    double operator()(const Eigen::VectorXd &xval, Eigen::VectorXd &) const
    {
        assert(xval.size() == 2);
        double x = xval(0);
        double y = xval(1);
        // Calculate ackley function, but no gradient. Let gradien be estimated
        // numerically.
        return -20.0 * std::exp(-0.2 * std::sqrt(0.5 * (x * x + y * y))) -
            std::exp(0.5 * (std::cos(2 * pi() * x) + std::cos(2 * pi() * y))) +
            std::exp(1) + 20.0;
    }
};

int main()
{
    // Create optimizer object with Ackley functor as objective.
    //
    // You can specify a StepSize functor as template parameter.
    // There are ConstantStepSize, LimitedChangeStep, BarzilaiBorweinStep and
    // WolfeLineSearch available. (Default is BarzilaiBorweinStep)
    //
    // You can additionally specify a Callback functor as template parameter.
    //
    // You can additionally specify a FiniteDifferences functor as template
    // parameter. There are Forward-, Backward- and CentralDifferences
    // available. (Default is CentralDifferences)
    gdc::GradientDescent<double, Ackley,
        gdc::WolfeLineSearch<double, Ackley>> optimizer;

    // Set number of iterations as stop criterion.
    // Set it to 0 or negative for infinite iterations (default is 0).
    optimizer.setMaxIterations(200);

    // Set the minimum length of the gradient.
    // The optimizer stops minimizing if the gradient length falls below this
    // value (default is 1e-9).
    optimizer.setMinGradientLength(1e-6);

    // Set the minimum length of the step.
    // The optimizer stops minimizing if the step length falls below this
    // value (default is 1e-9).
    optimizer.setMinStepLength(1e-6);

    // Set the momentum rate used for the step calculation (default is 0.0).
    // Defines how much momentum is kept from previous iterations.
    optimizer.setMomentum(0.4);

    // Turn verbosity on, so the optimizer prints status updates after each
    // iteration.
    optimizer.setVerbose(true);

    // Set initial guess.
    Eigen::VectorXd initialGuess(2);
    initialGuess << -2.7, 2.2;

    // Start the optimization
    auto result = optimizer.minimize(initialGuess);

    std::cout << "Done! Converged: " << (result.converged ? "true" : "false")
        << " Iterations: " << result.iterations << std::endl;

    // do something with final function value
    std::cout << "Final fval: " << result.fval << std::endl;

    // do something with final x-value
    std::cout << "Final xval: " << result.xval.transpose() << std::endl;

    return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -489,7 +489,7 @@ namespace gdc
            Scalar fval = evaluateObjective(xval, gradient);
            Scalar gradientLen = gradient.norm();
            Scalar stepSize = stepSize_(xval, fval, gradient);
            Vector step = stepSize * gradient;
            Vector step = (1 - momentum_) * stepSize * gradient;
            Scalar stepLen = step.norm();

            Index iterations = 0;