Coder Social home page Coder Social logo

igsolver's Introduction

IGsolver

This library implements basic optimization algorithms, including Newton's Method for unconstrained problems, SQP method for constrained problems and Gauss-Newton algorithm for non-linear least square problems. It uses Eigen as matrix wrapper and take modern C++ function object as input.

Unconstrained problem

IGsolver::NR_solver uses Newton's Method to solve unconstrained problems, and implements LM method to resolve singularity. You can customize the shifting matrix of LM method.

IGsolver::GN_solver uses Gauss-Newton algorithm to solve non-linear least sqaure problems, which also implements LM method.

If the hessian of optimization problem is not positive definite, Cholesky decomposition may fail. To fix this problem, change SOLVER defined in NR_solver.cpp to sparse matrix solvers that support non-positive definite matrices, like LU solver or LDLT solver.

Constrained problem

IGsolver::SQP_solver uses Sequential Quadratic Programming (SQP) method to solve constrained problems. It takes augmented Lagrangian as merit function, and LU solver to decomposite SQP matrix.

Installation

  git clone https://github.com/milkpku/IGsolver
  cd IGsolver
  mkdir build
  cd build
  cmake ..

After compilation, you can get library IGsolver.lib, link it to your own project.

Usage

Newton-Raphson solver

  #include <IGsolver/NR_Solver.h> 
  using namespace IGsolver::NR;
  /* f = 0.5 * x1^2 * (x_1^2/6 + 1) + x2 * arctan(x2) - 0.5 * ln(x2^2 + 1)
   * f' = [x1^3/3 + x1; arctan(x2)]
   * f'' = diag{x1^2 + 1, 1/(1+x2^2)}
   */
  Fun_grad_hessian f_grad = [](const dVec& X, double& eval, dVec& grad, SpMat& hessian)
  {
    double x1 = X(0);
    double x2 = X(1);

    eval = 0.5 * x1 * x1 * (x1 * x1 / 6 + 1) + x2 * atan(x2) - 0.5 * log(x2 * x2 + 1);

    grad.resize(2);
    grad(0) = x1 * x1 * x1 / 3 + x1;
    grad(1) = atan(x2);

    hessian.resize(2, 2);
    hessian.insert(0, 0) = x1 * x1 + 1;
    hessian.insert(1, 1) = 1 / (1 + x2 * x2);
  };

  Fun_eval f_eval = [](const dVec& X, const dVec& dX, const double e, double& e_next)
  {
    double x1 = X(0) + dX(0);
    double x2 = X(1) + dX(1);

    e_next = 0.5 * x1 * x1 * (x1 * x1 / 6 + 1) + x2 * atan(x2) - 0.5 * log(x2 * x2 + 1);
  };

  Fun_iter f_iter = [](const int n_iter, const int cut_cnt, const dVec& X, const double& eval, const dVec& dX, const dVec& grad)
  {
    printf("[iter %d] e = %g, grad = %g, dX = %g, cut_cnt = %d\n", 
      n_iter, eval, grad.norm(), dX.norm(), cut_cnt);
  };

  NR_Config config;
  dVec sol(2);
  sol << 1, 0.7;
  NR_solver(sol, f_eval, f_grad, f_iter, config);

SQP solver

  #include <IGsolver/SQP_Solver.h> 
  using namespace IGsolver::SQP;

  /* min x1^2 + x2^2 
   * s.t.  x1^2 - x2 -1 = 0
   */
  Fun_eval func_eval = [](const dVec& X, double& eval, dVec& c)
  {
    eval = X.squaredNorm();
    c.resize(1);
    c(0) = X(0) * X(0) - X(1) - 1;
  };

  Fun_grad_hess_Jc func_grad_hess_Jc = [](const dVec& X, double& eval, 
      dVec& grad, SpMat& hessian, dVec& c, SpMat& Jc)
  {
    eval = X.squaredNorm();
    grad = 2 * X;
    hessian.resize(2, 2);
    hessian.insert(0, 0) = 2;
    hessian.insert(1, 1) = 2;

    c.resize(1);
    c(0) = X(0) * X(0) - X(1) - 1;
    Jc.resize(1, 2);
    Jc.insert(0, 0) = 2 * X(0);
    Jc.insert(0, 1) = -1;
  };

  Fun_iter func_iter = [](const int n_iter, const int cut_cnt, const dVec& X, 
    const double& eval, const dVec& dX, const dVec& grad_res, const dVec& c)
  {
    printf("[iter %d] (x1, x2) = (%g, %g), f(x) = %g, gnorm = %g, c = %g\n",
        n_iter, X(0), X(1), eval, grad_res.norm(), c(0));
  };

  SQP_Config config;

  dVec sol = dVec::Random(2);

  SQP_solver(sol, func_eval, func_grad_hess_Jc, func_iter, config);

Advanced Usage

Eigen's sparse matrix solver is slow when matrix becomes big, so please consider other sparse matrix solvers like PARDISO or SuiteSparse. Fortunately, Eigen has convenient API to connect PARDISO and SuiteSparse.

Just redefine SOLVER in src/{NR|SQP|GN}_solver.cpp as recommended in comment. For example, adding

 #include <Eigen/CholmodSupport>
 #define SOLVER Eigen::CholmodSupernodalLLT<SpMat>

in the beginning of src/NR_solver.cpp or src/GN_solver replaces Eigen's solver with SuiteSparse Cholesky solver, which speeds up the decomposition for several magnitudes. Also, adding

  #include <Eigen/UmfPackSupport>
  #define SOLVER Eigen::UmfPackLU<SpMat>

in the beginning of src/SQP_solver.cpp replaces Eigen's solver with SuiteSparse Umfpack LU solver. For more information of thrid-party sparse matrix solvers, please refer to Eigen's manual of Solving Sparse System.

You can customize config settings in {NR|SQP|GN}_config, which are self-documented.

igsolver's People

Contributors

milkpku avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.