Optimist  0.0.0
A C++ library for optimization
Loading...
Searching...
No Matches
RootFinder.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_ROOTFINDER_HH
14#define OPTIMIST_ROOTFINDER_HH
15
17
18namespace Optimist
19{
20
24 namespace RootFinder
25 {
26
27 /*\
28 | ____ _ _____ _ _
29 | | _ \ ___ ___ | |_| ___(_)_ __ __| | ___ _ __
30 | | |_) / _ \ / _ \| __| |_ | | '_ \ / _` |/ _ \ '__|
31 | | _ < (_) | (_) | |_| _| | | | | | (_| | __/ |
32 | |_| \_\___/ \___/ \__|_| |_|_| |_|\__,_|\___|_|
33 |
34 \*/
35
46 template <typename Real, Integer N, typename DerivedSolver, bool ForceEigen = false>
47 class RootFinder : public SolverBase<Real, N, N, DerivedSolver, ForceEigen>
48 {
49 public:
50 // Fancy static assertions (just for fun, don't take it too seriously)
51 static_assert(N != static_cast<Integer>(0),
52 "Are you sure you want to solve a zero-dimensional system of equations?");
53
54 friend class SolverBase<Real, N, N, RootFinder<Real, N, DerivedSolver, ForceEigen>>;
55
56 static constexpr bool is_rootfinder{true};
57 static constexpr bool is_optimizer{false};
58
59 static constexpr bool requires_function{DerivedSolver::requires_function};
60 static constexpr bool requires_first_derivative{DerivedSolver::requires_first_derivative};
61 static constexpr bool requires_second_derivative{DerivedSolver::requires_second_derivative};
62
64
65 using SolverBase<Real, N, N, DerivedSolver, ForceEigen>::solve;
66
67 // I/O types
69
70 // Derivative types
73
74 // Function types
78
83
88 std::string name() const {return static_cast<const DerivedSolver *>(this)->name_impl();}
89
95
101
106 void max_jacobian_evaluations(Integer t_jacobian_evaluations)
107 {
108 this->max_first_derivative_evaluations(t_jacobian_evaluations);
109 }
110
116
122
127 void max_hessian_evaluations(Integer t_hessian_evaluations)
128 {
129 this->max_first_derivative_evaluations(t_hessian_evaluations);
130 }
131
132 protected:
139 void evaluate_jacobian(JacobianWrapper jacobian, const Vector & x, Matrix & out)
140 {
141 this->evaluate_first_derivative(jacobian, x, out);
142 }
143
150 void evaluate_hessian(HessianWrapper hessian, const Vector & x, Matrix & out)
151 {
152 this->evaluate_second_derivative(hessian, x, out);
153 }
154
155 public:
163 bool solve(FunctionWrapper function, Vector const & x_ini, Vector & x_sol)
164 {
165 #define CMD "Optimist::RootFinder::solve(...): "
166
167 static_assert(DerivedSolver::requires_function,
168 CMD "the solver requires a function.");
169 return static_cast<DerivedSolver *>(this)->solve_impl(function, x_ini, x_sol);
170
171 #undef CMD
172 }
173
182 bool solve(FunctionWrapper function, JacobianWrapper jacobian, Vector const & x_ini, Vector & x_sol)
183 {
184 #define CMD "Optimist::RootFinder::solve(...): "
185
186 static_assert(DerivedSolver::requires_function,
187 CMD "the solver requires a function.");
188 static_assert(DerivedSolver::requires_first_derivative,
189 CMD "the solver requires the first derivative.");
190 return static_cast<DerivedSolver *>(this)->solve_impl(function, jacobian, x_ini, x_sol);
191
192 #undef CMD
193 }
194
205 const & x_ini, Vector & x_sol)
206 {
207 #define CMD "Optimist::RootFinder::solve(...): "
208
209 static_assert(DerivedSolver::requires_function,
210 CMD "the solver requires the function.");
211 static_assert(DerivedSolver::requires_first_derivative,
212 CMD "the solver requires the first derivative.");
213 static_assert(DerivedSolver::requires_second_derivative,
214 CMD "the solver requires the second derivative.");
215 return static_cast<DerivedSolver *>(this)->solve_impl(function, jacobian, hessian, x_ini, x_sol);
216
217 #undef CMD
218 }
219
220 }; // class RootFinder
221
222 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
223
232 template <typename Real, typename DerivedSolver>
233 class RootFinder<Real, 1, DerivedSolver> : public SolverBase<Real, 1, 1, DerivedSolver>
234 {
235 public:
236 friend class SolverBase<Real, 1, 1, RootFinder<Real, 1, DerivedSolver>>;
237
238 static constexpr bool is_rootfinder{true};
239 static constexpr bool is_optimizer{false};
240
241 static constexpr bool requires_function{DerivedSolver::requires_function};
242 static constexpr bool requires_first_derivative{DerivedSolver::requires_first_derivative};
243 static constexpr bool requires_second_derivative{DerivedSolver::requires_second_derivative};
244
246
247 using FunctionWrapper = typename SolverBase<Real, 1, 1, DerivedSolver>::FunctionWrapper;
248 using FirstDerivativeWrapper = typename SolverBase<Real, 1, 1, DerivedSolver>::FirstDerivativeWrapper;
249 using SecondDerivativeWrapper = typename SolverBase<Real, 1, 1, DerivedSolver>::SecondDerivativeWrapper;
250
254 RootFinder<Real, 1, DerivedSolver>() {}
255
260 std::string name() const {return static_cast<const DerivedSolver *>(this)->name_impl();}
261
269 bool solve(FunctionWrapper function, Real x_ini, Real & x_sol)
270 {
271 return static_cast<DerivedSolver *>(this)->solve_impl(function, x_ini, x_sol);
272 }
273
282 bool solve(FunctionWrapper function, FirstDerivativeWrapper first_derivative, Real x_ini,
283 Real & x_sol)
284 {
285 return static_cast<DerivedSolver *>(this)->solve_impl(function, first_derivative, x_ini, x_sol);
286 }
287
298 second_derivate, Real x_ini, Real & x_sol)
299 {
300 return static_cast<DerivedSolver *>(this)->solve_impl(function, first_derivative,
301 second_derivate, x_ini, x_sol);
302 }
303
304 }; // class RootFinder
305
306 } // namespace RootFinder
307
308} // namespace Optimist
309
310#endif // OPTIMIST_ROOTFINDER_HH
#define OPTIMIST_BASIC_CONSTANTS(Real)
Definition Optimist.hh:70
#define CMD
static constexpr bool requires_function
Definition RootFinder.hh:241
bool solve(FunctionWrapper function, FirstDerivativeWrapper first_derivative, SecondDerivativeWrapper second_derivate, Real x_ini, Real &x_sol)
Definition RootFinder.hh:297
bool solve(FunctionWrapper function, Real x_ini, Real &x_sol)
Definition RootFinder.hh:269
typename SolverBase< Real, 1, 1, DerivedSolver >::FunctionWrapper FunctionWrapper
Definition RootFinder.hh:247
typename SolverBase< Real, 1, 1, DerivedSolver >::SecondDerivativeWrapper SecondDerivativeWrapper
Definition RootFinder.hh:249
static constexpr bool requires_second_derivative
Definition RootFinder.hh:243
bool solve(FunctionWrapper function, FirstDerivativeWrapper first_derivative, Real x_ini, Real &x_sol)
Definition RootFinder.hh:282
static constexpr bool is_optimizer
Definition RootFinder.hh:239
std::string name() const
Definition RootFinder.hh:260
typename SolverBase< Real, 1, 1, DerivedSolver >::FirstDerivativeWrapper FirstDerivativeWrapper
Definition RootFinder.hh:248
static constexpr bool requires_first_derivative
Definition RootFinder.hh:242
static constexpr bool is_rootfinder
Definition RootFinder.hh:238
Class container for the multi-dimensional root finder.
Definition RootFinder.hh:48
static constexpr bool is_optimizer
Definition RootFinder.hh:57
void max_jacobian_evaluations(Integer t_jacobian_evaluations)
Definition RootFinder.hh:106
static constexpr bool requires_first_derivative
Definition RootFinder.hh:60
bool solve(FunctionWrapper function, JacobianWrapper jacobian, HessianWrapper hessian, Vector const &x_ini, Vector &x_sol)
Definition RootFinder.hh:204
std::string name() const
Definition RootFinder.hh:88
bool solve(FunctionWrapper function, Vector const &x_ini, Vector &x_sol)
Definition RootFinder.hh:163
typename SolverBase< Real, N, N, DerivedSolver, ForceEigen >::InputType Vector
Definition RootFinder.hh:68
typename SolverBase< Real, N, N, DerivedSolver, ForceEigen >::SecondDerivativeWrapper HessianWrapper
Definition RootFinder.hh:77
void max_hessian_evaluations(Integer t_hessian_evaluations)
Definition RootFinder.hh:127
typename SolverBase< Real, N, N, DerivedSolver, ForceEigen >::FunctionWrapper FunctionWrapper
Definition RootFinder.hh:75
bool solve(FunctionWrapper function, JacobianWrapper jacobian, Vector const &x_ini, Vector &x_sol)
Definition RootFinder.hh:182
typename SolverBase< Real, N, N, DerivedSolver, ForceEigen >::SecondDerivativeType Tensor
Definition RootFinder.hh:72
RootFinder()
Definition RootFinder.hh:82
void evaluate_jacobian(JacobianWrapper jacobian, const Vector &x, Matrix &out)
Definition RootFinder.hh:139
typename SolverBase< Real, N, N, DerivedSolver, ForceEigen >::FirstDerivativeType Matrix
Definition RootFinder.hh:71
Integer hessian_evaluations() const
Definition RootFinder.hh:115
Integer jacobian_evaluations() const
Definition RootFinder.hh:94
void evaluate_hessian(HessianWrapper hessian, const Vector &x, Matrix &out)
Definition RootFinder.hh:150
static constexpr bool is_rootfinder
Definition RootFinder.hh:56
typename SolverBase< Real, N, N, DerivedSolver, ForceEigen >::FirstDerivativeWrapper JacobianWrapper
Definition RootFinder.hh:76
static constexpr bool requires_second_derivative
Definition RootFinder.hh:61
static constexpr bool requires_function
Definition RootFinder.hh:59
Integer max_jacobian_evaluations() const
Definition RootFinder.hh:100
Integer max_hessian_evaluations() const
Definition RootFinder.hh:121
Class container for the generic root-finding/optimization problem solver.
Definition SolverBase.hh:44
std::conditional_t< ForceEigen||(SolInDim > 1)||(SolOutDim > 1), Eigen::Matrix< Real, SolOutDim, SolInDim >, Real > FirstDerivativeType
Definition SolverBase.hh:61
Integer max_first_derivative_evaluations() const
Definition SolverBase.hh:273
typename std::function< void(const InputType &, SecondDerivativeType &)> SecondDerivativeWrapper
Definition SolverBase.hh:69
typename std::conditional_t< ForceEigen||(SolInDim > 1), Eigen::Vector< Real, SolInDim >, Real > InputType
Definition SolverBase.hh:54
void evaluate_second_derivative(SecondDerivativeWrapper function, const InputType &x, SecondDerivativeType &out)
Definition SolverBase.hh:745
typename std::function< void(const InputType &, OutputType &)> FunctionWrapper
Definition SolverBase.hh:67
void evaluate_first_derivative(FirstDerivativeWrapper function, const InputType &x, FirstDerivativeType &out)
Definition SolverBase.hh:731
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:62
Integer first_derivative_evaluations() const
Definition SolverBase.hh:267
typename std::function< void(const InputType &, FirstDerivativeType &)> FirstDerivativeWrapper
Definition SolverBase.hh:68
Namespace for the Optimist library.
Definition Optimist.hh:87
OPTIMIST_DEFAULT_INTEGER_TYPE Integer
The Integer type as used for the API.
Definition Optimist.hh:95