RFFGen
 All Classes Namespaces Files Functions Typedefs Enumerations Groups
chain.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_OPERATION_CHAIN_HH
22 #define RFFGEN_MATHEMATICAL_OPERATION_CHAIN_HH
23 
24 #include <type_traits>
25 #include <utility>
26 
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"
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 Chain : Base , Chainer< Chain<F,G,FunctionConceptCheck<F>,FunctionConceptCheck<G> > >
62  {
63  using Chainer< Chain<F,G,FunctionConceptCheck<F>,FunctionConceptCheck<G> > >::operator ();
64  private:
65  using FArg = decltype(std::declval<G>().d0());
66 
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 > >;
70 
71 
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 > >;
79 
80  public:
82  Chain() = default;
83 
88  template <class... InitFunction>
89  Chain(const InitFunction&... init)
90  : g(init...), f(g.d0())
91  { updateValue(); }
92 
98  Chain(const F& f_, const G& g_) : g(g_), f(f_)
99  {
100  f.update(g.d0());
101  updateValue();
102  }
103 
105  template <class Arg>
106  void update(const Arg& x)
107  {
108  g.update(x);
109  f.update(g.d0());
110  updateValue();
111  }
112 
114  template <int index, class Arg>
115  void updateVariable(const Arg & x)
116  {
117  g.template updateVariable<index>(x);
118  }
119 
121  const auto& d0() const noexcept
122  {
123  return value;
124  }
125 
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
135  {
136  return ComputeChainD1< F , D1<G,IndexedArg>, IndexedFArg >(f, D1<G,IndexedArg>(g,dx))();
137  }
138 
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
151  {
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))
155  )();
156  }
157 
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
173  {
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) )
183  )();
184  }
185 
186  private:
187  void updateValue()
188  {
189  value = f.d0();
190  }
191 
192  G g;
193  F f;
194  std::remove_const_t<std::remove_reference_t<decltype(std::declval<F>().d0())> > value;
195  };
196  }
197 }
198 
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