1#ifndef _FMATVEC_FUNCTION_H_
2#define _FMATVEC_FUNCTION_H_
4#include <fmatvec/fmatvec.h>
5#include <fmatvec/atom.h>
7#include <boost/mpl/list.hpp>
16#if !defined(SWIG) && !defined(MBSIM_COMPILE_SWIG)
21 throw std::runtime_error(
"Impossible type.");
36 enum { size1=1, size2=1 };
42 enum { size1=1, size2=1 };
46template<
typename Shape,
typename AT>
48 enum { size1=0, size2=1 };
52template<
typename Shape,
typename AT>
54 enum { size1=1, size2=0 };
58template<
int N,
typename AT>
60 enum { size1=N, size2=1 };
64template<
int N,
typename AT>
66 enum { size1=1, size2=N };
70template<
typename Storage,
typename RowShape,
typename ColShape,
typename AT>
72 enum { size1=0, size2=0 };
76template<
typename Storage,
int N,
int M,
typename AT>
78 enum { size1=N, size2=M };
82template<
typename Storage,
int N,
typename ColShape,
typename AT>
84 enum { size1=N, size2=0 };
88template<
typename Storage,
typename RowShape,
int M,
typename AT>
90 enum { size1=0, size2=M };
94template<
int N,
typename AT>
96 enum { size1=N, size2=N };
100template<
typename Shape,
typename AT>
102 enum { size1=0, size2=0 };
108template<
typename Dep,
typename Indep>
116template<
typename Dep>
126template<
typename IndepVecShape>
136template<
typename DepVecShape,
typename IndepVecShape>
170template<
typename IndepVecShape>
178template<
typename Dep,
typename Indep>
186template<
typename Indep>
201template<
typename Sig>
205template<
typename Ret,
typename Arg>
211 using DRetDDir =
typename DirDer<Ret, Arg>::type;
214 using ArgType = boost::mpl::list<Arg>;
223 virtual std::pair<int, int>
getRetSize()
const {
return std::make_pair(retSize1, retSize2); }
232 virtual DRetDArg
parDer(
const Arg &arg) {
233 throw std::runtime_error(
"parDer must be overloaded by derived class.");
237 virtual DRetDDir
dirDer(
const Arg &argDir,
const Arg &arg) {
238 if constexpr (std::is_same_v<DRetDArg, ErrorType>)
239 throw std::runtime_error(
"dirDer must be overloaded by derived class.");
241 return parDer(arg) * argDir;
246 throw std::runtime_error(
"parDerParDer must be overloaded by derived class.");
251 if constexpr (std::is_same_v<DDRetDDArg, ErrorType>)
252 throw std::runtime_error(
"parDerDirDer must be overloaded by derived class.");
254 return parDerParDer(arg) * argDir;
258 virtual DRetDDir
dirDerDirDer(
const Arg &argDir_1,
const Arg &argDir_2,
const Arg &arg) {
259 if constexpr (std::is_same_v<DRetDArg, ErrorType>)
260 throw std::runtime_error(
"dirDerDirDer must be overloaded by derived class.");
262 return parDerDirDer(argDir_2, arg) * argDir_1;
271template<
typename Ret,
typename Arg1,
typename Arg2>
277 using DRetDDir1 =
typename DirDer<Ret, Arg1>::type;
278 using DRetDDir2 =
typename DirDer<Ret, Arg2>::type;
283 using ArgType = boost::mpl::list<Arg1, Arg2>;
295 virtual std::pair<int, int>
getRetSize()
const {
return std::make_pair(retSize1, retSize2); }
303 virtual Ret
operator()(
const Arg1 &arg1,
const Arg2 &arg2)=0;
306 virtual DRetDArg1
parDer1(
const Arg1 &arg1,
const Arg2 &arg2) {
307 throw std::runtime_error(
"parDer1 must be overloaded by derived class.");
311 virtual DRetDDir1
dirDer1(
const Arg1 &arg1Dir,
const Arg1 &arg1,
const Arg2 &arg2) {
312 if constexpr (std::is_same_v<DRetDArg1, ErrorType>)
313 throw std::runtime_error(
"dirDer1 must be overloaded by derived class.");
315 return parDer1(arg1, arg2) * arg1Dir;
319 virtual DRetDArg2
parDer2(
const Arg1 &arg1,
const Arg2 &arg2) {
320 throw std::runtime_error(
"parDer2 must be overloaded by derived class.");
324 virtual DRetDDir2
dirDer2(
const Arg2 &arg2Dir,
const Arg1 &arg1,
const Arg2 &arg2) {
325 if constexpr (std::is_same_v<DRetDArg2, ErrorType>)
326 throw std::runtime_error(
"dirDer2 must be overloaded by derived class.");
328 return parDer2(arg1, arg2) * arg2Dir;
333 throw std::runtime_error(
"parDer1ParDer1 must be overloaded by derived class.");
337 virtual DRetDArg1
parDer1DirDer1(
const Arg1 &arg1Dir,
const Arg1 &arg1,
const Arg2 &arg2) {
338 if constexpr (std::is_same_v<DDRetDDArg1, ErrorType>)
339 throw std::runtime_error(
"parDer1DirDer1 must be overloaded by derived class.");
341 return parDer1ParDer1(arg1, arg2) * arg1Dir;
345 virtual DRetDDir1
dirDer1DirDer1(
const Arg1 &arg1Dir_1,
const Arg1 &arg1Dir_2,
const Arg1 &arg1,
const Arg2 &arg2) {
346 if constexpr (std::is_same_v<DDRetDDArg1, ErrorType>)
347 throw std::runtime_error(
"dirDer1DirDer1 must be overloaded by derived class.");
349 return parDer1ParDer1(arg1, arg2) * arg1Dir_1 * arg1Dir_2;
354 throw std::runtime_error(
"parDer2ParDer2 must be overloaded by derived class.");
358 virtual DRetDArg2
parDer2DirDer2(
const Arg2 &arg2Dir,
const Arg1 &arg1,
const Arg2 &arg2) {
359 if constexpr (std::is_same_v<DDRetDDArg2, ErrorType>)
360 throw std::runtime_error(
"parDer2DirDer2 must be overloaded by derived class.");
362 return parDer2ParDer2(arg1, arg2) * arg2Dir;
366 virtual DRetDDir2
dirDer2DirDer2(
const Arg2 &arg2Dir_1,
const Arg2 &arg2Dir_2,
const Arg1 &arg1,
const Arg2 &arg2) {
367 if constexpr (std::is_same_v<DDRetDDArg2, ErrorType>)
368 throw std::runtime_error(
"dirDer2DirDer2 must be overloaded by derived class.");
370 return parDer2ParDer2(arg1, arg2) * arg2Dir_1 * arg2Dir_2;
375 throw std::runtime_error(
"parDer1ParDer2 must be overloaded by derived class.");
379 virtual DRetDArg1
parDer1DirDer2(
const Arg2 &arg2Dir,
const Arg1 &arg1,
const Arg2 &arg2) {
380 if constexpr (std::is_same_v<DDRetDArg1DArg2, ErrorType>)
381 throw std::runtime_error(
"parDer1DirDer2 must be overloaded by derived class.");
383 return parDer1ParDer2(arg1, arg2) * arg2Dir;
387 virtual DRetDDir2
dirDer2DirDer1(
const Arg2 &arg2Dir,
const Arg1 &arg1Dir,
const Arg1 &arg1,
const Arg2 &arg2) {
388 if constexpr (std::is_same_v<DDRetDArg1DArg2, ErrorType>)
389 throw std::runtime_error(
"dirDer2DirDer1 must be overloaded by derived class.");
391 return parDer1ParDer2(arg1, arg2) * arg2Dir * arg1Dir;
395 virtual DRetDArg2
parDer2DirDer1(
const Arg1 &arg1Dir,
const Arg1 &arg1,
const Arg2 &arg2) {
396 if constexpr (std::is_same_v<DDRetDArg1DArg2, ErrorType>)
397 throw std::runtime_error(
"parDer2DirDer1 must be overloaded by derived class.");
399 return parDer1ParDer2(arg1, arg2) * arg1Dir;
Definition: function.h:14
virtual std::pair< int, int > getRetSize() const
Return the size of the return value: =0 == unknown size.
Definition: function.h:295
virtual DRetDDir2 dirDer2DirDer1(const Arg2 &arg2Dir, const Arg1 &arg1Dir, const Arg1 &arg1, const Arg2 &arg2)
Second mixed derivative: directional derivative of dirDer2 with respect to the first argument.
Definition: function.h:387
virtual DDRetDArg1DArg2 parDer1ParDer2(const Arg1 &arg1, const Arg2 &arg2)
Second mixed derivative: partial derivative of parDer1 with respect to the second argument.
Definition: function.h:374
virtual DRetDArg1 parDer1DirDer2(const Arg2 &arg2Dir, const Arg1 &arg1, const Arg2 &arg2)
Second mixed derivative: directional derivative of parDer1 with respect to the second argument.
Definition: function.h:379
virtual DRetDArg1 parDer1(const Arg1 &arg1, const Arg2 &arg2)
First derivative: partial derivative of the function value with respect to the first argument.
Definition: function.h:306
virtual int getArg1Size() const
Return the size of the first argument: =1 == scalar; >1 == vector; =0 == unknown vector size.
Definition: function.h:298
virtual DRetDDir2 dirDer2(const Arg2 &arg2Dir, const Arg1 &arg1, const Arg2 &arg2)
First derivative: directional derivative of the function value with respect to the second argument.
Definition: function.h:324
virtual DRetDArg2 parDer2(const Arg1 &arg1, const Arg2 &arg2)
First derivative: partial derivative of the function value with respect to the second argument.
Definition: function.h:319
virtual DRetDDir2 dirDer2DirDer2(const Arg2 &arg2Dir_1, const Arg2 &arg2Dir_2, const Arg1 &arg1, const Arg2 &arg2)
Second derivative: directional derivative of dirDer2 with respect to the first argument.
Definition: function.h:366
virtual DRetDArg1 parDer1DirDer1(const Arg1 &arg1Dir, const Arg1 &arg1, const Arg2 &arg2)
Second derivative: directional derivative of parDer1 with respect to the first argument.
Definition: function.h:337
virtual bool constParDer2() const
Returns true, if the partial derivative of the function value with respect to the second argument.
Definition: function.h:408
virtual int getArg2Size() const
Return the size of the second argument: =1 == scalar; >1 == vector; =0 == unknown vector size.
Definition: function.h:300
virtual DRetDArg2 parDer2DirDer2(const Arg2 &arg2Dir, const Arg1 &arg1, const Arg2 &arg2)
Second derivative: directional derivative of parDer2 with respect to the first argument.
Definition: function.h:358
virtual DRetDDir1 dirDer1DirDer1(const Arg1 &arg1Dir_1, const Arg1 &arg1Dir_2, const Arg1 &arg1, const Arg2 &arg2)
Second derivative: directional derivative of dirDer1 with respect to the first argument.
Definition: function.h:345
virtual DRetDArg2 parDer2DirDer1(const Arg1 &arg1Dir, const Arg1 &arg1, const Arg2 &arg2)
Second mixed derivative: partial derivative of dirDer1 with respect to the second argument.
Definition: function.h:395
virtual bool constParDer1() const
Returns true, if the partial derivative of the function value with respect to the first argument.
Definition: function.h:404
virtual Ret operator()(const Arg1 &arg1, const Arg2 &arg2)=0
Function value: pure virtual (MUST be implemented by derived class)
virtual DDRetDDArg1 parDer1ParDer1(const Arg1 &arg1, const Arg2 &arg2)
Second derivative: partial derivative of parDer1 with respect to the first argument.
Definition: function.h:332
virtual DRetDDir1 dirDer1(const Arg1 &arg1Dir, const Arg1 &arg1, const Arg2 &arg2)
First derivative: directional derivative of the function value with respect to the first argument.
Definition: function.h:311
virtual DDRetDDArg2 parDer2ParDer2(const Arg1 &arg1, const Arg2 &arg2)
Second derivative: partial derivative of parDer2 with respect to the first argument.
Definition: function.h:353
virtual DRetDArg parDer(const Arg &arg)
First derivative: partial derivative of the function value with respect to the argument.
Definition: function.h:232
virtual DRetDArg parDerDirDer(const Arg &argDir, const Arg &arg)
Second derivative: directional derivative of parDer with respect to the argument.
Definition: function.h:250
virtual DRetDDir dirDerDirDer(const Arg &argDir_1, const Arg &argDir_2, const Arg &arg)
Second derivative: directional derivative of dirDer with respect to the argument.
Definition: function.h:258
virtual Ret operator()(const Arg &arg)=0
Function value: pure virtual (MUST be implemented by derived class)
virtual DRetDDir dirDer(const Arg &argDir, const Arg &arg)
First derivative: directional derivative of the function value with respect to the argument.
Definition: function.h:237
virtual DDRetDDArg parDerParDer(const Arg &arg)
Second derivative: partial derivative of parDer with respect to the argument.
Definition: function.h:245
virtual int getArgSize() const
Return the size of the argument: =1 == scalar; >1 == vector; =0 == unknown vector size.
Definition: function.h:226
virtual std::pair< int, int > getRetSize() const
Return the size of the return value: =0 == unknown size.
Definition: function.h:223
virtual bool constParDer() const
Returns true, if the partial derivative of the function value with respect to the argument.
Definition: function.h:267
Definition: function.h:202
This is the basic matrix class for arbitrary matrices.
Definition: matrix.h:52
Shape class for rotation matrices.
Definition: types.h:140
Namespace fmatvec.
Definition: _memory.cc:28
SymbolicExpression parDer(const SymbolicExpression &dep, const IndependentVariable &indep)
Definition: ast.cc:299
Definition: function.h:109
Definition: function.h:179
Definition: function.h:31