86 using std::chrono::nanoseconds;
87 auto os =
opts.os ?
opts.os : this->os;
88 auto start_time = std::chrono::steady_clock::now();
91 const auto n = problem.get_n();
92 const auto m = problem.get_m();
119 bool need_grad_ψx̂ = Helpers::stop_crit_requires_grad_ψx̂(params.stop_crit);
121 curr->grad_ψx̂.resize(n);
130 (1 + std::abs(i.ψx)) * params.quadratic_upperbound_tolerance_factor;
131 return i.ψx̂ > i.ψx + i.grad_ψᵀp +
real_t(0.5) * i.L * i.pᵀp +
margin;
136 auto eval_ψ_grad_ψ = [&problem, &y, &Σ, &
work_n1, &work_m](
Iterate &i) {
137 i.ψx = problem.eval_ψ_grad_ψ(i.x, y, Σ, i.grad_ψ,
work_n1, work_m);
139 auto eval_grad_ψ = [&problem, &y, &Σ, &
work_n1, &work_m](
Iterate &i) {
140 problem.eval_grad_ψ(i.x, y, Σ, i.grad_ψ,
work_n1, work_m);
142 auto eval_prox_grad_step = [&problem](
Iterate &i) {
143 i.hx̂ = problem.eval_prox_grad_step(i.γ, i.x, i.grad_ψ, i.x̂, i.p);
144 i.pᵀp = i.p.squaredNorm();
145 i.grad_ψᵀp = i.p.dot(i.grad_ψ);
148 i.ψx̂ = problem.eval_ψ(i.x̂, y, Σ, i.ŷx̂);
152 problem.eval_grad_L(i.x̂, i.ŷx̂, i.grad_ψx̂,
work_n1);
165 *os <<
"┌─[FISTA]\n";
167 *os <<
"├─ " << std::setw(6) << k <<
'\n';
175 *os <<
"└─ " << status <<
" ──"
198 .grad_ψ_hat = it.grad_ψx̂,
205 .outer_iter =
opts.outer_iter,
221 curr->L = params.L_max;
226 else if (params.Lipschitz.L_0 <= 0) {
227 curr->L = Helpers::initial_lipschitz_estimate(
228 problem,
curr->x, y, Σ, params.Lipschitz.ε, params.Lipschitz.δ,
229 params.L_min, params.L_max,
235 curr->L = params.Lipschitz.L_0;
237 eval_ψ_grad_ψ(*
curr);
239 if (
not std::isfinite(
curr->L)) {
243 curr->γ = params.Lipschitz.Lγ_factor /
curr->L;
261 eval_prox_grad_step(*
curr);
274 eval_prox_grad_step(*
curr);
282 if (
no_progress > 0 || k % params.max_no_progress == 0)
285 real_t εₖ = Helpers::calc_error_stop_crit(
290 auto stop_status = Helpers::check_all_stop_conditions(
297 if (params.print_interval) {
307 opts.always_overwrite_results) {
309 if (
err_z.size() > 0)
327 params.print_interval != 0 && k % params.print_interval == 0;
341 if (params.disable_acceleration)
349 eval_ψ_grad_ψ(*
curr);
354 throw std::logic_error(
"[FISTA] loop error");