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  // /
53  PRIMIT_RULE(TYPXT2, POWER_S(A, B), UndefinedIntegral, type());
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  POWER_S(X, NUM(n)),
65  RATIO(POWER(X, NUM(n + 1)), NUM(n + 1)),
66  pow(_._1, num<n + 1>()) / num<n + 1>());
67 
68  // /
69  // | 1 / x ^ n dx = (- 1) / ((n - 1) x ^ (n - 1))
70  // /
72  RATIO_S(NUM(1), POWER_S(X, NUM(n))),
73  RATIO(NUM(-1), PROD(NUM(n - 1), POWER(X, NUM(n - 1)))),
74  num<-1>() / (num<n - 1>() * pow(_._2._1, num<n - 1>())));
75 
77  POWER_S(RATIO_S(NUM(1), X), NUM(n)),
78  RATIO(NUM(-1), PROD(NUM(n - 1), POWER(X, NUM(n - 1)))),
79  num<-1>() / (num<n - 1>() * pow(_._1._2, num<n - 1>())));
80 
81  // /
82  // | x ^ n/m dx = m / (n + m) (x)^ (n + m / m)
83  // /
85  POWER_S(X, FRACT_S(n, m)),
86  PROD(FRACT(m, n + m), POWER(X, FRACT(n + m, m))),
87  (fract<m, n + m>() * pow(_._1, fract<n + m, m>())));
88 
89  // /
90  // | sqrt(x) dx = 2/3 (x)^ 3/2
91  // /
92  PRIMIT_RULE(TYPX, SQRT_S(X), PRIMIT(X, POWER_S(X, FRACT_S(1, 2))), (fract<2, 3>() * pow(_._, fract<3, 2>())));
93 
94  // /
95  // | exp(x) dx = exp(x)
96  // /
97  PRIMIT_RULE(TYPX, EXP_S(X), EXP(X), _);
98 
99  // /
100  // | log(x) dx = x(log(x) - 1)
101  // /
102  PRIMIT_RULE(TYPX, LOG_S(X), PROD(X, DIFF(LOG(X), NUM(1))), _._*(_ - num<1>()));
103 
104  // /
105  // | sgn(x) dx = abs(x)
106  // /
107  PRIMIT_RULE(TYPX, SGN_S(X), ABS(X), abs(_._));
108 
109  // /
110  // | sin(x) dx = - cos(x)
111  // /
112  PRIMIT_RULE(TYPX, SIN_S(X), MINUS(COS(X)), -cos(_._));
113 
114  // /
115  // | cos(x) dx = sin(x)
116  // /
117  PRIMIT_RULE(TYPX, COS_S(X), SIN(X), sin(_._));
118 
119  // /
120  // | tan(x) dx = - log(abs(cos(x)))
121  // /
122  PRIMIT_RULE(TYPX, TAN_S(X), MINUS(LOG(ABS(COS(X)))), -log(abs(cos(_._))));
123 
124  // /
125  // | 1 / x dx = log(abs(x))
126  // /
127  PRIMIT_RULE(TYPX, RATIO_S(NUM(1), X), LOG(ABS(X)), log(abs(_._2)));
128 
129  PRIMIT_RULE(TYPX, POWER_S(X, NUM(-1)), LOG(ABS(X)), log(abs(_._1)));
130 
131  // /
132  // | 1 / cos(x)^2 dx = tan(x)
133  // /
134  PRIMIT_RULE(TYPX, RATIO_S(NUM(1), POWER_S(COS_S(X), NUM(2))), TAN(X), tan(_._2._1._));
135 
136  // /
137  // | 1 / sin(x)^2 dx = - 1 / tan(x)
138  // /
139  PRIMIT_RULE(TYPX, RATIO_S(NUM(1), POWER_S(SIN_S(X), NUM(2))), 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)), primitive<X>(_._1) + primitive<X>(_._2));
147 
148  // / /
149  // | (- f(x)) dx = - | f(x) dx
150  // / /
151  PRIMIT_RULE(TYPXT1, MINUS_S(A), MINUS(PRIMIT(X, A)), -primitive<X>(_._));
152 
153  // /
154  // | f * g dx : defined only for f or g indep. of x or part. int.
155  // /
156 
157  template <TYPXT2,
160  struct PartIntegral {
162  GET(PROD_S(A, B), type());
163  };
164 
165  TEMPL(XT2) struct PartIntegral<X, A, B, true, false> {
166  typedef PRIMIT(X, B) B1;
167  typedef DERIV(X, A) A1;
168  typedef PRIMIT(X, PROD(A1, B1)) AB1;
169  typedef DIFF(PROD(A, B1), PRIMIT(X, PROD(A1, B1))) type;
170  inline static type get(const PROD_S(A, B) & _) {
171  const A& a = _._1;
172  B1 b = primitive<X>(_._2);
173  return a * b - primitive<X>(derivative<X>(a) * b);
174  }
175  };
176 
177  TEMPL(XT2) struct PartIntegral<X, B, A, false, true> {
178  typedef PRIMIT(X, B) B1;
179  typedef DERIV(X, A) A1;
180  typedef PRIMIT(X, PROD(A1, B1)) AB1;
181  typedef DIFF(PROD(A, B1), PRIMIT(X, PROD(A1, B1))) type;
182  inline static type get(const PROD_S(B, A) & _) {
183  const A& a = _._2;
184  B1 b = primitive<X>(_._1);
185  return a * b - primitive<X>(derivative<X>(a) * b);
186  }
187  };
188 
189  TEMPL(XT2) struct PartIntegral<X, A, B, true, true> : public PartIntegral<X, A, B, true, false> {};
190 
192  struct ProductPrimitive : public PartIntegral<X, A, B> {};
193 
194  TEMPL(XT2) struct ProductPrimitive<X, A, B, true, false> {
195  typedef PROD(A, PRIMIT(X, B)) type;
196  GET(PROD_S(A, B), _._1* primitive<X>(_._2));
197  };
198 
199  TEMPL(XT2) struct ProductPrimitive<X, A, B, false, true> {
200  typedef PROD(B, PRIMIT(X, A)) type;
201  GET(PROD_S(A, B), _._2* primitive<X>(_._1));
202  };
203 
204  TEMPL(XT2) struct ProductPrimitive<X, A, B, true, true> {
205  typedef PROD(PROD(A, B), X) type;
206  GET(PROD_S(A, B), _* X());
207  };
208 
209  TEMPL(XT2) struct Primitive<PROD_S(A, B), X> : public ProductPrimitive<X, A, B> {};
210 
211  // /
212  // | f / g dx : defined only for f or g indep. of x; try part. int.
213  // /
214 
215  template <TYPXT2,
218  struct PartIntegral2 {
220  GET(RATIO_S(A, B), type());
221  };
222 
223  TEMPL(XT2) struct PartIntegral2<X, A, B, true, false> {
224  typedef PRIMIT(X, RATIO(NUM(1), B)) B1;
225  typedef DERIV(X, A) A1;
226  typedef PRIMIT(X, PROD(A1, B1)) AB1;
227  typedef DIFF(PROD(A, B1), AB1) type;
228  inline static type get(const RATIO_S(A, B) & _) {
229  const A& a = _._1;
230  B1 b = primitive<X>(num<1>() / _._2);
231  return a * b - primitive<X>(derivative<X>(a) * b);
232  }
233  };
234 
235  TEMPL(XT2) struct PartIntegral2<X, B, A, false, true> {
236  typedef PRIMIT(X, RATIO(NUM(1), B)) B1;
237  typedef DERIV(X, A) A1;
238  typedef PRIMIT(X, PROD(A1, B1)) AB1;
239  typedef DIFF(PROD(A, B1), AB1) type;
240  inline static type get(const RATIO_S(B, A) & _) {
241  const A& a = _._1;
242  B1 b = primitive<X>(num<1>() / _._2);
243  return a * b - primitive<X>(derivative<X>(a) * b);
244  }
245  };
246 
247  // should be improved: try both...
248  TEMPL(XT2) struct PartIntegral2<X, A, B, true, true> : public PartIntegral2<X, A, B, true, false> {};
249 
251  struct RatioPrimitive : public PartIntegral2<X, A, B> {};
252 
253  TEMPL(XT2) struct RatioPrimitive<X, A, B, true, false> {
254  typedef PROD(A, PRIMIT(X, RATIO(NUM(1), B))) type;
255  GET(RATIO_S(A, B), _._1* primitive<X>(num<1> / _._2));
256  };
257 
258  TEMPL(XT2) struct RatioPrimitive<X, A, B, false, true> {
259  typedef RATIO(PRIMIT(X, A), B) type;
260  GET(RATIO_S(A, B), primitive<X>(_._1) / _._2);
261  };
262 
263  TEMPL(XT2) struct RatioPrimitive<X, A, B, true, true> {
264  typedef RATIO(RATIO(A, B), X) type;
265  GET(RATIO_S(A, B), _* X());
266  };
267 
268  TEMPL(XT2) struct Primitive<RATIO_S(A, B), X> : public RatioPrimitive<X, A, B> {};
269 
270  // Function integrals
271 
272  // /
273  // | c dx = c * x
274  // /
275  template <>
278  inline static type get(const Parameter& p) { return p * Identity(); }
279  };
280 
281 } // namespace funct
282 
283 #define DECLARE_PRIMITIVE(X, F, P) \
284  namespace funct { \
285  template <typename X> \
286  struct Primitive<F, X> { \
287  typedef P type; \
288  inline static type get(const F& _) { return type(_._); } \
289  }; \
290  } \
291  struct __useless_ignoreme
292 
293 #define DECLARE_FUNCT_PRIMITIVE(F, P) \
294  namespace funct { \
295  template <> \
296  struct Primitive<F> { \
297  typedef P type; \
298  inline static type get(const F& _) { return type(); } \
299  }; \
300  } \
301  struct __useless_ignoreme
302 
304 
305 #endif
#define TYPXN2
#define TYPXT1
typedef DERIV(X, A) A1
#define EXP(A)
UndefinedIntegral type
Definition: Primitive.h:219
typedef POWER(A, NUM(n)) arg
Definition: Abs.h:5
#define COS(A)
#define MINUS(A)
PROD_S(B, C)>
Definition: Factorize.h:114
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
typedef MINUS_S(A) arg
#define SQRT_S(A)
#define X(str)
Definition: MuonsGrabber.cc:38
#define SGN_S(A)
#define ABS(A)
#define LOG(A)
#define TYPXN1
#define RATIO_S(A, B)
TEMPL(T2) struct Divides B
Definition: Factorize.h:24
Primitive< F, X >::type primitive(const F &f)
Definition: Primitive.h:41
UndefinedIntegral type
Definition: Primitive.h:161
#define FRACT(N, M)
#define LOG_S(A)
#define FRACT_S(N, M)
#define SUM_S(A, B)
GET(PROD_S(A, B), type())
#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:277
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:15
double b
Definition: hdecay.h:120
arg type
Definition: Factorize.h:32
typedef PROD(F, SUM(RATIO(A, F), RATIO(B, F))) type
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:48
PROD_S(A, B)> NUM(n))
Definition: Factorize.h:87
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
#define POWER_S(A, B)
GET(RATIO_S(A, B), type())
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
#define TYPXT2
#define TYPX
#define TAN_S(A)
UndefinedIntegral type
Definition: Primitive.h:21
#define SIN_S(A)