RFFGen
 All Classes Namespaces Files Functions Typedefs Enumerations Groups
squared.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_SQUARED_HH
22 #define RFFGEN_MATHEMATICAL_OPERATIONS_SQUARED_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 = FunctionConceptCheck<F> >
59  struct Squared : Base , Chainer< Squared< F , FunctionConceptCheck<F> > >
60  {
61  using Chainer< Squared< F , FunctionConceptCheck<F> > >::operator();
62  private:
63  template < class IndexedArgX , class IndexedArgY >
64  using D2Sum = ComputeSum< ComputeProduct< D0<F> , D2<F,IndexedArgX,IndexedArgY> >,
65  ComputeProduct< D1<F,IndexedArgY> , D1<F,IndexedArgX> > >;
66 
67  template < class IndexedArgX , class IndexedArgY , class IndexedArgZ >
68  using D3Sum = ComputeSum< ComputeProduct< D0<F> , D3<F,IndexedArgX,IndexedArgY,IndexedArgZ> > ,
69  ComputeProduct< D1<F,IndexedArgZ> , D2<F,IndexedArgX,IndexedArgY> > ,
70  ComputeProduct< D1<F,IndexedArgY> , D2<F,IndexedArgX,IndexedArgZ> > ,
71  ComputeProduct< D2<F,IndexedArgY,IndexedArgZ> , D1<F,IndexedArgX> > >;
72 
73  public:
75  Squared() = default;
76 
81  template <class InitF>
82  Squared(const InitF& f_)
83  : f(f_)
84  {
85  updateResultOfD0();
86  }
87 
89  template <class Arg>
90  void update(Arg const& x)
91  {
92  f.update(x);
93  updateResultOfD0();
94  }
95 
97  template <int index, class Arg>
98  void updateVariable(const Arg& x)
99  {
100  f.template updateVariable<index>(x);
101  }
102 
104  const auto& d0() const noexcept
105  {
106  return resultOfD0;
107  }
108 
113  template < int id , class Arg , class IndexedArg = IndexedType<Arg,id> , class = std::enable_if_t< ComputeProduct< D0<F> , D1<F,IndexedArg> >::present > >
114  auto d1(Arg const& dx) const
115  {
116  return 2 * f.d0() * f.template d1<id>(dx);
117  }
118 
124  template < int idx , int idy , class ArgX , class ArgY ,
125  class IndexedArgX = IndexedType<ArgX,idx> ,
126  class IndexedArgY = IndexedType<ArgY,idy> ,
127  class = std::enable_if_t< D2Sum<IndexedArgX,IndexedArgY>::present > >
128  auto d2(ArgX const& dx, ArgY const& dy) const
129  {
130  return 2 * D2Sum<IndexedArgX,IndexedArgY>( ComputeProduct< D0<F> , D2<F,IndexedArgX,IndexedArgY> >( D0<F>(f) , D2<F,IndexedArgX,IndexedArgY>(f,dx,dy) ),
131  ComputeProduct< D1<F,IndexedArgY> , D1<F,IndexedArgX> >( D1<F,IndexedArgY>(f,dy) , D1<F,IndexedArgX>(f,dx) )
132  )();
133  }
134 
141  template < int idx , int idy , int idz , class ArgX , class ArgY , class ArgZ ,
142  class IndexedArgX = IndexedType<ArgX,idx> ,
143  class IndexedArgY = IndexedType<ArgY,idy> ,
144  class IndexedArgZ = IndexedType<ArgZ,idz> ,
145  class = std::enable_if_t< D3Sum<IndexedArgX,IndexedArgY,IndexedArgZ>::present > >
146  auto d3(ArgX const& dx, ArgY const& dy, ArgZ const& dz) const
147  {
148  return 2 * D3Sum<IndexedArgX,IndexedArgY,IndexedArgZ>
149  ( ComputeProduct< D0<F> , D3<F,IndexedArgX,IndexedArgY,IndexedArgZ> > ( D0<F>(f) , D3<F,IndexedArgX,IndexedArgY,IndexedArgZ>(f,dx,dy,dz) ),
150  ComputeProduct< D1<F,IndexedArgZ> , D2<F,IndexedArgX,IndexedArgY> > ( D1<F,IndexedArgZ>(f,dz) , D2<F,IndexedArgX,IndexedArgY>(f,dx,dy) ),
151  ComputeProduct< D1<F,IndexedArgY> , D2<F,IndexedArgX,IndexedArgZ> > ( D1<F,IndexedArgY>(f,dy) , D2<F,IndexedArgX,IndexedArgZ>(f,dx,dz) ),
152  ComputeProduct< D2<F,IndexedArgY,IndexedArgZ> , D1<F,IndexedArgX> > ( D2<F,IndexedArgY,IndexedArgZ>(f,dy,dz) , D1<F,IndexedArgX>(f,dx) )
153  )();
154  }
155 
156  private:
157  void updateResultOfD0()
158  {
159  resultOfD0 = f.d0() * f.d0();
160  }
161 
162  F f;
163  std::remove_const_t<std::remove_reference_t<decltype(std::declval<F>().d0())> > resultOfD0;
164  };
165  }
166 }
167 
168 #endif // RFFGEN_MATHEMATICAL_OPERATIONS_SQUARED_HH
void update(Arg const &x)
Reset point of evaluation.
Definition: squared.hh:90
auto d2(ArgX const &dx, ArgY const &dy) const
Second directional derivative.
Definition: squared.hh:128
Base class for functions satisfying FunctionConcept. Required for enabling the operators in generate...
Definition: base.hh:27
Squared function (F must satisfy the requirements of Concepts::FunctionConcept).
Definition: squared.hh:59
auto d3(ArgX const &dx, ArgY const &dy, ArgZ const &dz) const
Third directional derivative.
Definition: squared.hh:146
Squared(const InitF &f_)
Constructor passing arguments to function constructor.
Definition: squared.hh:82
void updateVariable(const Arg &x)
Propagate call to updateVariable() to f.
Definition: squared.hh:98
auto d1(Arg const &dx) const
First directional derivative.
Definition: squared.hh:114
const auto & d0() const noexcept
Function value.
Definition: squared.hh:104
Squared()=default
Default constructor. May leave member variables uninitialized! Call update before using evaluation...