alpaqa 1.1.0a1
Nonconvex constrained optimization
Loading...
Searching...
No Matches
lbfgsb-adapter.tpp
Go to the documentation of this file.
1#pragma once
2
4#include <cmath>
5#include <exception>
6
7namespace alpaqa::lbfgspp {
8
9template <Config Conf>
10std::string LBFGSBSolver<Conf>::get_name() const {
11 return "LBFGSBSolver";
12}
13
14template <Config Conf>
16 /// [in] Problem description
17 const Problem &problem,
18 /// [in] Solve options
19 const SolveOptions &opts,
20 /// [inout] Decision variable @f$ x @f$
21 rvec x,
22 /// [inout] Lagrange multipliers @f$ y @f$
23 rvec y,
24 /// [in] Constraint weights @f$ \Sigma @f$
25 crvec Σ,
26 /// [out] Slack variable error @f$ g(x) - \Pi_D(g(x) + \Sigma^{-1} y) @f$
27 rvec err_z) -> Stats {
28
29 using std::chrono::nanoseconds;
30 auto start_time = std::chrono::steady_clock::now();
31 auto os = opts.os ? opts.os : this->os;
32 auto max_time = nanoseconds::max();
33 if (opts.max_time)
34 max_time = std::min(max_time, *opts.max_time);
35 Stats s;
36
37 const auto n = problem.get_num_variables();
38 const auto m = problem.get_num_constraints();
39 const auto &C = problem.get_variable_bounds();
40
41 vec work_n(n), work_m(m);
42 vec x_solve = x;
43
44 struct BreakException {
46 };
47
48 ::LBFGSpp::LBFGSBParam<real_t> effective_params = params;
49 effective_params.epsilon = opts.tolerance;
50 effective_params.epsilon_rel = 0;
51 ::LBFGSpp::LBFGSBSolver<real_t> solver{effective_params};
52
53 // Evaluate cost and its gradient, checking for termination
54 auto eval_objective_and_gradient = [&](crvec xk, rvec grad) {
55 // Check user interrupt
56 if (stop_signal.stop_requested()) {
57 x_solve = xk;
58 throw BreakException{SolverStatus::Interrupted};
59 }
60 // Check maximum run time
61 auto time_elapsed = std::chrono::steady_clock::now() - start_time;
62 bool out_of_time = time_elapsed > max_time;
63 if (out_of_time) {
64 if (opts.always_overwrite_results)
65 x_solve = xk;
66 else
67 s.final_ψ = problem.eval_augmented_lagrangian(xk, y, Σ, work_m);
68 throw BreakException{SolverStatus::MaxTime};
69 }
70 // Perform the actual evaluation
71 const auto ψx = problem.eval_augmented_lagrangian_and_gradient(
72 xk, y, Σ, grad, work_n, work_m);
73 // Check that the function value is finite
74 if (!std::isfinite(ψx)) {
75 if (opts.always_overwrite_results)
76 x_solve = xk;
77 s.final_ψ = ψx;
78 throw BreakException{SolverStatus::NotFinite};
79 }
80 return ψx;
81 };
82
83 // Solve problem
84 try {
85 s.iterations = solver.minimize(eval_objective_and_gradient, x_solve,
86 s.final_ψ, C.lower, C.upper);
88 if (static_cast<int>(s.iterations) == effective_params.max_iterations)
90 } catch (const BreakException &e) {
91 s.status = e.status;
92 } catch (const std::exception &e) {
94 *os << "[LBFGSB] Exception: " << e.what() << std::endl;
95 }
96 auto time_elapsed = std::chrono::steady_clock::now() - start_time;
97 s.elapsed_time = duration_cast<nanoseconds>(time_elapsed);
98
99 // Check final error
100 s.ε = solver.final_grad_norm();
101 // Update result vectors
104 opts.always_overwrite_results) {
105 auto &ŷ = work_m;
106 s.final_ψ = problem.eval_augmented_lagrangian(x_solve, y, Σ, ŷ);
107 if (err_z.size() > 0)
108 err_z = (ŷ - y).cwiseQuotient(Σ);
109 x = x_solve;
110 y = ŷ;
111 }
112 return s;
113}
114
115} // namespace alpaqa::lbfgspp
Stats operator()(const Problem &problem, const SolveOptions &opts, rvec x, rvec y, crvec Σ, rvec err_z)
InnerSolveOptions< config_t > SolveOptions
LBFGSBStats< config_t > Stats
guanaqo::AtomicStopSignal stop_signal
TypeErasedProblem< config_t > Problem
std::chrono::nanoseconds elapsed_time
SolverStatus
Exit status of a numerical solver such as ALM or PANOC.
@ Interrupted
Solver was interrupted by the user.
@ MaxTime
Maximum allowed execution time exceeded.
@ Exception
An unexpected exception was thrown.
@ MaxIter
Maximum number of iterations exceeded.
@ Converged
Converged and reached given tolerance.
@ NotFinite
Intermediate results were infinite or not-a-number.
typename Conf::rvec rvec
Definition config.hpp:91
typename Conf::crvec crvec
Definition config.hpp:92
typename Conf::vec vec
Definition config.hpp:88