alpaqa pi-pico
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_n();
38 const auto m = problem.get_m();
39 const auto &C = problem.get_box_C();
40
41 vec work_n(n), work_m(m);
42 vec x_solve = x;
43
44 struct BreakException {
45 SolverStatus status = SolverStatus::Busy;
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_f_grad_f = [&](crvec xk, rvec grad) {
55 // Check user interrupt
56 if (stop_signal.stop_requested()) {
57 x_solve = xk;
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_ψ(xk, y, Σ, work_m);
69 }
70 // Perform the actual evaluation
71 const auto ψx = problem.eval_ψ_grad_ψ(xk, y, Σ, grad, work_n, work_m);
72 // Check that the function value is finite
73 if (!std::isfinite(ψx)) {
74 if (opts.always_overwrite_results)
75 x_solve = xk;
76 s.final_ψ = ψx;
78 }
79 return ψx;
80 };
81
82 // Solve problem
83 try {
84 s.iterations = solver.minimize(eval_f_grad_f, x_solve, s.final_ψ,
85 C.lowerbound, C.upperbound);
87 if (static_cast<int>(s.iterations) == effective_params.max_iterations)
89 } catch (const BreakException &e) {
90 s.status = e.status;
91 } catch (const std::exception &e) {
93 *os << "[LBFGSB] Exception: " << e.what() << std::endl;
94 }
95 auto time_elapsed = std::chrono::steady_clock::now() - start_time;
97
98 // Check final error
99 s.ε = solver.final_grad_norm();
100 // Update result vectors
103 opts.always_overwrite_results) {
104 auto &ŷ = work_m;
105 s.final_ψ = problem.eval_ψ(x_solve, y, Σ, ŷ);
106 if (err_z.size() > 0)
107 err_z = (ŷ - y).cwiseQuotient(Σ);
108 x = x_solve;
109 y = ŷ;
110 }
111 return s;
112}
113
114} // namespace alpaqa::lbfgspp
Stats operator()(const Problem &problem, const SolveOptions &opts, rvec x, rvec y, crvec Σ, rvec err_z)
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.
constexpr const auto inf
Definition config.hpp:112
typename Conf::rvec rvec
Definition config.hpp:91
typename Conf::crvec crvec
Definition config.hpp:92
typename Conf::vec vec
Definition config.hpp:88