ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/ExtendedMath.C
Revision: 1.1
Committed: Wed Jun 26 05:24:04 2013 UTC (11 years, 10 months ago) by buchmann
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Log Message:
Good morning commit: some mathematical functions that surpass root's standard range: exponential integral ei and exponential integrals en (needed for ttbar shape normalization)

File Contents

# User Rev Content
1 buchmann 1.1 #include <math.h>
2     #include <TMath.h>
3    
4    
5    
6     //************** EXPONENTIAL INTEGRALS En *****
7     // define: E_n(x) = \int_1^infty{exp(-xt)/t^n}dt, x>0, n=0,1,...
8     double expint(int n, double x) {
9     // based on Numerical Recipes in C
10     const double euler = 0.57721566; // Euler's constant, gamma
11     const int maxit = 100; // max. no. of iterations allowed
12     const double fpmin = 1.0e-30; // close to smallest floating-point number
13     const double eps = 6.0e-8; // relative error, or absolute error near
14     // the zero of Ei at x=0.3725
15    
16     int i, ii, nm1;
17     double a,b,c,d,del,fact,h,psi,ans;
18    
19     nm1=n-1;
20     if(n<0 || x<0 || (x==0 && (n==0 || n==1))) {
21     cout << "Bad argument for expint(n,x)" << endl; return -1;
22     }
23     else {
24     if(n==0) ans=exp(-x)/x;
25     else {
26     if(x==0) ans=1.0/nm1;
27     else {
28     if(x>1) {
29     b=x+n;
30     c=1.0/fpmin;
31     d=1.0/b;
32     h=d;
33     for(i=1; i<maxit; i++) {
34     a = -i*(nm1+i);
35     b += 2.0;
36     d=1.0/(a*d+b);
37     c=b+a/c;
38     del=c*d;
39     h *= del;
40     if(fabs(del-1.0)<eps) {
41     ans=h*exp(-x);
42     return ans;
43     }
44     }
45     cout << "***continued fraction failed in expint(n,x)!!!" << endl;
46     return -1;
47     } else {
48     ans = (nm1!=0 ? 1.0/nm1 : -log(x)-euler);
49     fact=1;
50     for(i=1; i<=maxit; i++) {
51     fact *= -x/i;
52     if(i!=nm1) del = -fact/(i-nm1);
53     else {
54     psi = -euler;
55     for(ii=1; ii<=nm1; ii++) psi += 1.0/ii;
56     del = fact*(-log(x)+psi);
57     }
58     ans += del;
59     if(fabs(del)<fabs(ans)*eps) return ans;
60     }
61     cout << "***series failed in expint!!!" << endl;
62     return -1;
63     }
64     }
65     }
66     }
67    
68     return ans;
69     }
70     //*********************************************
71    
72    
73     //************** EXPONENTIAL INTEGRAL Ei ******
74     // define: ei(x) = -\int_{-x}^{\infty}{exp(-t)/t}dt, for x>0
75     // power series: ei(x) = eulerconst + ln(x) + x/(1*1!) + x^2/(2*2!) + ...
76     double ei(double x)
77     { // taken from Numerical Recipes in C
78     const double euler = 0.57721566; // Euler's constant, gamma
79     const int maxit = 100; // max. no. of iterations allowed
80     const double fpmin = 1.0e-40; // close to smallest floating-point number
81     const double eps = 1.0e-30; // relative error, or absolute error near
82     // the zero of Ei at x=0.3725
83     // I actually changed fpmin and eps into smaller values than in NR
84    
85     int k;
86     double fact, prev, sum, term;
87    
88     // special case
89     if(x < 0) return -expint(1,-x);
90    
91     if(x == 0.0) { cout << "Bad argument for ei(x)" << endl; return -1; }
92     if(x < fpmin) return log(x)+euler;
93     if(x <= -log(eps)) {
94     sum = 0;
95     fact = 1;
96     for(k=1; k<=maxit; k++) {
97     fact *= x/k;
98     term = fact/k;
99     sum += term;
100     if(term < eps*sum) break;
101     }
102     if(k>maxit) { cout << "Series failed in ei(x)" << endl; return -1; }
103     return sum+log(x)+euler;
104     } else {
105     sum = 0;
106     term = 1;
107     for(k=1; k<=maxit; k++) {
108     prev = term;
109     term *= k/x;
110     if(term<eps) break;
111     if(term<prev) sum+=term;
112     else {
113     sum -= prev;
114     break;
115     }
116     }
117     return exp(x)*(1.0+sum)/x;
118     }
119     }
120     //*********************************************