21 std::optional<rvec> Σ) {
22 using std::chrono::duration_cast;
23 using std::chrono::nanoseconds;
24 auto start_time = std::chrono::steady_clock::now();
32 auto m = p.get_num_constraints();
35 vec Σ_curr(0), error(0);
37 .always_overwrite_results =
true,
38 .max_time =
params.max_time,
39 .tolerance =
params.tolerance,
45 auto time_elapsed = std::chrono::steady_clock::now() - start_time;
52 s.
elapsed_time = duration_cast<nanoseconds>(time_elapsed);
58 vec Σ_curr = vec::Constant(m,
NaN);
59 vec error = vec::Constant(m,
NaN);
60 vec error_old = vec::Constant(m,
NaN);
63 std::array<char, 64> printbuf;
64 auto print_real = [&](
real_t x) {
65 return float_to_str_vw(printbuf, x,
params.print_precision);
70 if (Σ && Σ->allFinite() && Σ->norm() > 0) {
74 else if (
params.initial_penalty > 0) {
75 Σ_curr.setConstant(
params.initial_penalty);
85 for (
unsigned i = 0; i <
params.max_iter; ++i) {
86 p.eval_projection_multipliers(y,
params.max_multiplier);
87 bool out_of_iter = i + 1 ==
params.max_iter;
89 auto time_elapsed = std::chrono::steady_clock::now() - start_time;
90 auto time_remaining = time_elapsed <
params.max_time
91 ?
params.max_time - time_elapsed
92 :
decltype(time_elapsed){0};
94 .always_overwrite_results =
true,
95 .max_time = time_remaining,
111 norm_e = norm_inf(error);
113 time_elapsed = std::chrono::steady_clock::now() - start_time;
114 bool out_of_time = time_elapsed >
params.max_time;
117 if (
params.print_interval != 0 && i %
params.print_interval == 0) {
118 const char *color = inner_converged ?
"\x1b[0;32m" :
"\x1b[0;31m";
119 const char *color_end =
"\x1b[0m";
120 *
os <<
"[\x1b[0;34mALM\x1b[0m] " << std::setw(5) << i
121 <<
": ‖Σ‖ = " << print_real(Σ_curr.norm())
122 <<
", ‖y‖ = " << print_real(y.norm())
123 <<
", δ = " << print_real(norm_e)
124 <<
", ε = " << print_real(ps.ε) <<
", status = " << color
125 << std::setw(13) << ps.status << color_end
126 <<
", iter = " << std::setw(13) << ps.iterations
136 s.
elapsed_time = duration_cast<nanoseconds>(time_elapsed);
144 bool alm_converged = ps.ε <=
params.tolerance && inner_converged &&
145 norm_e <=
params.dual_tolerance;
146 bool exit = alm_converged || out_of_iter || out_of_time;
152 s.
elapsed_time = duration_cast<nanoseconds>(time_elapsed);
163 i == 0, error, error_old, norm_e,
166 ε = std::fmax(
params.tolerance_update_factor * ε,
params.tolerance);
169 error.swap(error_old);
171 throw std::logic_error(
"[ALM] loop error");
static void update_penalty_weights(const ALMParams< config_t > ¶ms, real_t Δ, bool first_iter, rvec e, rvec old_e, real_t norm_e, real_t old_norm_e, rvec Σ)