proxsuite-nlp  0.11.0
A primal-dual augmented Lagrangian-type solver for nonlinear programming on manifolds.
 
Loading...
Searching...
No Matches
prox-solver.hpp
Go to the documentation of this file.
1
4#pragma once
5
15
16#include <boost/mpl/bool.hpp>
17
18#include "proxsuite-nlp/modelling/costs/squared-distance.hpp"
19
21
22namespace proxsuite {
23namespace nlp {
24
25enum class MultiplierUpdateMode { NEWTON, PRIMAL, PRIMAL_DUAL };
26
37
38enum InertiaFlag { INERTIA_OK = 0, INERTIA_BAD = 1, INERTIA_HAS_ZEROS = 2 };
39
40enum KktSystem { KKT_CLASSIC, KKT_PRIMAL_DUAL };
41
45template <typename _Scalar> class ProxNLPSolverTpl {
46public:
47 using Scalar = _Scalar;
49 using Problem = ProblemTpl<Scalar>;
50 using Workspace = WorkspaceTpl<Scalar>;
51 using Results = ResultsTpl<Scalar>;
52 using Manifold = ManifoldAbstractTpl<Scalar>;
53 using LinesearchOptions = typename Linesearch<Scalar>::Options;
54 using CallbackPtr = shared_ptr<helpers::base_callback<Scalar>>;
55 using ConstraintSet = ConstraintSetTpl<Scalar>;
56 using ConstraintObject = ConstraintObjectTpl<Scalar>;
58
59protected:
61 Problem *problem_;
62
63public:
68
74 LinesearchStrategy ls_strat = LinesearchStrategy::ARMIJO;
75 MultiplierUpdateMode mul_update_mode = MultiplierUpdateMode::NEWTON;
76
77 mutable BFGS bfgs_strategy_;
78
80 std::size_t max_refinement_steps_ = 5;
81 Scalar kkt_tolerance_ = 1e-13;
82 LDLTChoice ldlt_choice_;
83 KktSystem kkt_system_ = KKT_CLASSIC;
84
86
87 Scalar inner_tol0 = 1.;
88 Scalar prim_tol0 = 1.;
89 Scalar inner_tol_ = inner_tol0;
90 Scalar prim_tol_ = prim_tol0;
91 Scalar rho_init_; //< Initial primal proximal penalty parameter.
92 Scalar mu_init_; //< Initial penalty parameter.
93private:
94 Scalar rho_ = rho_init_; //< Primal proximal penalty parameter.
95 Scalar mu_ = mu_init_; //< Penalty parameter.
96 Scalar mu_inv_ = 1. / mu_; //< Inverse penalty parameter.
97public:
98 Scalar inner_tol_min = 1e-9; //< Lower safeguard for the subproblem tolerance.
99 Scalar mu_upper_ = 1.; //< Upper safeguard for the penalty parameter.
100 Scalar mu_lower_ = 1e-9; //< Lower safeguard for the penalty parameter.
101 Scalar pdal_beta_ = 0.5; //< primal-dual weight for the dual variables.
102
105
107 LinesearchOptions ls_options;
108
111
114
116
117 Scalar del_inc_k = 8.; //< Inertia corrector increase factor
118 Scalar del_inc_big = 100.; //< Inertia corrector increase factor (big)
119 Scalar del_dec_k = 1. / 3.; //< Inertia corrector decrease factor
120 Scalar DELTA_MIN = 1e-14; //< Minimum nonzero regularization strength.
121 Scalar DELTA_MAX = 1e6; //< Maximum regularization strength.
122 Scalar DELTA_NONZERO_INIT = 1e-4;
123 Scalar DELTA_INIT = 0.;
124
125 std::size_t max_iters = 100; //< Solver maximum number of iterations.
126 std::size_t max_al_iters = 1000; //< Maximum outer (AL) iterations.
127
129 std::vector<CallbackPtr> callbacks_;
130
131 unique_ptr<Workspace> workspace_;
132 unique_ptr<Results> results_;
133
134 ProxNLPSolverTpl(Problem &prob, const Scalar tol = 1e-6,
135 const Scalar mu_eq_init = 1e-2, const Scalar rho_init = 0.,
136 const VerboseLevel verbose = QUIET,
137 const Scalar mu_lower = 1e-9, const Scalar prim_alpha = 0.1,
138 const Scalar prim_beta = 0.9, const Scalar dual_alpha = 1.,
139 const Scalar dual_beta = 1.,
141 const LinesearchOptions ls_options = LinesearchOptions());
142
143 const Problem &problem() const { return *problem_; }
144
145 const Manifold &manifold() const { return *problem_->manifold_; }
146
147 void setup() {
148 workspace_ = std::make_unique<Workspace>(*problem_, ldlt_choice_);
149 results_ = std::make_unique<Results>(*problem_);
150
151 if (hess_approx == HessianApprox::BFGS) {
152 // TODO: work on implementation of BFGS on manifolds
153 if (problem_->ndx() == problem_->nx()) {
154 BFGS valid_bfgs_strategy_ = BFGS(problem_->ndx());
155 bfgs_strategy_ = std::move(valid_bfgs_strategy_);
156 // set workspace hessian to identity matrix (init to zero in workspace)
157 workspace_->objective_hessian.setIdentity();
158 } else {
159 throw std::runtime_error("BFGS for hessian approximation currently "
160 "only works for Euclidean manifolds.");
161 }
162 }
163 }
164
173 ConvergenceFlag solve(const ConstVectorRef &x0,
174 const std::vector<VectorRef> &lams0);
175
176 PROXSUITE_NLP_DEPRECATED
177 const Workspace &getWorkspace() const { return *workspace_; }
178 PROXSUITE_NLP_DEPRECATED
179 const Results &getResults() const { return *results_; }
180
189 ConvergenceFlag solve(const ConstVectorRef &x0,
190 const ConstVectorRef &lams0 = VectorXs(0));
191
192 void innerLoop(Workspace &workspace, Results &results);
193
194 void assembleKktMatrix(Workspace &workspace);
195
197 PROXSUITE_NLP_INLINE bool iterativeRefinement(Workspace &workspace) const;
198
201 inline void updatePenalty();
202
204 void setDualPenalty(const Scalar beta) { pdal_beta_ = beta; }
205
208 void setPenalty(const Scalar &new_mu) noexcept;
209
211 void setProxParameter(const Scalar &new_rho) noexcept;
212
214 inline void registerCallback(const CallbackPtr &cb) noexcept {
215 callbacks_.push_back(cb);
216 }
217
219 void clearCallbacks() noexcept { callbacks_.clear(); }
220
227 void updateToleranceFailure() noexcept;
228
233 void updateToleranceSuccess() noexcept;
234
235 inline void tolerancePostUpdate() noexcept;
236
238 void acceptMultipliers(Results &results, Workspace &workspace) const;
239
247 void computeMultipliers(const ConstVectorRef &inner_lams_data,
248 Workspace &workspace) const;
249
259 void computeProblemDerivatives(const ConstVectorRef &x, Workspace &workspace,
260 boost::mpl::false_) const;
262 void computeProblemDerivatives(const ConstVectorRef &x, Workspace &workspace,
263 boost::mpl::true_) const;
264
271 void computePrimalResiduals(Workspace &workspace, Results &results) const;
272
280 void tryStep(Workspace &workspace, const Results &results, Scalar alpha);
281
282 void invokeCallbacks(Workspace &workspace, Results &results) {
283 for (auto cb : callbacks_) {
284 cb->call(workspace, results);
285 }
286 }
287};
288
293inline InertiaFlag checkInertia(const int ndx, const int nc,
294 const Eigen::VectorXi &signature);
295
296} // namespace nlp
297} // namespace proxsuite
298
300
301#ifdef PROXSUITE_NLP_ENABLE_TEMPLATE_INSTANTIATION
302#include "proxsuite-nlp/prox-solver.txx"
303#endif
void tryStep(Workspace &workspace, const Results &results, Scalar alpha)
Scalar target_tol
Target tolerance for the problem.
void clearCallbacks() noexcept
Remove all callbacks from the instance.
void updateToleranceSuccess() noexcept
Update primal-dual subproblem tolerances upon successful outer-loop iterate (good primal feasibility)
void setProxParameter(const Scalar &new_rho) noexcept
Set proximal penalty parameter.
void computeMultipliers(const ConstVectorRef &inner_lams_data, Workspace &workspace) const
void setDualPenalty(const Scalar beta)
Set the dual penalty weight for the merit function.
LinesearchStrategy ls_strat
Linesearch strategy.
void acceptMultipliers(Results &results, Workspace &workspace) const
Accept Lagrange multiplier estimates.
void updateToleranceFailure() noexcept
Update primal-dual subproblem tolerances upon failure (insufficient primal feasibility)
void computePrimalResiduals(Workspace &workspace, Results &results) const
void setPenalty(const Scalar &new_mu) noexcept
Set penalty parameter, its inverse and update the merit function.
ALMeritFunctionTpl< Scalar > merit_fun
Merit function.
Problem * problem_
General nonlinear program to solve.
PROXSUITE_NLP_INLINE bool iterativeRefinement(Workspace &workspace) const
Iterative refinement of the KKT linear system.
std::vector< CallbackPtr > callbacks_
Callbacks.
BCLParamsTpl< Scalar > bcl_params
BCL strategy parameters.
VerboseLevel verbose
Level of verbosity of the solver.
ConvergenceFlag solve(const ConstVectorRef &x0, const std::vector< VectorRef > &lams0)
Solve the problem.
QuadraticDistanceCostTpl< Scalar > prox_penalty
Proximal regularization penalty.
void computeProblemDerivatives(const ConstVectorRef &x, Workspace &workspace, boost::mpl::false_) const
void registerCallback(const CallbackPtr &cb) noexcept
Add a callback to the solver instance.
HessianApprox hess_approx
Use a Gauss-Newton approximation for the Lagrangian Hessian.
std::size_t max_refinement_steps_
linear algebra opts
LinesearchOptions ls_options
Linesearch options.
Forward declarations and configuration macros.
VerboseLevel
Verbosity level.
Definition fwd.hpp:126
@ BUNCHKAUFMAN
Use Bunch-Kaufman factorization.
Base structs for linesearch algorithms.
#define PROXSUITE_NLP_DYNAMIC_TYPEDEFS(Scalar)
Definition math.hpp:26
Definition fwd.hpp:51
Main package namespace.
Definition bcl-params.hpp:5
InertiaFlag checkInertia(const int ndx, const int nc, const Eigen::VectorXi &signature)
Check the matrix has the desired inertia.
@ GAUSS_NEWTON
Gauss-Newton (or rather SCQP) approximation.
@ BFGS
BFGS approximation.
@ EXACT
Exact Hessian construction from provided function Hessians.
Implementations for the prox solver.
Primal-dual augmented Lagrangian-type merit function.
Definition pdal.hpp:23
A logging utility.
Definition logger.hpp:35
Packs a ConstraintSetTpl and C2FunctionTpl together.
Base constraint set type.
polymorphic< Manifold > manifold_
The working manifold .
Weighted quadratic distance on a space.
Results struct, holding the returned data from the solver.
Definition results.hpp:20