Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JQuadrature.hh
Go to the documentation of this file.
1 #ifndef __JTOOLS__JQUADRATURE__
2 #define __JTOOLS__JQUADRATURE__
3 
4 #include <cmath>
5 
6 #include "TMath.h"
7 
8 #include "JTools/JConstants.hh"
9 #include "JTools/JElement.hh"
10 #include "JTools/JCollection.hh"
11 
12 
13 /**
14  * \file
15  *
16  * Auxiliary classes for numerical integration.
17  * \author mdejong
18  */
19 namespace JTOOLS {}
20 namespace JPP { using namespace JTOOLS; }
21 
22 namespace JTOOLS {
23 
24  /**
25  * Type definition of basic element for quadratures.
26  */
28 
29 
30  /**
31  * Type definition for numerical integration.
32  *
33  * \f$\displaystyle \int_{x_1}^{x_2} f(x) dx = \sum_{i=1}^{N} w_i f(x_i) \f$
34  *
35  * The abscissa and ordinate values of the collection can be used
36  * as abscissa and weight values of the summation to approximately
37  * determine the integral of the function.
38  */
39  class JQuadrature :
40  public JCollection<JElement2D_t>
41  {
42  public:
43  /**
44  * Default constructor.
45  */
47  {}
48 
49 
50  /**
51  * General purpose constructor.
52  *
53  * The template argument should correspond to a function requiring two arguments.
54  * These two arguments should correspond to the lower and upper integration limit, respectively.
55  * The given function should return the value of the integral between the two integration limits.
56  *
57  * \param xmin minimal x
58  * \param xmax maximal x
59  * \param nx number of points
60  * \param integral integral
61  * \param eps precision
62  */
63  template<class JFunction_t>
64  JQuadrature(const double xmin,
65  const double xmax,
66  const int nx,
67  JFunction_t integral,
68  const double eps = 1.0e-4)
69  {
70  double Xmin = xmin;
71  double Xmax = xmax;
72 
73  const double Vmin = integral(Xmin, Xmax) / (double) nx;
74 
75  for (int i = 0; i != nx; ++i) {
76 
77  for (double xmin = Xmin, xmax = Xmax; ; ) {
78 
79  const double x = 0.5 * (xmin + xmax);
80  const double v = integral(Xmin, x);
81 
82  if (fabs(Vmin - v) < eps * Vmin ||
83  fabs(xmax - xmin) < eps * (Xmax - Xmin)) {
84 
85  const double __x = 0.5 * (Xmin + x);
86  const double __y = Vmin / integral(__x);
87 
88  insert(JElement2D_t(__x,__y));
89 
90  Xmin = x;
91  xmax = Xmax;
92 
93  break;
94  }
95 
96  if (v < Vmin)
97  xmin = x;
98  else
99  xmax = x;
100  }
101  }
102  }
103  };
104 
105 
106  /**
107  * Numerical integrator for <tt>W(x) = 1</tt>.
108  *
109  * Gauss-Legendre integration code is taken from reference:
110  * Numerical Recipes in C++, W.H. Press, S.A. Teukolsky, W.T. Vetterling and B.P. Flannery,
111  * Cambridge University Press.
112  */
113  class JGaussLegendre :
114  public JQuadrature
115  {
116  public:
117  /**
118  * Constructor.
119  *
120  * \param n number of points
121  * \param eps precision
122  */
123  JGaussLegendre(const int n,
124  const double eps = 1.0e-12) :
125  JQuadrature()
126  {
127  resize(n);
128 
129  const int M = (n + 1) / 2;
130 
131  double p0, p1, p2, pp;
132 
133  for (int i = 0; i < M; ++i) {
134 
135  double z = cos(PI * (i+0.75) / (n+0.5));
136  double z1;
137 
138  do {
139 
140  p1 = 0.0;
141  p2 = 1.0;
142 
143  // recurrence relation
144 
145  for (int j = 0; j < n; ++j) {
146  p0 = p1;
147  p1 = p2;
148  p2 = ((2*j + 1) * z*p1 - j*p0) / (j+1);
149  }
150 
151  pp = n * (z*p2 - p1) / (z*z - 1.0);
152 
153  z1 = z;
154  z = z1 - p2/pp;
155 
156  } while (fabs(z-z1) > eps);
157 
158  const double y = 2.0 / ((1.0-z*z)*pp*pp);
159 
160  at( i ) = JElement2D_t(-z,y);
161  at(n-i-1) = JElement2D_t(+z,y);
162  }
163  }
164  };
165 
166 
167  /**
168  * Numerical integrator for <tt>W(x) = x^a e^(-x)</tt>.
169  *
170  * Gauss-Laguerre integration code is taken from reference:
171  * Numerical Recipes in C++, W.H. Press, S.A. Teukolsky, W.T. Vetterling and B.P. Flannery,
172  * Cambridge University Press.
173  */
174  class JGaussLaguerre :
175  public JQuadrature
176  {
177  public:
178  /**
179  * Constructor.
180  *
181  * \param n number of points
182  * \param alf power
183  * \param eps precision
184  */
185  JGaussLaguerre(const int n,
186  const double alf,
187  const double eps = 1.0e-12) :
188  JQuadrature()
189  {
190  const int number_of_iterations = 100;
191 
192  double z, z1;
193  double p0, p1, p2, pp;
194 
195  for (int i = 0; i < n; ++i) {
196 
197  switch (i) {
198 
199  case 0:
200  z = (1.0 + alf) * (3.0 + 0.92*alf) / (1.0 + 2.4*n + 1.8*alf);
201  break;
202 
203  case 1:
204  z += (15.0 + 6.25*alf) / (1.0 + 0.9*alf + 2.5*n);
205  break;
206 
207  default:
208  const double ai = i - 1;
209  z += ((1.0+2.55*ai)/(1.9*ai) + (1.26*ai*alf)/(1.0+3.5*ai)) * (z - at(i-2).getX()) / (1.0 + 0.3*alf);
210  break;
211  }
212 
213 
214  int k;
215 
216  for (k = 0; k != number_of_iterations; ++k) {
217 
218  p1 = 0.0;
219  p2 = 1.0;
220 
221  // recurrence relation
222 
223  for (int j = 0; j < n; ++j) {
224  p0 = p1;
225  p1 = p2;
226  p2 = ((2*j + 1 + alf - z) * p1 - (j + alf)*p0) / (j+1);
227  }
228 
229  pp = (n*p2 - (n+alf)*p1) / z;
230 
231  z1 = z;
232  z = z1 - p2/pp;
233 
234  if (fabs(z-z1) < eps)
235  break;
236  }
237 
238  const double y = -TMath::Gamma(alf+n) / TMath::Gamma((double) n) / (pp*n*p1);
239 
240  insert(JElement2D_t(z,y));
241  }
242  }
243  };
244 
245 
246  /**
247  * Numerical integrator for <tt>W(x) = e^-(x^2)</tt>.
248  *
249  * Gauss-Hermite integration code is taken from reference:
250  * Numerical Recipes in C++, W.H. Press, S.A. Teukolsky, W.T. Vetterling and B.P. Flannery,
251  * Cambridge University Press.
252  */
253  class JGaussHermite :
254  public JQuadrature
255  {
256  public:
257  /**
258  * Constructor.
259  *
260  * \param n number of points
261  * \param eps precision
262  */
263  JGaussHermite(const int n,
264  const double eps = 1.0e-12) :
265  JQuadrature()
266  {
267  resize(n);
268 
269  const double pii = 1.0 / pow(PI,0.25);
270 
271  const int number_of_iterations = 100;
272 
273  const int M = (n + 1) / 2;
274 
275  double p0, p1, p2, pp;
276  double z = 0.0;
277  double z1;
278 
279  for (int i = 0; i < M; ++i) {
280 
281  switch (i) {
282 
283  case 0:
284  z = sqrt((double) (2*n+1)) - 1.85575 * pow((double) (2*n+1),-0.16667);
285  break;
286 
287  case 1:
288  z -= 1.14 * pow((double) n,0.426) / z;
289  break;
290 
291  case 2:
292  z = 1.86*z + 0.86*at( 0 ).getX();
293  break;
294 
295  case 3:
296  z = 1.91*z + 0.91*at( 1 ).getX();
297  break;
298 
299  default:
300  z = 2.00*z + 1.00*at(i-2).getX();
301  break;
302  }
303 
304  for (int k = 0; k != number_of_iterations; ++k) {
305 
306  p1 = 0.0;
307  p2 = pii;
308 
309  // recurrence relation
310 
311  for (int j = 0; j < n; ++j) {
312  p0 = p1;
313  p1 = p2;
314  p2 = z * sqrt(2.0/(double) (j+1)) * p1 - sqrt((double) j / (double) (j+1)) * p0;
315  }
316 
317  pp = sqrt((double) (2*n)) * p1;
318 
319  z1 = z;
320  z = z1 - p2/pp;
321 
322  if (fabs(z-z1) < eps)
323  break;
324  }
325 
326  const double y = 2.0 / (pp*pp);
327 
328  at( i ) = JElement2D_t(-z,y);
329  at(n-i-1) = JElement2D_t(+z,y);
330  }
331  }
332  };
333 
334 
335  /**
336  * Numerical integrator for <tt>W(x) = (1 + g^2 - 2gx)^a</tt>.
337  * For this, <tt>g > 0</tt>.
338  *
339  * Henyey-Greenstein integration points and weights.
340  */
342  public JQuadrature
343  {
344  public:
345  /**
346  * Constructor.
347  *
348  * \param n number of points
349  * \param g angular dependence parameter
350  * \param a power
351  */
352  JHenyeyGreenstein(const int n,
353  const double g,
354  const double a) :
355  JQuadrature()
356  {
357  const double b = -2*g * (a + 1.0);
358  const double ai = 1.0 / (a + 1.0);
359 
360  const double ymin = pow(1.0 + g, 2*(a + 1.0)) / b;
361  const double ymax = pow(1.0 - g, 2*(a + 1.0)) / b;
362 
363  const double dy = (ymax - ymin) / (n + 1);
364 
365  for (double y = ymax - 0.5*dy; y > ymin; y -= dy) {
366 
367  const double v = y*b;
368  const double w = pow(v, ai);
369  const double x = (1.0 + g*g - w) / (2*g);
370  const double dx = pow(v, -a*ai)*dy;
371 
372  insert(JElement2D_t(x,dx));
373  }
374  }
375 
376 
377  /**
378  * Constructor.
379  *
380  * \param n number of points
381  * \param g angular dependence parameter
382  * \param a power
383  * \param xmin minimal value
384  * \param xmax maximal value
385  */
386  JHenyeyGreenstein(const int n,
387  const double g,
388  const double a,
389  const double xmin,
390  const double xmax) :
391  JQuadrature()
392  {
393  const double b = -2*g * (a + 1.0);
394  const double ai = 1.0 / (a + 1.0);
395 
396  const double ymin = pow(1.0 + g*g -2*g*xmin, a + 1.0) / b;
397  const double ymax = pow(1.0 + g*g -2*g*xmax, a + 1.0) / b;
398 
399  const double dy = (ymax - ymin) / (n + 1);
400 
401  for (double y = ymax - 0.5*dy; y > ymin; y -= dy) {
402 
403  const double v = y*b;
404  const double w = pow(v, ai);
405  const double x = (1.0 + g*g - w) / (2*g);
406  const double dx = pow(v, -a*ai)*dy;
407 
408  insert(JElement2D_t(x,dx));
409  }
410  }
411 
412 
413  /**
414  * Constructor for special case where a = -1.
415  *
416  * \param n number of points
417  * \param g angular dependence parameter
418  */
419  JHenyeyGreenstein(const int n,
420  const double g) :
421  JQuadrature()
422  {
423  const double dy = 1.0 / (n + 1);
424  const double gi = log((1.0 + g*g) / (1.0 - g*g)) / (2.0*g);
425 
426  for (double y = 1.0 - 0.5*dy; y > 0.0; y -= dy) {
427 
428  const double v = -y*2.0*g*gi + log(1.0 + g*g);
429  const double w = exp(v);
430  const double x = (1.0 + g*g - w) / (2.0*g);
431  const double dx = w*gi*dy;
432 
433  insert(JElement2D_t(x,dx));
434  }
435  }
436  };
437 
438 
439  /**
440  * Numerical integrator for <tt>W(x) = (1 + g*x*x)</tt>.
441  * For this, <tt>g > 0</tt>.
442  *
443  * Rayleigh integration points and weights.
444  */
445  class JRayleigh :
446  public JQuadrature
447  {
448  public:
449  /**
450  * Constructor.
451  *
452  * \param n number of points
453  * \param g angular dependence parameter
454  */
455  JRayleigh(const int n,
456  const double g) :
457  JQuadrature()
458  {
459  const double dy = 1.0 / (n + 1);
460  const double gi = 3.0/g + 1.0;
461 
462  // t^3 + 3pt + 2q = 0
463 
464  const double p = 1.0/g;
465 
466  for (double y = 0.5*dy; y < 1.0; y += dy) {
467 
468  const double q = 0.5*gi - gi*y;
469 
470  const double b = sqrt(q*q + p*p*p);
471  const double u = pow(-q + b, 1.0/3.0);
472  const double v = pow(+q + b, 1.0/3.0);
473 
474  const double x = u - v;
475  const double dx = (u + v) / (3.0*b);
476 
477  insert(JElement2D_t(x, dx*gi*dy));
478  }
479  }
480  };
481 
482 
483  /**
484  * Numerical integrator for <tt>W(x) = |x| / sqrt(1 - x*x)</tt>
485  *
486  * Co-tangent integration points and weights.
487  */
488  class JCotangent :
489  public JQuadrature
490  {
491  public:
492  /**
493  * Constructor.
494  *
495  * \param n number of points
496  */
497  JCotangent(const int n) :
498  JQuadrature()
499  {
500  for (double ds = 1.0 / (n/2), sb = 0.5*ds; sb < 1.0; sb += ds) {
501 
502  const double cb = sqrt((1.0 + sb)*(1.0 - sb));
503  const double dc = ds*sb/cb;
504 
505  insert(JElement2D_t(+cb, dc));
506  insert(JElement2D_t(-cb, dc));
507  }
508  }
509  };
510 
511 
512  /**
513  * Numerical integrator for <tt>W(x) = |x| / sqrt(1 - x*x), x > 0 </tt> and <tt>W(x) = 1, x <= 0</tt>.
514  *
515  * Bi-tangent integration points and weights.
516  */
517  class JBitangent :
518  public JQuadrature
519  {
520  public:
521  /**
522  * Constructor.
523  *
524  * \param n number of points
525  */
526  JBitangent(const int n) :
527  JQuadrature()
528  {
529  double sb, ds;
530  double cb = 0.0;
531  double dc = 0.0;
532 
533  for (ds = 1.0 / (n/2), sb = 0.5*ds; sb < 1.0; sb += ds) {
534 
535  cb = sqrt((1.0 + sb)*(1.0 - sb));
536  dc = ds*sb/cb;
537 
538  insert(JElement2D_t(cb, dc));
539  }
540 
541  for (dc = (cb + 1.0) / (n/2), cb -= 0.5*dc ; cb > -1.0; cb -= dc) {
542  insert(JElement2D_t(cb, dc));
543  }
544  }
545  };
546 }
547 
548 #endif
2D Element.
Definition: JElement.hh:44
Numerical integrator for W(x) = 1.
Definition: JQuadrature.hh:113
TPaveText * p1
General purpose class for collection of elements, see: &lt;a href=&quot;JTools.PDF&quot;;&gt;Collection of elements...
Definition: JCollection.hh:71
The elements in a collection are sorted according to their abscissa values and a given distance opera...
JGaussHermite(const int n, const double eps=1.0e-12)
Constructor.
Definition: JQuadrature.hh:263
Numerical integrator for W(x) = e^-(x^2).
Definition: JQuadrature.hh:253
JGaussLegendre(const int n, const double eps=1.0e-12)
Constructor.
Definition: JQuadrature.hh:123
Numerical integrator for W(x) = |x| / sqrt(1 - x*x)
Definition: JQuadrature.hh:488
static const double PI
Constants.
Definition: JConstants.hh:20
JGaussLaguerre(const int n, const double alf, const double eps=1.0e-12)
Constructor.
Definition: JQuadrature.hh:185
JQuadrature()
Default constructor.
Definition: JQuadrature.hh:46
void resize(typename container_type::size_type size)
Resize collection.
Definition: JCollection.hh:769
Numerical integrator for W(x) = (1 + g*x*x).
Definition: JQuadrature.hh:445
JHenyeyGreenstein(const int n, const double g, const double a, const double xmin, const double xmax)
Constructor.
Definition: JQuadrature.hh:386
Constants.
JRayleigh(const int n, const double g)
Constructor.
Definition: JQuadrature.hh:455
Numerical integrator for W(x) = |x| / sqrt(1 - x*x), x &gt; 0 and W(x) = 1, x &lt;= 0. ...
Definition: JQuadrature.hh:517
JQuadrature(const double xmin, const double xmax, const int nx, JFunction_t integral, const double eps=1.0e-4)
General purpose constructor.
Definition: JQuadrature.hh:64
JBitangent(const int n)
Constructor.
Definition: JQuadrature.hh:526
General purpose class for a collection of sorted elements.
Type definition for numerical integration.
Definition: JQuadrature.hh:39
Numerical integrator for W(x) = x^a e^(-x).
Definition: JQuadrature.hh:174
JHenyeyGreenstein(const int n, const double g)
Constructor for special case where a = -1.
Definition: JQuadrature.hh:419
Numerical integrator for W(x) = (1 + g^2 - 2gx)^a.
Definition: JQuadrature.hh:341
JTOOLS::JElement2D< double, double > JElement2D_t
Definition: JLED.hh:26
JCotangent(const int n)
Constructor.
Definition: JQuadrature.hh:497
pair_type insert(const value_type &element)
Insert element.
Definition: JCollection.hh:298
JHenyeyGreenstein(const int n, const double g, const double a)
Constructor.
Definition: JQuadrature.hh:352