21 #ifndef RFFGEN_MATHEMATICAL_OPERATION_CHAIN_HH
22 #define RFFGEN_MATHEMATICAL_OPERATION_CHAIN_HH
24 #include <type_traits>
27 #include "../Util/base.hh"
28 #include "../Util/computeSum.hh"
29 #include "../Util/computeChain.hh"
30 #include "../Util/derivativeWrappers.hh"
31 #include "../Util/indexedType.hh"
38 template <
class>
struct Chainer;
43 namespace MathematicalOperations
48 template <
class>
struct FunctionConceptCheck;
58 template <
class F ,
class G ,
59 class = FunctionConceptCheck<F>,
60 class = FunctionConceptCheck<G> >
61 struct Chain :
Base , Chainer< Chain<F,G,FunctionConceptCheck<F>,FunctionConceptCheck<G> > >
63 using Chainer< Chain<F,G,FunctionConceptCheck<F>,FunctionConceptCheck<G> > >::operator ();
65 using FArg = decltype(std::declval<G>().
d0());
67 template <
class IndexedArgX ,
class IndexedArgY ,
class IndexedFArgX ,
class IndexedFArgY >
68 using D2LazyType = ComputeSum< ComputeChainD2< F , D1<G,IndexedArgX> , D1<G,IndexedArgY> , IndexedFArgX , IndexedFArgY >,
69 ComputeChainD1< F , D2<G,IndexedArgX,IndexedArgY> , IndexedFArgX > >;
72 template <
class IndexedArgX ,
class IndexedArgY ,
class IndexedArgZ ,
73 class IndexedFArgX ,
class IndexedFArgY ,
class IndexedFArgZ >
74 using D3LazyType = ComputeSum< ComputeChainD3< F , D1<G,IndexedArgX> , D1<G,IndexedArgY> , D1<G,IndexedArgZ> , IndexedFArgX , IndexedFArgY , IndexedFArgZ >,
75 ComputeChainD2< F , D2<G,IndexedArgX,IndexedArgZ> , D1<G,IndexedArgY> , IndexedFArgX , IndexedFArgY >,
76 ComputeChainD2< F , D1<G,IndexedArgX> , D2<G,IndexedArgY,IndexedArgZ> , IndexedFArgX , IndexedFArgY >,
77 ComputeChainD2< F , D2<G,IndexedArgX,IndexedArgY> , D1<G,IndexedArgZ> , IndexedFArgX , IndexedFArgZ >,
78 ComputeChainD1< F , D3<G,IndexedArgX,IndexedArgY,IndexedArgZ> , IndexedFArgX > >;
88 template <
class... InitFunction>
89 Chain(
const InitFunction&... init)
90 : g(init...), f(g.
d0())
98 Chain(
const F& f_,
const G& g_) : g(g_), f(f_)
114 template <
int index,
class Arg>
117 g.template updateVariable<index>(x);
121 const auto&
d0() const noexcept
130 template <
int id ,
class Arg ,
131 class IndexedArg = IndexedType<Arg,id> ,
132 class IndexedFArg = IndexedType<FArg,id> ,
133 class = std::enable_if_t< ComputeChainD1< F , D1<G,IndexedArg> , IndexedFArg >::present> >
134 auto d1(Arg
const& dx)
const
136 return ComputeChainD1< F , D1<G,IndexedArg>, IndexedFArg >(f, D1<G,IndexedArg>(g,dx))();
144 template <
int idx ,
int idy ,
class ArgX ,
class ArgY ,
145 class IndexedArgX = IndexedType<ArgX,idx> ,
146 class IndexedArgY = IndexedType<ArgY,idy> ,
147 class IndexedFArgX = IndexedType<FArg,idx> ,
148 class IndexedFArgY = IndexedType<FArg,idy> ,
149 class = std::enable_if_t< D2LazyType<IndexedArgX,IndexedArgY,IndexedFArgX,IndexedFArgY>::present > >
150 auto d2(ArgX
const& dx, ArgY
const& dy)
const
152 return D2LazyType<IndexedArgX,IndexedArgY,IndexedFArgX,IndexedFArgY>
153 ( ComputeChainD2< F , D1<G,IndexedArgX> , D1<G,IndexedArgY>, IndexedFArgX , IndexedFArgY > (f,D1<G,IndexedArgX>(g,dx),D1<G,IndexedArgY>(g,dy)),
154 ComputeChainD1< F , D2<G,IndexedArgX,IndexedArgY> , IndexedFArgX > (f,D2<G,IndexedArgX,IndexedArgY>(g,dx,dy))
164 template <
int idx ,
int idy ,
int idz ,
class ArgX ,
class ArgY ,
class ArgZ ,
165 class IndexedArgX = IndexedType<ArgX,idx> ,
166 class IndexedArgY = IndexedType<ArgY,idy> ,
167 class IndexedArgZ = IndexedType<ArgZ,idz> ,
168 class IndexedFArgX = IndexedType<FArg,idx> ,
169 class IndexedFArgY = IndexedType<FArg,idy> ,
170 class IndexedFArgZ = IndexedType<FArg,idz> ,
171 class = std::enable_if_t< D3LazyType<IndexedArgX,IndexedArgY,IndexedArgZ,IndexedFArgX,IndexedFArgY,IndexedFArgZ>::present > >
172 auto d3(ArgX
const& dx, ArgY
const& dy, ArgZ
const& dz)
const
174 D1<G,IndexedArgX> dGdx(g,dx);
175 D1<G,IndexedArgY> dGdy(g,dy);
176 D1<G,IndexedArgZ> dGdz(g,dz);
177 return D3LazyType<IndexedArgX,IndexedArgY,IndexedArgZ,IndexedFArgX,IndexedFArgY,IndexedFArgZ>
178 ( ComputeChainD3< F , D1<G,IndexedArgX> , D1<G,IndexedArgY> , D1<G,IndexedArgZ> , IndexedFArgX , IndexedFArgY , IndexedFArgZ > ( f , dGdx , dGdy , dGdz ),
179 ComputeChainD2< F , D2<G,IndexedArgX,IndexedArgZ> , D1<G,IndexedArgY> , IndexedFArgX , IndexedFArgY > ( f , D2<G,IndexedArgX,IndexedArgZ>(g,dx,dz) , dGdy ),
180 ComputeChainD2< F , D1<G,IndexedArgX> , D2<G,IndexedArgY,IndexedArgZ> , IndexedFArgX , IndexedFArgY > ( f , dGdx , D2<G,IndexedArgY,IndexedArgZ>(g,dy,dz) ),
181 ComputeChainD2< F , D2<G,IndexedArgX,IndexedArgY> , D1<G,IndexedArgZ> , IndexedFArgX , IndexedFArgZ > ( f , D2<G,IndexedArgX,IndexedArgY>(g,dx,dy) , dGdz ),
182 ComputeChainD1< F , D3<G,IndexedArgX,IndexedArgY,IndexedArgZ> , IndexedFArgX > ( f , D3<G,IndexedArgX,IndexedArgY,IndexedArgZ> (g,dx,dy,dz) )
194 std::remove_const_t<std::remove_reference_t<decltype(std::declval<F>().
d0())> > value;
199 #endif // RFFGEN_MATHEMATICAL_OPERATION_CHAIN_HH
auto d1(Arg const &dx) const
First directional derivative.
Definition: chain.hh:134
void update(const Arg &x)
Reset point of evaluation.
Definition: chain.hh:106
Chain(const InitFunction &...init)
Constructor.
Definition: chain.hh:89
const auto & d0() const noexcept
Function value.
Definition: chain.hh:121
Base class for functions satisfying FunctionConcept. Required for enabling the operators in generate...
Definition: base.hh:27
Chain of functions and of type F resp. G (F and G must satisfy the requirements of Concepts::Funct...
Definition: chain.hh:61
auto d3(ArgX const &dx, ArgY const &dy, ArgZ const &dz) const
Third directional derivative.
Definition: chain.hh:172
void updateVariable(const Arg &x)
Propagate call to updateVariable() to f and g.
Definition: chain.hh:115
Chain()=default
Default constructor. May leave member variables uninitialized! Call update before using evaluation...
Chain(const F &f_, const G &g_)
Constructor taking copies of the functions to be chained.
Definition: chain.hh:98
auto d2(ArgX const &dx, ArgY const &dy) const
Second directional derivative.
Definition: chain.hh:150