/************************************************************************** * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * * * Author: The ALICE Off-line Project. * * Contributors are mentioned in the code where appropriate. * * * * Permission to use, copy, modify and distribute this software and its * * documentation strictly for non-commercial purposes is hereby granted * * without fee, provided that the above copyright notice appears in all * * copies and that both the copyright notice and this permission notice * * appear in the supporting documentation. The authors make no claims * * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ /* $Log$ Revision 1.2 1999/09/29 09:24:28 fca Introduction of the Copyright and cvs Log */ /////////////////////////////////////////////////////////////////////////// // Class AliMath // Various mathematical tools which may be very convenient while // performing physics analysis. // // Example : Probability of a Chi-squared value // ========= // // AliMath M; // Float_t chi2=20; // The chi-squared value // Int_t ndf=12; // The number of degrees of freedom // Float_t p=M.Prob(chi2,ndf); // The probability that at least a Chi-squared // // value of chi2 will be observed, even for a // // correct model // //--- Author: Nick van Eijndhoven 14-nov-1998 UU-SAP Utrecht /////////////////////////////////////////////////////////////////////////// #include "AliMath.h" ClassImp(AliMath) // Class implementation to enable ROOT I/O AliMath::AliMath() { // Default constructor } /////////////////////////////////////////////////////////////////////////// AliMath::~AliMath() { // Destructor } /////////////////////////////////////////////////////////////////////////// Float_t AliMath::Gamma(Float_t z) { // Computation of gamma(z) for all z>0. // // The algorithm is based on the article by C.Lanczos [1] as denoted in // Numerical Recipes 2nd ed. on p. 207 (W.H.Press et al.). // // [1] C.Lanczos, SIAM Journal of Numerical Analysis B1 (1964), 86. // //--- Nve 14-nov-1998 UU-SAP Utrecht if (z<=0.) { cout << "*Gamma(z)* Wrong argument z = " << z << endl; return 0; } Float_t v=LnGamma(z); return exp(v); } /////////////////////////////////////////////////////////////////////////// Float_t AliMath::Gamma(Float_t a,Float_t x) { // Computation of the incomplete gamma function P(a,x) // // The algorithm is based on the formulas and code as denoted in // Numerical Recipes 2nd ed. on p. 210-212 (W.H.Press et al.). // //--- Nve 14-nov-1998 UU-SAP Utrecht if (a<=0.) { cout << "*Gamma(a,x)* Invalid argument a = " << a << endl; return 0; } if (x<=0.) { if (x<0) cout << "*Gamma(a,x)* Invalid argument x = " << x << endl; return 0; } if (x<(a+1.)) { return GamSer(a,x); } else { return GamCf(a,x); } } /////////////////////////////////////////////////////////////////////////// Float_t AliMath::LnGamma(Float_t z) { // Computation of ln[gamma(z)] for all z>0. // // The algorithm is based on the article by C.Lanczos [1] as denoted in // Numerical Recipes 2nd ed. on p. 207 (W.H.Press et al.). // // [1] C.Lanczos, SIAM Journal of Numerical Analysis B1 (1964), 86. // // The accuracy of the result is better than 2e-10. // //--- Nve 14-nov-1998 UU-SAP Utrecht if (z<=0.) { cout << "*LnGamma(z)* Wrong argument z = " << z << endl; return 0; } // Coefficients for the series expansion Double_t c[7]; c[0]= 2.5066282746310005; c[1]= 76.18009172947146; c[2]=-86.50532032941677; c[3]= 24.01409824083091; c[4]= -1.231739572450155; c[5]= 0.1208650973866179e-2; c[6]= -0.5395239384953e-5; Double_t x=z; Double_t y=x; Double_t tmp=x+5.5; tmp=(x+0.5)*log(tmp)-tmp; Double_t ser=1.000000000190015; for (Int_t i=1; i<7; i++) { y+=1.; ser+=c[i]/y; } Float_t v=tmp+log(c[0]*ser/x); return v; } /////////////////////////////////////////////////////////////////////////// Float_t AliMath::GamSer(Float_t a,Float_t x) { // Computation of the incomplete gamma function P(a,x) // via its series representation. // // The algorithm is based on the formulas and code as denoted in // Numerical Recipes 2nd ed. on p. 210-212 (W.H.Press et al.). // //--- Nve 14-nov-1998 UU-SAP Utrecht Int_t itmax=100; // Maximum number of iterations Float_t eps=3.e-7; // Relative accuracy if (a<=0.) { cout << "*GamSer(a,x)* Invalid argument a = " << a << endl; return 0; } if (x<=0.) { if (x<0) cout << "*GamSer(a,x)* Invalid argument x = " << x << endl; return 0; } Float_t gln=LnGamma(a); Float_t ap=a; Float_t sum=1./a; Float_t del=sum; for (Int_t n=1; n<=itmax; n++) { ap+=1.; del=del*x/ap; sum+=del; if (fabs(del)30 && q>0.) // { // Float_t v=0.5*(1.-Erf(q/sqrt(2.))); // return v; // } // Evaluate the incomplete gamma function Float_t a=float(ndf)/2.; Float_t x=chi2/2.; return (1.-Gamma(a,x)); } ///////////////////////////////////////////////////////////////////////////