CMS 3D CMS Logo

Primitive.h
Go to the documentation of this file.
1 #ifndef PhysicsTools_Utilities_Primitive_h
2 #define PhysicsTools_Utilities_Primitive_h
9 #include <type_traits>
10 
12 
13 namespace funct {
14 
15  struct no_var;
16 
17  struct UndefinedIntegral { };
18 
20  struct ConstPrimitive {
22  inline static type get(const F& f) { return type(); }
23  };
24 
25  // /
26  // | c dx = c * x
27  // /
28  template<typename X, typename F>
29  struct ConstPrimitive<X, F, true> {
30  typedef PROD(F, X) type;
31  inline static type get(const F& f) { return f * X(); }
32  };
33 
34  template<typename F, typename X = no_var>
35  struct Primitive : public ConstPrimitive<X, F> { };
36 
37  template<typename F>
38  struct Primitive<F> { };
39 
40  template<typename X, typename F>
41  typename Primitive<F, X>::type primitive(const F& f) {
42  return Primitive<F, X>::get(f);
43  }
44 
45  template<typename F>
46  typename Primitive<F>::type primitive(const F& f) {
47  return Primitive<F>::get(f);
48  }
49 
50  // /
51  // | f ^ g dx : UNDEFINED
52  // /
54 
55  // /
56  // | x dx = x ^ 2 / 2
57  // /
58  PRIMIT_RULE(TYPX, X, RATIO(POWER(X, NUM(2)), NUM(2)), pow(_, num<2>()) / num<2>());
59 
60  // /
61  // | x ^ n dx = x ^ (n + 1) / (n + 1)
62  // /
64  RATIO(POWER(X, NUM(n + 1)), NUM(n + 1)),
65  pow(_._1, num<n + 1>()) / num<n + 1>());
66 
67  // /
68  // | 1 / x ^ n dx = (- 1) / ((n - 1) x ^ (n - 1))
69  // /
71  RATIO(NUM(-1), PROD(NUM(n - 1), POWER(X, NUM(n - 1)))),
72  num<-1>()/(num<n - 1>() * pow(_._2._1, num<n - 1>())));
73 
75  RATIO(NUM(-1), PROD(NUM(n - 1), POWER(X, NUM(n - 1)))),
76  num<-1>()/(num<n - 1>() * pow(_._1._2, num<n - 1>())));
77 
78  // /
79  // | x ^ n/m dx = m / (n + m) (x)^ (n + m / m)
80  // /
82  PROD(FRACT(m, n + m), POWER(X, FRACT(n + m, m))),
83  (fract<m, n + m>() * pow(_._1, fract<n + m, m>())));
84 
85  // /
86  // | sqrt(x) dx = 2/3 (x)^ 3/2
87  // /
89  (fract<2, 3>() * pow(_._, fract<3, 2>())));
90 
91  // /
92  // | exp(x) dx = exp(x)
93  // /
94  PRIMIT_RULE(TYPX, EXP_S(X), EXP(X), _);
95 
96  // /
97  // | log(x) dx = x(log(x) - 1)
98  // /
99  PRIMIT_RULE(TYPX, LOG_S(X), PROD(X, DIFF(LOG(X), NUM(1))),
100  _._ * (_ - num<1>()));
101 
102  // /
103  // | sgn(x) dx = abs(x)
104  // /
105  PRIMIT_RULE(TYPX, SGN_S(X), ABS(X), abs(_._));
106 
107 
108  // /
109  // | sin(x) dx = - cos(x)
110  // /
111  PRIMIT_RULE(TYPX, SIN_S(X), MINUS(COS(X)), - cos(_._));
112 
113  // /
114  // | cos(x) dx = sin(x)
115  // /
116  PRIMIT_RULE(TYPX, COS_S(X), SIN(X), sin(_._));
117 
118  // /
119  // | tan(x) dx = - log(abs(cos(x)))
120  // /
121  PRIMIT_RULE(TYPX, TAN_S(X), MINUS(LOG(ABS(COS(X)))), - log(abs(cos(_._))));
122 
123  // /
124  // | 1 / x dx = log(abs(x))
125  // /
126  PRIMIT_RULE(TYPX, RATIO_S(NUM(1), X), LOG(ABS(X)), log(abs(_._2)));
127 
128  PRIMIT_RULE(TYPX, POWER_S(X, NUM(-1)), LOG(ABS(X)), log(abs(_._1)));
129 
130  // /
131  // | 1 / cos(x)^2 dx = tan(x)
132  // /
133  PRIMIT_RULE(TYPX, RATIO_S(NUM(1), POWER_S(COS_S(X), NUM(2))), TAN(X), tan(_._2._1._));
134 
135  // /
136  // | 1 / sin(x)^2 dx = - 1 / tan(x)
137  // /
138  PRIMIT_RULE(TYPX, RATIO_S(NUM(1), POWER_S(SIN_S(X), NUM(2))),
139  RATIO(NUM(-1), TAN(X)), num<-1>() / tan(_._2._1._));
140 
141  // composite primitives
142 
143  // / / /
144  // | (f(x) + g(x)) dx = | f(x) dx + | g(x) dx
145  // / / /
146  PRIMIT_RULE(TYPXT2, SUM_S(A, B), SUM(PRIMIT(X, A), PRIMIT(X, B)),
147  primitive<X>(_._1) + primitive<X>(_._2));
148 
149  // / /
150  // | (- f(x)) dx = - | f(x) dx
151  // / /
152  PRIMIT_RULE(TYPXT1, MINUS_S(A), MINUS(PRIMIT(X, A)), - primitive<X>(_._));
153 
154  // /
155  // | f * g dx : defined only for f or g indep. of x or part. int.
156  // /
157 
158  template <TYPXT2,
161  struct PartIntegral {
163  GET(PROD_S(A, B), type());
164  };
165 
166  TEMPL(XT2) struct PartIntegral<X, A, B, true, false> {
167  typedef PRIMIT(X, B) B1;
168  typedef DERIV(X, A) A1;
169  typedef PRIMIT(X, PROD(A1, B1)) AB1;
170  typedef DIFF(PROD(A, B1), PRIMIT(X, PROD(A1, B1))) type;
171  inline static type get(const PROD_S(A, B)& _) {
172  const A& a = _._1;
173  B1 b = primitive<X>(_._2);
174  return a * b - primitive<X>(derivative<X>(a) * b);
175  }
176  };
177 
178  TEMPL(XT2) struct PartIntegral<X, B, A, false, true> {
179  typedef PRIMIT(X, B) B1;
180  typedef DERIV(X, A) A1;
181  typedef PRIMIT(X, PROD(A1, B1)) AB1;
182  typedef DIFF(PROD(A, B1), PRIMIT(X, PROD(A1, B1))) type;
183  inline static type get(const PROD_S(B, A)& _) {
184  const A& a = _._2;
185  B1 b = primitive<X>(_._1);
186  return a * b - primitive<X>(derivative<X>(a) * b);
187  }
188  };
189 
190  TEMPL(XT2) struct PartIntegral<X, A, B, true, true> :
191  public PartIntegral<X, A, B, true, false> { };
192 
194  bool indepg = Independent<X, B>::value>
195  struct ProductPrimitive : public PartIntegral<X, A, B> { };
196 
197  TEMPL(XT2) struct ProductPrimitive<X, A, B, true, false> {
198  typedef PROD(A, PRIMIT(X, B)) type;
199  GET(PROD_S(A, B), _._1 * primitive<X>(_._2));
200  };
201 
202  TEMPL(XT2) struct ProductPrimitive<X, A, B, false, true> {
203  typedef PROD(B, PRIMIT(X, A)) type;
204  GET(PROD_S(A, B), _._2 * primitive<X>(_._1));
205  };
206 
207  TEMPL(XT2) struct ProductPrimitive<X, A, B, true, true> {
208  typedef PROD(PROD(A, B), X) type;
209  GET(PROD_S(A, B), _ * X());
210  };
211 
212  TEMPL(XT2) struct Primitive<PROD_S(A, B), X> :
213  public ProductPrimitive<X, A, B> { };
214 
215  // /
216  // | f / g dx : defined only for f or g indep. of x; try part. int.
217  // /
218 
219  template <TYPXT2,
222  struct PartIntegral2 {
224  GET(RATIO_S(A, B), type());
225  };
226 
227  TEMPL(XT2) struct PartIntegral2<X, A, B, true, false> {
228  typedef PRIMIT(X, RATIO(NUM(1), B)) B1;
229  typedef DERIV(X, A) A1;
230  typedef PRIMIT(X, PROD(A1, B1)) AB1;
231  typedef DIFF(PROD(A, B1), AB1) type;
232  inline static type get(const RATIO_S(A, B)& _) {
233  const A& a = _._1;
234  B1 b = primitive<X>(num<1>() / _._2);
235  return a * b - primitive<X>(derivative<X>(a) * b);
236  }
237  };
238 
239  TEMPL(XT2) struct PartIntegral2<X, B, A, false, true> {
240  typedef PRIMIT(X, RATIO(NUM(1), B)) B1;
241  typedef DERIV(X, A) A1;
242  typedef PRIMIT(X, PROD(A1, B1)) AB1;
243  typedef DIFF(PROD(A, B1), AB1) type;
244  inline static type get(const RATIO_S(B, A)& _) {
245  const A& a = _._1;
246  B1 b = primitive<X>(num<1>() / _._2);
247  return a * b - primitive<X>(derivative<X>(a) * b);
248  }
249  };
250 
251  // should be improved: try both...
252  TEMPL(XT2) struct PartIntegral2<X, A, B, true, true> :
253  public PartIntegral2<X, A, B, true, false> { };
254 
256  bool indepb = Independent<X, B>::value>
257  struct RatioPrimitive : public PartIntegral2<X, A, B> { };
258 
259  TEMPL(XT2) struct RatioPrimitive<X, A, B, true, false> {
260  typedef PROD(A, PRIMIT(X, RATIO(NUM(1), B))) type;
261  GET(RATIO_S(A, B), _._1 * primitive<X>(num<1> / _._2));
262  };
263 
264  TEMPL(XT2) struct RatioPrimitive<X, A, B, false, true> {
265  typedef RATIO(PRIMIT(X, A), B) type;
266  GET(RATIO_S(A, B), primitive<X>(_._1) / _._2);
267  };
268 
269  TEMPL(XT2) struct RatioPrimitive<X, A, B, true, true> {
270  typedef RATIO(RATIO(A, B), X) type;
271  GET(RATIO_S(A, B), _ * X());
272  };
273 
274  TEMPL(XT2) struct Primitive<RATIO_S(A, B), X> :
275  public RatioPrimitive<X, A, B> { };
276 
277  // Function integrals
278 
279  // /
280  // | c dx = c * x
281  // /
282  template<>
285  inline static type get(const Parameter & p) {
286  return p * Identity();
287  }
288  };
289 
290 }
291 
292 #define DECLARE_PRIMITIVE(X, F, P) \
293 namespace funct { \
294 template<typename X> struct Primitive<F, X> { \
295  typedef P type; \
296  inline static type get(const F& _) \
297  { return type(_._); } \
298 }; \
299 } \
300 struct __useless_ignoreme
301 
302 #define DECLARE_FUNCT_PRIMITIVE(F, P) \
303 namespace funct { \
304 template<> struct Primitive<F> { \
305  typedef P type; \
306  inline static type get(const F& _) \
307  { return type(); } \
308 }; \
309 } \
310 struct __useless_ignoreme
311 
313 
314 #endif
#define TYPXN2
#define TYPXT1
typedef DERIV(X, A) A1
#define EXP(A)
UndefinedIntegral type
Definition: Primitive.h:223
typedef POWER(A, NUM(n)) arg
Definition: Abs.h:5
#define COS(A)
MINUS_S(B)>
Definition: Factorize.h:101
#define MINUS(A)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
#define SQRT_S(A)
PROD_S(A, B)>
Definition: Factorize.h:46
#define X(str)
Definition: MuonsGrabber.cc:48
POWER_S(A, NUM(n))>
Definition: Factorize.h:50
#define SGN_S(A)
#define ABS(A)
#define LOG(A)
#define TYPXN1
#define RATIO_S(A, B)
Primitive< F, X >::type primitive(const F &f)
Definition: Primitive.h:41
UndefinedIntegral type
Definition: Primitive.h:162
#define FRACT(N, M)
#define LOG_S(A)
#define FRACT_S(N, M)
#define SUM_S(A, B)
#define TAN(A)
#define RATIO(A, B)
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
#define COS_S(A)
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
typedef PRIMIT(X, PROD(A1, B1)) AB1
Product< Parameter, Identity >::type type
Definition: Primitive.h:284
static type get(const F &f)
Definition: Primitive.h:22
Log< T >::type log(const T &t)
Definition: Log.h:22
#define SUM(A, B)
#define EXP_S(A)
TEMPL(T1) struct Divides0
Definition: Factorize.h:20
double b
Definition: hdecay.h:120
arg type
Definition: Factorize.h:39
typedef PROD(F, SUM(RATIO(A, F), RATIO(B, F))) type
GET(arg, _)
double a
Definition: hdecay.h:121
PRIMIT_RULE(TYPXT2, POWER_S(A, B), UndefinedIntegral, type())
typedef DIFF(PROD(A, B1), PRIMIT(X, PROD(A1, B1))) type
#define SIN(A)
static const int p
Definition: Factorize.h:59
NUM(n))
Definition: Factorize.h:94
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
static type get(const PROD_S(A, B)&_)
Definition: Primitive.h:171
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
#define TYPXT2
#define TYPX
#define TAN_S(A)
UndefinedIntegral type
Definition: Primitive.h:21
#define SIN_S(A)