Optimist  0.0.0
A C++ library for optimization
Loading...
Searching...
No Matches
Optimizer.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2 * Copyright (c) 2025, Davide Stocco, Mattia Piazza and Enrico Bertolazzi. *
3 * *
4 * The Optimist project is distributed under the BSD 2-Clause License. *
5 * *
6 * Davide Stocco Mattia Piazza Enrico Bertolazzi *
7 * University of Trento University of Trento University of Trento *
8 * davide.stocco@unitn.it mattia.piazza@unitn.it enrico.bertolazzi@unitn.it *
9\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
10
11#pragma once
12
13#ifndef OPTIMIST_OPTIMIZER_HH
14#define OPTIMIST_OPTIMIZER_HH
15
17
18namespace Optimist
19{
20
24 namespace Optimizer
25 {
26
27 /*\
28 | ___ _ _ _
29 | / _ \ _ __ | |_(_)_ __ ___ (_)_______ _ __
30 | | | | | '_ \| __| | '_ ` _ \| |_ / _ \ '__|
31 | | |_| | |_) | |_| | | | | | | |/ / __/ |
32 | \___/| .__/ \__|_|_| |_| |_|_/___\___|_|
33 | |_|
34 \*/
35
45 template <typename Real, Integer N, typename DerivedSolver, bool ForceEigen = false>
46 class Optimizer : public SolverBase<Real, N, 1, DerivedSolver, ForceEigen>
47 {
48 public:
49 // Fancy static assertions (just for fun, don't take it too seriously)
50 static_assert(N != 0, "Have you ever heard of a zero-dimensional optimization problem?");
51
52 friend class SolverBase<Real, N, 1, Optimizer<Real, N, DerivedSolver, ForceEigen>>;
53
54 static constexpr bool is_rootfinder{false};
55 static constexpr bool is_optimizer{true};
56
58
59 // I/O types
60 using Vector = typename SolverBase<Real, N, 1, DerivedSolver, ForceEigen>::InputType;
61
62 // Derivative types
63 using RowVector = typename SolverBase<Real, N, 1, DerivedSolver, ForceEigen>::FirstDerivativeType;
64 using Matrix = typename SolverBase<Real, N, 1, DerivedSolver, ForceEigen>::SecondDerivativeType;
65
70
75 std::string name() const {return static_cast<const DerivedSolver *>(this)->name_impl();}
76
82
88
93 void max_gradient_evaluations(Integer t_gradient_evaluations)
94 {
95 this->max_first_derivative_evaluations(t_gradient_evaluations);
96 }
97
103
109
114 void max_hessian_evaluations(Integer t_hessian_evaluations)
115 {
116 this->max_second_derivative_evaluations(t_hessian_evaluations);
117 }
118
119 protected:
128 template <typename GradientLambda>
129 bool evaluate_gradient(GradientLambda && gradient, Vector const & x, Matrix & out)
130 {
131 return this->evaluate_first_derivative(std::forward<GradientLambda>(gradient), x, out);
132 }
133
142 template <typename HessianLambda>
143 bool evaluate_hessian(HessianLambda && hessian, Vector const & x, Matrix & out)
144 {
145 return this->evaluate_second_derivative(std::forward<HessianLambda>(hessian), x, out);
146 }
147
156 bool solve(FunctionLambda && function, Vector const & x_ini, Vector & x_sol)
157 {
158 #define CMD "Optimist::Optimizer::solve(...): "
159
160 static_assert(DerivedSolver::requires_function,
161 CMD "the solver requires the function.");
162 return static_cast<DerivedSolver *>(this)->solve_impl(
163 std::forward<FunctionLambda>(function),
164 x_ini, x_sol);
165
166 #undef CMD
167 }
168
179 template <typename FunctionLambda, typename GradientLambda>
180 bool solve(FunctionLambda && function, GradientLambda && gradient, Vector const & x_ini, Vector & x_sol)
181 {
182 #define CMD "Optimist::Optimizer::solve(...): "
183
184 static_assert(DerivedSolver::requires_function,
185 CMD "the solver requires the function.");
186 static_assert(DerivedSolver::requires_first_derivative,
187 CMD "the solver requires the first derivative.");
188 return static_cast<DerivedSolver *>(this)->solve_impl(
189 std::forward<FunctionLambda>(function),
190 std::forward<GradientLambda>(gradient),
191 x_ini, x_sol);
192
193 #undef CMD
194 }
195
208 template <typename FunctionLambda, typename GradientLambda, typename HessianLambda>
209 bool solve(FunctionLambda && function, GradientLambda && gradient, HessianLambda && hessian,
210 Vector const & x_ini, Vector & x_sol)
211 {
212 #define CMD "Optimist::Optimizer::solve(...): "
213
214 static_assert(DerivedSolver::requires_function,
215 CMD "the solver requires the function.");
216 static_assert(DerivedSolver::requires_first_derivative,
217 CMD "the solver requires the first derivative.");
218 static_assert(DerivedSolver::requires_second_derivative,
219 CMD "the solver requires the second derivative.");
220 return static_cast<DerivedSolver *>(this)->solve_impl(
221 std::forward<FunctionLambda>(function),
222 std::forward<GradientLambda>(gradient),
223 std::forward<HessianLambda>(hessian),
224 x_ini, x_sol);
225
226 #undef CMD
227 }
228
229 }; // class Optimizer
230
239 template <typename Real, typename DerivedSolver>
240 class Optimizer<Real, 1, DerivedSolver> : public SolverBase<Real, 1, 1, DerivedSolver>
241 {
242 public:
243 friend class SolverBase<Real, 1, 1, Optimizer<Real, 1, DerivedSolver>>;
244
245 static constexpr bool is_rootfinder{false};
246 static constexpr bool is_optimizer{true};
247
249
250
254
259 std::string name() const {return static_cast<const DerivedSolver *>(this)->name_impl();}
260
261 }; // class Optimizer
262
263 } // namespace Optimizer
264
265} // namespace Optimist
266
267#endif // OPTIMIST_OPTIMIZER_HH
#define OPTIMIST_BASIC_CONSTANTS(Real)
Definition Optimist.hh:71
#define CMD
std::string name() const
Definition Optimizer.hh:259
static constexpr bool is_rootfinder
Definition Optimizer.hh:245
static constexpr bool is_optimizer
Definition Optimizer.hh:246
Class container for the multi-dimensional optimizer.
Definition Optimizer.hh:47
Optimizer()
Definition Optimizer.hh:69
typename SolverBase< Real, N, 1, DerivedSolver, ForceEigen >::InputType Vector
Definition Optimizer.hh:60
std::string name() const
Definition Optimizer.hh:75
static constexpr bool is_rootfinder
Definition Optimizer.hh:54
Integer max_gradient_evaluations() const
Definition Optimizer.hh:87
bool solve(FunctionLambda &&function, Vector const &x_ini, Vector &x_sol)
Definition Optimizer.hh:156
static constexpr bool is_optimizer
Definition Optimizer.hh:55
typename SolverBase< Real, N, 1, DerivedSolver, ForceEigen >::FirstDerivativeType RowVector
Definition Optimizer.hh:63
bool evaluate_hessian(HessianLambda &&hessian, Vector const &x, Matrix &out)
Definition Optimizer.hh:143
Integer hessian_evaluations() const
Definition Optimizer.hh:102
Integer max_hessian_evaluations() const
Definition Optimizer.hh:108
void max_gradient_evaluations(Integer t_gradient_evaluations)
Definition Optimizer.hh:93
Integer gradient_evaluations() const
Definition Optimizer.hh:81
bool evaluate_gradient(GradientLambda &&gradient, Vector const &x, Matrix &out)
Definition Optimizer.hh:129
void max_hessian_evaluations(Integer t_hessian_evaluations)
Definition Optimizer.hh:114
typename SolverBase< Real, N, 1, DerivedSolver, ForceEigen >::SecondDerivativeType Matrix
Definition Optimizer.hh:64
bool solve(FunctionLambda &&function, GradientLambda &&gradient, Vector const &x_ini, Vector &x_sol)
Definition Optimizer.hh:180
bool solve(FunctionLambda &&function, GradientLambda &&gradient, HessianLambda &&hessian, Vector const &x_ini, Vector &x_sol)
Definition Optimizer.hh:209
bool evaluate_second_derivative(SecondDerivativeLambda &&function, InputType const &x, SecondDerivativeType &out)
Definition SolverBase.hh:801
Integer max_first_derivative_evaluations() const
Definition SolverBase.hh:289
Integer max_second_derivative_evaluations() const
Definition SolverBase.hh:312
Integer second_derivative_evaluations() const
Definition SolverBase.hh:306
std::conditional_t< ForceEigen||(SolInDim > 1)||(SolOutDim > 1), std::conditional_t< SolInDim==1||SolOutDim==1, Eigen::Matrix< Real, SolInDim, SolInDim >, std::vector< Eigen::Matrix< Real, SolInDim, SolInDim > > >, Real > SecondDerivativeType
Definition SolverBase.hh:64
typename std::conditional_t< ForceEigen||(SolInDim > 1), Eigen::Vector< Real, SolInDim >, Real > InputType
Definition SolverBase.hh:53
std::conditional_t< ForceEigen||(SolInDim > 1)||(SolOutDim > 1), Eigen::Matrix< Real, SolOutDim, SolInDim >, Real > FirstDerivativeType
Definition SolverBase.hh:62
Integer first_derivative_evaluations() const
Definition SolverBase.hh:283
bool evaluate_first_derivative(FirstDerivativeLambda &&function, InputType const &x, FirstDerivativeType &out)
Definition SolverBase.hh:785
Namespace for the Optimist library.
Definition Optimist.hh:88
OPTIMIST_DEFAULT_INTEGER_TYPE Integer
The Integer type as used for the API.
Definition Optimist.hh:96