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();
34 max_time = std::min(max_time, *opts.max_time);
37 const auto n = problem.get_num_variables();
38 const auto m = problem.get_num_constraints();
39 const auto &C = problem.get_variable_bounds();
41 vec work_n(n), work_m(m);
44 struct BreakException {
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};
54 auto eval_objective_and_gradient = [&](
crvec xk,
rvec grad) {
61 auto time_elapsed = std::chrono::steady_clock::now() - start_time;
62 bool out_of_time = time_elapsed > max_time;
64 if (opts.always_overwrite_results)
67 s.
final_ψ = problem.eval_augmented_lagrangian(xk, y, Σ, work_m);
71 const auto ψx = problem.eval_augmented_lagrangian_and_gradient(
72 xk, y, Σ, grad, work_n, work_m);
74 if (!std::isfinite(ψx)) {
75 if (opts.always_overwrite_results)
85 s.
iterations = solver.minimize(eval_objective_and_gradient, x_solve,
88 if (
static_cast<int>(s.
iterations) == effective_params.max_iterations)
90 }
catch (
const BreakException &e) {
92 }
catch (
const std::exception &e) {
94 *
os <<
"[LBFGSB] Exception: " << e.what() << std::endl;
96 auto time_elapsed = std::chrono::steady_clock::now() - start_time;
97 s.
elapsed_time = duration_cast<nanoseconds>(time_elapsed);
100 s.
ε = solver.final_grad_norm();
104 opts.always_overwrite_results) {
106 s.
final_ψ = problem.eval_augmented_lagrangian(x_solve, y, Σ, ŷ);
107 if (err_z.size() > 0)
108 err_z = (ŷ - y).cwiseQuotient(Σ);