• Stars
    star
    493
  • Rank 85,859 (Top 2 %)
  • Language
    C++
  • License
    MIT License
  • Created over 7 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A header-only C++ library for L-BFGS and L-BFGS-B algorithms

LBFGS++ LBFGS++

UPDATE on 2020-03-06: LBFGS++ now includes a new L-BFGS-B solver for box-constrained optimization problems. Check the example below for its usage.

LBFGS++ is a header-only C++ library that implements the Limited-memory BFGS algorithm (L-BFGS) for unconstrained minimization problems, and a modified version of the L-BFGS-B algorithm for box-constrained ones.

The code for the L-BFGS solver is derived and modified from the libLBFGS library developed by Naoaki Okazaki.

LBFGS++ is implemented as a header-only C++ library, whose only dependency, Eigen, is also header-only.

A Quick Example

To use LBFGS++, one needs to first define a functor to represent the multivariate function to be minimized. It should return the objective function value on a vector x and overwrite the vector grad with the gradient evaluated on x. For example we could define the Rosenbrock function in the following way:

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

using Eigen::VectorXd;
using namespace LBFGSpp;

class Rosenbrock
{
private:
    int n;
public:
    Rosenbrock(int n_) : n(n_) {}
    double operator()(const VectorXd& x, VectorXd& grad)
    {
        double fx = 0.0;
        for(int i = 0; i < n; i += 2)
        {
            double t1 = 1.0 - x[i];
            double t2 = 10 * (x[i + 1] - x[i] * x[i]);
            grad[i + 1] = 20 * t2;
            grad[i]     = -2.0 * (x[i] * grad[i + 1] + t1);
            fx += t1 * t1 + t2 * t2;
        }
        return fx;
    }
};

Then we just need to set up parameters, create solver object, provide initial guess, and then run the minimization function.

int main()
{
    const int n = 10;
    // Set up parameters
    LBFGSParam<double> param;
    param.epsilon = 1e-6;
    param.max_iterations = 100;

    // Create solver and function object
    LBFGSSolver<double> solver(param);
    Rosenbrock fun(n);

    // Initial guess
    VectorXd x = VectorXd::Zero(n);
    // x will be overwritten to be the best point found
    double 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;
}

The example can then be compiled and run.

$ g++ -I/path/to/eigen -I/path/to/lbfgspp/include -O2 example.cpp
$ ./a.out
23 iterations
x =
1 1 1 1 1 1 1 1 1 1
f(x) = 1.87948e-19

You can also use a different line search algorithm by providing a second template parameter to LBFGSSolver. For example, the code below illustrates the bracketing line search algorithm (contributed by @DirkToewe).

int main()
{
    const int n = 10;
    // Set up parameters
    LBFGSParam<double> param;
    param.epsilon = 1e-6;
    param.max_iterations = 100;

    // Create solver and function object
    LBFGSSolver<double, LineSearchBracketing> solver(param);
    Rosenbrock fun(n);

    // Initial guess
    VectorXd x = VectorXd::Zero(n);
    // x will be overwritten to be the best point found
    double 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;
}

Box-constrained Problem

If the parameters to be optimized have simple bounds, then the L-BFGS-B solver class LBFGSBSolver can be used. The code is very similar to that of LBFGSSolver. Below is the same Rosenbrock example, but we require that all variables should be between 2 and 4.

#include <Eigen/Core>
#include <iostream>
#include <LBFGSB.h>  // Note the different header file

using Eigen::VectorXd;
using namespace LBFGSpp;

class Rosenbrock
{
private:
    int n;
public:
    Rosenbrock(int n_) : n(n_) {}
    double operator()(const VectorXd& x, VectorXd& grad)
    {
        double fx = 0.0;
        for(int i = 0; i < n; i += 2)
        {
            double t1 = 1.0 - x[i];
            double t2 = 10 * (x[i + 1] - x[i] * x[i]);
            grad[i + 1] = 20 * t2;
            grad[i]     = -2.0 * (x[i] * grad[i + 1] + t1);
            fx += t1 * t1 + t2 * t2;
        }
        return fx;
    }
};

int main()
{
    const int n = 10;
    // Set up parameters
    LBFGSBParam<double> param;  // New parameter class
    param.epsilon = 1e-6;
    param.max_iterations = 100;

    // Create solver and function object
    LBFGSBSolver<double> solver(param);  // New solver class
    Rosenbrock fun(n);

    // Bounds
    VectorXd lb = VectorXd::Constant(n, 2.0);
    VectorXd ub = VectorXd::Constant(n, 4.0);

    // Initial guess
    VectorXd x = VectorXd::Constant(n, 3.0);

    // x will be overwritten to be the best point found
    double fx;
    int niter = solver.minimize(fun, x, fx, lb, ub);

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

    return 0;
}

