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 > 0 && FunOutDim > 0,
47 "Negative-dimensional function? Are you serious?");
48
50
51 // I/O types
52 using InputType = typename std::conditional_t<ForceEigen || (FunInDim > 1),
53 Eigen::Vector<Real, FunInDim>, Real>;
54 using OutputType = typename std::conditional_t<ForceEigen || (FunOutDim > 1),
55 Eigen::Vector<Real, FunOutDim>, Real>;
56
57 // Derivative types
58 using FirstDerivativeType = std::conditional_t<ForceEigen || (FunInDim > 1) || (FunOutDim > 1),
59 Eigen::Matrix<Real, FunOutDim, FunInDim>, Real>;
60 using SecondDerivativeType = std::conditional_t<ForceEigen || (FunInDim > 1) || (FunOutDim > 1),
61 std::conditional_t<FunInDim == 1 || FunOutDim == 1, Eigen::Matrix<Real, FunInDim, FunInDim>,
62 std::vector<Eigen::Matrix<Real, FunInDim, FunInDim>>>, Real>;
63
64 protected:
65 std::vector<InputType> m_solutions;
66 std::vector<InputType> m_guesses;
67
68 public:
73
78 std::string name() const {return static_cast<const DerivedFunction *>(this)->name();};
79
86 bool evaluate(const InputType & x, OutputType & out) const
87 {
88 return static_cast<const DerivedFunction *>(this)->evaluate_impl(x, out);
89 }
90
97 bool first_derivative(const InputType & x, FirstDerivativeType & out) const
98 {
99 return static_cast<const DerivedFunction *>(this)->first_derivative_impl(x, out);
100 }
101
109 {
110 return static_cast<const DerivedFunction *>(this)->second_derivative_impl(x, out);
111 }
112
117 constexpr Integer input_dimension() const {return FunInDim;}
118
123 constexpr Integer output_dimension() const {return FunOutDim;}
124
129 const std::vector<InputType> & solutions() const {return this->m_solutions;}
130
135 const std::vector<InputType> & guesses() const {return this->m_guesses;}
136
142 const InputType & solution(Integer const i) const {return this->m_solutions.at(i);}
143
149 const InputType & guess(Integer const i) const {return this->m_guesses.at(i);}
150
157 bool is_solution(const InputType & x, Real const tol = EPSILON_LOW) const
158 {
159 for (const auto & s : this->m_solutions) {
160 if constexpr (ForceEigen || FunInDim > 1) {
161 if((x - s).norm() < tol) {return true;}
162 } else {
163 if (std::abs(x - s) < tol) {return true;}
164 }
165 }
166 return false;
167 }
168
169 }; // class FunctionBase
170
171 /*\
172 | _____ _ _
173 | | ___| _ _ __ ___| |_(_) ___ _ __
174 | | |_ | | | | '_ \ / __| __| |/ _ \| '_ \
175 | | _|| |_| | | | | (__| |_| | (_) | | | |
176 | |_| \__,_|_| |_|\___|\__|_|\___/|_| |_|
177 |
178 \*/
179
188 template <typename Real, Integer N, Integer M, typename DerivedFunction, bool ForceEigen = false>
189 class Function : public FunctionBase<Real, N, M, DerivedFunction, ForceEigen>
190 {
191 public:
192 friend class FunctionBase<Real, N, M, Function<Real, N, M, DerivedFunction, ForceEigen>>;
193
194 // Fancy static assertions (just for fun, don't take it too seriously)
195 static_assert(N != 0 && M != 0,
196 "Are you sure you want to a zero-dimensional system of equations?");
197
198 // I/O types
201
202 // Derivative types
205
210
215 std::string name() const {return static_cast<const DerivedFunction *>(this)->name_impl();}
216
223 bool evaluate(const InputVector & x, OutputVector & out) const
224 {
225 return static_cast<const DerivedFunction *>(this)->evaluate_impl(x, out);
226 }
227
234 bool jacobian(const InputVector & x, Matrix & out) const
235 {
236 return static_cast<const DerivedFunction *>(this)->first_derivative_impl(x, out);
237 }
238
245 bool hessian(const InputVector & x, Tensor & out) const
246 {
247 return static_cast<const DerivedFunction *>(this)->second_derivative_impl(x, out);
248 }
249
250 }; // class Function
251
252 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
253
261 template <typename Real, Integer N, typename DerivedFunction>
262 class Function<Real, N, 1, DerivedFunction> : public FunctionBase<Real, N, 1, DerivedFunction>
263 {
264 public:
265 friend class FunctionBase<Real, N, 1, Function<Real, N, 1, DerivedFunction>>;
266
267 // Fancy static assertions (just for fun, don't take it too seriously)
268 static_assert(N != 0,
269 "Are you sure you want to a zero-dimensional system of equations?");
270
271 // I/O types
273
274 // Derivative types
277
282
287 std::string name() const {return static_cast<const DerivedFunction *>(this)->name_impl();}
288
295 bool evaluate(Vector const & x, Vector & out) const
296 {
297 return static_cast<const DerivedFunction *>(this)->evaluate_impl(x, out);
298 }
299
306 bool gradient(Vector const & x, RowVector & out) const
307 {
308 return static_cast<const DerivedFunction *>(this)->first_derivative_impl(x, out);
309 }
310
317 bool hessian(Vector const & x, Matrix & out) const
318 {
319 return static_cast<const DerivedFunction *>(this)->second_derivative_impl(x, out);
320 }
321
322 }; // class Function
323
324 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
325
332 template <typename Real, typename DerivedFunction>
333 class Function<Real, 1, 1, DerivedFunction> : public FunctionBase<Real, 1, 1, DerivedFunction>
334 {
335 public:
336 friend class FunctionBase<Real, 1, 1, Function<Real, 1, 1, DerivedFunction>>;
337
342
347 std::string name() const {return static_cast<const DerivedFunction *>(this)->name_impl();}
348
355 bool evaluate(Real x, Real & out) const
356 {
357 return static_cast<const DerivedFunction *>(this)->evaluate_impl(x, out);
358 }
359
366 bool first_derivative(Real x, Real & out) const
367 {
368 return static_cast<const DerivedFunction *>(this)->first_derivative_impl(x, out);
369 }
370
377 bool second_derivative(Real x, Real & out) const
378 {
379 return static_cast<const DerivedFunction *>(this)->second_derivative_impl(x, out);
380 }
381
382 }; // class Function
383
384} // namespace Optimist
385
386#endif // OPTIMIST_FUNCTION_HH
#define OPTIMIST_BASIC_CONSTANTS(Real)
Definition Optimist.hh:71
bool second_derivative(Real x, Real &out) const
Definition Function.hh:377
bool first_derivative(Real x, Real &out) const
Definition Function.hh:366
bool evaluate(Real x, Real &out) const
Definition Function.hh:355
std::string name() const
Definition Function.hh:347
typename FunctionBase< Real, N, 1, DerivedFunction >::InputType Vector
Definition Function.hh:272
bool gradient(Vector const &x, RowVector &out) const
Definition Function.hh:306
typename FunctionBase< Real, N, 1, DerivedFunction >::FirstDerivativeType RowVector
Definition Function.hh:275
bool evaluate(Vector const &x, Vector &out) const
Definition Function.hh:295
typename FunctionBase< Real, N, 1, DerivedFunction >::SecondDerivativeType Matrix
Definition Function.hh:276
std::string name() const
Definition Function.hh:287
const InputType & guess(Integer const i) const
Definition Function.hh:149
const std::vector< InputType > & solutions() const
Definition Function.hh:129
FunctionBase()
Definition Function.hh:72
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:60
std::vector< InputType > m_guesses
Definition Function.hh:66
bool second_derivative(const InputType &x, SecondDerivativeType &out) const
Definition Function.hh:108
std::vector< InputType > m_solutions
Definition Function.hh:65
typename std::conditional_t< ForceEigen||(FunInDim > 1), Eigen::Vector< Real, FunInDim >, Real > InputType
Definition Function.hh:52
std::string name() const
Definition Function.hh:78
std::conditional_t< ForceEigen||(FunInDim > 1)||(FunOutDim > 1), Eigen::Matrix< Real, FunOutDim, FunInDim >, Real > FirstDerivativeType
Definition Function.hh:58
bool first_derivative(const InputType &x, FirstDerivativeType &out) const
Definition Function.hh:97
const std::vector< InputType > & guesses() const
Definition Function.hh:135
typename std::conditional_t< ForceEigen||(FunOutDim > 1), Eigen::Vector< Real, FunOutDim >, Real > OutputType
Definition Function.hh:54
constexpr Integer input_dimension() const
Definition Function.hh:117
const InputType & solution(Integer const i) const
Definition Function.hh:142
bool is_solution(const InputType &x, Real const tol=EPSILON_LOW) const
Definition Function.hh:157
constexpr Integer output_dimension() const
Definition Function.hh:123
bool evaluate(const InputType &x, OutputType &out) const
Definition Function.hh:86
bool jacobian(const InputVector &x, Matrix &out) const
Definition Function.hh:234
typename FunctionBase< Real, N, M, DerivedFunction, ForceEigen >::OutputType OutputVector
Definition Function.hh:200
bool evaluate(const InputVector &x, OutputVector &out) const
Definition Function.hh:223
std::string name() const
Definition Function.hh:215
typename FunctionBase< Real, N, M, DerivedFunction, ForceEigen >::InputType InputVector
Definition Function.hh:199
bool hessian(const InputVector &x, Tensor &out) const
Definition Function.hh:245
Function()
Definition Function.hh:209
typename FunctionBase< Real, N, M, DerivedFunction, ForceEigen >::FirstDerivativeType Matrix
Definition Function.hh:203
typename FunctionBase< Real, N, M, DerivedFunction, ForceEigen >::SecondDerivativeType Tensor
Definition Function.hh:204
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