RFFGen
 All Classes Namespaces Files Functions Typedefs Enumerations Groups
generate.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_GENERATE_HH
22 #define RFFGEN_GENERATE_HH
23 
24 #include <cassert>
25 #include <iostream>
26 #include <type_traits>
27 
28 #include "constant.hh"
29 #include "operations.hh"
30 #include "Util/addMissingOperators.hh"
31 #include "Util/base.hh"
32 #include "variable.hh"
33 
34 namespace RFFGen
35 {
39  namespace GenerateDetail
40  {
41  template <class F, class G,
42  bool = std::is_base_of<Base,F>::value,
43  bool = std::is_base_of<Base,G>::value>
44  struct SumGenerator;
45 
46  template <class F, class G>
47  struct SumGenerator<F,G,true,true>
48  {
49  static auto apply(const F& f, const G& g)
50  {
51  return MathematicalOperations::Sum<F,G>(f,g);
52  }
53  };
54 
55  template <class F, class G>
56  struct SumGenerator<F,G,true,false>
57  {
58  static auto apply(const F& f, const G& g)
59  {
60  return MathematicalOperations::Sum< F , Constant<G> >( f , constant(g) );
61  }
62  };
63 
64  template <class F, class G>
65  struct SumGenerator<F,G,false,true>
66  {
67  static auto apply(const F& f, const G& g)
68  {
69  return MathematicalOperations::Sum< Constant<F> , G >( constant(f) , g );
70  }
71  };
72 
73  template <class F, class G,
74  bool = std::is_base_of<Base,F>::value,
75  bool = std::is_base_of<Base,G>::value,
76  bool = std::is_arithmetic<F>::value,
77  bool = std::is_arithmetic<G>::value>
78  struct ProductGenerator;
79 
80  template <class F, class G>
81  struct ProductGenerator<F,G,true,true,false,false>
82  {
83  static auto apply(const F& f, const G& g)
84  {
85  return MathematicalOperations::Product<F,G>(f,g);
86  }
87  };
88 
89  template <class F, class G>
90  struct ProductGenerator<F,G,false,true,true,false>
91  {
92  static auto apply(F f, const G& g)
93  {
94  return MathematicalOperations::Scale<G>(f,g);
95  }
96  };
97 
98  template <class F, class G>
99  struct ProductGenerator<F,G,true,false,false,true>
100  {
101  static auto apply(const F& f, G g)
102  {
103  return ProductGenerator<G,F,false,true,true,false>(g,f);
104  }
105  };
106 
107  template <class F, class G>
108  struct ProductGenerator<F,G,false,true,false,false>
109  {
110  static auto apply(const F& f, const G& g)
111  {
112  return MathematicalOperations::Product<Constant<F>,G>(Constant<F>(f),g);
113  }
114  };
115 
116  template <class F, class G>
117  struct ProductGenerator<F,G,true,false,false,false>
118  {
119  static auto apply(const F& f, const G& g)
120  {
121  return MathematicalOperations::Product< F,Constant<G> >( f , Constant<G>(g) );
122  }
123  };
124  }
135  template <class F, class G,
136  class = std::enable_if_t< std::is_base_of<Base,F>::value ||
137  std::is_base_of<Base,G>::value > >
138  auto operator+ (const F& f, const G& g)
139  {
140  return GenerateDetail::SumGenerator<F,G>::apply(f,g);
141  }
142 
149  template <class F, class G,
150  class = std::enable_if_t< std::is_base_of<Base,F>::value || std::is_base_of<Base,G>::value > >
151  auto operator*(const F& f, const G& g)
152  {
153  return GenerateDetail::ProductGenerator<F,G>::apply(f,g);
154  }
155 
156 
163  template <class F,
164  class = std::enable_if_t< std::is_base_of<Base,F>::value > >
165  auto operator^ (const F& f, int k)
166  {
167  assert(k==2);
168  if(k!=2)
169  {
170  std::cerr << "operator^ only defined for k=2. Terminating." << std::endl;
171  exit(1);
172  }
174  }
175 
183  template <class F, class G,
184  class = std::enable_if_t<std::is_base_of<Base,F>::value &&
185  std::is_base_of<Base,G>::value> >
186  auto operator<< (const F& f, const G& g)
187  {
188  static_assert(!Checks::hasVariable<F>(),"Independent variables can not be on the left side of the chain operator.");
190  }
191 
198  template <class F, class T,
199  class = std::enable_if_t<std::is_convertible<T,decltype(std::declval<F>().d0())>::value &&
200  std::is_base_of<Base,F>::value> >
201  auto operator-(const F& f, const T& t)
202  {
203  return f + ( -1 * t );
204  }
205 
212  template <class F, class T,
213  class = std::enable_if_t<std::is_convertible<T,decltype(std::declval<F>().d0())>::value &&
214  std::is_base_of<Base,F>::value> >
215  auto operator-(const T& t, const F& f)
216  {
217  return t + ( -1 * f );
218  }
219 }
220 
221 #endif // RFFGEN_GENERATE_HH
auto operator*(const F &f, const G &g)
overload of "*"-operator for the generation of functions.
Definition: generate.hh:151
auto operator^(const F &f, int k)
overload of "^"-operator for the generation of functions.
Definition: generate.hh:165
auto constant(const Arg &x)
Wrap a constant.
Definition: constant.hh:75
Chain of functions and of type F resp. G (F and G must satisfy the requirements of Concepts::Funct...
Definition: chain.hh:61
Squared function (F must satisfy the requirements of Concepts::FunctionConcept).
Definition: squared.hh:59
auto operator<<(const F &f, const G &g)
overload of "<<"-operator for chaining functions and to .
Definition: generate.hh:186
auto operator+(const F &f, const G &g)
overload of "+"-operator for the generation of functions.
Definition: generate.hh:138