Import Geant4 0.0.0 source tree
This commit is contained in:
@@ -0,0 +1,272 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 GEANT4 collaboration.
|
||||
//
|
||||
// By copying, distributing or modifying the Program (or any work
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4ChebyshevApproximation.cc,v 2.0 1998/07/02 17:32:15 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
|
||||
#include "G4ChebyshevApproximation.hh"
|
||||
|
||||
|
||||
// Constructor for initialisation of the class data members. It creates the array
|
||||
// fChebyshevCof[0,...,fNumber-1], fNumber = n ; which consists of Chebyshev
|
||||
// coefficients describing the function pointed by pFunction. The values a and b
|
||||
// fixe the interval of validity of Chebyshev approximation.
|
||||
|
||||
|
||||
G4ChebyshevApproximation::G4ChebyshevApproximation( function pFunction,
|
||||
G4int n,
|
||||
G4double a,
|
||||
G4double b )
|
||||
{
|
||||
G4int i, j ;
|
||||
G4double rootSum, cof, cofj, weight ;
|
||||
|
||||
fFunction = pFunction ;
|
||||
fNumber = n ;
|
||||
fDiff = 0.5*(b-a) ;
|
||||
fMean = 0.5*(b+a) ;
|
||||
fChebyshevCof = new G4double[fNumber] ;
|
||||
|
||||
G4double* tempFunction = new G4double[fNumber] ;
|
||||
|
||||
weight = 2.0/fNumber ;
|
||||
cof = 0.5*weight*pi ; // pi/n
|
||||
|
||||
for (i=0;i<fNumber;i++)
|
||||
{
|
||||
rootSum = cos(cof*(i+0.5)) ;
|
||||
tempFunction[i]= fFunction(rootSum*fDiff+fMean) ;
|
||||
}
|
||||
for (j=0;j<fNumber;j++)
|
||||
{
|
||||
cofj = cof*j ;
|
||||
rootSum = 0.0 ;
|
||||
|
||||
for (i=0;i<fNumber;i++)
|
||||
{
|
||||
rootSum += tempFunction[i]*cos(cofj*(i+0.5)) ;
|
||||
}
|
||||
fChebyshevCof[j] = weight*rootSum ;
|
||||
}
|
||||
delete[] tempFunction ;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// Constructor for creation of Chebyshev coefficients for m-derivative
|
||||
// from pFunction. The value of m ! MUST BE ! < n , because the result
|
||||
// array of fChebyshevCof will be of (n-m) size. The values a and b
|
||||
// fixe the interval of validity of Chebyshev approximation.
|
||||
|
||||
|
||||
G4ChebyshevApproximation::
|
||||
G4ChebyshevApproximation( function pFunction,
|
||||
G4int n,
|
||||
G4int m,
|
||||
G4double a,
|
||||
G4double b )
|
||||
{
|
||||
if(n <= m)
|
||||
{
|
||||
G4Exception
|
||||
("Invalid arguments in G4ChebyshevApproximation::G4ChebyshevApproximation") ;
|
||||
}
|
||||
G4int i, j ;
|
||||
G4double rootSum, cof, cofj, weight ;
|
||||
|
||||
fFunction = pFunction ;
|
||||
fNumber = n ;
|
||||
fDiff = 0.5*(b-a) ;
|
||||
fMean = 0.5*(b+a) ;
|
||||
fChebyshevCof = new G4double[fNumber] ;
|
||||
|
||||
G4double* tempFunction = new G4double[fNumber] ;
|
||||
|
||||
weight = 2.0/fNumber ;
|
||||
cof = 0.5*weight*pi ; // pi/n
|
||||
|
||||
for (i=0;i<fNumber;i++)
|
||||
{
|
||||
rootSum = cos(cof*(i+0.5)) ;
|
||||
tempFunction[i] = fFunction(rootSum*fDiff+fMean) ;
|
||||
}
|
||||
for (j=0;j<fNumber;j++)
|
||||
{
|
||||
cofj = cof*j ;
|
||||
rootSum = 0.0 ;
|
||||
|
||||
for (i=0;i<fNumber;i++)
|
||||
{
|
||||
rootSum += tempFunction[i]*cos(cofj*(i+0.5)) ;
|
||||
}
|
||||
fChebyshevCof[j] = weight*rootSum ; // corresponds to pFunction
|
||||
}
|
||||
// Chebyshev coefficients for (m)-derivative of pFunction
|
||||
|
||||
for(i=1;i<=m;i++)
|
||||
{
|
||||
DerivativeChebyshevCof(tempFunction) ;
|
||||
fNumber-- ;
|
||||
for(j=0;j<fNumber;j++)
|
||||
{
|
||||
fChebyshevCof[j] = tempFunction[j] ; // corresponds to (i)-derivative
|
||||
}
|
||||
}
|
||||
delete[] tempFunction ; // delete of dynamically allocated tempFunction
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
//
|
||||
// Constructor for creation of Chebyshev coefficients for integral
|
||||
// from pFunction.
|
||||
|
||||
G4ChebyshevApproximation::G4ChebyshevApproximation( function pFunction,
|
||||
G4double a,
|
||||
G4double b,
|
||||
G4int n )
|
||||
{
|
||||
G4int i,j;
|
||||
G4double rootSum, cof, cofj, weight ;
|
||||
|
||||
fFunction = pFunction ;
|
||||
fNumber = n ;
|
||||
fDiff = 0.5*(b-a) ;
|
||||
fMean = 0.5*(b+a) ;
|
||||
fChebyshevCof = new G4double[fNumber] ;
|
||||
|
||||
G4double* tempFunction = new G4double[fNumber] ;
|
||||
|
||||
weight = 2.0/fNumber ;
|
||||
cof = 0.5*weight*pi ; // pi/n
|
||||
|
||||
for (i=0;i<fNumber;i++)
|
||||
{
|
||||
rootSum = cos(cof*(i+0.5)) ;
|
||||
tempFunction[i]= fFunction(rootSum*fDiff+fMean) ;
|
||||
}
|
||||
for (j=0;j<fNumber;j++)
|
||||
{
|
||||
cofj = cof*j ;
|
||||
rootSum = 0.0 ;
|
||||
|
||||
for (i=0;i<fNumber;i++)
|
||||
{
|
||||
rootSum += tempFunction[i]*cos(cofj*(i+0.5)) ;
|
||||
}
|
||||
fChebyshevCof[j] = weight*rootSum ; // corresponds to pFunction
|
||||
}
|
||||
// Chebyshev coefficients for integral of pFunction
|
||||
|
||||
IntegralChebyshevCof(tempFunction) ;
|
||||
for(j=0;j<fNumber;j++)
|
||||
{
|
||||
fChebyshevCof[j] = tempFunction[j] ; // corresponds to integral
|
||||
}
|
||||
delete[] tempFunction ; // delete of dynamically allocated tempFunction
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
//
|
||||
// Destructor deletes the array of Chebyshev coefficients
|
||||
|
||||
G4ChebyshevApproximation::~G4ChebyshevApproximation()
|
||||
{
|
||||
delete[] fChebyshevCof ;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
//
|
||||
// Access function for Chebyshev coefficients
|
||||
//
|
||||
|
||||
|
||||
G4double
|
||||
G4ChebyshevApproximation::GetChebyshevCof(G4int number) const
|
||||
{
|
||||
if(number < 0 && number >= fNumber)
|
||||
{
|
||||
G4Exception
|
||||
("Argument out of range in G4ChebyshevApproximation::GetChebyshevCof") ;
|
||||
}
|
||||
return fChebyshevCof[number] ;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
//
|
||||
// Evaluate the value of fFunction at the point x via the Chebyshev coefficients
|
||||
// fChebyshevCof[0,...,fNumber-1]
|
||||
|
||||
G4double
|
||||
G4ChebyshevApproximation::ChebyshevEvaluation(G4double x) const
|
||||
{
|
||||
G4int i;
|
||||
G4double evaluate = 0.0, evaluate2 = 0.0, temp, xReduced, xReduced2 ;
|
||||
|
||||
if ((x-fMean+fDiff)*(x-fMean-fDiff) > 0.0)
|
||||
{
|
||||
G4Exception("Invalid argument in G4ChebyshevApproximation::ChebyshevEvaluation");
|
||||
}
|
||||
xReduced = (x-fMean)/fDiff ;
|
||||
xReduced2 = 2.0*xReduced ;
|
||||
for (i=fNumber-1;i>=1;i--)
|
||||
{
|
||||
temp = evaluate ;
|
||||
evaluate = xReduced2*evaluate - evaluate2 + fChebyshevCof[i] ;
|
||||
evaluate2 = temp ;
|
||||
}
|
||||
return xReduced*evaluate - evaluate2 + 0.5*fChebyshevCof[0] ;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
//
|
||||
// Returns the array derCof[0,...,fNumber-2], the Chebyshev coefficients of the
|
||||
// derivative of the function whose coefficients are fChebyshevCof
|
||||
|
||||
void
|
||||
G4ChebyshevApproximation::DerivativeChebyshevCof(G4double derCof[]) const
|
||||
{
|
||||
G4int i ;
|
||||
G4double cof = 1.0/fDiff ;
|
||||
derCof[fNumber-1] = 0.0 ;
|
||||
derCof[fNumber-2] = 2*(fNumber-1)*fChebyshevCof[fNumber-1] ;
|
||||
for(i=fNumber-3;i>=0;i--)
|
||||
{
|
||||
derCof[i] = derCof[i+2] + 2*(i+1)*fChebyshevCof[i+1] ;
|
||||
}
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
derCof[i] *= cof ;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
//
|
||||
// This function produces the array integralCof[0,...,fNumber-1] , the Chebyshev
|
||||
// coefficients of the integral of the function whose coefficients are
|
||||
// fChebyshevCof[]. The constant of integration is set so that the integral
|
||||
// vanishes at the point (fMean - fDiff), i.e. at the begining of the interval of
|
||||
// validity (we start the integration from this point).
|
||||
//
|
||||
|
||||
void
|
||||
G4ChebyshevApproximation::IntegralChebyshevCof(G4double integralCof[]) const
|
||||
{
|
||||
G4int i ;
|
||||
G4double cof = 0.5*fDiff, sum = 0.0, factor = 1.0 ;
|
||||
for(i=1;i<fNumber-1;i++)
|
||||
{
|
||||
integralCof[i] = cof*(fChebyshevCof[i-1] - fChebyshevCof[i+1])/i ;
|
||||
sum += factor*integralCof[i] ;
|
||||
factor = -factor ;
|
||||
}
|
||||
integralCof[fNumber-1] = cof*fChebyshevCof[fNumber-2]/(fNumber-1) ;
|
||||
sum += factor*integralCof[fNumber-1] ;
|
||||
integralCof[0] = 2.0*sum ; // set the constant of integration
|
||||
}
|
||||
@@ -0,0 +1,481 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 GEANT4 collaboration.
|
||||
//
|
||||
// By copying, distributing or modifying the Program (or any work
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4DataInterpolation.cc,v 2.1 1998/07/12 02:58:47 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
#include "G4DataInterpolation.hh"
|
||||
|
||||
|
||||
// Constructor for initializing of fArgument, fFunction and fNumber data members
|
||||
|
||||
G4DataInterpolation::G4DataInterpolation( G4double pX[],
|
||||
G4double pY[],
|
||||
G4int number )
|
||||
{
|
||||
G4int i ;
|
||||
fNumber = number ;
|
||||
fArgument = new G4double[fNumber] ;
|
||||
fFunction = new G4double[fNumber] ;
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
fArgument[i] = pX[i] ;
|
||||
fFunction[i] = pY[i] ;
|
||||
}
|
||||
}
|
||||
|
||||
// Constructor for cubic spline interpolation. It creates the array
|
||||
// fSecondDerivative[0,...fNumber-1] which is used in this interpolation by
|
||||
// the function
|
||||
|
||||
|
||||
G4DataInterpolation::G4DataInterpolation( G4double pX[],
|
||||
G4double pY[],
|
||||
G4int number,
|
||||
G4double pFirstDerStart,
|
||||
G4double pFirstDerFinish )
|
||||
{
|
||||
G4int i, k ;
|
||||
G4double p, qn, sig, un ;
|
||||
const G4double maxDerivative = 0.99e30 ;
|
||||
fNumber = number ;
|
||||
fArgument = new G4double[fNumber] ;
|
||||
fFunction = new G4double[fNumber] ;
|
||||
fSecondDerivative = new G4double[fNumber] ;
|
||||
G4double* u = new G4double[fNumber - 1] ;
|
||||
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
fArgument[i] = pX[i] ;
|
||||
fFunction[i] = pY[i] ;
|
||||
}
|
||||
if(pFirstDerStart > maxDerivative)
|
||||
{
|
||||
fSecondDerivative[0] = 0.0 ;
|
||||
u[0] = 0.0 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fSecondDerivative[0] = -0.5 ;
|
||||
u[0] = (3.0/(fArgument[1]-fArgument[0]))*
|
||||
((fFunction[1]-fFunction[0])/(fArgument[1]-fArgument[0]) -
|
||||
pFirstDerStart) ;
|
||||
}
|
||||
|
||||
// Decomposition loop for tridiagonal algorithm. fSecondDerivative[i] and u[i]
|
||||
// are used for temporary storage of the decomposed factors.
|
||||
|
||||
for(i=1;i<fNumber-1;i++)
|
||||
{
|
||||
sig = (fArgument[i]-fArgument[i-1])/(fArgument[i+1]-fArgument[i-1]) ;
|
||||
p = sig*fSecondDerivative[i-1] + 2.0 ;
|
||||
fSecondDerivative[i] = (sig - 1.0)/p ;
|
||||
u[i] = (fFunction[i+1]-fFunction[i])/(fArgument[i+1]-fArgument[i]) -
|
||||
(fFunction[i]-fFunction[i-1])/(fArgument[i]-fArgument[i-1]) ;
|
||||
u[i] =(6.0*u[i]/(fArgument[i+1]-fArgument[i-1]) - sig*u[i-1])/p ;
|
||||
}
|
||||
if(pFirstDerFinish > maxDerivative)
|
||||
{
|
||||
qn = 0.0 ;
|
||||
un = 0.0 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
qn = 0.5 ;
|
||||
un =(3.0/(fArgument[fNumber-1]-fArgument[fNumber-2]))*(pFirstDerFinish -
|
||||
(fFunction[fNumber-1]-fFunction[fNumber-2])/
|
||||
(fArgument[fNumber-1]-fArgument[fNumber-2])) ;
|
||||
}
|
||||
fSecondDerivative[fNumber-1] = (un - qn*u[fNumber-2])/
|
||||
(qn*fSecondDerivative[fNumber-2] + 1.0) ;
|
||||
|
||||
// The backsubstitution loop for the triagonal algorithm of solving a linear
|
||||
// system of equations.
|
||||
|
||||
for(k=fNumber-2;k>=0;k--)
|
||||
{
|
||||
fSecondDerivative[k] = fSecondDerivative[k]*fSecondDerivative[k+1] + u[k] ;
|
||||
}
|
||||
delete[] u ;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Destructor deletes dynamically created arrays for data members: fArgument,
|
||||
// fFunction and fSecondDerivative, all have dimension of fNumber
|
||||
|
||||
G4DataInterpolation::~G4DataInterpolation()
|
||||
{
|
||||
delete[] fArgument ;
|
||||
delete[] fFunction ;
|
||||
if(fSecondDerivative) delete[] fSecondDerivative ;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
//
|
||||
// This function returns the value P(pX), where P(x) is polynom of fNumber-1 degree
|
||||
// such that P(fArgument[i]) = fFunction[i], for i = 0, ..., fNumber-1 . This is
|
||||
// Lagrange's form of interpolation and it is based on Neville's algorithm
|
||||
|
||||
G4double
|
||||
G4DataInterpolation::PolynomInterpolation(G4double pX,
|
||||
G4double& deltaY ) const
|
||||
{
|
||||
G4int i, m, k = 0 ;
|
||||
G4double mult, diff, difi, deltaLow, deltaUp, cd, y ;
|
||||
G4double* c = new G4double[fNumber] ;
|
||||
G4double* d = new G4double[fNumber] ;
|
||||
diff = fabs(pX-fArgument[0]) ;
|
||||
for(i=1;i<fNumber;i++)
|
||||
{
|
||||
difi = fabs(pX-fArgument[i]) ;
|
||||
if(difi <diff)
|
||||
{
|
||||
k = i ;
|
||||
diff = difi ;
|
||||
}
|
||||
c[i] = fFunction[i] ;
|
||||
d[i] = fFunction[i] ;
|
||||
}
|
||||
y = fFunction[k--] ;
|
||||
for(m=1;m<fNumber;m++)
|
||||
{
|
||||
for(i=0;i<fNumber-m;i++)
|
||||
{
|
||||
deltaLow = fArgument[i] - pX ;
|
||||
deltaUp = fArgument[i+m] - pX ;
|
||||
cd = c[i+1] - d[i] ;
|
||||
mult = deltaLow - deltaUp ;
|
||||
if(mult == 0.0)
|
||||
{
|
||||
G4Exception
|
||||
("Coincident nodes in G4DataInterpolation::PolynomInterpolation") ;
|
||||
}
|
||||
mult = cd/mult ;
|
||||
d[i] = deltaUp*mult ;
|
||||
c[i] = deltaLow*mult ;
|
||||
}
|
||||
y += (deltaY = (2*k < (fNumber - m -1) ? c[k+1] : d[k--] )) ;
|
||||
}
|
||||
delete[] c ;
|
||||
delete[] d ;
|
||||
|
||||
return y ;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
//
|
||||
// Given arrays fArgument[0,..,fNumber-1] and fFunction[0,..,fNumber-1] , this
|
||||
// function calculates an array of coefficients. The coefficients don't provide
|
||||
// usually (fNumber>10) better accuracy for polynom interpolation, as compared with
|
||||
// PolynomInterpolation function. They could be used instead for derivate
|
||||
// calculations and some other applications.
|
||||
|
||||
void
|
||||
G4DataInterpolation::PolIntCoefficient( G4double cof[]) const
|
||||
{
|
||||
G4int i, j ;
|
||||
G4double factor, reducedY, mult ;
|
||||
G4double* tempArgument = new G4double[fNumber] ;
|
||||
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
tempArgument[i] = cof[i] = 0.0 ;
|
||||
}
|
||||
tempArgument[fNumber-1] = -fArgument[0] ;
|
||||
|
||||
for(i=1;i<fNumber;i++)
|
||||
{
|
||||
for(j=fNumber-1-i;j<fNumber-1;j++)
|
||||
{
|
||||
tempArgument[j] -= fArgument[i]*tempArgument[j+1] ;
|
||||
}
|
||||
tempArgument[fNumber-1] -= fArgument[i] ;
|
||||
}
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
factor = fNumber ;
|
||||
for(j=fNumber-1;j>=1;j--)
|
||||
{
|
||||
factor = j*tempArgument[j] + factor*fArgument[i] ;
|
||||
}
|
||||
reducedY = fFunction[i]/factor ;
|
||||
mult = 1.0 ;
|
||||
for(j=fNumber-1;j>=0;j--)
|
||||
{
|
||||
cof[j] += mult*reducedY ;
|
||||
mult = tempArgument[j] + mult*fArgument[i] ;
|
||||
}
|
||||
}
|
||||
delete[] tempArgument ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// The function returns diagonal rational function (Bulirsch and Stoer algorithm
|
||||
// of Neville type) Pn(x)/Qm(x) where P and Q are polynoms.
|
||||
// Tests showed the method is not stable and hasn't advantage if compared with
|
||||
// polynomial interpolation ?!
|
||||
|
||||
|
||||
G4double
|
||||
G4DataInterpolation::RationalPolInterpolation(G4double pX,
|
||||
G4double& deltaY ) const
|
||||
{
|
||||
G4int i, m, k = 0 ;
|
||||
const G4double tolerance = 1.6e-24 ;
|
||||
G4double mult, difi, diff, cd, y, cof ;
|
||||
G4double* c = new G4double[fNumber] ;
|
||||
G4double* d = new G4double[fNumber] ;
|
||||
diff = fabs(pX-fArgument[0]) ;
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
difi = fabs(pX-fArgument[i]) ;
|
||||
if(difi == 0.0)
|
||||
{
|
||||
y = fFunction[i] ;
|
||||
deltaY = 0.0 ;
|
||||
delete[] c ;
|
||||
delete[] d ;
|
||||
return y ;
|
||||
}
|
||||
else if(difi < diff)
|
||||
{
|
||||
k = i ;
|
||||
diff = difi ;
|
||||
}
|
||||
c[i] = fFunction[i] ;
|
||||
d[i] = fFunction[i] + tolerance ; // to prevent rare zero/zero cases
|
||||
}
|
||||
y = fFunction[k--] ;
|
||||
for(m=1;m<fNumber;m++)
|
||||
{
|
||||
for(i=0;i<fNumber-m;i++)
|
||||
{
|
||||
cd = c[i+1] - d[i] ;
|
||||
difi = fArgument[i+m] - pX ;
|
||||
cof = (fArgument[i] - pX)*d[i]/difi ;
|
||||
mult = cof - c[i+1] ;
|
||||
if(mult == 0.0) // function to be interpolated has pole at pX
|
||||
{
|
||||
G4Exception("Error in G4DataInterpolation::RationalPolInterpolation") ;
|
||||
}
|
||||
mult = cd/mult ;
|
||||
d[i] = c[i+1]*mult ;
|
||||
c[i] = cof*mult ;
|
||||
}
|
||||
y += (deltaY = (2*k < (fNumber - m - 1) ? c[k+1] : d[k--] )) ;
|
||||
}
|
||||
delete[] c ;
|
||||
delete[] d ;
|
||||
|
||||
return y ;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// Cubic spline interpolation in point pX for function given by the table:
|
||||
// fArgument, fFunction. The constructor, which creates fSecondDerivative, must be
|
||||
// called before. The function works optimal, if sequential calls are in random
|
||||
// values of pX.
|
||||
|
||||
G4double
|
||||
G4DataInterpolation::CubicSplineInterpolation(G4double pX) const
|
||||
{
|
||||
G4int kLow, kHigh, k ;
|
||||
G4double deltaHL, a, b ;
|
||||
|
||||
// Searching in the table by means of bisection method.
|
||||
// fArgument must be monotonic, either increasing or decreasing
|
||||
|
||||
kLow = 0 ;
|
||||
kHigh = fNumber - 1 ;
|
||||
while((kHigh - kLow) > 1)
|
||||
{
|
||||
k = (kHigh + kLow) >> 1 ; // compute midpoint 'bisection'
|
||||
if(fArgument[k] > pX)
|
||||
{
|
||||
kHigh = k ;
|
||||
}
|
||||
else
|
||||
{
|
||||
kLow = k ;
|
||||
}
|
||||
} // kLow and kHigh now bracket the input value of pX
|
||||
deltaHL = fArgument[kHigh] - fArgument[kLow] ;
|
||||
if(deltaHL == 0.0)
|
||||
{
|
||||
G4Exception(
|
||||
"Bad fArgument input in G4DataInterpolation::CubicSplineInterpolation") ;
|
||||
}
|
||||
a = (fArgument[kHigh] - pX)/deltaHL ;
|
||||
b = (pX - fArgument[kLow])/deltaHL ;
|
||||
|
||||
// Final evaluation of cubic spline polynomial for return
|
||||
|
||||
return a*fFunction[kLow] + b*fFunction[kHigh] +
|
||||
((a*a*a - a)*fSecondDerivative[kLow] +
|
||||
(b*b*b - b)*fSecondDerivative[kHigh])*deltaHL*deltaHL/6.0 ;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Return cubic spline interpolation in the point pX which is located between
|
||||
// fArgument[index] and fArgument[index+1]. It is usually called in sequence of
|
||||
// known from external analysis values of index.
|
||||
|
||||
|
||||
G4double
|
||||
G4DataInterpolation::FastCubicSpline(G4double pX,
|
||||
G4int index) const
|
||||
{
|
||||
G4double delta, a, b ;
|
||||
delta = fArgument[index+1] - fArgument[index] ;
|
||||
if(delta == 0.0)
|
||||
{
|
||||
G4Exception("Bad fArgument input in G4DataInterpolation::FastCubicSpline") ;
|
||||
}
|
||||
a = (fArgument[index+1] - pX)/delta ;
|
||||
b = (pX - fArgument[index])/delta ;
|
||||
|
||||
// Final evaluation of cubic spline polynomial for return
|
||||
|
||||
return a*fFunction[index] + b*fFunction[index+1] +
|
||||
((a*a*a - a)*fSecondDerivative[index] +
|
||||
(b*b*b - b)*fSecondDerivative[index+1])*delta*delta/6.0 ;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// Given argument pX, returns index k, so that pX bracketed by fArgument[k] and
|
||||
// fArgument[k+1]
|
||||
|
||||
G4int
|
||||
G4DataInterpolation::LocateArgument(G4double pX) const
|
||||
{
|
||||
G4int kLow, kHigh, k ;
|
||||
G4bool ascend ;
|
||||
kLow = -1 ;
|
||||
kHigh = fNumber ;
|
||||
ascend = (fArgument[fNumber-1] >= fArgument[0]) ;
|
||||
while((kHigh - kLow) > 1)
|
||||
{
|
||||
k = (kHigh + kLow) >> 1 ; // compute midpoint 'bisection'
|
||||
if(pX >= fArgument[k] == ascend)
|
||||
{
|
||||
kLow = k ;
|
||||
}
|
||||
else
|
||||
{
|
||||
kHigh = k ;
|
||||
}
|
||||
}
|
||||
if(pX == fArgument[0])
|
||||
{
|
||||
return 1 ;
|
||||
}
|
||||
else if(pX == fArgument[fNumber-1])
|
||||
{
|
||||
return fNumber - 2 ;
|
||||
}
|
||||
else return kLow ;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
//
|
||||
// Given a value pX, returns a value 'index' such that pX is between fArgument[index]
|
||||
// and fArgument[index+1]. fArgument MUST BE MONOTONIC, either increasing or
|
||||
// decreasing. If index = -1 or fNumber, this indicates that pX is out of range.
|
||||
// The value index on input is taken as the initial approximation for index on
|
||||
// output.
|
||||
|
||||
|
||||
void
|
||||
G4DataInterpolation::CorrelatedSearch( G4double pX,
|
||||
G4int& index ) const
|
||||
{
|
||||
G4int kHigh, k, Increment ;
|
||||
// ascend = true for ascending order of table, false otherwise
|
||||
G4bool ascend = (fArgument[fNumber-1] >= fArgument[0]) ;
|
||||
if(index < 0 || index > fNumber-1)
|
||||
{
|
||||
index = -1 ;
|
||||
kHigh = fNumber ;
|
||||
}
|
||||
else
|
||||
{
|
||||
Increment = 1 ; // What value would be the best ?
|
||||
if((pX >= fArgument[index]) == ascend)
|
||||
{
|
||||
if(index == fNumber -1)
|
||||
{
|
||||
index = fNumber ;
|
||||
return ;
|
||||
}
|
||||
kHigh = index + 1 ;
|
||||
while((pX >= fArgument[kHigh]) == ascend)
|
||||
{
|
||||
index = kHigh ;
|
||||
Increment += Increment ; // double the Increment
|
||||
kHigh = index + Increment ;
|
||||
if(kHigh > (fNumber - 1))
|
||||
{
|
||||
kHigh = fNumber ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(index == 0)
|
||||
{
|
||||
index = -1 ;
|
||||
return ;
|
||||
}
|
||||
kHigh = index-- ;
|
||||
while((pX < fArgument[index]) == ascend)
|
||||
{
|
||||
kHigh = index ;
|
||||
Increment <<= 1 ; // double the Increment
|
||||
if(Increment >= kHigh)
|
||||
{
|
||||
index = -1 ;
|
||||
break ;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = kHigh - Increment ;
|
||||
}
|
||||
}
|
||||
} // Value bracketed
|
||||
}
|
||||
// final bisection searching
|
||||
|
||||
while((kHigh - index) != 1)
|
||||
{
|
||||
k = (kHigh + index) >> 1 ;
|
||||
if((pX >= fArgument[k]) == ascend)
|
||||
{
|
||||
index = k ;
|
||||
}
|
||||
else
|
||||
{
|
||||
kHigh = k ;
|
||||
}
|
||||
}
|
||||
if(pX == fArgument[fNumber-1])
|
||||
{
|
||||
index = fNumber - 2 ;
|
||||
}
|
||||
if(pX == fArgument[0])
|
||||
{
|
||||
index = 0 ;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 GEANT4 collaboration.
|
||||
//
|
||||
// By copying, distributing or modifying the Program (or any work
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4GaussChebyshevQ.cc,v 2.0 1998/07/02 17:32:01 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
#include "G4GaussChebyshevQ.hh"
|
||||
|
||||
// -----------------------------------------------------
|
||||
//
|
||||
// Constructor for Gauss-Chebyshev quadrature method
|
||||
|
||||
G4GaussChebyshevQ::G4GaussChebyshevQ( function pFunction ,
|
||||
G4int nChebyshev )
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
{
|
||||
G4int i ;
|
||||
fNumber = nChebyshev ; // Try to reduce fNumber twice ??
|
||||
G4double cof = pi/fNumber ;
|
||||
fAbscissa = new G4double[fNumber] ;
|
||||
fWeight = new G4double[fNumber] ;
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
fAbscissa[i] = cos(cof*(i + 0.5)) ;
|
||||
fWeight[i] = cof*sqrt(1 - fAbscissa[i]*fAbscissa[i]) ;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
|
||||
G4GaussChebyshevQ::~G4GaussChebyshevQ()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
//
|
||||
// Integrates function pointed by fFunction from a to b by Gauss-Chebyshev
|
||||
// quadrature method
|
||||
|
||||
G4double
|
||||
G4GaussChebyshevQ::Integral(G4double a, G4double b) const
|
||||
{
|
||||
G4int i ;
|
||||
G4double xDiff, xMean, dx, integral = 0.0 ;
|
||||
|
||||
xMean = 0.5*(a + b) ;
|
||||
xDiff = 0.5*(b - a) ;
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
dx = xDiff*fAbscissa[i] ;
|
||||
integral += fWeight[i]*fFunction(xMean + dx) ;
|
||||
}
|
||||
return integral *= xDiff ;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 GEANT4 collaboration.
|
||||
//
|
||||
// By copying, distributing or modifying the Program (or any work
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4GaussHermiteQ.cc,v 2.0 1998/07/02 17:32:03 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
#include "G4GaussHermiteQ.hh"
|
||||
|
||||
|
||||
// ----------------------------------------------------------
|
||||
//
|
||||
// Constructor for Gauss-Hermite
|
||||
|
||||
G4GaussHermiteQ::G4GaussHermiteQ( function pFunction,
|
||||
G4int nHermite )
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
{
|
||||
const G4double tolerance = 1.0e-12 ;
|
||||
const G4int maxNumber = 12 ;
|
||||
|
||||
G4int i, j, k ;
|
||||
G4double newton, newton1, temp1, temp2, temp3, temp ;
|
||||
G4double piInMinusQ = pow(pi,-0.25) ; // 1.0/sqrt(sqrt(pi)) ??
|
||||
|
||||
fNumber = (nHermite +1)/2 ;
|
||||
fAbscissa = new G4double[fNumber] ;
|
||||
fWeight = new G4double[fNumber] ;
|
||||
|
||||
for(i=1;i<=fNumber;i++)
|
||||
{
|
||||
if(i == 1)
|
||||
{
|
||||
newton = sqrt((G4double)(2*nHermite + 1)) -
|
||||
1.85575001*pow((G4double)(2*nHermite + 1),-0.16666999) ;
|
||||
}
|
||||
else if(i == 2)
|
||||
{
|
||||
newton -= 1.14001*pow((G4double)nHermite,0.425999)/newton ;
|
||||
}
|
||||
else if(i == 3)
|
||||
{
|
||||
newton = 1.86002*newton - 0.86002*fAbscissa[0] ;
|
||||
}
|
||||
else if(i == 4)
|
||||
{
|
||||
newton = 1.91001*newton - 0.91001*fAbscissa[1] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
newton = 2.0*newton - fAbscissa[i - 3] ;
|
||||
}
|
||||
for(k=1;k<=maxNumber;k++)
|
||||
{
|
||||
temp1 = piInMinusQ ;
|
||||
temp2 = 0.0 ;
|
||||
for(j=1;j<=nHermite;j++)
|
||||
{
|
||||
temp3 = temp2 ;
|
||||
temp2 = temp1 ;
|
||||
temp1 = newton*sqrt(2.0/j)*temp2 - sqrt(((G4double)(j - 1))/j)*temp3 ;
|
||||
}
|
||||
temp = sqrt((G4double)2*nHermite)*temp2 ;
|
||||
newton1 = newton ;
|
||||
newton = newton1 - temp1/temp ;
|
||||
if(fabs(newton - newton1) <= tolerance)
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if(k > maxNumber)
|
||||
{
|
||||
G4Exception("Too many iterations in Gauss-Hermite constructor") ;
|
||||
}
|
||||
fAbscissa[i-1] = newton ;
|
||||
fWeight[i-1] = 2.0/(temp*temp) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------
|
||||
//
|
||||
// Gauss-Hermite method for integration of exp(-x*x)*nFunction(x) from minus infinity
|
||||
// to plus infinity .
|
||||
|
||||
G4double
|
||||
G4GaussHermiteQ::Integral() const
|
||||
{
|
||||
G4int i ;
|
||||
G4double integral = 0.0 ;
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
integral += fWeight[i]*(fFunction(fAbscissa[i]) + fFunction(-fAbscissa[i])) ;
|
||||
}
|
||||
return integral ;
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 GEANT4 collaboration.
|
||||
//
|
||||
// By copying, distributing or modifying the Program (or any work
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4GaussJacobiQ.cc,v 2.0 1998/07/02 17:32:05 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
#include "G4GaussJacobiQ.hh"
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
//
|
||||
// Constructor for Gauss-Jacobi integration method.
|
||||
//
|
||||
|
||||
G4GaussJacobiQ::G4GaussJacobiQ( function pFunction,
|
||||
G4double alpha,
|
||||
G4double beta,
|
||||
G4int nJacobi )
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
|
||||
{
|
||||
const G4double tolerance = 1.0e-12 ;
|
||||
const G4double maxNumber = 12 ;
|
||||
G4int i, k, j ;
|
||||
G4double alphaBeta, alphaReduced, betaReduced, root1, root2, root3 ;
|
||||
G4double a, b, c, newton1, newton2, newton3, newton, temp, root, rootTemp ;
|
||||
|
||||
fNumber = nJacobi ;
|
||||
fAbscissa = new G4double[fNumber] ;
|
||||
fWeight = new G4double[fNumber] ;
|
||||
|
||||
for (i=1;i<=nJacobi;i++)
|
||||
{
|
||||
if (i == 1)
|
||||
{
|
||||
alphaReduced = alpha/nJacobi ;
|
||||
betaReduced = beta/nJacobi ;
|
||||
root1 = (1.0+alpha)*(2.78002/(4.0+nJacobi*nJacobi)+
|
||||
0.767999*alphaReduced/nJacobi) ;
|
||||
root2 = 1.0+1.48*alphaReduced+0.96002*betaReduced +
|
||||
0.451998*alphaReduced*alphaReduced+0.83001*alphaReduced*betaReduced ;
|
||||
root = 1.0-root1/root2 ;
|
||||
}
|
||||
else if (i == 2)
|
||||
{
|
||||
root1=(4.1002+alpha)/((1.0+alpha)*(1.0+0.155998*alpha)) ;
|
||||
root2=1.0+0.06*(nJacobi-8.0)*(1.0+0.12*alpha)/nJacobi ;
|
||||
root3=1.0+0.012002*beta*(1.0+0.24997*fabs(alpha))/nJacobi ;
|
||||
root -= (1.0-root)*root1*root2*root3 ;
|
||||
}
|
||||
else if (i == 3)
|
||||
{
|
||||
root1=(1.67001+0.27998*alpha)/(1.0+0.37002*alpha) ;
|
||||
root2=1.0+0.22*(nJacobi-8.0)/nJacobi ;
|
||||
root3=1.0+8.0*beta/((6.28001+beta)*nJacobi*nJacobi) ;
|
||||
root -= (fAbscissa[0]-root)*root1*root2*root3 ;
|
||||
}
|
||||
else if (i == nJacobi-1)
|
||||
{
|
||||
root1=(1.0+0.235002*beta)/(0.766001+0.118998*beta) ;
|
||||
root2=1.0/(1.0+0.639002*(nJacobi-4.0)/(1.0+0.71001*(nJacobi-4.0))) ;
|
||||
root3=1.0/(1.0+20.0*alpha/((7.5+alpha)*nJacobi*nJacobi)) ;
|
||||
root += (root-fAbscissa[nJacobi-4])*root1*root2*root3 ;
|
||||
}
|
||||
else if (i == nJacobi)
|
||||
{
|
||||
root1 = (1.0+0.37002*beta)/(1.67001+0.27998*beta) ;
|
||||
root2 = 1.0/(1.0+0.22*(nJacobi-8.0)/nJacobi) ;
|
||||
root3 = 1.0/(1.0+8.0*alpha/((6.28002+alpha)*nJacobi*nJacobi)) ;
|
||||
root += (root-fAbscissa[nJacobi-3])*root1*root2*root3 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
root = 3.0*fAbscissa[i-2]-3.0*fAbscissa[i-3]+fAbscissa[i-4] ;
|
||||
}
|
||||
alphaBeta = alpha + beta ;
|
||||
for (k=1;k<=maxNumber;k++)
|
||||
{
|
||||
temp = 2.0 + alphaBeta ;
|
||||
newton1 = (alpha-beta+temp*root)/2.0 ;
|
||||
newton2 = 1.0 ;
|
||||
for (j=2;j<=nJacobi;j++)
|
||||
{
|
||||
newton3 = newton2 ;
|
||||
newton2 = newton1 ;
|
||||
temp = 2*j+alphaBeta ;
|
||||
a = 2*j*(j+alphaBeta)*(temp-2.0) ;
|
||||
b = (temp-1.0)*(alpha*alpha-beta*beta+temp*(temp-2.0)*root) ;
|
||||
c = 2.0*(j-1+alpha)*(j-1+beta)*temp ;
|
||||
newton1 = (b*newton2-c*newton3)/a ;
|
||||
}
|
||||
newton = (nJacobi*(alpha - beta - temp*root)*newton1 +
|
||||
2.0*(nJacobi + alpha)*(nJacobi + beta)*newton2)/
|
||||
(temp*(1.0 - root*root)) ;
|
||||
rootTemp = root ;
|
||||
root = rootTemp - newton1/newton ;
|
||||
if (fabs(root-rootTemp) <= tolerance)
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if (k > maxNumber)
|
||||
{
|
||||
G4Exception("Too many iterations in G4GaussJacobiQ::G4GaussJacobiQ") ;
|
||||
}
|
||||
fAbscissa[i-1] = root ;
|
||||
fWeight[i-1] = exp(GammaLogarithm((G4double)(alpha+nJacobi)) +
|
||||
GammaLogarithm((G4double)(beta+nJacobi)) -
|
||||
GammaLogarithm((G4double)(nJacobi+1.0)) -
|
||||
GammaLogarithm((G4double)(nJacobi + alphaBeta + 1.0)))
|
||||
*temp*pow(2.0,alphaBeta)/(newton*newton2) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------
|
||||
//
|
||||
// Gauss-Jacobi method for integration of ((1-x)^alpha)*((1+x)^beta)*pFunction(x)
|
||||
// from minus unit to plus unit .
|
||||
|
||||
|
||||
G4double
|
||||
G4GaussJacobiQ::Integral() const
|
||||
{
|
||||
G4int i ;
|
||||
G4double integral = 0.0 ;
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
integral += fWeight[i]*fFunction(fAbscissa[i]) ;
|
||||
}
|
||||
return integral ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 GEANT4 collaboration.
|
||||
//
|
||||
// By copying, distributing or modifying the Program (or any work
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4GaussLaguerreQ.cc,v 2.0 1998/07/02 17:32:06 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
#include "G4GaussLaguerreQ.hh"
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
//
|
||||
// Constructor for Gauss-Laguerre quadrature method: integral from zero to
|
||||
// infinity of pow(x,alpha)*exp(-x)*f(x). The value of nLaguerre sets the accuracy.
|
||||
// The constructor creates arrays fAbscissa[0,..,nLaguerre-1] and
|
||||
// fWeight[0,..,nLaguerre-1] .
|
||||
//
|
||||
|
||||
G4GaussLaguerreQ::G4GaussLaguerreQ( function pFunction,
|
||||
G4double alpha,
|
||||
G4int nLaguerre )
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
{
|
||||
const G4double tolerance = 1.0e-10 ;
|
||||
const G4int maxNumber = 12 ;
|
||||
G4int i, j, k ;
|
||||
G4double newton, newton1, temp1, temp2, temp3, temp, cofi ;
|
||||
|
||||
fNumber = nLaguerre ;
|
||||
fAbscissa = new G4double[fNumber] ;
|
||||
fWeight = new G4double[fNumber] ;
|
||||
|
||||
for(i=1;i<=fNumber;i++) // Loop over the desired roots
|
||||
{
|
||||
if(i == 1)
|
||||
{
|
||||
newton = (1.0 + alpha)*(3.0 + 0.92*alpha)/(1.0 + 2.4*fNumber + 1.8*alpha) ;
|
||||
}
|
||||
else if(i == 2)
|
||||
{
|
||||
newton += (15.0 + 6.25*alpha)/(1.0 + 0.9*alpha + 2.5*fNumber) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
cofi = i - 2 ;
|
||||
newton += ((1.0+2.55*cofi)/(1.9*cofi) + 1.26*cofi*alpha/(1.0+3.5*cofi))*
|
||||
(newton - fAbscissa[i-3])/(1.0 + 0.3*alpha) ;
|
||||
}
|
||||
for(k=1;k<=maxNumber;k++)
|
||||
{
|
||||
temp1 = 1.0 ;
|
||||
temp2 = 0.0 ;
|
||||
for(j=1;j<=fNumber;j++)
|
||||
{
|
||||
temp3 = temp2 ;
|
||||
temp2 = temp1 ;
|
||||
temp1 = ((2*j - 1 + alpha - newton)*temp2 - (j - 1 + alpha)*temp3)/j ;
|
||||
}
|
||||
temp = (fNumber*temp1 - (fNumber +alpha)*temp2)/newton ;
|
||||
newton1 = newton ;
|
||||
newton = newton1 - temp1/temp ;
|
||||
if(fabs(newton - newton1) <= tolerance)
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if(k > maxNumber)
|
||||
{
|
||||
G4Exception("Too many iterations in Gauss-Laguerre constructor") ;
|
||||
}
|
||||
|
||||
fAbscissa[i-1] = newton ;
|
||||
fWeight[i-1] = -exp(GammaLogarithm(alpha + fNumber) -
|
||||
GammaLogarithm((G4double)fNumber))/(temp*fNumber*temp2) ;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
//
|
||||
// Gauss-Laguerre method for integration of pow(x,alpha)*exp(-x)*pFunction(x)
|
||||
// from zero up to infinity. pFunction is evaluated in fNumber points for which
|
||||
// fAbscissa[i] and fWeight[i] arrays were created in
|
||||
// G4VGaussianQuadrature(double,int) constructor
|
||||
|
||||
G4double
|
||||
G4GaussLaguerreQ::Integral() const
|
||||
{
|
||||
G4int i ;
|
||||
G4double integral = 0.0 ;
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
integral += fWeight[i]*fFunction(fAbscissa[i]) ;
|
||||
}
|
||||
return integral ;
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 GEANT4 collaboration.
|
||||
//
|
||||
// By copying, distributing or modifying the Program (or any work
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4GaussLegendreQ.cc,v 2.1 1998/07/12 02:58:48 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
#include "G4GaussLegendreQ.hh"
|
||||
|
||||
|
||||
G4GaussLegendreQ::G4GaussLegendreQ( function pFunction )
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Constructor for GaussLegendre quadrature method. The value nLegendre set the
|
||||
// accuracy required, i.e the number of points where the function pFunction will
|
||||
// be evaluated during integration. The constructor creates the arrays for
|
||||
// abscissas and weights that used in Gauss-Legendre quadrature method.
|
||||
// The values a and b are the limits of integration of the pFunction.
|
||||
// nLegendre MUST BE EVEN !!!
|
||||
|
||||
G4GaussLegendreQ::G4GaussLegendreQ( function pFunction,
|
||||
G4int nLegendre )
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
{
|
||||
const G4double tolerance = 1.6e-10 ;
|
||||
G4int i, j, k = nLegendre ;
|
||||
fNumber = (nLegendre + 1)/2 ;
|
||||
if(2*fNumber != k)
|
||||
{
|
||||
G4Exception("Invalid nLegendre in G4GaussLegendreQ::G4GaussLegendreQ") ;
|
||||
}
|
||||
G4double newton, newton1, temp1, temp2, temp3, temp ;
|
||||
|
||||
fAbscissa = new G4double[fNumber] ;
|
||||
fWeight = new G4double[fNumber] ;
|
||||
|
||||
for(i=1;i<=fNumber;i++) // Loop over the desired roots
|
||||
{
|
||||
newton = cos(pi*(i - 0.25)/(k + 0.5)) ; // Initial root approximation
|
||||
do
|
||||
{ // loop of Newton's method
|
||||
temp1 = 1.0 ;
|
||||
temp2 = 0.0 ;
|
||||
for(j=1;j<=k;j++)
|
||||
{
|
||||
temp3 = temp2 ;
|
||||
temp2 = temp1 ;
|
||||
temp1 = ((2.0*j - 1.0)*newton*temp2 - (j - 1.0)*temp3)/j ;
|
||||
}
|
||||
temp = k*(newton*temp1 - temp2)/(newton*newton - 1.0) ;
|
||||
newton1 = newton ;
|
||||
newton = newton1 - temp1/temp ; // Newton's method
|
||||
}
|
||||
while(fabs(newton - newton1) > tolerance) ;
|
||||
|
||||
fAbscissa[fNumber-i] = newton ;
|
||||
fWeight[fNumber-i] = 2.0/((1.0 - newton*newton)*temp*temp) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
//
|
||||
// Returns the integral of the function to be pointed by fFunction between a and b,
|
||||
// by 2*fNumber point Gauss-Legendre integration: the function is evaluated exactly
|
||||
// 2*fNumber Times at interior points in the range of integration. Since the weights
|
||||
// and abscissas are, in this case, symmetric around the midpoint of the range of
|
||||
// integration, there are actually only fNumber distinct values of each.
|
||||
|
||||
G4double
|
||||
G4GaussLegendreQ::Integral(G4double a, G4double b) const
|
||||
{
|
||||
G4int i ;
|
||||
G4double xDiff, xMean, dx, integral ;
|
||||
|
||||
xMean = 0.5*(a + b) ;
|
||||
xDiff = 0.5*(b - a) ;
|
||||
integral = 0.0 ;
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
dx = xDiff*fAbscissa[i] ;
|
||||
integral += fWeight[i]*(fFunction(xMean + dx) + fFunction(xMean - dx)) ;
|
||||
}
|
||||
return integral *= xDiff ;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
//
|
||||
// Returns the integral of the function to be pointed by fFunction between a and b,
|
||||
// by ten point Gauss-Legendre integration: the function is evaluated exactly
|
||||
// ten Times at interior points in the range of integration. Since the weights
|
||||
// and abscissas are, in this case, symmetric around the midpoint of the range of
|
||||
// integration, there are actually only five distinct values of each
|
||||
|
||||
G4double
|
||||
G4GaussLegendreQ::QuickIntegral(G4double a, G4double b) const
|
||||
{
|
||||
G4int i ;
|
||||
G4double xDiff, xMean, dx, integral ;
|
||||
|
||||
// From Abramowitz M., Stegan I.A. 1964 , Handbook of Math... , p. 916
|
||||
|
||||
static G4double abscissa[] = { 0.148874338981631, 0.433395394129247,
|
||||
0.679409568299024, 0.865063366688985,
|
||||
0.973906528517172 } ;
|
||||
|
||||
static G4double weight[] = { 0.295524224714753, 0.269266719309996,
|
||||
0.219086362515982, 0.149451349150581,
|
||||
0.066671344308688 } ;
|
||||
xMean = 0.5*(a + b) ;
|
||||
xDiff = 0.5*(b - a) ;
|
||||
integral = 0.0 ;
|
||||
for(i=0;i<5;i++)
|
||||
{
|
||||
dx = xDiff*abscissa[i] ;
|
||||
integral += weight[i]*(fFunction(xMean + dx) + fFunction(xMean - dx)) ;
|
||||
}
|
||||
return integral *= xDiff ;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
//
|
||||
// Returns the integral of the function to be pointed by fFunction between a and b,
|
||||
// by 96 point Gauss-Legendre integration: the function is evaluated exactly
|
||||
// ten Times at interior points in the range of integration. Since the weights
|
||||
// and abscissas are, in this case, symmetric around the midpoint of the range of
|
||||
// integration, there are actually only five distinct values of each
|
||||
|
||||
G4double
|
||||
G4GaussLegendreQ::AccurateIntegral(G4double a, G4double b) const
|
||||
{
|
||||
G4int i ;
|
||||
G4double xDiff, xMean, dx, integral ;
|
||||
|
||||
// From Abramowitz M., Stegan I.A. 1964 , Handbook of Math... , p. 919
|
||||
|
||||
static
|
||||
G4double abscissa[] = {
|
||||
0.016276744849602969579, 0.048812985136049731112,
|
||||
0.081297495464425558994, 0.113695850110665920911,
|
||||
0.145973714654896941989, 0.178096882367618602759, // 6
|
||||
|
||||
0.210031310460567203603, 0.241743156163840012328,
|
||||
0.273198812591049141487, 0.304364944354496353024,
|
||||
0.335208522892625422616, 0.365696861472313635031, // 12
|
||||
|
||||
0.395797649828908603285, 0.425478988407300545365,
|
||||
0.454709422167743008636, 0.483457973920596359768,
|
||||
0.511694177154667673586, 0.539388108324357436227, // 18
|
||||
|
||||
0.566510418561397168404, 0.593032364777572080684,
|
||||
0.618925840125468570386, 0.644163403784967106798,
|
||||
0.668718310043916153953, 0.692564536642171561344, // 24
|
||||
|
||||
0.715676812348967626225, 0.738030643744400132851,
|
||||
0.759602341176647498703, 0.780369043867433217604,
|
||||
0.800308744139140817229, 0.819400310737931675539, // 30
|
||||
|
||||
0.837623511228187121494, 0.854959033434601455463,
|
||||
0.871388505909296502874, 0.886894517402420416057,
|
||||
0.901460635315852341319, 0.915071423120898074206, // 36
|
||||
|
||||
0.927712456722308690965, 0.939370339752755216932,
|
||||
0.950032717784437635756, 0.959688291448742539300,
|
||||
0.968326828463264212174, 0.975939174585136466453, // 42
|
||||
|
||||
0.982517263563014677447, 0.988054126329623799481,
|
||||
0.992543900323762624572, 0.995981842987209290650,
|
||||
0.998364375863181677724, 0.999689503883230766828 // 48
|
||||
} ;
|
||||
|
||||
static
|
||||
G4double weight[] = {
|
||||
0.032550614492363166242, 0.032516118713868835987,
|
||||
0.032447163714064269364, 0.032343822568575928429,
|
||||
0.032206204794030250669, 0.032034456231992663218, // 6
|
||||
|
||||
0.031828758894411006535, 0.031589330770727168558,
|
||||
0.031316425596862355813, 0.031010332586313837423,
|
||||
0.030671376123669149014, 0.030299915420827593794, // 12
|
||||
|
||||
0.029896344136328385984, 0.029461089958167905970,
|
||||
0.028994614150555236543, 0.028497411065085385646,
|
||||
0.027970007616848334440, 0.027412962726029242823, // 18
|
||||
|
||||
0.026826866725591762198, 0.026212340735672413913,
|
||||
0.025570036005349361499, 0.024900633222483610288,
|
||||
0.024204841792364691282, 0.023483399085926219842, // 24
|
||||
|
||||
0.022737069658329374001, 0.021966644438744349195,
|
||||
0.021172939892191298988, 0.020356797154333324595,
|
||||
0.019519081140145022410, 0.018660679627411467385, // 30
|
||||
|
||||
0.017782502316045260838, 0.016885479864245172450,
|
||||
0.015970562902562291381, 0.015038721026994938006,
|
||||
0.014090941772314860916, 0.013128229566961572637, // 36
|
||||
|
||||
0.012151604671088319635, 0.011162102099838498591,
|
||||
0.010160770535008415758, 0.009148671230783386633,
|
||||
0.008126876925698759217, 0.007096470791153865269, // 42
|
||||
|
||||
0.006058545504235961683, 0.005014202742927517693,
|
||||
0.003964554338444686674, 0.002910731817934946408,
|
||||
0.001853960788946921732, 0.000796792065552012429 // 48
|
||||
} ;
|
||||
xMean = 0.5*(a + b) ;
|
||||
xDiff = 0.5*(b - a) ;
|
||||
integral = 0.0 ;
|
||||
for(i=0;i<48;i++)
|
||||
{
|
||||
dx = xDiff*abscissa[i] ;
|
||||
integral += weight[i]*(fFunction(xMean + dx) + fFunction(xMean - dx)) ;
|
||||
}
|
||||
return integral *= xDiff ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 GEANT4 collaboration.
|
||||
//
|
||||
// By copying, distributing or modifying the Program (or any work
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4SimpleIntegration.cc,v 2.1 1998/07/12 02:58:49 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Implementation file for simple integration methods
|
||||
//
|
||||
|
||||
#include "G4SimpleIntegration.hh"
|
||||
|
||||
|
||||
G4int G4SimpleIntegration::fMaxDepth = 100 ;
|
||||
|
||||
|
||||
G4SimpleIntegration::G4SimpleIntegration( function pFunction )
|
||||
{
|
||||
fFunction = pFunction ;
|
||||
}
|
||||
|
||||
G4SimpleIntegration::G4SimpleIntegration( function pFunction,
|
||||
G4double pTolerance)
|
||||
{
|
||||
fFunction = pFunction ;
|
||||
fTolerance = pTolerance ;
|
||||
}
|
||||
|
||||
|
||||
G4SimpleIntegration::~G4SimpleIntegration()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
// Simple integration methods
|
||||
|
||||
G4double
|
||||
G4SimpleIntegration::Trapezoidal(G4double xInitial,
|
||||
G4double xFinal,
|
||||
G4int iterationNumber )
|
||||
{
|
||||
G4int i ;
|
||||
G4double Step = (xFinal - xInitial)/iterationNumber ;
|
||||
G4double mean = (fFunction(xInitial) + fFunction(xFinal))*0.5 ;
|
||||
G4double x = xInitial ;
|
||||
for(i=1;i<iterationNumber;i++)
|
||||
{
|
||||
x += Step ;
|
||||
mean += fFunction(x) ;
|
||||
}
|
||||
return mean*Step ;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4SimpleIntegration::MidPoint(G4double xInitial,
|
||||
G4double xFinal,
|
||||
G4int iterationNumber )
|
||||
{
|
||||
G4int i ;
|
||||
G4double Step = (xFinal - xInitial)/iterationNumber ;
|
||||
G4double x = xInitial + 0.5*Step;
|
||||
G4double mean = fFunction(x) ;
|
||||
for(i=1;i<iterationNumber;i++)
|
||||
{
|
||||
x += Step ;
|
||||
mean += fFunction(x) ;
|
||||
}
|
||||
return mean*Step ;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4SimpleIntegration::Gauss(G4double xInitial,
|
||||
G4double xFinal,
|
||||
G4int iterationNumber )
|
||||
{
|
||||
G4int i ;
|
||||
G4double x ;
|
||||
static G4double root = 1.0/sqrt(3.0) ;
|
||||
G4double Step = (xFinal - xInitial)/(2.0*iterationNumber) ;
|
||||
G4double delta = Step*root ;
|
||||
G4double mean = 0.0 ;
|
||||
for(i=0;i<iterationNumber;i++)
|
||||
{
|
||||
x = (2*i + 1)*Step ;
|
||||
mean += (fFunction(x+delta) + fFunction(x-delta)) ;
|
||||
}
|
||||
return mean*Step ;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4SimpleIntegration::Simpson(G4double xInitial,
|
||||
G4double xFinal,
|
||||
G4int iterationNumber )
|
||||
{
|
||||
G4int i ;
|
||||
G4double Step = (xFinal - xInitial)/iterationNumber ;
|
||||
G4double x = xInitial ;
|
||||
G4double xPlus = xInitial + 0.5*Step ;
|
||||
G4double mean = (fFunction(xInitial) + fFunction(xFinal))*0.5 ;
|
||||
G4double sum = fFunction(xPlus) ;
|
||||
for(i=1;i<iterationNumber;i++)
|
||||
{
|
||||
x += Step ;
|
||||
xPlus += Step ;
|
||||
mean += fFunction(x) ;
|
||||
sum += fFunction(xPlus) ;
|
||||
}
|
||||
mean += 2.0*sum ;
|
||||
return mean*Step/3.0 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Adaptive Gauss integration
|
||||
|
||||
G4double
|
||||
G4SimpleIntegration::AdaptGaussIntegration( G4double xInitial,
|
||||
G4double xFinal )
|
||||
{
|
||||
G4int depth = 0 ;
|
||||
G4double sum = 0.0 ;
|
||||
AdaptGauss(xInitial,xFinal,sum,depth) ;
|
||||
return sum ;
|
||||
}
|
||||
|
||||
|
||||
G4double
|
||||
G4SimpleIntegration::Gauss( G4double xInitial,
|
||||
G4double xFinal )
|
||||
{
|
||||
static G4double root = 1.0/sqrt(3.0) ;
|
||||
|
||||
G4double xMean = (xInitial + xFinal)/2.0 ;
|
||||
G4double Step = (xFinal - xInitial)/2.0 ;
|
||||
G4double delta = Step*root ;
|
||||
G4double sum = (fFunction(xMean + delta) + fFunction(xMean - delta)) ;
|
||||
|
||||
return sum*Step ;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
G4SimpleIntegration::AdaptGauss( G4double xInitial,
|
||||
G4double xFinal,
|
||||
G4double& sum,
|
||||
G4int& depth )
|
||||
{
|
||||
if(depth >fMaxDepth)
|
||||
{
|
||||
G4Exception("Function varies too rapidly in G4SimpleIntegration::AdaptGauss") ;
|
||||
}
|
||||
G4double xMean = (xInitial + xFinal)/2.0 ;
|
||||
G4double leftHalf = Gauss(xInitial,xMean) ;
|
||||
G4double rightHalf = Gauss(xMean,xFinal) ;
|
||||
G4double full = Gauss(xInitial,xFinal) ;
|
||||
if(fabs(leftHalf+rightHalf-full) < fTolerance)
|
||||
{
|
||||
sum += full ;
|
||||
}
|
||||
else
|
||||
{
|
||||
depth++ ;
|
||||
AdaptGauss(xInitial,xMean,sum,depth) ;
|
||||
AdaptGauss(xMean,xFinal,sum,depth) ;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 GEANT4 collaboration.
|
||||
//
|
||||
// By copying, distributing or modifying the Program (or any work
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4VGaussianQuadrature.cc,v 2.1 1998/07/13 16:55:26 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Implementation file for G4VGaussianQuadrature virtual base class
|
||||
//
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4VGaussianQuadrature.hh"
|
||||
|
||||
|
||||
|
||||
|
||||
G4VGaussianQuadrature::G4VGaussianQuadrature( function pFunction )
|
||||
{
|
||||
fFunction = pFunction ;
|
||||
fAbscissa = 0;
|
||||
fWeight = 0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// Virtual destructor which deletes dynamically allocated memory
|
||||
//
|
||||
|
||||
G4VGaussianQuadrature::~G4VGaussianQuadrature()
|
||||
{
|
||||
delete[] fAbscissa ;
|
||||
delete[] fWeight ;
|
||||
}
|
||||
|
||||
// -------------------------- Access functions ----------------------------------
|
||||
|
||||
|
||||
G4double
|
||||
G4VGaussianQuadrature::GetAbscissa(G4int index) const
|
||||
{
|
||||
return fAbscissa[index] ;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4VGaussianQuadrature::GetWeight(G4int index) const
|
||||
{
|
||||
return fWeight[index] ;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Auxiliary function which returns the value of log(gamma-function(x))
|
||||
//
|
||||
|
||||
G4double
|
||||
G4VGaussianQuadrature::GammaLogarithm(G4double xx)
|
||||
{
|
||||
|
||||
// Returns the value ln(Gamma(xx) for xx > 0. Full accuracy is obtained for
|
||||
// xx > 1. For 0 < xx < 1. the reflection formula (6.1.4) can be used first.
|
||||
// (Adapted from Numerical Recipes in C)
|
||||
|
||||
static G4double cof[6] = { 76.18009172947146, -86.50532032941677,
|
||||
24.01409824083091, -1.231739572450155,
|
||||
0.1208650973866179e-2, -0.5395239384953e-5 } ;
|
||||
register HepInt j;
|
||||
G4double x = xx - 1.0;
|
||||
G4double tmp = x + 5.5;
|
||||
tmp -= (x + 0.5) * log(tmp);
|
||||
G4double ser = 1.000000000190015;
|
||||
|
||||
for ( j = 0; j <= 5; j++ )
|
||||
{
|
||||
x += 1.0;
|
||||
ser += cof[j]/x;
|
||||
}
|
||||
return -tmp + log(2.5066282746310005*ser);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user