Gamma.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 // $Id: Gamma.cc 69796 2013-05-15 13:26:12Z gcosmo $
00027 //
00028 //
00029 // ------------------------------------------------------------
00030 // GEANT 4 class implementation
00031 // ------------------------------------------------------------
00032 
00033 #include <cmath>
00034 #include <string.h>
00035 #include "Gamma.hh"
00036 
00037 MyGamma::MyGamma(){}
00038 
00039 MyGamma::~MyGamma(){}
00040 
00041 //____________________________________________________________________________
00042 double MyGamma::Gamma(double z)
00043 {
00044   // Computation of gamma(z) for all z>0.
00045   //
00046   // The algorithm is based on the article by C.Lanczos [1] as denoted in
00047   // Numerical Recipes 2nd ed. on p. 207 (W.H.Press et al.).
00048   //
00049   // [1] C.Lanczos, SIAM Journal of Numerical Analysis B1 (1964), 86.
00050   //
00051   //--- Nve 14-nov-1998 UU-SAP Utrecht
00052   
00053   if (z<=0) return 0;
00054   
00055   double v = LnGamma(z);
00056   return std::exp(v);
00057 }
00058 
00059 //____________________________________________________________________________
00060 double MyGamma::Gamma(double a,double x)
00061 {
00062   // Computation of the incomplete gamma function P(a,x)
00063   //
00064   // The algorithm is based on the formulas and code as denoted in
00065   // Numerical Recipes 2nd ed. on p. 210-212 (W.H.Press et al.).
00066   //
00067   //--- Nve 14-nov-1998 UU-SAP Utrecht
00068   
00069   if (a <= 0 || x <= 0) return 0;
00070   
00071   if (x < (a+1)) return GamSer(a,x);
00072   else           return GamCf(a,x);
00073 }
00074 
00075 //____________________________________________________________________________
00076 double MyGamma::GamCf(double a,double x)
00077 {
00078   // Computation of the incomplete gamma function P(a,x)
00079   // via its continued fraction representation.
00080   //
00081   // The algorithm is based on the formulas and code as denoted in
00082   // Numerical Recipes 2nd ed. on p. 210-212 (W.H.Press et al.).
00083   //
00084   //--- Nve 14-nov-1998 UU-SAP Utrecht
00085   
00086   int itmax    = 100;      // Maximum number of iterations
00087   double eps   = 3.e-7;    // Relative accuracy
00088   double fpmin = 1.e-30;   // Smallest double value allowed here
00089   
00090   if (a <= 0 || x <= 0) return 0;
00091   
00092   double gln = LnGamma(a);
00093   double b   = x+1-a;
00094   double c   = 1/fpmin;
00095   double d   = 1/b;
00096   double h   = d;
00097   double an,del;
00098   for (int i=1; i<=itmax; i++) {
00099     an = double(-i)*(double(i)-a);
00100     b += 2;
00101     d  = an*d+b;
00102     if (Abs(d) < fpmin) d = fpmin;
00103     c = b+an/c;
00104     if (Abs(c) < fpmin) c = fpmin;
00105     d   = 1/d;
00106     del = d*c;
00107     h   = h*del;
00108     if (Abs(del-1) < eps) break;
00109     //if (i==itmax) cout << "*GamCf(a,x)* a too large or itmax too small" << endl;
00110   }
00111   double v = Exp(-x+a*Log(x)-gln)*h;
00112   return (1-v);
00113 }
00114 
00115 //____________________________________________________________________________
00116 double MyGamma::GamSer(double a,double x)
00117 {
00118   // Computation of the incomplete gamma function P(a,x)
00119   // via its series representation.
00120   //
00121   // The algorithm is based on the formulas and code as denoted in
00122   // Numerical Recipes 2nd ed. on p. 210-212 (W.H.Press et al.).
00123   //
00124   //--- Nve 14-nov-1998 UU-SAP Utrecht
00125   
00126   int itmax  = 100;   // Maximum number of iterations
00127   double eps = 3.e-7; // Relative accuracy
00128   
00129   if (a <= 0 || x <= 0) return 0;
00130   
00131   double gln = LnGamma(a);
00132   double ap  = a;
00133   double sum = 1/a;
00134   double del = sum;
00135   for (int n=1; n<=itmax; n++) {
00136     ap  += 1;
00137     del  = del*x/ap;
00138     sum += del;
00139     if (MyGamma::Abs(del) < Abs(sum*eps)) break;
00140     //if (n==itmax) cout << "*GamSer(a,x)* a too large or itmax too small" << endl;
00141   }
00142   double v = sum*Exp(-x+a*Log(x)-gln);
00143   return v;
00144 }
00145 
00146 
00147 double MyGamma::LnGamma(double z)
00148 {
00149   // Computation of ln[gamma(z)] for all z>0.
00150   //
00151   // The algorithm is based on the article by C.Lanczos [1] as denoted in
00152   // Numerical Recipes 2nd ed. on p. 207 (W.H.Press et al.).
00153   //
00154   // [1] C.Lanczos, SIAM Journal of Numerical Analysis B1 (1964), 86.
00155   //
00156   // The accuracy of the result is better than 2e-10.
00157   //
00158   //--- Nve 14-nov-1998 UU-SAP Utrecht
00159   
00160   if (z<=0) return 0;
00161   
00162   // Coefficients for the series expansion
00163   double c[7] = { 2.5066282746310005, 76.18009172947146, -86.50532032941677
00164     ,24.01409824083091,  -1.231739572450155, 0.1208650973866179e-2
00165     ,-0.5395239384953e-5};
00166   
00167   double x   = z;
00168   double y   = x;
00169   double tmp = x+5.5;
00170   tmp = (x+0.5)*Log(tmp)-tmp;
00171   double ser = 1.000000000190015;
00172   for (int i=1; i<7; i++) {
00173     y   += 1;
00174     ser += c[i]/y;
00175   }
00176   double v = tmp+Log(c[0]*ser/x);
00177   return v;
00178 }

Generated on Mon May 27 17:50:28 2013 for Geant4 by  doxygen 1.4.7