14 if (not std::isfinite(yᵀs))
25 bool cbfgs_cond = a_yᵀs >= sᵀs * ϵ * std::pow(pᵀp,
α / 2);
33template <
class VecS,
class VecY>
35 real_t pₙₑₓₜᵀpₙₑₓₜ,
bool forced) {
58 const auto s = xₙₑₓₜ - xₖ;
72 real_t yᵀy =
y(new_idx).squaredNorm();
73 γ = 1 / (
ρ(new_idx) * yᵀy);
77 α(i) =
ρ(i) *
s(i).dot(q);
86 q -= (β -
α(i)) *
s(i);
92template <
class IndexVec>
97 const bool fullJ = q.size() ==
static_cast<index_t>(J.size());
100 throw std::invalid_argument(
"CBFGS check not supported when using "
101 "masked version of LBFGS::apply()");
111 const auto dotJ = [&J, fullJ](
const auto &a,
const auto &b) {
122 const auto axmyJ = [&J, fullJ](
real_t a,
const auto &x,
auto &
y) {
131 const auto scalJ = [&J, fullJ](
real_t a,
auto &x) {
153 α(i) =
ρ(i) * dotJ(
s(i), q);
154 axmyJ(
α(i),
y(i), q);
159 γ = 1 / (
ρ(i) * yᵀy);
171 if (std::isnan(
ρ(i)))
174 axmyJ(β -
α(i),
s(i), q);
187 throw std::invalid_argument(
"LBFGS::Params::memory must be >= 1");
void foreach_rev(const F &fun) const
Iterate over the indices in the history buffer, newest first.
static bool update_valid(const LBFGSParams ¶ms, real_t yᵀs, real_t sᵀs, real_t pᵀp)
Check if the new vectors s and y allow for a valid BFGS update that preserves the positive definitene...
index_t succ(index_t i) const
Get the next index in the circular buffer of previous s and y vectors.
index_t pred(index_t i) const
Get the previous index in the circular buffer of s and y vectors.
length_t n() const
Get the size of the s and y vectors in the buffer.
bool apply(rvec q, real_t γ=-1)
Apply the inverse Hessian approximation to the given vector q.
length_t history() const
Get the number of previous vectors s and y stored in the buffer.
void foreach_fwd(const F &fun) const
Iterate over the indices in the history buffer, oldest first.
void resize(length_t n)
Re-allocate storage for a problem with a different size.
void reset()
Throw away the approximation and all previous vectors s and y.
Sign
The sign of the vectors passed to the LBFGS::update method.
void scale_y(real_t factor)
Scale the stored y vectors by the given factor.
bool update(crvec xₖ, crvec xₙₑₓₜ, crvec pₖ, crvec pₙₑₓₜ, Sign sign=Sign::Positive, bool forced=false)
Update the inverse Hessian approximation using the new vectors xₖ₊₁ and pₖ₊₁.
bool update_sy(const anymat< VecS > &s, const anymat< VecY > &y, real_t pₙₑₓₜᵀpₙₑₓₜ, bool forced=false)
Update the inverse Hessian approximation using the new vectors sₖ = xₖ₊₁ - xₖ and yₖ = pₖ₊₁ - pₖ.
Eigen::Ref< const vec > crvec
Default type for immutable references to vectors.
real_t min_abs_s
Reject update if .
CBFGSParams cbfgs
Parameters in the cautious BFGS update condition.
constexpr real_t NaN
Not a number.
length_t memory
Length of the history to keep.
index_t length_t
Default type for vector sizes.
bool force_pos_def
If set to true, the inverse Hessian estimate should remain definite, i.e.
Eigen::Index index_t
Default type for vector indices.
double real_t
Default floating point type.
Eigen::MatrixBase< Derived > anymat
Generic type for vector and matrix arguments.
real_t min_div_fac
Reject update if .
Eigen::Ref< vec > rvec
Default type for mutable references to vectors.
Parameters for the LBFGS class.
real_t ϵ
Set to zero to disable CBFGS check.
void resize(length_t n, length_t history)
Re-allocate storage for a problem with a different size.
length_t n() const
Get the size of the s and y vectors in the buffer.
length_t history() const
Get the number of previous vectors s and y stored in the buffer.