LCOV - code coverage report
Current view: top level - src/include/panoc-alm/inner/directions/decl - specialized-lbfgs.hpp (source / functions) Hit Total Coverage
Test: ecee3ec3a495b05c61f077aa7a236b7e00601437 Lines: 18 18 100.0 %
Date: 2021-11-04 22:49:09 Functions: 13 13 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <panoc-alm/inner/directions/decl/lbfgs.hpp>
       4             : 
       5             : namespace pa {
       6             : 
       7             : /// Limited memory Broyden–Fletcher–Goldfarb–Shanno (L-BFGS) algorithm that can
       8             : /// handle updates of the γ parameter.
       9             : /// @ingroup    grp_PANOCDirectionProviders
      10           4 : class SpecializedLBFGS {
      11             :   public:
      12             :     using Params = LBFGSParams;
      13             : 
      14             :     SpecializedLBFGS(Params params) : params(params) {}
      15          12 :     SpecializedLBFGS(Params params, size_t n, size_t history) : params(params) {
      16           4 :         resize(n, history);
      17           4 :     }
      18             : 
      19             :     /// Standard L-BFGS update without changing the step size γ.
      20             :     bool standard_update(crvec xₖ, crvec xₖ₊₁, crvec pₖ,
      21             :                          crvec pₖ₊₁, crvec gradₖ₊₁);
      22             :     /// L-BFGS update when changing the step size γ, recomputing everything.
      23             :     bool full_update(crvec xₖ, crvec xₖ₊₁, crvec pₖ_old_γ,
      24             :                      crvec pₖ₊₁, crvec gradₖ₊₁, const Box &C,
      25             :                      real_t γ);
      26             :     /// Update the inverse Hessian approximation using the new vectors xₖ₊₁
      27             :     /// and pₖ₊₁.
      28             :     bool update(crvec xₖ, crvec xₖ₊₁, crvec pₖ, crvec pₖ₊₁,
      29             :                 crvec gradₖ₊₁, const Box &C, real_t γ);
      30             : 
      31             :     /// Apply the inverse Hessian approximation to the given vector q.
      32             :     template <class Vec>
      33             :     void apply(Vec &&q);
      34             : 
      35             :     /// Initialize with the starting point x₀ and the gradient in that point.
      36             :     void initialize(crvec x₀, crvec grad₀);
      37             : 
      38             :     /// Throw away the approximation and all previous vectors s and y.
      39             :     void reset();
      40             :     /// Re-allocate storage for a problem with a different size. 
      41             :     void resize(size_t n, size_t history);
      42             : 
      43             :     std::string get_name() const { return "SpecializedLBFGS"; }
      44             : 
      45             :     /// Get the size of the s, y, x and g vectors in the buffer.
      46         582 :     size_t n() const { return sto.rows() - 1; }
      47             :     /// Get the number of previous vectors s, y, x and g stored in the buffer.
      48         428 :     size_t history() const { return (sto.cols() - 2) / 4; }
      49             :     /// Get the next index in the circular buffer of previous s, y, x and g
      50             :     /// vectors.
      51          96 :     size_t succ(size_t i) const { return i + 1 < history() ? i + 1 : 0; }
      52             :     /// Get the previous index in the circular buffer of previous s, y, x and g
      53             :     /// vectors.
      54          20 :     size_t pred(size_t i) const { return i == 0 ? history() - 1 : i - 1; }
      55             : 
      56         104 :     auto s(size_t i) { return sto.col(2 * i).topRows(n()); }
      57             :     auto s(size_t i) const { return sto.col(2 * i).topRows(n()); }
      58         124 :     auto y(size_t i) { return sto.col(2 * i + 1).topRows(n()); }
      59             :     auto y(size_t i) const { return sto.col(2 * i + 1).topRows(n()); }
      60         158 :     auto x(size_t i) { return sto.col(2 * history() + 2 * i).topRows(n()); }
      61             :     auto x(size_t i) const {
      62             :         return sto.col(2 * history() + 2 * i).topRows(n());
      63             :     }
      64         152 :     auto g(size_t i) { return sto.col(2 * history() + 2 * i + 1).topRows(n()); }
      65             :     auto g(size_t i) const {
      66             :         return sto.col(2 * history() + 2 * i + 1).topRows(n());
      67             :     }
      68           6 :     auto p() { return sto.col(4 * history()).topRows(n()); }
      69             :     auto p() const { return sto.col(4 * history()).topRows(n()); }
      70           6 :     auto w() { return sto.col(4 * history() + 1).topRows(n()); }
      71             :     auto w() const { return sto.col(4 * history() + 1).topRows(n()); }
      72          32 :     real_t &ρ(size_t i) { return sto.coeffRef(n(), 2 * i); }
      73             :     const real_t &ρ(size_t i) const { return sto.coeff(n(), 2 * i); }
      74             :     real_t &α(size_t i) { return sto.coeffRef(n(), 2 * i + 1); }
      75             :     const real_t &α(size_t i) const { return sto.coeff(n(), 2 * i + 1); }
      76             : 
      77             :   private:
      78             :     using storage_t = Eigen::Matrix<real_t, Eigen::Dynamic, Eigen::Dynamic>;
      79             : 
      80             :     storage_t sto;
      81           4 :     size_t idx   = 0;
      82           4 :     bool full    = false;
      83           4 :     real_t old_γ = 0;
      84             :     Params params;
      85             : };
      86             : 
      87             : } // namespace pa

Generated by: LCOV version 1.15