RFFGen
 All Classes Namespaces Files Functions Typedefs Enumerations Groups
product.hh
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the C++-library RFFGen. */
4 /* Copyright 2015 Lars Lubkoll */
5 /* */
6 /* RFFGen is free software: you can redistribute it and/or modify */
7 /* it under the terms of the GNU General Public License as published by */
8 /* the Free Software Foundation, either version 3 of the License, or */
9 /* (at your option) any later version. */
10 /* */
11 /* RFFGen is distributed in the hope that it will be useful, */
12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14 /* GNU General Public License for more details. */
15 /* */
16 /* You should have received a copy of the GNU General Public License */
17 /* along with RFFGen. If not, see <http://www.gnu.org/licenses/>. */
18 /* */
19 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
20 
21 #ifndef RFFGEN_MATHEMATICAL_OPERATIONS_PRODUCT_HH
22 #define RFFGEN_MATHEMATICAL_OPERATIONS_PRODUCT_HH
23 
24 #include <type_traits>
25 #include <utility>
26 
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"
32 
33 namespace RFFGen
34 {
38  template <class> struct Chainer;
43  namespace MathematicalOperations
44  {
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> > >
62  {
63  using Chainer<Product<F,G,FunctionConceptCheck<F>,FunctionConceptCheck<G> > >::operator();
64  private:
65  template <class IndexedArg>
66  using D1Type = ComputeSum< ComputeProduct< D1<F,IndexedArg> , D0<G> >,
67  ComputeProduct< D0<F> , D1<G,IndexedArg> > >;
68 
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> >
74  >;
75 
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> >
85  >;
86 
87  public:
89  Product() = default;
90 
96  template <class InitF, class InitG>
97  Product(const InitF& f_, const InitG& g_) : f(f_), g(g_)
98  { updateResultOfD0(); }
99 
101  template <class Arg>
102  void update(Arg const& x)
103  {
104  f.update(x);
105  g.update(x);
106  updateResultOfD0();
107  }
108 
110  template <int index, class Arg>
111  void updateVariable(const Arg& x)
112  {
113  f.template updateVariable<index>(x);
114  g.template updateVariable<index>(x);
115  }
116 
118  auto d0() const noexcept
119  {
120  return resultOfD0;
121  }
122 
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
131  {
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) ) )();
134  }
135 
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
146  {
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))
151  )();
152  }
153 
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
166  {
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) ) )();
183  }
184 
185  private:
186  void updateResultOfD0()
187  {
188  resultOfD0 = f.d0() * g.d0();
189  }
190 
191  F f;
192  G g;
193 
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;
198  };
199  }
200 }
201 
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