12 const real_t min_divisor = std::sqrt(std::numeric_limits<real_t>::min());
15 if (not std::isfinite(yᵀs))
17 if (yᵀs < min_divisor)
19 if (sᵀs < min_divisor)
26 bool cbfgs_cond = yᵀs / sᵀs >= ϵ * std::pow(pᵀp,
α / 2);
35 const auto s = xₖ₊₁ - xₖ;
67 real_t yᵀy =
y(new_idx).squaredNorm();
68 γ = 1. / (
ρ(new_idx) * yᵀy);
71 auto update1 = [&](
size_t i) {
72 α(i) =
ρ(i) * (
s(i).dot(q));
76 for (
size_t i =
idx; i-- > 0;)
85 auto update2 = [&](
size_t i) {
87 q += (
α(i) - β) *
s(i);
92 for (
size_t i = 0; i <
idx; ++i)
98template <
class Vec,
class IndexVec>
103 using Index =
typename std::remove_reference_t<Vec>::Index;
104 bool fullJ = q.size() == Index(J.size());
112 auto dotJ = [&J, fullJ](
const auto &
a,
const auto &
b) {
123 auto update1 = [&](
size_t i) {
128 ρ(i) = 1. / dotJ(
s(i),
y(i));
133 α(i) =
ρ(i) * dotJ(
s(i), q);
138 q(j) -=
α(i) *
y(i)(j);
143 γ = 1. / (
ρ(i) * yᵀy);
147 for (
size_t i =
idx; i-- > 0;)
164 auto update2 = [&](
size_t i) {
169 q += (
α(i) - β) *
s(i);
172 q(j) += (
α(i) - β) *
s(i)(j);
177 for (
size_t i = 0; i <
idx; ++i)
190 throw std::invalid_argument(
"LBFGSParams::memory must be > 1");
197 for (
size_t i = 0; i <
history(); ++i) {
202 for (
size_t i = 0; i <
idx; ++i) {
211 lbfgs.resize(x₀.size());
231 return lbfgs.apply(qₖ, γ);
235 if (lbfgs.get_params().rescale_when_γ_changes)
236 lbfgs.scale_y(γₖ / old_γₖ);
244 return lbfgs.get_name();
248 return lbfgs.get_params();
size_t succ(size_t i) const
Get the next index in the circular buffer of previous s and y vectors.
bool apply(Vec &&q, real_t γ)
Apply the inverse Hessian approximation to the given vector q.
bool update(crvec xₖ, crvec xₖ₊₁, crvec pₖ, crvec pₖ₊₁, Sign sign, bool forced=false)
Update the inverse Hessian approximation using the new vectors xₖ₊₁ and pₖ₊₁.
void resize(size_t n)
Re-allocate storage for a problem with a different size.
size_t history() const
Get the number of previous vectors s and y stored in the buffer.
static bool update_valid(LBFGSParams params, 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...
size_t n() const
Get the size of the s and y vectors in the buffer.
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.
Eigen::Ref< const vec > crvec
Default type for immutable references to vectors.
unsigned memory
Length of the history to keep.
struct alpaqa::LBFGSParams::@0 cbfgs
Parameters in the cautious BFGS update condition.
double real_t
Default floating point type.
Eigen::Ref< vec > rvec
Default type for mutable references to vectors.
Parameters for the LBFGS and SpecializedLBFGS classes.
static bool update(DirectionProviderT &dp, crvec xₖ, crvec xₖ₊₁, crvec pₖ, crvec pₖ₊₁, crvec gradₖ₊₁, const Box &C, real_t γₖ₊₁)=delete
static bool apply(DirectionProviderT &dp, crvec xₖ, crvec x̂ₖ, crvec pₖ, real_t γ, rvec qₖ)=delete
Apply the direction estimation in the current point.
static void changed_γ(DirectionProviderT &dp, real_t γₖ, real_t old_γₖ)=delete
static void initialize(DirectionProviderT &dp, crvec x₀, crvec x̂₀, crvec p₀, crvec grad₀)=delete