Pipal  1.2.0
Penalty Interior-Point ALgorithm
Loading...
Searching...
No Matches
Solver.hxx
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2 * Copyright (c) 2025, Davide Stocco and Enrico Bertolazzi. *
3 * *
4 * The Pipal project is distributed under the MIT License. *
5 * *
6 * Davide Stocco Enrico Bertolazzi *
7 * University of Trento University of Trento *
8 * e-mail: davide.stocco@unitn.it e-mail: enrico.bertolazzi@unitn.it *
9\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
10
11#pragma once
12
13#ifndef INCLUDE_PIPAL_SOLVER_HXX
14#define INCLUDE_PIPAL_SOLVER_HXX
15
16namespace Pipal {
17
26 template <typename Real>
27 class Solver
28 {
29 static_assert(std::is_floating_point_v<Real>,
30 "Pipal::Solver<Real>: Real must be a floating-point type.");
31
32 public:
40
41 private:
50
51 // Some options for the solver
52 bool m_verbose{false};
53 bool m_bfgs{false};
54
55 void buildIterate();
56 void evalStep();
57 void updateParameters();
58 void lineSearch();
59 void bfgsUpdate(Vector<Real> const & s, Vector<Real> const & y);
60 void updateIterate();
61 void updatePoint();
62 void backtracking();
63 void evalFunctions();
64 void evalGradients();
65 void evalHessian();
66 void evalNewtonMatrix();
67 void evalScalings();
68 void evalModels();
69 void fractionToBoundary();
70 void evalNewtonRhs();
71 void evalSlacks();
72 void evalMerit();
73 void initNewtonMatrix();
74 void resetDirection(Direction<Real> & d) const;
75 void evalLambdaOriginal(Vector<Real> & l) const;
76 Real evalViolation(Array<Real> const & cE, Array<Real> const & cI) const;
77 void evalNewtonStep();
78 void evalTrialStep(Direction<Real> & v) const;
83 void setDirection(Vector<Real> const & dx, Vector<Real> const & dr1, Vector<Real> const & dr2,
84 Vector<Real> const & ds1, Vector<Real> const & ds2, Vector<Real> const & dlE,
85 Vector<Real> const & dlI, Real const dx_norm, Real const dl_norm);
87 void evalTrialStepCut();
88 void evalLinearCombination(Direction<Real> const & d1, Direction<Real> const & d2,
89 Direction<Real> const & d3, Real const a1, Real const a2, Real const a3);
90 Real evalKKTError(Real const rho, Real const mu);
91 void evalKKTErrors();
92 void setPrimals(Vector<Real> const & x, Array<Real> const & r1, Array<Real> const & r2,
93 Array<Real> const & s1, Array<Real> const & s2, Array<Real> const & lE, Array<Real> const & lI,
94 Real const f, Array<Real> const & cE, Array<Real> const & cI, Real const phi);
95 void buildInput(std::string const & name, Vector<Real> const & x0, Vector<Real> const & bl,
96 Vector<Real> const & bu, Vector<Real> const & cl, Vector<Real> const & cu);
97
104 {
105 // Evaluate scaled and unscaled feasibility violations
106 z.v = this->evalViolation(z.cE, z.cI)/std::max(1.0, z.v0);
107 z.vu = this->evalViolation(z.cEu, z.cIu);
108 }
109
114 void resetMuMaxExp() {this->m_parameter.mu_max_exp = this->m_parameter.mu_max_exp0;}
115
120 void buildParameter(Algorithm t_algorithm) {this->m_parameter.algorithm = t_algorithm;}
121
125 void setMuMaxExpZero() {this->m_parameter.mu_max_exp = 0.0;}
126
132 void setRho(Real const rho) {this->m_iterate.rho = rho;}
133
139 void setRhoLast(Real const rho) {this->m_iterate.rho_ = rho;}
140
146 void setMu(Real const mu) {this->m_iterate.mu = mu;}
147
155 {
156 // Evaluate quantities dependent on penalty and interior-point parameters
157 this->evalSlacks();
158 this->evalMerit();
159 this->evalKKTErrors();
160 }
161
166 {
167 this->m_counter.f = this->m_counter.g = this->m_counter.H = this->m_counter.k = this->m_counter.M = 0;
168 }
169
173 void incrementFactorizationCount() {++this->m_counter.M;}
174
178 void incrementFunctionCount() {++this->m_counter.f;}
179
183 void incrementGradientCount() {++this->m_counter.g;}
184
188 void incrementHessianCount() {++this->m_counter.H;}
189
193 void incrementIterationCount() {++this->m_counter.k;}
194
195 public:
202 Solver() = default;
203
220 std::string const & name,
221 ObjectiveFunc const & objective,
222 ObjectiveGradientFunc const & objective_gradient,
223 ConstraintsFunc const & constraints,
224 ConstraintsJacobianFunc const & constraints_jacobian,
225 LagrangianHessianFunc const & lagrangian_hessian,
226 BoundsFunc const & primal_lower_bounds,
227 BoundsFunc const & primal_upper_bounds,
228 BoundsFunc const & constraints_lower_bounds,
229 BoundsFunc const & constraints_upper_bounds
230 ) : m_problem(std::make_unique<ProblemWrapper<Real>>(
231 name,
232 objective,
233 objective_gradient,
234 constraints,
235 constraints_jacobian,
236 lagrangian_hessian,
237 primal_lower_bounds,
238 primal_upper_bounds,
239 constraints_lower_bounds,
240 constraints_upper_bounds
241 )) {}
242
251
256 Solver(Solver const &) = delete;
257
262 Solver & operator=(Solver const &) = delete;
263
268 Solver(Solver &&) = delete;
269
274 Solver & operator=(Solver &&) = delete;
275
281 ~Solver() = default;
282
289 void problem(ProblemPtr && problem) {this->m_problem = std::move(problem);}
290
295 Problem<Real> const & problem() const {return this->m_problem.get();}
296
301 bool verbose_mode() const {return this->m_verbose;}
302
307 void verbose_mode(bool const t_verbose) {this->m_verbose = t_verbose;}
308
313 bool bfgs() const {return this->m_bfgs;}
314
319 void bfgs(bool const t_bfgs) {this->m_bfgs = t_bfgs;}
320
325 Algorithm algorithm() const {return this->m_parameter.algorithm;}
326
334 void algorithm(Algorithm const t_algorithm) {this->m_parameter.algorithm = t_algorithm;}
335
344 void tolerance(Real const t_tolerance)
345 {
346 PIPAL_ASSERT(t_tolerance > 0.0,
347 "Pipal::Solver::tolerance(...): input value must be positive");
348 this->m_parameter.opt_err_tol = t_tolerance;
349 }
350
355 Real tolerance() const {return this->m_parameter.opt_err_tol;}
356
365 void max_iterations(Integer const t_max_iterations) {
366 PIPAL_ASSERT(t_max_iterations > 0,
367 "Pipal::Solver::max_iterations(...): input value must be positive");
368 this->m_parameter.iter_max = t_max_iterations;
369 }
370
375 Integer max_iterations() const {return this->m_parameter.iter_max;}
376
386 bool optimize(Vector<Real> const & x_guess, Vector<Real> & x_sol)
387 {
388
389 #define CMD "Pipal::Solver::optimize(...): "
390
391 // Create alias for easier access
392 Counter & c{this->m_counter};
393 Input<Real> & i{this->m_input};
394 Iterate<Real> & z{this->m_iterate};
395 Direction<Real> & d{this->m_direction};
396 Acceptance<Real> & a{this->m_acceptance};
397
398 // Check that the problem is set
399 PIPAL_ASSERT(this->m_problem.get() != nullptr,
400 CMD "problem not set, use 'problem(...)' method to set it");
401
402 // Get variable bounds
403 Vector<Real> bl, bu;
404 PIPAL_ASSERT(this->m_problem->primal_lower_bounds(bl),
405 CMD "error in evaluating lower bounds on primal variables");
406 PIPAL_ASSERT(this->m_problem->primal_upper_bounds(bu),
407 CMD "error in evaluating upper bounds on primal variables");
408
409 // Get constraint bounds
410 Vector<Real> cl, cu;
411 PIPAL_ASSERT(this->m_problem->constraints_lower_bounds(cl),
412 CMD "error in evaluating lower bounds on constraints");
413 PIPAL_ASSERT(this->m_problem->constraints_upper_bounds(cu),
414 CMD "error in evaluating upper bounds on constraints");
415
416 // Reset counters
417 resetCounter();
418
419 // Fill input structure
420 buildInput(this->m_problem->name(), x_guess, bl, bu, cl, cu);
421 buildIterate();
423
424 // Print header and break line
425 if (this->m_verbose) {this->m_output.printHeader(i, z); this->m_output.printBreak(c);}
426
427 // Iterations loop
428 while (!this->checkTermination()) {
429
430 // Print iterate
431 if (this->m_verbose) {this->m_output.printIterate(c, z);}
432
433 // Evaluate the step
434 this->evalStep();
435
436 // Print direction
437 if (this->m_verbose) {this->m_output.printDirection(z, d);}
438
439 this->lineSearch();
440
441 // Print accepted
442 if (this->m_verbose) {this->m_output.printAcceptance(a);}
443
444 this->updateIterate();
445
446 // Increment iteration counter
448
449 // Print break
450 if (this->m_verbose) {this->m_output.printBreak(c);}
451 }
452 // Print footer and terminate
453 if (this->m_verbose) {this->m_output.printFooter(c, z, this->checkTermination());}
454
455 // Get solution in original variables
456 this->evalXOriginal(x_sol);
457
458 // Return success if is finite
459 return x_sol.allFinite();
460
461 #undef CMD
462 }
463
471 {
472 this->evalXOriginal(x);
473 this->evalLambdaOriginal(l);
474 }
475
476 }; // class Solver
477
478} // namespace Solver
479
480#endif // INCLUDE_PIPAL_SOLVER_HXX
#define CMD
#define PIPAL_ASSERT(COND, MSG)
Definition Types.hxx:50
Pretty-printing and timing utilities for solver output.
Definition Output.hxx:28
void printBreak(Counter const &c) const
Print a formatted break line and column headers periodically.
Definition Output.hxx:93
void printFooter(Counter const &c, Iterate< Real > const &z, Integer const b) const
Print final summary footer and termination message.
Definition Output.hxx:151
void printAcceptance(Acceptance< Real > const &a) const
Print acceptance information for the chosen trial step.
Definition Output.hxx:138
void printIterate(Counter const &c, Iterate< Real > const &z) const
Print a single iterate row to the console table.
Definition Output.hxx:124
void printHeader(Input< Real > const &i, Iterate< Real > const &z) const
Print problem header information.
Definition Output.hxx:64
void printDirection(Iterate< Real > const &z, Direction< Real > const &d) const
Print a summary of the current search direction.
Definition Output.hxx:108
Problem class for the Pipal library.
Definition Problem.hxx:28
std::unique_ptr< Problem > UniquePtr
Definition Problem.hxx:35
Wrapper class for the Problem class.
Definition Problem.hxx:172
std::function< bool(Vector< Real > &)> BoundsFunc
Definition Problem.hxx:179
std::function< bool(Vector< Real > const &, Vector< Real > &)> ObjectiveGradientFunc
Definition Problem.hxx:176
std::function< bool(Vector< Real > const &, Vector< Real > const &, SparseMatrix< Real > &)> LagrangianHessianFunc
Definition Problem.hxx:178
std::function< bool(Vector< Real > const &, Real &)> ObjectiveFunc
Definition Problem.hxx:174
std::function< bool(Vector< Real > const &, Vector< Real > &)> ConstraintsFunc
Definition Problem.hxx:175
std::function< bool(Vector< Real > const &, SparseMatrix< Real > &)> ConstraintsJacobianFunc
Definition Problem.hxx:177
void max_iterations(Integer const t_max_iterations)
Set the maximum number of iterations for the solver.
Definition Solver.hxx:365
Real evalKKTError(Real const rho, Real const mu)
Compute the infinity-norm of the KKT optimality vector.
Definition Iterate.hxx:433
void evalMerit()
Compute the merit function value for the current iterate.
Definition Iterate.hxx:524
void evalTrialStep(Direction< Real > &v) const
Store a trial step into another direction object.
Definition Direction.hxx:377
Algorithm algorithm() const
Get the algorithm mode.
Definition Solver.hxx:325
void setRho(Real const rho)
Set penalty parameter rho.
Definition Solver.hxx:132
void incrementFactorizationCount()
Increment the matrix factorization counter.
Definition Solver.hxx:173
Acceptance< Real > m_acceptance
Definition Solver.hxx:43
void resetMuMaxExp()
Reset maximum exponent used for mu increases to its default.
Definition Solver.hxx:114
Solver()=default
Default constructor for the Pipal class.
ProblemPtr m_problem
Definition Solver.hxx:49
void setRhoLast(Real const rho)
Set last (previous) penalty parameter value.
Definition Solver.hxx:139
Real evalViolation(Array< Real > const &cE, Array< Real > const &cI) const
Compute the 1-norm feasibility violation from equality/inequality values.
Definition Iterate.hxx:1027
Solver(std::string const &name, ObjectiveFunc const &objective, ObjectiveGradientFunc const &objective_gradient, ConstraintsFunc const &constraints, ConstraintsJacobianFunc const &constraints_jacobian, LagrangianHessianFunc const &lagrangian_hessian, BoundsFunc const &primal_lower_bounds, BoundsFunc const &primal_upper_bounds, BoundsFunc const &constraints_lower_bounds, BoundsFunc const &constraints_upper_bounds)
Constructor for the Pipal class.
Definition Solver.hxx:219
void buildInput(std::string const &name, Vector< Real > const &x0, Vector< Real > const &bl, Vector< Real > const &bu, Vector< Real > const &cl, Vector< Real > const &cu)
Build the input data for the solver.
Definition Input.hxx:29
Input< Real > m_input
Definition Solver.hxx:44
void algorithm(Algorithm const t_algorithm)
Set the algorithm mode.
Definition Solver.hxx:334
bool optimize(Vector< Real > const &x_guess, Vector< Real > &x_sol)
Solves the optimization problem using the interior-point method.
Definition Solver.hxx:386
void initNewtonMatrix()
Reserve and initialize the internal sparse Newton matrix structure.
Definition Iterate.hxx:797
void evalDependent()
Evaluate quantities that depend on penalty/interior parameters.
Definition Solver.hxx:154
void incrementGradientCount()
Increment the gradient evaluation counter.
Definition Solver.hxx:183
void verbose_mode(bool const t_verbose)
Set the verbose mode.
Definition Solver.hxx:307
void bfgsUpdate(Vector< Real > const &s, Vector< Real > const &y)
Browder-Broyden-Fletcher-Goldfarb-Shanno (BFGS) update for the Hessian approximation.
Definition Iterate.hxx:895
void evalTrialSteps(Direction< Real > &d1, Direction< Real > &d2, Direction< Real > &d3)
Compute and store directions for a few parameter combinations.
Definition Direction.hxx:413
void evalLinearCombination(Direction< Real > const &d1, Direction< Real > const &d2, Direction< Real > const &d3, Real const a1, Real const a2, Real const a3)
Evaluate a linear combination of up to three directions.
Definition Direction.hxx:53
void evalStep()
Compute the search direction for the current iterate.
Definition Direction.hxx:201
Integer max_iterations() const
Get the maximum number of iterations.
Definition Solver.hxx:375
void resetDirection(Direction< Real > &d) const
Reset a search direction to zero and initialize norms.
Definition Direction.hxx:24
Direction< Real > m_direction
Definition Solver.hxx:45
Solver(Solver &&)=delete
Deleted move constructor.
Problem< Real > const & problem() const
Get the problem being solved.
Definition Solver.hxx:295
void backtracking()
Backtracking line search.
Definition Acceptance.hxx:27
Real tolerance() const
Get the tolerance for convergence.
Definition Solver.hxx:355
void buildIterate()
Initialize an Iterate object for a given problem/input.
Definition Iterate.hxx:23
void bfgs(bool const t_bfgs)
Set the BFGS mode.
Definition Solver.hxx:319
~Solver()=default
Destructor for the Pipal class.
void evalInfeasibility(Iterate< Real > &z) const
Compute scaled and unscaled feasibility violations.
Definition Solver.hxx:103
void incrementHessianCount()
Increment the Hessian evaluation counter.
Definition Solver.hxx:188
void incrementFunctionCount()
Increment the function evaluation counter.
Definition Solver.hxx:178
bool m_verbose
Definition Solver.hxx:52
void updateIterate()
Update the iterate after a trial step is accepted.
Definition Iterate.hxx:917
void evalNewtonRhs()
Build the right-hand side vector for the Newton system.
Definition Iterate.hxx:647
void setMu(Real const mu)
Set interior-point parameter mu.
Definition Solver.hxx:146
Iterate< Real > m_iterate
Definition Solver.hxx:46
bool m_bfgs
Definition Solver.hxx:53
void resetCounter()
Reset all internal counters to zero.
Definition Solver.hxx:165
void evalSlacks()
Compute internal slack variables from current iterate.
Definition Iterate.hxx:737
typename ProblemWrapper< Real >::ObjectiveGradientFunc ObjectiveGradientFunc
Definition Solver.hxx:35
typename Problem< Real >::UniquePtr ProblemPtr
Definition Solver.hxx:33
Counter m_counter
Definition Solver.hxx:42
void updatePoint()
Apply a step to the primal and dual variables of the iterate.
Definition Iterate.hxx:1003
void evalXOriginal(Vector< Real > &x)
Reconstruct the full primal vector in the original variable ordering.
Definition Iterate.hxx:775
void getSolution(Vector< Real > &x, Vector< Real > &l)
Extract a primal-dual solution in original ordering.
Definition Solver.hxx:470
typename ProblemWrapper< Real >::ConstraintsFunc ConstraintsFunc
Definition Solver.hxx:36
void buildParameter(Algorithm t_algorithm)
Initialize algorithm parameters.
Definition Solver.hxx:120
void problem(ProblemPtr &&problem)
Set the problem to be solved using a unique pointer.
Definition Solver.hxx:289
void evalNewtonMatrix()
Assemble and (attempt to) factorize the Newton system matrix.
Definition Iterate.hxx:549
typename ProblemWrapper< Real >::ConstraintsJacobianFunc ConstraintsJacobianFunc
Definition Solver.hxx:37
Output< Real > m_output
Definition Solver.hxx:47
Integer secondOrderCorrection()
Second-order correction (SOC).
Definition Acceptance.hxx:284
Solver & operator=(Solver const &)=delete
Deleted assignment operator.
void setMuMaxExpZero()
Force mu exponent increases to use zero as maximum exponent.
Definition Solver.hxx:125
void evalModels()
Evaluate model reductions and quality metric for a direction.
Definition Direction.hxx:85
void evalGradients()
Evaluate objective gradient and constraint Jacobian.
Definition Iterate.hxx:213
void incrementIterationCount()
Increment the iteration counter.
Definition Solver.hxx:193
Parameter< Real > m_parameter
Definition Solver.hxx:48
void setPrimals(Vector< Real > const &x, Array< Real > const &r1, Array< Real > const &r2, Array< Real > const &s1, Array< Real > const &s2, Array< Real > const &lE, Array< Real > const &lI, Real const f, Array< Real > const &cE, Array< Real > const &cI, Real const phi)
Set primal/dual blocks and associated quantities on an iterate.
Definition Iterate.hxx:861
typename ProblemWrapper< Real >::LagrangianHessianFunc LagrangianHessianFunc
Definition Solver.hxx:38
typename ProblemWrapper< Real >::BoundsFunc BoundsFunc
Definition Solver.hxx:39
void evalNewtonStep()
Recover direction components from the Newton system solution.
Definition Direction.hxx:166
void evalKKTErrors()
Compute the three KKT error measures used by the solver.
Definition Iterate.hxx:472
void fractionToBoundary()
Fraction-to-boundary rule for primal and dual variables.
Definition Acceptance.hxx:100
void setDirection(Vector< Real > const &dx, Vector< Real > const &dr1, Vector< Real > const &dr2, Vector< Real > const &ds1, Vector< Real > const &ds2, Vector< Real > const &dlE, Vector< Real > const &dlI, Real const dx_norm, Real const dl_norm)
Populate a Direction object from its component vectors.
Definition Direction.hxx:457
void evalLambdaOriginal(Vector< Real > &l) const
Reconstruct multipliers in the original variable/constraint space.
Definition Iterate.hxx:489
Integer checkTermination() const
Check termination criteria for the solver.
Definition Iterate.hxx:94
Integer fullStepCheck()
Full-step check for trial penalty parameters.
Definition Acceptance.hxx:165
bool bfgs() const
Get the BFGS mode.
Definition Solver.hxx:313
void evalFunctions()
Evaluate objective and constraint functions at the current iterate.
Definition Iterate.hxx:125
bool verbose_mode() const
Get the verbose mode.
Definition Solver.hxx:301
Solver(Solver const &)=delete
Deleted copy constructor.
void evalHessian()
Evaluate the Hessian of the Lagrangian and assemble internal H.
Definition Iterate.hxx:350
void evalTrialStepCut()
Scale a trial step by the fraction-to-boundary values.
Definition Direction.hxx:392
void evalScalings()
Evaluate scaling multipliers for objective and constraints.
Definition Iterate.hxx:687
void tolerance(Real const t_tolerance)
Set the convergence tolerance for the solver.
Definition Solver.hxx:344
void updateParameters()
Update penalty and interior-point parameters based on KKT errors.
Definition Iterate.hxx:959
Solver(ProblemPtr &&problem)
Constructor for the Pipal class (with a unique pointer to a Problem object).
Definition Solver.hxx:250
void lineSearch()
Line-search driver.
Definition Acceptance.hxx:253
typename ProblemWrapper< Real >::ObjectiveFunc ObjectiveFunc
Definition Solver.hxx:34
Solver & operator=(Solver &&)=delete
Deleted move assignment operator.
Namespace for the Pipal library.
Definition Acceptance.hxx:16
enum class Algorithm :Integer {CONSERVATIVE=0, ADAPTIVE=1} Algorithm
Enumeration for the algorithm choice.
Definition Types.hxx:126
PIPAL_DEFAULT_INTEGER_TYPE Integer
The Integer type as used for the API.
Definition Types.hxx:110
Eigen::Array< Real, Eigen::Dynamic, 1 > Array
Definition Types.hxx:115
Eigen::Vector< Real, Eigen::Dynamic > Vector
Definition Types.hxx:112
struct Counter { Integer f{0}; Integer g{0}; Integer H{0}; Integer k{0}; Integer M{0}; Counter()=default; Counter(Counter const &)=delete; Counter &operator=(Counter const &)=delete; } Counter
Internal counters for solver statistics.
Definition Types.hxx:285
Class for managing the acceptance criteria of the solver.
Definition Types.hxx:486
Class for managing the current search direction of the solver.
Definition Types.hxx:446
Input structure holding all the data defining the optimization problem.
Definition Types.hxx:316
Class for managing the current iterate of the solver.
Definition Types.hxx:377
Real rho
Definition Types.hxx:381
Array< Real > cE
Definition Types.hxx:389
Real v
Definition Types.hxx:401
Real mu
Definition Types.hxx:383
Array< Real > cIu
Definition Types.hxx:417
Real rho_
Definition Types.hxx:382
Array< Real > cI
Definition Types.hxx:395
Real v0
Definition Types.hxx:403
Real vu
Definition Types.hxx:402
Array< Real > cEu
Definition Types.hxx:415
Internal parameters for the solver algorithm.
Definition Types.hxx:229
static constexpr Real mu_max_exp0
Definition Types.hxx:253
Algorithm algorithm
Definition Types.hxx:260
Integer iter_max
Definition Types.hxx:259
Real mu_max_exp
Definition Types.hxx:261
Real opt_err_tol
Definition Types.hxx:258