Nonconvex constrained optimization
Loading...
Searching...
No Matches
alm-driver.hpp
Go to the documentation of this file.
1#pragma once
2
8
10
11namespace alpaqa::driver {
12
13template <class InnerSolver>
14auto make_alm_solver(InnerSolver &&inner_solver, Options &opts) {
15 // Settings for the ALM solver
17 typename ALMSolver::Params alm_param;
18 alm_param.max_iter = 200;
19 alm_param.tolerance = 1e-8;
20 alm_param.dual_tolerance = 1e-8;
21 alm_param.print_interval = 1;
22 alm_param.print_precision = 1;
23 set_params(alm_param, "alm", opts);
24 return ALMSolver{alm_param, std::forward<InnerSolver>(inner_solver)};
25}
26
28
29template <class InnerSolver>
31 // Settings for the solver
32 typename InnerSolver::Params solver_param;
33 solver_param.max_iter = 50'000;
34 solver_param.print_interval = 0;
35 solver_param.stop_crit = PANOCStopCrit::ProjGradUnitNorm;
36 set_params(solver_param, "solver", opts);
37
38 if constexpr (requires { typename InnerSolver::Direction; }) {
39 // Settings for the direction provider
40 using Direction = typename InnerSolver::Direction;
41 typename Direction::DirectionParams dir_param;
42 typename Direction::AcceleratorParams accel_param;
43 set_params(dir_param, "dir", opts);
44 set_params(accel_param, "accel", opts);
45 return InnerSolver{
46 solver_param,
47 Direction{{
48 .accelerator = accel_param,
49 .direction = dir_param,
50 }},
51 };
52 } else {
53 return InnerSolver{solver_param};
54 }
55}
56
57template <class Solver>
59 std::ostream &os, unsigned N_exp) {
60
61 solver.os = &os;
62
63 // Initial guess
64 vec x = problem.initial_guess_x, y = problem.initial_guess_y;
65 // Final penalties
66 vec Σ = vec::Constant(problem.problem.get_num_constraints(), NaN<config_t>);
67
68 // Solve the problem
69 auto stats = solver(problem.problem, x, y, Σ);
70
71 // Solve the problems again to average runtimes
72 auto avg_duration = stats.elapsed_time;
73 os.setstate(std::ios_base::badbit); // suppress output
74 for (unsigned i = 0; i < N_exp; ++i) {
75 x = problem.initial_guess_x;
76 y = problem.initial_guess_y;
77 auto s = solver(problem.problem, x, y);
78 if (s.status == SolverStatus::Interrupted) {
79 os.clear();
80 os << "\rInterrupted after " << i << " runs" << std::endl;
81 N_exp = i;
82 break;
83 }
84 avg_duration += s.elapsed_time;
85 }
86 os.clear();
87 avg_duration /= (N_exp + 1);
88
89 solver.os = &std::cout;
90
91 // Store the evaluation counters
92 auto evals = *problem.evaluations;
93
94 // Results
95 real_t final_γ = 0, final_h = 0;
96 if constexpr (requires { stats.inner.final_γ; })
97 final_γ = stats.inner.final_γ;
98 if constexpr (requires { stats.inner.final_h; })
99 final_h = stats.inner.final_h;
100 decltype(SolverResults::extra) extra{};
101 if constexpr (requires { stats.inner.linesearch_failures; })
102 extra.emplace_back(
103 "linesearch_failures",
104 static_cast<index_t>(stats.inner.linesearch_failures));
105 if constexpr (requires { stats.inner.linesearch_backtracks; })
106 extra.emplace_back(
107 "linesearch_backtracks",
108 static_cast<index_t>(stats.inner.linesearch_backtracks));
109 if constexpr (requires { stats.inner.stepsize_backtracks; })
110 extra.emplace_back(
111 "stepsize_backtracks",
112 static_cast<index_t>(stats.inner.stepsize_backtracks));
113 if constexpr (requires { stats.inner.direction_failures; })
114 extra.emplace_back(
115 "direction_failures",
116 static_cast<index_t>(stats.inner.direction_failures));
117 if constexpr (requires { stats.inner.direction_update_rejected; })
118 extra.emplace_back(
119 "direction_update_rejected",
120 static_cast<index_t>(stats.inner.direction_update_rejected));
121 if constexpr (requires { stats.inner.accelerated_step_rejected; })
122 extra.emplace_back(
123 "accelerated_step_rejected",
124 static_cast<index_t>(stats.inner.accelerated_step_rejected));
125 if constexpr (requires { stats.inner.direction_failures; })
126 extra.emplace_back(
127 "direction_failures",
128 static_cast<index_t>(stats.inner.direction_failures));
129 if constexpr (requires { stats.inner.direction_update_rejected; })
130 extra.emplace_back(
131 "direction_update_rejected",
132 static_cast<index_t>(stats.inner.direction_update_rejected));
133 return SolverResults{
134 .status = enum_name(stats.status),
135 .success = stats.status == SolverStatus::Converged,
136 .evals = evals,
137 .duration = avg_duration,
138 .solver = solver.get_name(),
139 .h = final_h,
140 .δ = stats.δ,
141 .ε = stats.ε,
142 .γ = final_γ,
143 .Σ = stats.norm_penalty,
144 .solution = x,
145 .multipliers = y,
146 .multipliers_bounds = vec(0),
147 .penalties = Σ,
148 .outer_iter = static_cast<index_t>(stats.outer_iterations),
149 .inner_iter = static_cast<index_t>(stats.inner.iterations),
150 .extra = std::move(extra),
151 };
152}
153
154} // namespace alpaqa::driver
Augmented Lagrangian Method solver.
Definition alm.hpp:69
ALMParams< config_t > Params
Definition alm.hpp:73
length_t get_num_constraints() const
[Required] Number of constraints.
#define USING_ALPAQA_CONFIG(Conf)
Definition config.hpp:77
real_t tolerance
Primal tolerance (used for stopping criterion of inner solver).
Definition alm.hpp:25
unsigned int max_iter
Maximum number of outer ALM iterations.
Definition alm.hpp:51
real_t dual_tolerance
Dual tolerance (constraint violation and complementarity).
Definition alm.hpp:27
unsigned print_interval
When to print progress.
Definition alm.hpp:57
int print_precision
The precision of the floating point values printed by the solver.
Definition alm.hpp:59
auto make_inner_solver(Options &opts)
SolverResults run_alm_solver(LoadedProblem &problem, Solver &solver, std::ostream &os, unsigned N_exp)
auto make_alm_solver(InnerSolver &&inner_solver, Options &opts)
@ ProjGradUnitNorm
∞-norm of the projected gradient with unit step size:
vec initial_guess_y
Multipliers g.
EigenConfigd DefaultConfig
Definition config.hpp:31
@ Interrupted
Solver was interrupted by the user.
@ Converged
Converged and reached given tolerance.
typename Conf::real_t real_t
Definition config.hpp:86
constexpr const auto NaN
Definition config.hpp:114
typename Conf::index_t index_t
Definition config.hpp:104
alpaqa::TypeErasedProblem< config_t > problem
void set_params(T &t, std::string_view prefix, Options &opts)
Definition options.hpp:128
typename Conf::vec vec
Definition config.hpp:88
constexpr const char * enum_name(LBFGSStepSize s)
Definition lbfgs.hpp:229
std::shared_ptr< alpaqa::EvalCounter > evaluations
std::vector< std::pair< std::string, any_stat_t > > extra
Definition results.hpp:37