12 using std::chrono::duration_cast;
13 using std::chrono::microseconds;
15 template <
class InnerSolverT>
18 auto start_time = std::chrono::steady_clock::now();
20 constexpr
auto sigNaN = std::numeric_limits<real_t>::signaling_NaN();
34 if (
params.preconditioning)
51 bool first_successful_iter =
true;
53 for (
unsigned int i = 0; i <
params.max_iter; ++i) {
58 bool out_of_penalty_factor_updates =
59 (first_successful_iter
63 params.max_total_num_retries);
64 bool out_of_iter = i + 1 ==
params.max_iter;
68 bool overwrite_results = out_of_iter || out_of_penalty_factor_updates;
75 auto ps = inner_solver(
p,
Σ,
ε, overwrite_results,
x,
y, error₂);
76 bool inner_converged = ps.status == SolverStatus::Converged;
81 auto time_elapsed = std::chrono::steady_clock::now() - start_time;
82 bool out_of_time = time_elapsed >
params.max_time;
84 not inner_converged && not overwrite_results && not out_of_time;
87 if (
params.print_interval != 0 && i %
params.print_interval == 0) {
89 auto color = inner_converged ?
"\x1b[0;32m" :
"\x1b[0;31m";
90 auto color_end =
"\x1b[0m";
91 std::cout <<
"[\x1b[0;34mALM\x1b[0m] " << std::setw(5) << i
92 <<
": ‖Σ‖ = " << std::setw(13) <<
Σ.norm()
93 <<
", ‖y‖ = " << std::setw(13) <<
y.norm()
94 <<
", δ = " << std::setw(13) << δ
95 <<
", ε = " << std::setw(13) << ps.ε
96 <<
", Δ = " << std::setw(13) << Δ
97 <<
", status = " <<
color << std::setw(13) << ps.status
98 << color_end <<
", iter = " << std::setw(13)
99 << ps.iterations <<
"\r\n";
108 s.
elapsed_time = duration_cast<microseconds>(time_elapsed);
110 if (
params.preconditioning)
111 y = prec_g.asDiagonal() *
y / prec_f;
127 if (not first_successful_iter) {
130 Δ = std::fmax(1., Δ *
params.Δ_lower);
132 error₁, error₂, norm_e₁, norm_e₂,
135 ρ = std::fmin(0.5, ρ *
params.ρ_increase);
136 ε = std::fmax(ρ * ε_old,
params.ε);
157 ps.ε <=
params.ε && inner_converged && norm_e₁ <=
params.δ;
158 bool exit = alm_converged || out_of_iter || out_of_time;
164 s.
elapsed_time = duration_cast<microseconds>(time_elapsed);
165 s.
status = alm_converged ? SolverStatus::Converged
166 : out_of_time ? SolverStatus::MaxTime
167 : out_of_iter ? SolverStatus::MaxIter
168 : SolverStatus::Unknown;
169 if (
params.preconditioning)
170 y = prec_g.asDiagonal() *
y / prec_f;
178 error₁, error₂, norm_e₁, norm_e₂,
181 ε_old = std::exchange(
ε, std::fmax(ρ *
ε,
params.ε));
182 first_successful_iter =
false;
185 throw std::logic_error(
"[ALM] loop error");
188 template <
class InnerSolverT>
191 auto start_time = std::chrono::steady_clock::now();
193 constexpr
auto sigNaN = std::numeric_limits<real_t>::signaling_NaN();
195 vec Σ1_old = vec::Constant(
problem.m1, sigNaN);
197 vec Σ2_old = vec::Constant(
problem.m2, sigNaN);
198 vec error1₁ = vec::Constant(
problem.m1, sigNaN);
199 vec error1₂ = vec::Constant(
problem.m1, sigNaN);
200 vec error2₁ = vec::Constant(
problem.m2, sigNaN);
201 vec error2₂ = vec::Constant(
problem.m2, sigNaN);
233 bool first_successful_iter =
true;
235 for (
unsigned int i = 0; i <
params.max_iter; ++i) {
240 bool out_of_penalty_factor_updates =
241 (first_successful_iter
245 params.max_total_num_retries);
246 bool out_of_iter = i + 1 ==
params.max_iter;
250 bool overwrite_results = out_of_iter || out_of_penalty_factor_updates;
257 auto time_elapsed = std::chrono::steady_clock::now() - start_time;
258 auto ps = inner_solver(
p, Σ1, Σ2,
ε, overwrite_results,
x,
y, error1₂, error2₂, std::chrono::duration_cast<std::chrono::microseconds>(
params.max_time - time_elapsed));
259 bool inner_converged = ps.status == SolverStatus::Converged;
264 time_elapsed = std::chrono::steady_clock::now() - start_time;
265 bool out_of_time = time_elapsed >
params.max_time;
267 not inner_converged && not overwrite_results && not out_of_time;
270 if (
params.print_interval != 0 && i %
params.print_interval == 0) {
272 auto color = inner_converged ?
"\x1b[0;32m" :
"\x1b[0;31m";
273 auto color_end =
"\x1b[0m";
274 std::cout <<
"[\x1b[0;34mALM\x1b[0m] " << std::setw(5) << i
275 <<
": ‖Σ1‖ = " << std::setw(13) << Σ1.norm()
276 <<
": ‖Σ2‖ = " << std::setw(13) << Σ2.norm()
277 <<
", ‖y‖ = " << std::setw(13) <<
y.norm()
278 <<
", δ = " << std::setw(13) << δ
279 <<
", ε = " << std::setw(13) << ps.ε
280 <<
", Δ = " << std::setw(13) << Δ
281 <<
", status = " <<
color << std::setw(13) << ps.status
282 << color_end <<
", iter = " << std::setw(13)
283 << ps.iterations <<
"\r\n";
295 s.
elapsed_time = duration_cast<microseconds>(time_elapsed);
314 if (not first_successful_iter) {
317 Δ = std::fmax(1., Δ *
params.Δ_lower);
319 error1₁, error1₂, norm_e1₁, norm_e1₂,
322 error2₁, error2₂, norm_e2₁, norm_e2₂,
325 ρ = std::fmin(0.5, ρ *
params.ρ_increase);
326 ε = std::fmax(ρ * ε_old,
params.ε);
343 error1₂.swap(error1₁);
345 error2₂.swap(error2₁);
349 bool alm_converged = ps.ε <=
params.ε && inner_converged &&
351 bool exit = alm_converged || out_of_iter || out_of_time;
360 s.
elapsed_time = duration_cast<microseconds>(time_elapsed);
361 s.
status = alm_converged ? SolverStatus::Converged
362 : out_of_time ? SolverStatus::MaxTime
363 : out_of_iter ? SolverStatus::MaxIter
364 : SolverStatus::Unknown;
375 error1₁, error1₂, norm_e1₁, norm_e1₂,
378 error2₁, error2₂, norm_e2₁, norm_e2₂,
381 ε_old = std::exchange(
ε, std::fmax(ρ *
ε,
params.ε));
382 first_successful_iter =
false;
385 throw std::logic_error(
"[ALM] loop error");