Note that we also allow infinite values for the lower and upper bounds. In such cases one can define ub[i] = std::numeric_limits<double>::infinity(), for example.

Documentation

The API reference page contains the documentation of LBFGS++ generated by Doxygen.

License

LBFGS++ is an open source project under the MIT license.

More Repositories

1

spectra

A header-only C++ library for large scale eigenvalue problems
C++
704
star
2

showtext

Using Fonts More Easily in R Graphs
C
466
star
3

prettydoc

Creating Pretty HTML From R Markdown
SCSS
459
star
4

MiniDNN

A header-only C++ library for deep neural networks
C++
374
star
5

recosystem

Recommender System Using Parallel Matrix Factorization
C++
85
star
6

RSpectra

R Interface to the Spectra Library for Large Scale Eigenvalue and SVD Problems
C++
77
star
7

ADMM

Solving Statistical Optimization Problems Using the ADMM Algorithm
C++
74
star
8

RcppNumerical

Rcpp Integration for Numerical Computing Libraries
C++
55
star
9

rARPACK

Solvers for Large Scale Eigenvalue and SVD Problems
R
45
star
10

tinydnn

Tiny yet Powerful Deep Neural Networks
C++
42
star
11

conan-danmu

ć€Šåä¾¦ęŽ¢ęŸÆå—ć€‹Bē«™å¼¹å¹•ęµč§ˆå™Ø
R
38
star
12

ADMM-Spark

Implementation of ADMM algorithm on Apache Spark
Scala
24
star
13

fontr

Extracting Glyphs From Font Files
C++
23
star
14

sysfonts

Loading Fonts into R
R
22
star
15

arpack-eigen

A header-only C++ redesign of ARPACK using the Eigen library
C++
21
star
16

fastncdf

Fast Computation of Normal CDF
C
18
star
17

almond

ALMOND: Adaptive Latent Modeling and Optimization via Neural Networks and Langevin Diffusion
Python
12
star
18

COS-article

ē»Ÿč®”之都äø»ē«™ (http://cos.name/) ꖇē« ē›ø关代ē 
HTML
10
star
19

parallel-translation

Chinese translation of the vignette of "parallel" package
10
star
20

hugo-blog-en

My English blog built with Hugo
HTML
10
star
21

arpack-arma

A header-only C++ redesign of ARPACK using the Armadillo library
C++
9
star
22

temperflow

Efficient Multimodal Sampling via Tempered Distribution Flow
Python
9
star
23

rcpp-note

Rcpp API reference
HTML
8
star
24

cdtau

Unbiased Contrastive Divergence Algorithm
C++
8
star
25

Rmath-Java

Java wrapper of Rmath library for statistical distribution functions
C
7
star
26

miniGPU

A Minimal Example of Using OpenCL in R Packages
C
5
star
27

markerpen

Marker Gene Detection via Penalized Principal Component Analysis
C++
5
star
28

fontemoji

Plotting Emojis in R Graphs
R
5
star
29

Science

Master of Science
4
star
30

clplite

High Performance Linear Programming Solver Based on Clp
C++
3
star
31

Layer

An R Graphics Device with Layer Support
Shell
3
star
32

R2SWF

Convert R Graphics to SWF (Flash)
C
3
star
33

cutest-lbfgs

Testing and benchmarking L-BFGS/L-BFGS-B solvers with CUTEst
C++
3
star
34

R2SWF-archive

Convert R Graphics to SWF (Flash)
C
3
star
35

cleveland-r-meetup

Slides and code for the presentation given at the Greater Cleveland R Group
R
2
star
36

fdaplus

Enhancement of the 'fda' package for functional data analysis
C
2
star
37

en

My (old) English blog. New one at https://github.com/yixuan/hugo-blog-en
HTML
2
star
38

gradfps

Gradient-based Fantope projection and selection algorithm for sparse PCA
C
2
star
39

bigspline

Smoothing Spline on Spark
Scala
1
star
40

test

R
1
star
41

cn

My Chinese Blog
CSS
1
star
42

Algorithms

A place to hold code snippets of algorithms
C++
1
star
43

yixuan.github.com

My homepage
HTML
1
star
44

rationalfun

An R package to manipulate rational functions
R
1
star