yixuan / LBFGSpp

A header-only C++ library for L-BFGS and L-BFGS-B algorithms
https://lbfgspp.statr.me/
MIT License
532 stars 101 forks source link

LBFGS Breaks on this trivial case #21

Closed mrlooi closed 2 years ago

mrlooi commented 2 years ago

Dear oh dear....

OUTPUT

terminate called after throwing an instance of 'std::runtime_error'
  what():  the line search routine reached the maximum number of iterations
Aborted (core dumped)

CODE

#include <Eigen/Core>
#include <iostream>
#include <LBFGS.h>

using Eigen::VectorXf;
using Eigen::MatrixXf;
using namespace LBFGSpp;

class Rosenbrock
{
private:
    int n;
public:
    Rosenbrock(int n_) : n(n_) {}
    float operator()(const VectorXf& x, VectorXf& grad)
    {
        float out = 0;
        for (int i = 0; i < n-1; ++i) {
            out += 100 * pow(x[i + 1] - pow(x[i], 2), 2) + pow(1 - x[i], 2);
        }

        grad[0] = -400 * x[0] * (x[1] - pow(x[0], 2)) - 2 * (1 - x[0]);
        grad[n - 1] = 200 * (x[n - 1] - pow(x[n - 2], 2));
        for (int i = 1; i < n - 1; ++i) {
            float xm = x[i];
            grad[i] = 200 * (xm - pow(x[i - 1], 2)) - 400 * (x[i + 1] - pow(xm, 2)) * xm - 2 * (1 - xm);
        }
        return out;
    }
};

int main()
{
    const int n = 5;
    LBFGSParam<float> param;
    LBFGSSolver<float> solver(param);
    Rosenbrock fun(n);

    VectorXf x = VectorXf::Zero(n);
    x << 1.3, 0.7, 0.8, 1.9, 1.2;//, 0.5, 1.3, 1.5, 1.2, 0.9;

    float fx;
    int niter = solver.minimize(fun, x, fx);

    std::cout << niter << " iterations" << std::endl;
    std::cout << "x = \n" << x.transpose() << std::endl;
    std::cout << "f(x) = " << fx << std::endl;

    return 0;
}
mrlooi commented 2 years ago

It seems to work fine with LBFGS-B with infinity/-infinity bounds But fails with the standard LBFGS

mrlooi commented 2 years ago

any luck?