Geant4-11
Gamma.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27//
28// ------------------------------------------------------------
29// GEANT 4 class implementation
30// ------------------------------------------------------------
31
32#include <cmath>
33#include <string.h>
34#include "Gamma.hh"
35
37
39
40//____________________________________________________________________________
41double MyGamma::Gamma(double z)
42{
43 if (z <= 0)
44 return 0;
45
46 return std::tgamma(z);
47}
48
49//____________________________________________________________________________
50double MyGamma::Gamma(double a,double x)
51{
52 // Computation of the incomplete gamma function P(a,x)
53 //
54 // The algorithm is based on the formulas and code as denoted in
55 // Numerical Recipes 2nd ed. on p. 210-212 (W.H.Press et al.).
56 //
57 //--- Nve 14-nov-1998 UU-SAP Utrecht
58
59 if (a <= 0 || x <= 0) return 0;
60
61 if (x < (a+1)) return GamSer(a,x);
62 else return GamCf(a,x);
63}
64
65//____________________________________________________________________________
66double MyGamma::GamCf(double a,double x)
67{
68 // Computation of the incomplete gamma function P(a,x)
69 // via its continued fraction representation.
70 //
71 // The algorithm is based on the formulas and code as denoted in
72 // Numerical Recipes 2nd ed. on p. 210-212 (W.H.Press et al.).
73 //
74 //--- Nve 14-nov-1998 UU-SAP Utrecht
75
76 int itmax = 100; // Maximum number of iterations
77 double eps = 3.e-7; // Relative accuracy
78 double fpmin = 1.e-30; // Smallest double value allowed here
79
80 if (a <= 0 || x <= 0) return 0;
81
82 double gln = LnGamma(a);
83 double b = x+1-a;
84 double c = 1/fpmin;
85 double d = 1/b;
86 double h = d;
87 double an,del;
88 for (int i=1; i<=itmax; i++) {
89 an = double(-i)*(double(i)-a);
90 b += 2;
91 d = an*d+b;
92 if (Abs(d) < fpmin) d = fpmin;
93 c = b+an/c;
94 if (Abs(c) < fpmin) c = fpmin;
95 d = 1/d;
96 del = d*c;
97 h = h*del;
98 if (Abs(del-1) < eps) break;
99 //if (i==itmax) cout << "*GamCf(a,x)* a too large or itmax too small" << endl;
100 }
101 double v = Exp(-x+a*Log(x)-gln)*h;
102 return (1-v);
103}
104
105//____________________________________________________________________________
106double MyGamma::GamSer(double a,double x)
107{
108 // Computation of the incomplete gamma function P(a,x)
109 // via its series representation.
110 //
111 // The algorithm is based on the formulas and code as denoted in
112 // Numerical Recipes 2nd ed. on p. 210-212 (W.H.Press et al.).
113 //
114 //--- Nve 14-nov-1998 UU-SAP Utrecht
115
116 int itmax = 100; // Maximum number of iterations
117 double eps = 3.e-7; // Relative accuracy
118
119 if (a <= 0 || x <= 0) return 0;
120
121 double gln = LnGamma(a);
122 double ap = a;
123 double sum = 1/a;
124 double del = sum;
125 for (int n=1; n<=itmax; n++) {
126 ap += 1;
127 del = del*x/ap;
128 sum += del;
129 if (MyGamma::Abs(del) < Abs(sum*eps)) break;
130 //if (n==itmax) cout << "*GamSer(a,x)* a too large or itmax too small" << endl;
131 }
132 double v = sum*Exp(-x+a*Log(x)-gln);
133 return v;
134}
135
136
137double MyGamma::LnGamma(double z)
138{
139 if (z <= 0)
140 return 0;
141
142 return std::lgamma(z);
143}
static const G4double eps
static short Abs(short d)
Definition: Gamma.hh:61
MyGamma()
Definition: Gamma.cc:36
static double LnGamma(double z)
Definition: Gamma.cc:137
~MyGamma()
Definition: Gamma.cc:38
double GamCf(double a, double x)
Definition: Gamma.cc:66
double Gamma(double z)
Definition: Gamma.cc:41
static double Log(double x)
Definition: Gamma.hh:67
double GamSer(double a, double x)
Definition: Gamma.cc:106
static double Exp(double x)
Definition: Gamma.hh:68