https://github.com/patwie/cppnumericalsolvers
a lightweight header-only C++17 library of numerical optimization methods for nonlinear functions based on Eigen
https://github.com/patwie/cppnumericalsolvers
bfgs cpp11 eigen gradient-computation lbfgs lbfgs-solver lbfgsb-solver mathematics minimization minimization-algorithm newton numerical-optimization-methods optim optimisation optimization optimization-algorithms optimization-tools solver solvers
Last synced: 7 days ago
JSON representation
a lightweight header-only C++17 library of numerical optimization methods for nonlinear functions based on Eigen
- Host: GitHub
- URL: https://github.com/patwie/cppnumericalsolvers
- Owner: PatWie
- License: mit
- Created: 2014-05-29T15:45:13.000Z (almost 11 years ago)
- Default Branch: main
- Last Pushed: 2024-01-03T14:58:33.000Z (over 1 year ago)
- Last Synced: 2024-10-29T18:07:10.999Z (7 months ago)
- Topics: bfgs, cpp11, eigen, gradient-computation, lbfgs, lbfgs-solver, lbfgsb-solver, mathematics, minimization, minimization-algorithm, newton, numerical-optimization-methods, optim, optimisation, optimization, optimization-algorithms, optimization-tools, solver, solvers
- Language: C++
- Homepage:
- Size: 620 KB
- Stars: 872
- Watchers: 53
- Forks: 201
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# CppNumericalSolvers (A header-only C++17 optimization library)
CppNumericalSolvers is a header-only C++17 optimization library providing a
suite of solvers for both unconstrained and constrained optimization problems.
The library is designed for efficiency, modern C++ compliance, and easy
integration into existing projects. It is distributed under a permissive
license, making it suitable for commercial use.Key Features:
- **Unconstrained Optimization**: Supports algorithms such as **Gradient Descent, Conjugate Gradient, Newton's Method, BFGS, L-BFGS, and Nelder-Mead**.
- **Constrained Optimization**: Provides support for **L-BFGS-B** and **Augmented Lagrangian methods**.
- **Expression Templates**: Enable efficient evaluation of function expressions without unnecessary allocations.
- **First- and Second-Order Methods**: Support for both **gradient-based** and **Hessian-based** optimizations.
- **Differentiation Utilities**: Tools to check gradient and Hessian correctness.
- **Header-Only**: Easily integrate into any C++17 project with no dependencies.## Quick Start
### **Minimizing a Function (BFGS Solver)**
```cpp
#include
#include "cppoptlib/function.h"
#include "cppoptlib/solver/bfgs.h"using namespace cppoptlib::function;
class ExampleFunction : public FunctionXd {
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW/**
* The function is defined as:
*
* f(x) = 5 * x₀² + 100 * x₁² + 5
*
* Its gradient is given by:
*
* ∇f(x) = [10 * x₀, 200 * x₁]ᵀ
*
* And its Hessian is:
*
* ∇²f(x) = [ [10, 0],
* [ 0, 200] ]
*/
ScalarType operator()(const VectorType &x, VectorType *gradient = nullptr,
MatrixType *hessian = nullptr) const override {
if (gradient) {
*gradient = VectorType::Zero(2);
(*gradient)[0] = 2 * 5 * x[0];
(*gradient)[1] = 2 * 100 * x[1];
}if (hessian) {
*hessian = MatrixType::Zero(2, 2);
(*hessian)(0, 0) = 10;
(*hessian)(0, 1) = 0;
(*hessian)(1, 0) = 0;
(*hessian)(1, 1) = 200;
}return 5 * x[0] * x[0] + 100 * x[1] * x[1] + 5;
}
};int main() {
ExampleFunction f;
Eigen::VectorXd x(2);
x << -1, 2;using Solver = cppoptlib::solver::Bfgs;
auto init_state = f.GetState(x);
Solver solver;
auto [solution_state, solver_progress] = solver.Minimize(f, init_state);std::cout << "Optimal solution: " << solution_state.x.transpose() << std::endl;
return 0;
}
```### **Solving a Constrained Optimization Problem**
CppNumericalSolvers allows solving constrained optimization problems using the
**Augmented Lagrangian** method. Below, we solve the problem:```
min f(x) = x_0 + x_1
```subject to the constraint:
```
x_0^2 + x_1^2 = 2
``````cpp
#include
#include "cppoptlib/function.h"
#include "cppoptlib/solver/augmented_lagrangian.h"
#include "cppoptlib/solver/lbfgs.h"using namespace cppoptlib::function;
using namespace cppoptlib::solver;class SumObjective : public FunctionXd {
public:
ScalarType operator()(const VectorType &x, VectorType *gradient = nullptr) const {
if (gradient) *gradient = VectorType::Ones(2);
return x.sum();
}
};class Circle : public FunctionXd {
public:
ScalarType operator()(const VectorType &x, VectorType *gradient = nullptr) const {
if (gradient) *gradient = 2 * x;
return x.squaredNorm();
}
};int main() {
SumObjective::VectorType x(2);
x << 2, 10;FunctionExpr objective = SumObjective();
FunctionExpr circle = Circle();ConstrainedOptimizationProblem prob(
objective,
// 1. Equality constraint: circle(x) - 2 == 0, forcing the solution onto
// the circle's boundary.
{FunctionExpr(circle - 2)},
// 2. Inequality constraint: 2 - circle(x) >= 0, ensuring the solution
// remains inside the circle.
{FunctionExpr(2 - circle)});Lbfgs inner_solver;
AugmentedLagrangian solver(prob, inner_solver);AugmentedLagrangeState l_state(x, /* num_eq=*/1,
/* num_ineq=*/1,
/* penalty=*/1.0);
auto [solution, solver_state] = solver.Minimize(prob, l_state);std::cout << "Optimal x: " << solution.x.transpose() << std::endl;
return 0;
}```
## Use in Your Project
Either use Bazel or CMake:
```sh
git clone https://github.com/PatWie/CppNumericalSolvers.git
```Compile with:
```sh
g++ -std=c++17 -Ipath/to/CppNumericalSolvers/include myfile.cpp -o myprogram
```### Citing this implementation
If you find this implementation useful and wish to cite it, please use the following bibtex entry:
```bibtex
@misc{wieschollek2016cppoptimizationlibrary,
title={CppOptimizationLibrary},
author={Wieschollek, Patrick},
year={2016},
howpublished={\url{https://github.com/PatWie/CppNumericalSolvers}},
}
```