21 #ifndef RFFGEN_MATHEMATICAL_OPERATIONS_PRODUCT_HH
22 #define RFFGEN_MATHEMATICAL_OPERATIONS_PRODUCT_HH
24 #include <type_traits>
27 #include "../Util/base.hh"
28 #include "../Util/computeSum.hh"
29 #include "../Util/computeProduct.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 Product:
Base , Chainer<Product<F,G,FunctionConceptCheck<F>,FunctionConceptCheck<G> > >
63 using Chainer<Product<F,G,FunctionConceptCheck<F>,FunctionConceptCheck<G> > >::operator();
65 template <
class IndexedArg>
66 using D1Type = ComputeSum< ComputeProduct< D1<F,IndexedArg> , D0<G> >,
67 ComputeProduct< D0<F> , D1<G,IndexedArg> > >;
69 template <
class IndexedArgX ,
class IndexedArgY >
70 using D2Type = ComputeSum< ComputeProduct< D2<F,IndexedArgX,IndexedArgY> , D0<G> >,
71 ComputeProduct< D1<F,IndexedArgX> , D1<G,IndexedArgY> >,
72 ComputeProduct< D1<F,IndexedArgY> , D1<G,IndexedArgX> >,
73 ComputeProduct< D0<F> , D2<G,IndexedArgX,IndexedArgY> >
76 template <
class IndexedArgX,
class IndexedArgY,
class IndexedArgZ>
77 using D3Type = ComputeSum< ComputeProduct< D3<F,IndexedArgX,IndexedArgY,IndexedArgZ> , D0<G> > ,
78 ComputeProduct< D2<F,IndexedArgX,IndexedArgY> , D1<G,IndexedArgZ> >,
79 ComputeProduct< D2<F,IndexedArgX,IndexedArgZ> , D1<G,IndexedArgY> > ,
80 ComputeProduct< D1<F,IndexedArgX> , D2<G,IndexedArgY,IndexedArgZ> >,
81 ComputeProduct< D2<F,IndexedArgY,IndexedArgZ> , D1<G,IndexedArgX> > ,
82 ComputeProduct< D1<F,IndexedArgY> , D2<G,IndexedArgX,IndexedArgZ> >,
83 ComputeProduct< D1<F,IndexedArgZ> , D2<G,IndexedArgX,IndexedArgY> > ,
84 ComputeProduct< D0<F> , D3<G,IndexedArgX,IndexedArgY,IndexedArgZ> >
96 template <
class InitF,
class InitG>
97 Product(
const InitF& f_,
const InitG& g_) : f(f_), g(g_)
98 { updateResultOfD0(); }
110 template <
int index,
class Arg>
113 f.template updateVariable<index>(x);
114 g.template updateVariable<index>(x);
118 auto d0() const noexcept
127 template <
int id ,
class Arg ,
128 class IndexedArg = IndexedType<Arg,id> ,
129 class = std::enable_if_t< D1Type<IndexedArg>::present > >
130 auto d1(Arg
const& dx)
const
132 return D1Type<IndexedArg>( ComputeProduct< D1<F,IndexedArg> , D0<G> >( D1<F,IndexedArg>(f,dx), D0<G>(g) ),
133 ComputeProduct< D0<F> , D1<G,IndexedArg> >( D0<F>(f), D1<G,IndexedArg>(g,dx) ) )();
141 template <
int idx ,
int idy ,
class ArgX ,
class ArgY ,
142 class IndexedArgX = IndexedType<ArgX,idx> ,
143 class IndexedArgY = IndexedType<ArgY,idy> ,
144 class = std::enable_if_t< D2Type<IndexedArgX,IndexedArgY>::present > >
145 auto d2(ArgX
const& dx, ArgY
const& dy)
const
147 return D2Type<IndexedArgX,IndexedArgY>( ComputeProduct< D2<F,IndexedArgX,IndexedArgY> , D0<G> > ( D2<F,IndexedArgX,IndexedArgY>(f,dx,dy) , D0<G>(g) ),
148 ComputeProduct< D1<F,IndexedArgX> , D1<G,IndexedArgY> > ( D1<F,IndexedArgX>(f,dx) , D1<G,IndexedArgY>(g,dy) ),
149 ComputeProduct< D1<F,IndexedArgY> , D1<G,IndexedArgX> > (D1<F,IndexedArgY>(f,dy),D1<G,IndexedArgX>(g,dx)),
150 ComputeProduct< D0<F> , D2<G,IndexedArgX,IndexedArgY> >(D0<F>(f),D2<G,IndexedArgX,IndexedArgY>(g,dx,dy))
160 template <
int idx ,
int idy ,
int idz ,
class ArgX ,
class ArgY ,
class ArgZ ,
161 class IndexedArgX = IndexedType<ArgX,idx> ,
162 class IndexedArgY = IndexedType<ArgY,idy> ,
163 class IndexedArgZ = IndexedType<ArgZ,idz> ,
164 class = std::enable_if_t< D3Type<IndexedArgX,IndexedArgY,IndexedArgZ>::present > >
165 auto d3(ArgX
const& dx, ArgY
const& dy, ArgZ
const& dz)
const
167 return D3Type<IndexedArgX,IndexedArgY,IndexedArgZ>( ComputeProduct< D3<F,IndexedArgX,IndexedArgY,IndexedArgZ> , D0<G> >
168 ( D3<F,IndexedArgX,IndexedArgY,IndexedArgZ>(f,dx,dy,dz) , D0<G>(g) ),
169 ComputeProduct< D2<F,IndexedArgX,IndexedArgY> , D1<G,IndexedArgZ> >
170 ( D2<F,IndexedArgX,IndexedArgY>(f,dx,dy) , D1<G,IndexedArgZ>(g,dz) ),
171 ComputeProduct< D2<F,IndexedArgX,IndexedArgZ> , D1<G,IndexedArgY> >
172 ( D2<F,IndexedArgX,IndexedArgZ>(f,dx,dz) , D1<G,IndexedArgY>(g,dy) ),
173 ComputeProduct< D1<F,IndexedArgX> , D2<G,IndexedArgY,IndexedArgZ> >
174 ( D1<F,IndexedArgX>(f,dx) , D2<G,IndexedArgY,IndexedArgZ>(g,dy,dz) ),
175 ComputeProduct< D2<F,IndexedArgY,IndexedArgZ> , D1<G,IndexedArgX> >
176 ( D2<F,IndexedArgY,IndexedArgZ>(f,dy,dz) , D1<G,IndexedArgX>(g,dx) ),
177 ComputeProduct< D1<F,IndexedArgY> , D2<G,IndexedArgX,IndexedArgZ> >
178 ( D1<F,IndexedArgY>(f,dy) , D2<G,IndexedArgX,IndexedArgZ>(g,dx,dz) ),
179 ComputeProduct< D1<F,IndexedArgZ> , D2<G,IndexedArgX,IndexedArgY> >
180 ( D1<F,IndexedArgZ>(f,dz) , D2<G,IndexedArgX,IndexedArgY>(g,dx,dy) ),
181 ComputeProduct< D0<F> , D3<G,IndexedArgX,IndexedArgY,IndexedArgZ> >
182 ( D0<F>(f) , D3<G,IndexedArgX,IndexedArgY,IndexedArgZ>(g,dx,dy,dz) ) )();
186 void updateResultOfD0()
188 resultOfD0 = f.d0() * g.d0();
194 using type = std::conditional_t<std::is_same<std::decay_t<decltype(std::declval<F>().
d0())>,std::decay_t<decltype(std::declval<G>().d0())> >::value,
195 decltype(std::declval<F>().d0()),
196 decltype(std::declval<F>().d0() * std::declval<G>().
d0())>;
197 std::remove_const_t<std::remove_reference_t<type> > resultOfD0;
202 #endif // RFFGEN_MATHEMATICAL_OPERATIONS_PRODUCT_HH
auto d0() const noexcept
Function value.
Definition: product.hh:118
Product(const InitF &f_, const InitG &g_)
Constructor passing arguments to function constructors.
Definition: product.hh:97
void update(Arg const &x)
Reset point of evaluation.
Definition: product.hh:102
void updateVariable(const Arg &x)
Propagate call to updateVariable() to f and g.
Definition: product.hh:111
Base class for functions satisfying FunctionConcept. Required for enabling the operators in generate...
Definition: base.hh:27
Product()=default
Default constructor. May leave member variables uninitialized! Call update before using evaluation...
auto d2(ArgX const &dx, ArgY const &dy) const
Second directional derivative.
Definition: product.hh:145
Product of functions of type F and G (F and G must satisfy the requirements of Concepts::FunctionCon...
Definition: product.hh:61
auto d1(Arg const &dx) const
First directional derivative.
Definition: product.hh:130
auto d3(ArgX const &dx, ArgY const &dy, ArgZ const &dz) const
Third directional derivative.
Definition: product.hh:165