Optimist  0.0.0
A C++ library for optimization
Loading...
Searching...
No Matches
Function.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_FUNCTION_HH
14#define OPTIMIST_FUNCTION_HH
15
16#include "Optimist.hh"
17
18namespace Optimist
19{
20
21 /*\
22 | _____ _ _ ____
23 | | ___| _ _ __ ___| |_(_) ___ _ __ | __ ) __ _ ___ ___
24 | | |_ | | | | '_ \ / __| __| |/ _ \| '_ \| _ \ / _` / __|/ _ \
25 | | _|| |_| | | | | (__| |_| | (_) | | | | |_) | (_| \__ \ __/
26 | |_| \__,_|_| |_|\___|\__|_|\___/|_| |_|____/ \__,_|___/\___|
27 |
28 \*/
29
41 template <typename Real, Integer FunInDim, Integer FunOutDim, typename DerivedFunction, bool ForceEigen = false>
43 {
44 public:
45 // Fancy static assertios (just for fun, don't take it too seriously)
46 static_assert(FunInDim > static_cast<Integer>(0) && FunOutDim > static_cast<Integer>(0),
47 "Negative-dimensional function? Are you serious?");
48
50
51 // I/O types
52 using InputType = typename std::conditional_t<ForceEigen || (FunInDim > 1), Eigen::Vector<Real, FunInDim>, Real>;
53 using OutputType = typename std::conditional_t<ForceEigen || (FunOutDim > 1), Eigen::Vector<Real, FunOutDim>, Real>;
54
55 // Derivative types
56 using FirstDerivativeType = std::conditional_t<ForceEigen || (FunInDim > 1) || (FunOutDim > 1), Eigen::Matrix<Real, FunOutDim, FunInDim>, Real>;
57 using SecondDerivativeType = std::conditional_t<ForceEigen || (FunInDim > 1) || (FunOutDim > 1),
58 std::conditional_t<FunInDim == 1 || FunOutDim == 1, Eigen::Matrix<Real, FunInDim, FunInDim>,
59 std::vector<Eigen::Matrix<Real, FunInDim, FunInDim>>>, Real>;
60
61 protected:
62 std::vector<InputType> m_solutions;
63 std::vector<InputType> m_guesses;
64
65 public:
70
75 std::string name() const {return static_cast<const DerivedFunction *>(this)->name();};
76
82 void evaluate(const InputType & x, OutputType & out) const
83 {
84 static_cast<const DerivedFunction *>(this)->evaluate_impl(x, out);
85 }
86
92 void first_derivative(const InputType & x, FirstDerivativeType & out) const
93 {
94 static_cast<const DerivedFunction *>(this)->first_derivative_impl(x, out);
95 }
96
103 {
104 static_cast<const DerivedFunction *>(this)->second_derivative_impl(x, out);
105 }
106
111 constexpr Integer input_dimension() const {return FunInDim;}
112
117 constexpr Integer output_dimension() const {return FunOutDim;}
118
123 const std::vector<InputType> & solutions() const {return this->m_solutions;}
124
129 const std::vector<InputType> & guesses() const {return this->m_guesses;}
130
136 const InputType & solution(const Integer i) const {return this->m_solutions.at(i);}
137
143 const InputType & guess(const Integer i) const {return this->m_guesses.at(i);}
144
151 bool is_solution(const InputType & x, const Real tol = EPSILON_LOW) const
152 {
153 for (const auto & s : this->m_solutions) {
154 if constexpr (ForceEigen || FunInDim > 1) {
155 if((x - s).norm() < tol) {return true;}
156 } else {
157 if (std::abs(x - s) < tol) {return true;}
158 }
159 }
160 return false;
161 }
162
163 }; // class FunctionBase
164
165 /*\
166 | _____ _ _
167 | | ___| _ _ __ ___| |_(_) ___ _ __
168 | | |_ | | | | '_ \ / __| __| |/ _ \| '_ \
169 | | _|| |_| | | | | (__| |_| | (_) | | | |
170 | |_| \__,_|_| |_|\___|\__|_|\___/|_| |_|
171 |
172 \*/
173
182 template <typename Real, Integer N, Integer M, typename DerivedFunction, bool ForceEigen = false>
183 class Function : public FunctionBase<Real, N, M, DerivedFunction, ForceEigen>
184 {
185 public:
186 friend class FunctionBase<Real, N, M, Function<Real, N, M, DerivedFunction, ForceEigen>>;
187
188 // Fancy static assertions (just for fun, don't take it too seriously)
189 static_assert(N != static_cast<Integer>(0) && M != static_cast<Integer>(0),
190 "Are you sure you want to a zero-dimensional system of equations?");
191
192 // I/O types
195
196 // Derivative types
199
204
209 std::string name() const {return static_cast<const DerivedFunction *>(this)->name_impl();}
210
216 void evaluate(const InputVector & x, OutputVector & out) const
217 {
218 static_cast<const DerivedFunction *>(this)->evaluate_impl(x, out);
219 }
220
226 void jacobian(const InputVector & x, Matrix & out) const
227 {
228 static_cast<const DerivedFunction *>(this)->first_derivative_impl(x, out);
229 }
230
236 void hessian(const InputVector & x, Tensor & out) const
237 {
238 static_cast<const DerivedFunction *>(this)->second_derivative_impl(x, out);
239 }
240
241 }; // class Function
242
243 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
244
252 template <typename Real, Integer N, typename DerivedFunction>
253 class Function<Real, N, 1, DerivedFunction> : public FunctionBase<Real, N, 1, DerivedFunction>
254 {
255 public:
256 friend class FunctionBase<Real, N, 1, Function<Real, N, 1, DerivedFunction>>;
257
258 // Fancy static assertions (just for fun, don't take it too seriously)
259 static_assert(N != static_cast<Integer>(0),
260 "Are you sure you want to a zero-dimensional system of equations?");
261
262 // I/O types
264
265 // Derivative types
268
273
278 std::string name() const {return static_cast<const DerivedFunction *>(this)->name_impl();}
279
285 void evaluate(const Vector & x, Vector & out) const
286 {
287 static_cast<const DerivedFunction *>(this)->evaluate_impl(x, out);
288 }
289
295 void gradient(const Vector & x, RowVector & out) const
296 {
297 static_cast<const DerivedFunction *>(this)->first_derivative_impl(x, out);
298 }
299
305 void hessian(const Vector & x, Matrix & out) const
306 {
307 static_cast<const DerivedFunction *>(this)->second_derivative_impl(x, out);
308 }
309
310 }; // class Function
311
312 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
313
320 template <typename Real, typename DerivedFunction>
321 class Function<Real, 1, 1, DerivedFunction> : public FunctionBase<Real, 1, 1, DerivedFunction>
322 {
323 public:
324 friend class FunctionBase<Real, 1, 1, Function<Real, 1, 1, DerivedFunction>>;
325
330
335 std::string name() const {return static_cast<const DerivedFunction *>(this)->name_impl();}
336
342 void evaluate(Real x, Real & out) const
343 {
344 static_cast<const DerivedFunction *>(this)->evaluate_impl(x, out);
345 }
346
352 void first_derivative(Real x, Real & out) const
353 {
354 static_cast<const DerivedFunction *>(this)->first_derivative_impl(x, out);
355 }
356
362 void second_derivative(Real x, Real & out) const
363 {
364 static_cast<const DerivedFunction *>(this)->second_derivative_impl(x, out);
365 }
366
367 }; // class Function
368
369} // namespace Optimist
370
371#endif // OPTIMIST_FUNCTION_HH
#define OPTIMIST_BASIC_CONSTANTS(Real)
Definition Optimist.hh:70
void first_derivative(Real x, Real &out) const
Definition Function.hh:352
void second_derivative(Real x, Real &out) const
Definition Function.hh:362
void evaluate(Real x, Real &out) const
Definition Function.hh:342
std::string name() const
Definition Function.hh:335
typename FunctionBase< Real, N, 1, DerivedFunction >::InputType Vector
Definition Function.hh:263
typename FunctionBase< Real, N, 1, DerivedFunction >::FirstDerivativeType RowVector
Definition Function.hh:266
void evaluate(const Vector &x, Vector &out) const
Definition Function.hh:285
void gradient(const Vector &x, RowVector &out) const
Definition Function.hh:295
typename FunctionBase< Real, N, 1, DerivedFunction >::SecondDerivativeType Matrix
Definition Function.hh:267
std::string name() const
Definition Function.hh:278
typename std::conditional_t< ForceEigen||(FunOutDim > 1), Eigen::Vector< Real, FunOutDim >, Real > OutputType
Definition Function.hh:53
const InputType & guess(const Integer i) const
Definition Function.hh:143
const std::vector< InputType > & solutions() const
Definition Function.hh:123
void second_derivative(const InputType &x, SecondDerivativeType &out) const
Definition Function.hh:102
bool is_solution(const InputType &x, const Real tol=EPSILON_LOW) const
Definition Function.hh:151
FunctionBase()
Definition Function.hh:69
std::conditional_t< ForceEigen||(FunInDim > 1)||(FunOutDim > 1), std::conditional_t< FunInDim==1||FunOutDim==1, Eigen::Matrix< Real, FunInDim, FunInDim >, std::vector< Eigen::Matrix< Real, FunInDim, FunInDim > > >, Real > SecondDerivativeType
Definition Function.hh:57
std::vector< InputType > m_guesses
Definition Function.hh:63
std::conditional_t< ForceEigen||(FunInDim > 1)||(FunOutDim > 1), Eigen::Matrix< Real, FunOutDim, FunInDim >, Real > FirstDerivativeType
Definition Function.hh:56
std::vector< InputType > m_solutions
Definition Function.hh:62
typename std::conditional_t< ForceEigen||(FunInDim > 1), Eigen::Vector< Real, FunInDim >, Real > InputType
Definition Function.hh:52
std::string name() const
Definition Function.hh:75
const InputType & solution(const Integer i) const
Definition Function.hh:136
const std::vector< InputType > & guesses() const
Definition Function.hh:129
constexpr Integer input_dimension() const
Definition Function.hh:111
void first_derivative(const InputType &x, FirstDerivativeType &out) const
Definition Function.hh:92
constexpr Integer output_dimension() const
Definition Function.hh:117
void evaluate(const InputType &x, OutputType &out) const
Definition Function.hh:82
typename FunctionBase< Real, N, M, DerivedFunction, ForceEigen >::OutputType OutputVector
Definition Function.hh:194
std::string name() const
Definition Function.hh:209
void evaluate(const InputVector &x, OutputVector &out) const
Definition Function.hh:216
void jacobian(const InputVector &x, Matrix &out) const
Definition Function.hh:226
typename FunctionBase< Real, N, M, DerivedFunction, ForceEigen >::InputType InputVector
Definition Function.hh:193
void hessian(const InputVector &x, Tensor &out) const
Definition Function.hh:236
Function()
Definition Function.hh:203
typename FunctionBase< Real, N, M, DerivedFunction, ForceEigen >::FirstDerivativeType Matrix
Definition Function.hh:197
typename FunctionBase< Real, N, M, DerivedFunction, ForceEigen >::SecondDerivativeType Tensor
Definition Function.hh:198
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