16#include <boost/mpl/bool.hpp>
18#include "proxsuite-nlp/modelling/costs/squared-distance.hpp"
25enum class MultiplierUpdateMode { NEWTON, PRIMAL, PRIMAL_DUAL };
38enum InertiaFlag { INERTIA_OK = 0, INERTIA_BAD = 1, INERTIA_HAS_ZEROS = 2 };
40enum KktSystem { KKT_CLASSIC, KKT_PRIMAL_DUAL };
45template <
typename _Scalar>
class ProxNLPSolverTpl {
47 using Scalar = _Scalar;
54 using CallbackPtr = shared_ptr<helpers::base_callback<Scalar>>;
74 LinesearchStrategy
ls_strat = LinesearchStrategy::ARMIJO;
75 MultiplierUpdateMode mul_update_mode = MultiplierUpdateMode::NEWTON;
77 mutable BFGS bfgs_strategy_;
81 Scalar kkt_tolerance_ = 1e-13;
83 KktSystem kkt_system_ = KKT_CLASSIC;
87 Scalar inner_tol0 = 1.;
88 Scalar prim_tol0 = 1.;
89 Scalar inner_tol_ = inner_tol0;
90 Scalar prim_tol_ = prim_tol0;
94 Scalar rho_ = rho_init_;
95 Scalar mu_ = mu_init_;
96 Scalar mu_inv_ = 1. / mu_;
98 Scalar inner_tol_min = 1e-9;
99 Scalar mu_upper_ = 1.;
100 Scalar mu_lower_ = 1e-9;
101 Scalar pdal_beta_ = 0.5;
117 Scalar del_inc_k = 8.;
118 Scalar del_inc_big = 100.;
119 Scalar del_dec_k = 1. / 3.;
120 Scalar DELTA_MIN = 1e-14;
121 Scalar DELTA_MAX = 1e6;
122 Scalar DELTA_NONZERO_INIT = 1e-4;
123 Scalar DELTA_INIT = 0.;
125 std::size_t max_iters = 100;
126 std::size_t max_al_iters = 1000;
131 unique_ptr<Workspace> workspace_;
132 unique_ptr<Results> results_;
134 ProxNLPSolverTpl(Problem &prob,
const Scalar tol = 1e-6,
135 const Scalar mu_eq_init = 1e-2,
const Scalar rho_init = 0.,
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());
143 const Problem &problem()
const {
return *
problem_; }
148 workspace_ = std::make_unique<Workspace>(*
problem_, ldlt_choice_);
149 results_ = std::make_unique<Results>(*
problem_);
154 BFGS valid_bfgs_strategy_ = BFGS(
problem_->ndx());
155 bfgs_strategy_ = std::move(valid_bfgs_strategy_);
157 workspace_->objective_hessian.setIdentity();
159 throw std::runtime_error(
"BFGS for hessian approximation currently "
160 "only works for Euclidean manifolds.");
173 ConvergenceFlag
solve(
const ConstVectorRef &x0,
174 const std::vector<VectorRef> &lams0);
176 PROXSUITE_NLP_DEPRECATED
177 const Workspace &getWorkspace()
const {
return *workspace_; }
178 PROXSUITE_NLP_DEPRECATED
179 const Results &getResults()
const {
return *results_; }
189 ConvergenceFlag
solve(
const ConstVectorRef &x0,
190 const ConstVectorRef &lams0 = VectorXs(0));
192 void innerLoop(Workspace &workspace, Results &results);
194 void assembleKktMatrix(Workspace &workspace);
208 void setPenalty(
const Scalar &new_mu)
noexcept;
235 inline
void tolerancePostUpdate() noexcept;
248 Workspace &workspace) const;
260 boost::mpl::false_) const;
263 boost::mpl::true_) const;
280 void tryStep(Workspace &workspace, const Results &results, Scalar alpha);
282 void invokeCallbacks(Workspace &workspace, Results &results) {
284 cb->call(workspace, results);
293inline InertiaFlag
checkInertia(
const int ndx,
const int nc,
294 const Eigen::VectorXi &signature);
301#ifdef PROXSUITE_NLP_ENABLE_TEMPLATE_INSTANTIATION
302#include "proxsuite-nlp/prox-solver.txx"
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.
@ BUNCHKAUFMAN
Use Bunch-Kaufman factorization.
Base structs for linesearch algorithms.
#define PROXSUITE_NLP_DYNAMIC_TYPEDEFS(Scalar)
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.
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.