1#ifndef STAN_MATH_MIX_FUNCTOR_BARZILAI_BORWEIN_STEP_SIZE_HPP
2#define STAN_MATH_MIX_FUNCTOR_BARZILAI_BORWEIN_STEP_SIZE_HPP
64 const Eigen::VectorXd& g_curr,
65 const Eigen::VectorXd& g_prev,
66 double prev_step,
int last_backtracks,
67 double min_alpha,
double max_alpha) {
69 auto safe_fallback = [&]() ->
double {
70 double a = std::clamp(
71 prev_step > 0.0 && std::isfinite(prev_step) ? prev_step : 1.0,
72 min_alpha, max_alpha);
76 const Eigen::VectorXd y = g_curr - g_prev;
77 const double sty = s.dot(y);
78 const double sts = s.squaredNorm();
79 const double yty = y.squaredNorm();
82 constexpr double eps = 1
e-16;
83 if (!(std::isfinite(sty) && std::isfinite(sts) && std::isfinite(yty))
84 || sts <= eps || yty <= eps || sty <= eps || last_backtracks == -1) {
85 return safe_fallback();
89 double alpha_bb1 = std::clamp(std::abs(sts / sty), min_alpha, max_alpha);
90 double alpha_bb2 = std::clamp(std::abs(sty / yty), min_alpha, max_alpha);
93 if (!std::isfinite(alpha_bb1) || !std::isfinite(alpha_bb2) || alpha_bb1 <= 0.0
94 || alpha_bb2 <= 0.0) {
95 return safe_fallback();
99 const double r = (sty * sty) / (sts * yty);
102 constexpr double kLoose = 0.9;
103 constexpr double kTight = 0.1;
105 double alpha0 = alpha_bb2;
106 if (r > kLoose && last_backtracks <= 1) {
109 }
else if (r >= kTight && r <= kLoose) {
111 alpha0 = std::sqrt(alpha_bb1 * alpha_bb2);
115 alpha0 = std::clamp(alpha0, min_alpha, max_alpha);
117 if (!std::isfinite(alpha0) || alpha0 <= 0.0) {
118 return safe_fallback();
double barzilai_borwein_step_size(const Eigen::VectorXd &s, const Eigen::VectorXd &g_curr, const Eigen::VectorXd &g_prev, double prev_step, int last_backtracks, double min_alpha, double max_alpha)
Curvature-aware Barzilai–Borwein (BB) step length with robust safeguards.
A comparator that works for any container type that has the brackets operator.
static constexpr double e()
Return the base of the natural logarithm.