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