Nonconvex constrained optimization
Loading...
Searching...
No Matches
panoc-ocp.hpp
Go to the documentation of this file.
1#pragma once
2
6
7#include <chrono>
8#include <iostream>
9#include <limits>
10#include <string>
11
12namespace alpaqa {
13
14/// Tuning parameters for the PANOC algorithm.
15/// @ingroup grp_Parameters
16template <Config Conf = DefaultConfig>
19
20 /// Parameters related to the Lipschitz constant estimate and step size.
22 /// Maximum number of inner PANOC iterations.
23 unsigned max_iter = 100;
24 /// Maximum duration.
25 std::chrono::nanoseconds max_time = std::chrono::minutes(5);
26 /// Minimum weight factor between Newton step and projected gradient step,
27 /// line search parameter.
29 /// Parameter β used in the line search (see Algorithm 2 in
30 /// @cite de_marchi_proximal_2022). @f$ 0 < \beta < 1 @f$
32 /// Minimum Lipschitz constant estimate.
34 /// Maximum Lipschitz constant estimate.
36 /// Maximum number of times to double the Lipschitz constant estimate per
37 /// iteration.
38 unsigned L_max_inc = 16;
39 /// What stopping criterion to use.
41 /// Maximum number of iterations without any progress before giving up.
42 unsigned max_no_progress = 10;
43 /// How often to use a Gauss-Newton step. Zero to disable GN entirely.
44 unsigned gn_interval = 1;
45 /// Keep trying to apply a Gauss-Newton step as long as they keep getting
46 /// accepted with step size one.
47 bool gn_sticky = true;
48 /// Flush the L-BFGS buffer when a Gauss-Newton step is accepted.
50 /// Use a Cholesky factorization for the Riccati recursion. Use LU if set
51 /// to false.
53
54 /// L-BFGS parameters (e.g. memory).
56
57 /// When to print progress. If set to zero, nothing will be printed.
58 /// If set to N != 0, progress is printed every N iterations.
59 unsigned print_interval = 0;
60 /// The precision of the floating point values printed by the solver.
61 int print_precision = std::numeric_limits<real_t>::max_digits10 / 2;
62
63 /// Tolerance factor used in the quadratic upper bound condition that
64 /// determines the step size. Its goal is to account for numerical errors
65 /// in the function and gradient evaluations. If you notice that the step
66 /// size γ becomes very small, you may want to increase this factor.
68 real_t(1e2) * std::numeric_limits<real_t>::epsilon();
69 /// Tolerance factor used in the line search. Its goal is to account for
70 /// numerical errors in the function and gradient evaluations. If you notice
71 /// that accelerated steps are rejected (τ = 0) when getting closer to the
72 /// solution, you may want to increase this factor.
74 real_t(1e2) * std::numeric_limits<real_t>::epsilon();
75
76 /// Don't compute accelerated steps, fall back to forward-backward splitting.
77 /// For testing purposes.
79};
80
81template <Config Conf = DefaultConfig>
114
115template <Config Conf = DefaultConfig>
118
121 std::chrono::nanoseconds elapsed_time{};
122 std::chrono::nanoseconds time_prox{};
123 std::chrono::nanoseconds time_forward{};
124 std::chrono::nanoseconds time_backward{};
125 std::chrono::nanoseconds time_jacobians{};
126 std::chrono::nanoseconds time_hessians{};
127 std::chrono::nanoseconds time_indices{};
128 std::chrono::nanoseconds time_lqr_factor{};
129 std::chrono::nanoseconds time_lqr_solve{};
130 std::chrono::nanoseconds time_lbfgs_indices{};
131 std::chrono::nanoseconds time_lbfgs_apply{};
132 std::chrono::nanoseconds time_lbfgs_update{};
133 std::chrono::nanoseconds time_progress_callback{};
134 unsigned iterations = 0;
138 unsigned direction_failures = 0;
140 unsigned τ_1_accepted = 0;
141 unsigned count_τ = 0;
147};
148
149template <Config Conf>
151 public:
153
159
161
162 Stats operator()(const Problem &problem, // in
163 const SolveOptions &opts, // in
164 rvec u, // inout
165 rvec y, // in
166 crvec μ, // in
167 rvec err_z); // out
168
169 template <class P>
170 Stats operator()(const P &problem, const SolveOptions &opts, rvec u, rvec y,
171 crvec μ, rvec e) {
172 return operator()(Problem{&problem}, opts, u, y, μ, e);
173 }
174
175 template <class P>
176 Stats operator()(const P &problem, const SolveOptions &opts, rvec u) {
177 if (problem.get_num_constraints() != 0)
178 throw std::invalid_argument("Missing arguments y, Σ, e");
179 mvec y{nullptr, 0}, Σ{nullptr, 0}, e{nullptr, 0};
180 return operator()(problem, opts, u, y, Σ, e);
181 }
182
183 /// Specify a callable that is invoked with some intermediate results on
184 /// each iteration of the algorithm.
185 /// @see @ref ProgressInfo
187 set_progress_callback(std::function<void(const ProgressInfo &)> cb) {
188 this->progress_cb = cb;
189 return *this;
190 }
191
192 std::string get_name() const;
193
194 void stop() { stop_signal.stop(); }
195
196 const Params &get_params() const { return params; }
197
198 private:
200 guanaqo::AtomicStopSignal stop_signal;
201 std::function<void(const ProgressInfo &)> progress_cb;
203
204 public:
205 std::ostream *os = &std::cout;
206};
207
208template <Config Conf>
211
212 /// Total elapsed time in the inner solver.
213 std::chrono::nanoseconds elapsed_time{};
214 /// Total time spent computing proximal mappings.
215 std::chrono::nanoseconds time_prox{};
216 /// Total time spent doing forward simulations.
217 std::chrono::nanoseconds time_forward{};
218 /// Total time spent doing backward gradient evaluations.
219 std::chrono::nanoseconds time_backward{};
220 /// Total time spent computing dynamics Jacobians.
221 std::chrono::nanoseconds time_jacobians{};
222 /// Total time spent computing cost Hessians and Hessian-vector products.
223 std::chrono::nanoseconds time_hessians{};
224 /// Total time spent determining active indices.
225 std::chrono::nanoseconds time_indices{};
226 /// Total time spent performing LQR factorizations.
227 std::chrono::nanoseconds time_lqr_factor{};
228 /// Total time spent solving the (factorized) LQR problem.
229 std::chrono::nanoseconds time_lqr_solve{};
230 /// Total time spent determining active indices for L-BFGS applications.
231 std::chrono::nanoseconds time_lbfgs_indices{};
232 /// Total time spent applying L-BFGS estimates.
233 std::chrono::nanoseconds time_lbfgs_apply{};
234 /// Total time spent updating the L-BFGS estimate.
235 std::chrono::nanoseconds time_lbfgs_update{};
236 /// Total time spent in the user-provided progress callback.
237 std::chrono::nanoseconds time_progress_callback{};
238 /// Total number of inner PANOC iterations.
239 unsigned iterations = 0;
240 /// Total number of PANOC line search failures.
242 /// Total number of PANOC line search backtracking steps.
244 /// Total number of PANOC step size reductions.
246 /// Total number of times that the L-BFGS direction was not finite.
247 unsigned direction_failures = 0;
248 /// Total number of times that the L-BFGS update was rejected (i.e. it
249 /// could have resulted in a non-positive definite Hessian estimate).
251 /// Total number of times that a line search parameter of @f$ \tau = 1 @f$
252 /// was accepted (i.e. no backtracking necessary).
253 unsigned τ_1_accepted = 0;
254 /// The total number of line searches performed (used for computing the
255 /// average value of @f$ \tau @f$).
256 unsigned count_τ = 0;
257 /// The sum of the line search parameter @f$ \tau @f$ in all iterations
258 /// (used for computing the average value of @f$ \tau @f$).
260 /// The final PANOC step size γ.
262 /// Final value of the smooth cost @f$ \psi(\hat x) @f$.
264 /// Final value of the nonsmooth cost @f$ h(\hat x) @f$.
266 /// Final value of the forward-backward envelope, @f$ \varphi_\gamma(x) @f$
267 /// (note that this is in the point @f$ x @f$, not @f$ \hat x @f$).
269};
270
271template <Config Conf>
274 const PANOCOCPStats<Conf> &s) {
275 acc.iterations += s.iterations;
276 acc.elapsed_time += s.elapsed_time;
277 acc.time_prox += s.time_prox;
278 acc.time_forward += s.time_forward;
279 acc.time_backward += s.time_backward;
280 acc.time_jacobians += s.time_jacobians;
281 acc.time_hessians += s.time_hessians;
282 acc.time_indices += s.time_indices;
283 acc.time_lqr_factor += s.time_lqr_factor;
284 acc.time_lqr_solve += s.time_lqr_solve;
285 acc.time_lbfgs_indices += s.time_lbfgs_indices;
286 acc.time_lbfgs_apply += s.time_lbfgs_apply;
287 acc.time_lbfgs_update += s.time_lbfgs_update;
288 acc.time_progress_callback += s.time_progress_callback;
289 acc.linesearch_failures += s.linesearch_failures;
290 acc.linesearch_backtracks += s.linesearch_backtracks;
291 acc.stepsize_backtracks += s.stepsize_backtracks;
292 acc.direction_failures += s.direction_failures;
293 acc.direction_update_rejected += s.direction_update_rejected;
294 acc.τ_1_accepted += s.τ_1_accepted;
295 acc.count_τ += s.count_τ;
296 acc.sum_τ += s.sum_τ;
297 acc.final_γ = s.final_γ;
298 acc.final_ψ = s.final_ψ;
299 acc.final_h = s.final_h;
300 acc.final_φγ = s.final_φγ;
301 return acc;
302}
303// clang-format off
304ALPAQA_EXPORT_EXTERN_TEMPLATE(struct, PANOCOCPProgressInfo, EigenConfigd);
305ALPAQA_IF_FLOAT(ALPAQA_EXPORT_EXTERN_TEMPLATE(struct, PANOCOCPProgressInfo, EigenConfigf);)
306ALPAQA_IF_LONGD(ALPAQA_EXPORT_EXTERN_TEMPLATE(struct, PANOCOCPProgressInfo, EigenConfigl);)
307ALPAQA_IF_QUADF(ALPAQA_EXPORT_EXTERN_TEMPLATE(struct, PANOCOCPProgressInfo, EigenConfigq);)
308
309ALPAQA_EXPORT_EXTERN_TEMPLATE(class, PANOCOCPSolver, EigenConfigd);
310ALPAQA_IF_FLOAT(ALPAQA_EXPORT_EXTERN_TEMPLATE(class, PANOCOCPSolver, EigenConfigf);)
311ALPAQA_IF_LONGD(ALPAQA_EXPORT_EXTERN_TEMPLATE(class, PANOCOCPSolver, EigenConfigl);)
312ALPAQA_IF_QUADF(ALPAQA_EXPORT_EXTERN_TEMPLATE(class, PANOCOCPSolver, EigenConfigq);)
313// clang-format on
314
315} // namespace alpaqa
std::string get_name() const
Definition panoc-ocp.tpp:41
PANOCOCPProgressInfo< config_t > ProgressInfo
std::function< void(const ProgressInfo &)> progress_cb
InnerSolveOptions< config_t > SolveOptions
Stats operator()(const P &problem, const SolveOptions &opts, rvec u, rvec y, crvec μ, rvec e)
PANOCOCPSolver(const Params &params)
alpaqa::TypeErasedControlProblem< config_t > Problem
const Params & get_params() const
Stats operator()(const Problem &problem, const SolveOptions &opts, rvec u, rvec y, crvec μ, rvec err_z)
Definition panoc-ocp.tpp:46
Stats operator()(const P &problem, const SolveOptions &opts, rvec u)
guanaqo::AtomicStopSignal stop_signal
PANOCOCPParams< config_t > Params
PANOCOCPStats< config_t > Stats
detail::PANOCHelpers< config_t > Helpers
PANOCOCPSolver & set_progress_callback(std::function< void(const ProgressInfo &)> cb)
Specify a callable that is invoked with some intermediate results on each iteration of the algorithm.
Nonlinear optimal control problem with finite horizon .
#define USING_ALPAQA_CONFIG(Conf)
Definition config.hpp:77
#define ALPAQA_IF_QUADF(...)
Definition config.hpp:223
#define ALPAQA_IF_LONGD(...)
Definition config.hpp:235
#define ALPAQA_IF_FLOAT(...)
Definition config.hpp:229
#define ALPAQA_EXPORT_EXTERN_TEMPLATE(...)
Definition export.hpp:23
LipschitzEstimateParams< config_t > Lipschitz
Definition panoc-ocp.hpp:21
std::chrono::nanoseconds max_time
Definition panoc-ocp.hpp:25
LBFGSParams< config_t > lbfgs_params
Definition panoc-ocp.hpp:55
Parameters for the LBFGS class.
Definition lbfgs.hpp:42
Parameters for the estimation of the Lipschitz constant of the gradient of the smooth term of the cos...
Definition lipschitz.hpp:12
Tuning parameters for the PANOC algorithm.
Definition panoc-ocp.hpp:17
typename Conf::mvec mvec
Definition config.hpp:89
std::chrono::nanoseconds time_jacobians
@ ApproxKKT
Find an ε-approximate KKT point in the ∞-norm:
std::chrono::nanoseconds time_hessians
std::chrono::nanoseconds time_lbfgs_apply
std::chrono::nanoseconds time_lbfgs_indices
SolverStatus
Exit status of a numerical solver such as ALM or PANOC.
std::chrono::nanoseconds time_progress_callback
std::chrono::nanoseconds time_indices
std::chrono::nanoseconds elapsed_time
std::chrono::nanoseconds time_backward
typename Conf::real_t real_t
Definition config.hpp:86
std::chrono::nanoseconds time_lqr_factor
InnerStatsAccumulator< FISTAStats< Conf > > & operator+=(InnerStatsAccumulator< FISTAStats< Conf > > &acc, const FISTAStats< Conf > &s)
Definition fista.hpp:191
typename Conf::length_t length_t
Definition config.hpp:103
constexpr const auto inf
Definition config.hpp:112
typename Conf::rvec rvec
Definition config.hpp:91
typename Conf::crvec crvec
Definition config.hpp:92
std::chrono::nanoseconds time_prox
std::chrono::nanoseconds time_forward
typename Conf::vec vec
Definition config.hpp:88
std::chrono::nanoseconds time_lbfgs_update
std::chrono::nanoseconds time_lqr_solve
const TypeErasedControlProblem< config_t > * problem
const PANOCOCPParams< config_t > * params
PANOCOCPProgressInfo & operator=(const PANOCOCPProgressInfo &)=delete