laura is hosted by Hepforge, IPPP Durham
Laura++  v3r5
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauIntegrals.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2004 University of Warwick
4 
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 */
17 
18 /*
19 Laura++ package authors:
20 John Back
21 Paul Harrison
22 Thomas Latham
23 */
24 
29 #include <iostream>
30 using std::cout;
31 using std::endl;
32 
33 #include "TMath.h"
34 
35 #include "LauConstants.hh"
36 #include "LauIntegrals.hh"
37 
38 
40 
41 
42 LauIntegrals::LauIntegrals(Double_t weightsPrecision) :
43  weightsPrecision_( weightsPrecision )
44 {
45 }
46 
48 {
49 }
50 
52  weightsPrecision_( rhs.weightsPrecision_ )
53 {
54 }
55 
57 {
58  if ( &rhs != this ) {
60  }
61  return *this;
62 }
63 
64 void LauIntegrals::calcGaussLegendreWeights(const Int_t numPoints, std::vector<Double_t>& abscissas, std::vector<Double_t>& weights)
65 {
66  // Calculate the Gauss-Legendre weights that will be used for the
67  // simple Gaussian integration method given the number of points
68 
69  abscissas.clear();
70  weights.clear();
71  abscissas.resize(numPoints);
72  weights.resize(numPoints);
73 
74  Int_t m = (numPoints+1)/2;
75  Double_t dnumPoints(numPoints);
76  Double_t dnumPointsPlusHalf = static_cast<Double_t>(numPoints + 0.5);
77  Int_t i(0), j(0);
78  Double_t p1(0.0), p2(0.0), p3(0.0), pp(0.0), z(0.0), zSq(0.0), z1(0.0), di(0.0);
79 
80  for (i = 1; i <= m; i++){
81 
82  di = static_cast<Double_t>(i);
83  z = TMath::Cos(LauConstants::pi*(di - 0.25)/dnumPointsPlusHalf);
84  zSq = z*z;
85 
86  // Starting with the above approximation for the ith root, we enter the
87  // main loop of refinement by Newton's method
88  do{
89  p1 = 1.0;
90  p2 = 0.0;
91 
92  // Calculate the Legendre polynomial at z - recurrence relation
93  for (j = 1; j <= numPoints; j++){
94  p3 = p2;
95  p2 = p1;
96  p1 = (( 2.0*j - 1.0) * z * p2 - (j - 1.0)*p3)/static_cast<Double_t>(j);
97  }
98  // p1 = Legendre polynomial. Compute its derivative, pp.
99 
100  pp = dnumPoints * (z*p1 - p2)/(zSq - 1.0);
101  z1 = z;
102  z = z1 - p1/pp; // Newton's method
103  } while (TMath::Abs(z-z1) > weightsPrecision_);
104 
105  // Scale the root to the desired interval
106  // Remember that the vector entries start with 0, hence i-1 (where first i value is 1)
107  abscissas[i-1] = z;
108  abscissas[numPoints-i] = abscissas[i-1]; // Symmetric abscissa
109  weights[i-1] = 2.0/((1.0 - zSq)*pp*pp);
110  weights[numPoints-i] = weights[i-1]; // Symmetric weight
111 
112  }
113 }
114 
115 void LauIntegrals::calcGaussHermiteWeights(const Int_t numPoints, std::vector<Double_t>& abscissas, std::vector<Double_t>& weights)
116 {
117  // Calculate the Gauss-Hermite weights that will be used for the
118  // simple Gaussian integration method for a function weighted by an exp(-x**2) term
119  // These weights are common to all integration intervals - therefore they
120  // should only be calculated once - when the constructor is called, for example.
121 
122  abscissas.clear();
123  weights.clear();
124  abscissas.resize(numPoints); weights.resize(numPoints);
125 
126  Int_t m = (numPoints+1)/2;
127  Double_t dnumPoints(numPoints);
128  Int_t i(0), j(0), its(0);
129  Double_t p1(0.0), p2(0.0), p3(0.0), pp(0.0), z(0.0), z1(0.0);
130  Double_t numPointsTerm(2*numPoints+1);
131 
132  // The roots are symmetric about the origin. Therefore, we only need to find half of them
133  // Loop over the desired roots.
134  for (i = 1; i <= m; i++) {
135 
136  if (i == 1) {
137  // Initial guess for largest root
138  z = TMath::Sqrt(numPointsTerm) - 1.85575*TMath::Power(numPointsTerm, -0.16667);
139  } else if (i == 2) {
140  // Initial guess for second largest root
141  z -= 1.14*TMath::Power(dnumPoints, 0.426)/z;
142  } else if (i == 3) {
143  // Initial guess for third largest root
144  z = 1.86*z - 0.86*abscissas[0];
145  } else if (i == 4) {
146  // Initial guess for fourth largest root
147  z = 1.91*z - 0.91*abscissas[1];
148  } else {
149  // Initial guess for other roots
150  z = 2.0*z - abscissas[i-3];
151  }
152 
153  for (its = 1; its <= 10; its++) {
155  p2 = 0.0;
156 
157  for (j = 1; j <= numPoints; j++) {
158  Double_t dj(j);
159  p3 = p2;
160  p2 = p1;
161  p1 = z*TMath::Sqrt(2.0/dj)*p2 - TMath::Sqrt((dj-1.0)/dj)*p3;
162  }
163  // p1 is now the desired Hermite polynomial. Compute its derivative, pp
164  pp = TMath::Sqrt(2.0*dnumPoints)*p2;
165  z1 = z;
166  if (pp > 1e-10) {z = z1 - p1/pp;}
167  if (TMath::Abs(z - z1) < weightsPrecision_) break;
168  }
169 
170  // Scale the root to the desired interval
171  // Remember that the vector entries start with 0, hence i-1 (where first i value is 1)
172  abscissas[i-1] = z;
173  abscissas[numPoints-i] = -z; // Symmetric abscissa
174  weights[i-1] = 2.0/(pp*pp);
175  weights[numPoints-i] = weights[i-1]; // Symmetric weight
176 
177  }
178 }
static double p1(double t, double a, double b)
ClassImp(LauAbsCoeffSet)
Class for performing numerical integration routines.
Definition: LauIntegrals.hh:44
LauIntegrals(Double_t weightsPrecision=1.0e-6)
Constructor.
Definition: LauIntegrals.cc:42
void calcGaussHermiteWeights(const Int_t numPoints, std::vector< Double_t > &abscissas, std::vector< Double_t > &weights)
Calculate the Gauss-Hermite weights.
void calcGaussLegendreWeights(const Int_t numPoints, std::vector< Double_t > &abscissas, std::vector< Double_t > &weights)
Calculate the Gauss-Legendre weights.
Definition: LauIntegrals.cc:64
static double p3(double t, double a, double b, double c, double d)
const Double_t pi
Pi.
static double p2(double t, double a, double b, double c)
Double_t weightsPrecision_
The precision to which the weights should be calculated.
Definition: LauIntegrals.hh:80
LauIntegrals & operator=(const LauIntegrals &rhs)
Copy assignment operator.
Definition: LauIntegrals.cc:56
File containing LauConstants namespace.
File containing declaration of LauIntegrals class.
virtual ~LauIntegrals()
Destructor.
Definition: LauIntegrals.cc:47
const Double_t pim4
One over Pi to the one-fourth.