Import Geant4 10.7.0.beta source tree
This commit is contained in:
@@ -23,21 +23,23 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4AnalyticalPolSolver class implementation
|
||||
//
|
||||
//
|
||||
// Author: V.Grichine, 24.04.97
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "globals.hh"
|
||||
#include <complex>
|
||||
#include "globals.hh"
|
||||
#include <complex>
|
||||
|
||||
#include "G4AnalyticalPolSolver.hh"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4AnalyticalPolSolver::G4AnalyticalPolSolver() {;}
|
||||
G4AnalyticalPolSolver::G4AnalyticalPolSolver() { ; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4AnalyticalPolSolver::~G4AnalyticalPolSolver() {;}
|
||||
G4AnalyticalPolSolver::~G4AnalyticalPolSolver() { ; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -46,29 +48,29 @@ G4AnalyticalPolSolver::~G4AnalyticalPolSolver() {;}
|
||||
//
|
||||
// x = r[1][k] + i r[2][k]; k = 1, 2
|
||||
|
||||
G4int G4AnalyticalPolSolver::QuadRoots( G4double p[5], G4double r[3][5] )
|
||||
G4int G4AnalyticalPolSolver::QuadRoots(G4double p[5], G4double r[3][5])
|
||||
{
|
||||
G4double b, c, d2, d;
|
||||
|
||||
b = -p[1]/p[0]/2.;
|
||||
c = p[2]/p[0];
|
||||
d2 = b*b - c;
|
||||
|
||||
if( d2 >= 0. )
|
||||
b = -p[1] / p[0] / 2.;
|
||||
c = p[2] / p[0];
|
||||
d2 = b * b - c;
|
||||
|
||||
if(d2 >= 0.)
|
||||
{
|
||||
d = std::sqrt(d2);
|
||||
r[1][1] = b - d;
|
||||
r[1][2] = b + d;
|
||||
r[2][1] = 0.;
|
||||
r[1][1] = b - d;
|
||||
r[1][2] = b + d;
|
||||
r[2][1] = 0.;
|
||||
r[2][2] = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
d = std::sqrt(-d2);
|
||||
r[2][1] = d;
|
||||
r[2][1] = d;
|
||||
r[2][2] = -d;
|
||||
r[1][1] = b;
|
||||
r[1][2] = b;
|
||||
r[1][1] = b;
|
||||
r[1][2] = b;
|
||||
}
|
||||
|
||||
return 2;
|
||||
@@ -81,83 +83,113 @@ G4int G4AnalyticalPolSolver::QuadRoots( G4double p[5], G4double r[3][5] )
|
||||
// x=r[1][k] + i r[2][k] k=1,...,3
|
||||
// Assumes 0<arctan(x)<pi/2 for x>0
|
||||
|
||||
G4int G4AnalyticalPolSolver::CubicRoots( G4double p[5], G4double r[3][5] )
|
||||
G4int G4AnalyticalPolSolver::CubicRoots(G4double p[5], G4double r[3][5])
|
||||
{
|
||||
G4double x,t,b,c,d;
|
||||
G4double x, t, b, c, d;
|
||||
G4int k;
|
||||
|
||||
if( p[0] != 1. )
|
||||
if(p[0] != 1.)
|
||||
{
|
||||
for(k = 1; k < 4; k++ ) { p[k] = p[k]/p[0]; }
|
||||
for(k = 1; k < 4; k++)
|
||||
{
|
||||
p[k] = p[k] / p[0];
|
||||
}
|
||||
p[0] = 1.;
|
||||
}
|
||||
x = p[1]/3.0;
|
||||
t = x*p[1];
|
||||
b = 0.5*( x*( t/1.5 - p[2] ) + p[3] );
|
||||
t = ( t - p[2] )/3.0;
|
||||
c = t*t*t;
|
||||
d = b*b - c;
|
||||
x = p[1] / 3.0;
|
||||
t = x * p[1];
|
||||
b = 0.5 * (x * (t / 1.5 - p[2]) + p[3]);
|
||||
t = (t - p[2]) / 3.0;
|
||||
c = t * t * t;
|
||||
d = b * b - c;
|
||||
|
||||
if( d >= 0. )
|
||||
if(d >= 0.)
|
||||
{
|
||||
d = std::pow( (std::sqrt(d) + std::fabs(b) ), 1.0/3.0 );
|
||||
|
||||
if( d != 0. )
|
||||
{
|
||||
if( b > 0. ) { b = -d; }
|
||||
else { b = d; }
|
||||
c = t/b;
|
||||
}
|
||||
d = std::sqrt(0.75)*(b - c);
|
||||
r[2][2] = d;
|
||||
b = b + c;
|
||||
c = -0.5*b-x;
|
||||
r[1][2] = c;
|
||||
d = std::pow((std::sqrt(d) + std::fabs(b)), 1.0 / 3.0);
|
||||
|
||||
if( ( b > 0. && x <= 0. ) || ( b < 0. && x > 0. ) )
|
||||
if(d != 0.)
|
||||
{
|
||||
r[1][1] = c;
|
||||
r[2][1] = -d;
|
||||
r[1][3] = b - x;
|
||||
r[2][3] = 0;
|
||||
if(b > 0.)
|
||||
{
|
||||
b = -d;
|
||||
}
|
||||
else
|
||||
{
|
||||
b = d;
|
||||
}
|
||||
c = t / b;
|
||||
}
|
||||
d = std::sqrt(0.75) * (b - c);
|
||||
r[2][2] = d;
|
||||
b = b + c;
|
||||
c = -0.5 * b - x;
|
||||
r[1][2] = c;
|
||||
|
||||
if((b > 0. && x <= 0.) || (b < 0. && x > 0.))
|
||||
{
|
||||
r[1][1] = c;
|
||||
r[2][1] = -d;
|
||||
r[1][3] = b - x;
|
||||
r[2][3] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
r[1][1] = b - x;
|
||||
r[2][1] = 0.;
|
||||
r[1][3] = c;
|
||||
r[2][3] = -d;
|
||||
r[1][1] = b - x;
|
||||
r[2][1] = 0.;
|
||||
r[1][3] = c;
|
||||
r[2][3] = -d;
|
||||
}
|
||||
} // end of 2 equal or complex roots
|
||||
} // end of 2 equal or complex roots
|
||||
else
|
||||
{
|
||||
if( b == 0. ) { d = std::atan(1.0)/1.5; }
|
||||
else { d = std::atan( std::sqrt(-d)/std::fabs(b) )/3.0; }
|
||||
|
||||
if( b < 0. ) { b = std::sqrt(t)*2.0; }
|
||||
else { b = -2.0*std::sqrt(t); }
|
||||
|
||||
c = std::cos(d)*b;
|
||||
t = -std::sqrt(0.75)*std::sin(d)*b - 0.5*c;
|
||||
d = -t - c - x;
|
||||
c = c - x;
|
||||
t = t - x;
|
||||
|
||||
if( std::fabs(c) > std::fabs(t) ) { r[1][3] = c; }
|
||||
if(b == 0.)
|
||||
{
|
||||
d = std::atan(1.0) / 1.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
r[1][3] = t;
|
||||
d = std::atan(std::sqrt(-d) / std::fabs(b)) / 3.0;
|
||||
}
|
||||
|
||||
if(b < 0.)
|
||||
{
|
||||
b = std::sqrt(t) * 2.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
b = -2.0 * std::sqrt(t);
|
||||
}
|
||||
|
||||
c = std::cos(d) * b;
|
||||
t = -std::sqrt(0.75) * std::sin(d) * b - 0.5 * c;
|
||||
d = -t - c - x;
|
||||
c = c - x;
|
||||
t = t - x;
|
||||
|
||||
if(std::fabs(c) > std::fabs(t))
|
||||
{
|
||||
r[1][3] = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
r[1][3] = t;
|
||||
t = c;
|
||||
}
|
||||
if( std::fabs(d) > std::fabs(t) ) { r[1][2] = d; }
|
||||
if(std::fabs(d) > std::fabs(t))
|
||||
{
|
||||
r[1][2] = d;
|
||||
}
|
||||
else
|
||||
{
|
||||
r[1][2] = t;
|
||||
r[1][2] = t;
|
||||
t = d;
|
||||
}
|
||||
r[1][1] = t;
|
||||
|
||||
for(k = 1; k < 4; k++ ) { r[2][k] = 0.; }
|
||||
for(k = 1; k < 4; k++)
|
||||
{
|
||||
r[2][k] = 0.;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -168,107 +200,143 @@ G4int G4AnalyticalPolSolver::CubicRoots( G4double p[5], G4double r[3][5] )
|
||||
// Roots of poly p[0] x^4 + p[1] x^3...+p[4]=0
|
||||
// x=r[1][k] + i r[2][k] k=1,...,4
|
||||
|
||||
G4int G4AnalyticalPolSolver::BiquadRoots( G4double p[5], G4double r[3][5] )
|
||||
G4int G4AnalyticalPolSolver::BiquadRoots(G4double p[5], G4double r[3][5])
|
||||
{
|
||||
G4double a, b, c, d, e;
|
||||
G4int i, k, j;
|
||||
|
||||
if(p[0] != 1.0)
|
||||
{
|
||||
for( k = 1; k < 5; k++) { p[k] = p[k]/p[0]; }
|
||||
for(k = 1; k < 5; k++)
|
||||
{
|
||||
p[k] = p[k] / p[0];
|
||||
}
|
||||
p[0] = 1.;
|
||||
}
|
||||
e = 0.25*p[1];
|
||||
b = 2*e;
|
||||
c = b*b;
|
||||
d = 0.75*c;
|
||||
b = p[3] + b*( c - p[2] );
|
||||
e = 0.25 * p[1];
|
||||
b = 2 * e;
|
||||
c = b * b;
|
||||
d = 0.75 * c;
|
||||
b = p[3] + b * (c - p[2]);
|
||||
a = p[2] - d;
|
||||
c = p[4] + e*( e*a - p[3] );
|
||||
c = p[4] + e * (e * a - p[3]);
|
||||
a = a - d;
|
||||
|
||||
p[1] = 0.5*a;
|
||||
p[2] = (p[1]*p[1]-c)*0.25;
|
||||
p[3] = b*b/(-64.0);
|
||||
p[1] = 0.5 * a;
|
||||
p[2] = (p[1] * p[1] - c) * 0.25;
|
||||
p[3] = b * b / (-64.0);
|
||||
|
||||
if( p[3] < 0. )
|
||||
if(p[3] < 0.)
|
||||
{
|
||||
CubicRoots(p,r);
|
||||
CubicRoots(p, r);
|
||||
|
||||
for( k = 1; k < 4; k++ )
|
||||
for(k = 1; k < 4; k++)
|
||||
{
|
||||
if( r[2][k] == 0. && r[1][k] > 0 )
|
||||
if(r[2][k] == 0. && r[1][k] > 0)
|
||||
{
|
||||
d = r[1][k]*4;
|
||||
d = r[1][k] * 4;
|
||||
a = a + d;
|
||||
|
||||
if ( a >= 0. && b >= 0.) { p[1] = std::sqrt(d); }
|
||||
else if( a <= 0. && b <= 0.) { p[1] = std::sqrt(d); }
|
||||
else { p[1] = -std::sqrt(d); }
|
||||
|
||||
b = 0.5*( a + b/p[1] );
|
||||
|
||||
p[2] = c/b;
|
||||
QuadRoots(p,r);
|
||||
|
||||
for( i = 1; i < 3; i++ )
|
||||
if(a >= 0. && b >= 0.)
|
||||
{
|
||||
for( j = 1; j < 3; j++ ) { r[j][i+2] = r[j][i]; }
|
||||
p[1] = std::sqrt(d);
|
||||
}
|
||||
else if(a <= 0. && b <= 0.)
|
||||
{
|
||||
p[1] = std::sqrt(d);
|
||||
}
|
||||
else
|
||||
{
|
||||
p[1] = -std::sqrt(d);
|
||||
}
|
||||
p[1] = -p[1];
|
||||
p[2] = b;
|
||||
QuadRoots(p,r);
|
||||
|
||||
for( i = 1; i < 5; i++ ) { r[1][i] = r[1][i] - e; }
|
||||
b = 0.5 * (a + b / p[1]);
|
||||
|
||||
p[2] = c / b;
|
||||
QuadRoots(p, r);
|
||||
|
||||
for(i = 1; i < 3; i++)
|
||||
{
|
||||
for(j = 1; j < 3; j++)
|
||||
{
|
||||
r[j][i + 2] = r[j][i];
|
||||
}
|
||||
}
|
||||
p[1] = -p[1];
|
||||
p[2] = b;
|
||||
QuadRoots(p, r);
|
||||
|
||||
for(i = 1; i < 5; i++)
|
||||
{
|
||||
r[1][i] = r[1][i] - e;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( p[2] < 0. )
|
||||
if(p[2] < 0.)
|
||||
{
|
||||
b = std::sqrt(c);
|
||||
b = std::sqrt(c);
|
||||
d = b + b - a;
|
||||
p[1] = 0.;
|
||||
|
||||
if( d > 0. ) { p[1] = std::sqrt(d); }
|
||||
p[1] = 0.;
|
||||
|
||||
if(d > 0.)
|
||||
{
|
||||
p[1] = std::sqrt(d);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( p[1] > 0.) { b = std::sqrt(p[2])*2.0 + p[1]; }
|
||||
else { b = -std::sqrt(p[2])*2.0 + p[1]; }
|
||||
|
||||
if( b != 0.) { p[1] = 0; }
|
||||
if(p[1] > 0.)
|
||||
{
|
||||
b = std::sqrt(p[2]) * 2.0 + p[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
for(k = 1; k < 5; k++ )
|
||||
b = -std::sqrt(p[2]) * 2.0 + p[1];
|
||||
}
|
||||
|
||||
if(b != 0.)
|
||||
{
|
||||
p[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(k = 1; k < 5; k++)
|
||||
{
|
||||
r[1][k] = -e;
|
||||
r[2][k] = 0;
|
||||
r[1][k] = -e;
|
||||
r[2][k] = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
p[2] = c/b;
|
||||
QuadRoots(p,r);
|
||||
p[2] = c / b;
|
||||
QuadRoots(p, r);
|
||||
|
||||
for( k = 1; k < 3; k++ )
|
||||
for(k = 1; k < 3; k++)
|
||||
{
|
||||
for( j = 1; j < 3; j++ ) { r[j][k+2] = r[j][k]; }
|
||||
for(j = 1; j < 3; j++)
|
||||
{
|
||||
r[j][k + 2] = r[j][k];
|
||||
}
|
||||
}
|
||||
p[1] = -p[1];
|
||||
p[2] = b;
|
||||
QuadRoots(p,r);
|
||||
p[1] = -p[1];
|
||||
p[2] = b;
|
||||
QuadRoots(p, r);
|
||||
|
||||
for( k = 1; k < 5; k++ ) { r[1][k] = r[1][k] - e; }
|
||||
for(k = 1; k < 5; k++)
|
||||
{
|
||||
r[1][k] = r[1][k] - e;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4int G4AnalyticalPolSolver::QuarticRoots( G4double p[5], G4double r[3][5])
|
||||
G4int G4AnalyticalPolSolver::QuarticRoots(G4double p[5], G4double r[3][5])
|
||||
{
|
||||
G4double a0, a1, a2, a3, y1;
|
||||
G4double R2, D2, E2, D, E, R = 0.;
|
||||
@@ -276,12 +344,18 @@ G4int G4AnalyticalPolSolver::QuarticRoots( G4double p[5], G4double r[3][5])
|
||||
|
||||
G4double reRoot[4];
|
||||
G4int k, noReRoots = 0;
|
||||
|
||||
for( k = 0; k < 4; k++ ) { reRoot[k] = DBL_MAX; }
|
||||
|
||||
if( p[0] != 1.0 )
|
||||
for(k = 0; k < 4; k++)
|
||||
{
|
||||
for( k = 1; k < 5; k++) { p[k] = p[k]/p[0]; }
|
||||
reRoot[k] = DBL_MAX;
|
||||
}
|
||||
|
||||
if(p[0] != 1.0)
|
||||
{
|
||||
for(k = 1; k < 5; k++)
|
||||
{
|
||||
p[k] = p[k] / p[0];
|
||||
}
|
||||
p[0] = 1.;
|
||||
}
|
||||
a3 = p[1];
|
||||
@@ -292,148 +366,152 @@ G4int G4AnalyticalPolSolver::QuarticRoots( G4double p[5], G4double r[3][5])
|
||||
// resolvent cubic equation cofs:
|
||||
|
||||
p[1] = -a2;
|
||||
p[2] = a1*a3 - 4*a0;
|
||||
p[3] = 4*a2*a0 - a1*a1 - a3*a3*a0;
|
||||
p[2] = a1 * a3 - 4 * a0;
|
||||
p[3] = 4 * a2 * a0 - a1 * a1 - a3 * a3 * a0;
|
||||
|
||||
CubicRoots(p,r);
|
||||
CubicRoots(p, r);
|
||||
|
||||
for( k = 1; k < 4; k++ )
|
||||
for(k = 1; k < 4; k++)
|
||||
{
|
||||
if( r[2][k] == 0. ) // find a real root
|
||||
if(r[2][k] == 0.) // find a real root
|
||||
{
|
||||
noReRoots++;
|
||||
reRoot[k] = r[1][k];
|
||||
}
|
||||
else reRoot[k] = DBL_MAX; // kInfinity;
|
||||
else
|
||||
reRoot[k] = DBL_MAX; // kInfinity;
|
||||
}
|
||||
y1 = DBL_MAX; // kInfinity;
|
||||
for( k = 1; k < 4; k++ )
|
||||
y1 = DBL_MAX; // kInfinity;
|
||||
for(k = 1; k < 4; k++)
|
||||
{
|
||||
if ( reRoot[k] < y1 ) { y1 = reRoot[k]; }
|
||||
if(reRoot[k] < y1)
|
||||
{
|
||||
y1 = reRoot[k];
|
||||
}
|
||||
}
|
||||
|
||||
R2 = 0.25*a3*a3 - a2 + y1;
|
||||
b = 0.25*(4*a3*a2 - 8*a1 - a3*a3*a3);
|
||||
c = 0.75*a3*a3 - 2*a2;
|
||||
R2 = 0.25 * a3 * a3 - a2 + y1;
|
||||
b = 0.25 * (4 * a3 * a2 - 8 * a1 - a3 * a3 * a3);
|
||||
c = 0.75 * a3 * a3 - 2 * a2;
|
||||
a = c - R2;
|
||||
d = 4*y1*y1 - 16*a0;
|
||||
d = 4 * y1 * y1 - 16 * a0;
|
||||
|
||||
if( R2 > 0.)
|
||||
if(R2 > 0.)
|
||||
{
|
||||
R = std::sqrt(R2);
|
||||
D2 = a + b/R;
|
||||
E2 = a - b/R;
|
||||
R = std::sqrt(R2);
|
||||
D2 = a + b / R;
|
||||
E2 = a - b / R;
|
||||
|
||||
if( D2 >= 0. )
|
||||
if(D2 >= 0.)
|
||||
{
|
||||
D = std::sqrt(D2);
|
||||
r[1][1] = -0.25*a3 + 0.5*R + 0.5*D;
|
||||
r[1][2] = -0.25*a3 + 0.5*R - 0.5*D;
|
||||
r[1][1] = -0.25 * a3 + 0.5 * R + 0.5 * D;
|
||||
r[1][2] = -0.25 * a3 + 0.5 * R - 0.5 * D;
|
||||
r[2][1] = 0.;
|
||||
r[2][2] = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
D = std::sqrt(-D2);
|
||||
r[1][1] = -0.25*a3 + 0.5*R;
|
||||
r[1][2] = -0.25*a3 + 0.5*R;
|
||||
r[2][1] = 0.5*D;
|
||||
r[2][2] = -0.5*D;
|
||||
r[1][1] = -0.25 * a3 + 0.5 * R;
|
||||
r[1][2] = -0.25 * a3 + 0.5 * R;
|
||||
r[2][1] = 0.5 * D;
|
||||
r[2][2] = -0.5 * D;
|
||||
}
|
||||
if( E2 >= 0. )
|
||||
if(E2 >= 0.)
|
||||
{
|
||||
E = std::sqrt(E2);
|
||||
r[1][3] = -0.25*a3 - 0.5*R + 0.5*E;
|
||||
r[1][4] = -0.25*a3 - 0.5*R - 0.5*E;
|
||||
r[1][3] = -0.25 * a3 - 0.5 * R + 0.5 * E;
|
||||
r[1][4] = -0.25 * a3 - 0.5 * R - 0.5 * E;
|
||||
r[2][3] = 0.;
|
||||
r[2][4] = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
E = std::sqrt(-E2);
|
||||
r[1][3] = -0.25*a3 - 0.5*R;
|
||||
r[1][4] = -0.25*a3 - 0.5*R;
|
||||
r[2][3] = 0.5*E;
|
||||
r[2][4] = -0.5*E;
|
||||
r[1][3] = -0.25 * a3 - 0.5 * R;
|
||||
r[1][4] = -0.25 * a3 - 0.5 * R;
|
||||
r[2][3] = 0.5 * E;
|
||||
r[2][4] = -0.5 * E;
|
||||
}
|
||||
}
|
||||
else if( R2 < 0.)
|
||||
else if(R2 < 0.)
|
||||
{
|
||||
R = std::sqrt(-R2);
|
||||
G4complex CD2(a,-b/R);
|
||||
G4complex CD2(a, -b / R);
|
||||
G4complex CD = std::sqrt(CD2);
|
||||
|
||||
r[1][1] = -0.25*a3 + 0.5*real(CD);
|
||||
r[1][2] = -0.25*a3 - 0.5*real(CD);
|
||||
r[2][1] = 0.5*R + 0.5*imag(CD);
|
||||
r[2][2] = 0.5*R - 0.5*imag(CD);
|
||||
G4complex CE2(a,b/R);
|
||||
r[1][1] = -0.25 * a3 + 0.5 * real(CD);
|
||||
r[1][2] = -0.25 * a3 - 0.5 * real(CD);
|
||||
r[2][1] = 0.5 * R + 0.5 * imag(CD);
|
||||
r[2][2] = 0.5 * R - 0.5 * imag(CD);
|
||||
G4complex CE2(a, b / R);
|
||||
G4complex CE = std::sqrt(CE2);
|
||||
|
||||
r[1][3] = -0.25*a3 + 0.5*real(CE);
|
||||
r[1][4] = -0.25*a3 - 0.5*real(CE);
|
||||
r[2][3] = -0.5*R + 0.5*imag(CE);
|
||||
r[2][4] = -0.5*R - 0.5*imag(CE);
|
||||
r[1][3] = -0.25 * a3 + 0.5 * real(CE);
|
||||
r[1][4] = -0.25 * a3 - 0.5 * real(CE);
|
||||
r[2][3] = -0.5 * R + 0.5 * imag(CE);
|
||||
r[2][4] = -0.5 * R - 0.5 * imag(CE);
|
||||
}
|
||||
else // R2=0 case
|
||||
else // R2=0 case
|
||||
{
|
||||
if(d >= 0.)
|
||||
{
|
||||
D2 = c + std::sqrt(d);
|
||||
E2 = c - std::sqrt(d);
|
||||
|
||||
if( D2 >= 0. )
|
||||
if(D2 >= 0.)
|
||||
{
|
||||
D = std::sqrt(D2);
|
||||
r[1][1] = -0.25*a3 + 0.5*R + 0.5*D;
|
||||
r[1][2] = -0.25*a3 + 0.5*R - 0.5*D;
|
||||
r[1][1] = -0.25 * a3 + 0.5 * R + 0.5 * D;
|
||||
r[1][2] = -0.25 * a3 + 0.5 * R - 0.5 * D;
|
||||
r[2][1] = 0.;
|
||||
r[2][2] = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
D = std::sqrt(-D2);
|
||||
r[1][1] = -0.25*a3 + 0.5*R;
|
||||
r[1][2] = -0.25*a3 + 0.5*R;
|
||||
r[2][1] = 0.5*D;
|
||||
r[2][2] = -0.5*D;
|
||||
r[1][1] = -0.25 * a3 + 0.5 * R;
|
||||
r[1][2] = -0.25 * a3 + 0.5 * R;
|
||||
r[2][1] = 0.5 * D;
|
||||
r[2][2] = -0.5 * D;
|
||||
}
|
||||
if( E2 >= 0. )
|
||||
if(E2 >= 0.)
|
||||
{
|
||||
E = std::sqrt(E2);
|
||||
r[1][3] = -0.25*a3 - 0.5*R + 0.5*E;
|
||||
r[1][4] = -0.25*a3 - 0.5*R - 0.5*E;
|
||||
r[1][3] = -0.25 * a3 - 0.5 * R + 0.5 * E;
|
||||
r[1][4] = -0.25 * a3 - 0.5 * R - 0.5 * E;
|
||||
r[2][3] = 0.;
|
||||
r[2][4] = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
E = std::sqrt(-E2);
|
||||
r[1][3] = -0.25*a3 - 0.5*R;
|
||||
r[1][4] = -0.25*a3 - 0.5*R;
|
||||
r[2][3] = 0.5*E;
|
||||
r[2][4] = -0.5*E;
|
||||
r[1][3] = -0.25 * a3 - 0.5 * R;
|
||||
r[1][4] = -0.25 * a3 - 0.5 * R;
|
||||
r[2][3] = 0.5 * E;
|
||||
r[2][4] = -0.5 * E;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ds = std::sqrt(-d);
|
||||
G4complex CD2(c,ds);
|
||||
G4complex CD2(c, ds);
|
||||
G4complex CD = std::sqrt(CD2);
|
||||
|
||||
r[1][1] = -0.25*a3 + 0.5*real(CD);
|
||||
r[1][2] = -0.25*a3 - 0.5*real(CD);
|
||||
r[2][1] = 0.5*R + 0.5*imag(CD);
|
||||
r[2][2] = 0.5*R - 0.5*imag(CD);
|
||||
r[1][1] = -0.25 * a3 + 0.5 * real(CD);
|
||||
r[1][2] = -0.25 * a3 - 0.5 * real(CD);
|
||||
r[2][1] = 0.5 * R + 0.5 * imag(CD);
|
||||
r[2][2] = 0.5 * R - 0.5 * imag(CD);
|
||||
|
||||
G4complex CE2(c,-ds);
|
||||
G4complex CE2(c, -ds);
|
||||
G4complex CE = std::sqrt(CE2);
|
||||
|
||||
r[1][3] = -0.25*a3 + 0.5*real(CE);
|
||||
r[1][4] = -0.25*a3 - 0.5*real(CE);
|
||||
r[2][3] = -0.5*R + 0.5*imag(CE);
|
||||
r[2][4] = -0.5*R - 0.5*imag(CE);
|
||||
}
|
||||
r[1][3] = -0.25 * a3 + 0.5 * real(CE);
|
||||
r[1][4] = -0.25 * a3 - 0.5 * real(CE);
|
||||
r[2][3] = -0.5 * R + 0.5 * imag(CE);
|
||||
r[2][4] = -0.5 * R - 0.5 * imag(CE);
|
||||
}
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ChebyshevApproximation class implementation
|
||||
//
|
||||
//
|
||||
// Author: V.Grichine, 24.04.97
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ChebyshevApproximation.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
@@ -33,39 +35,39 @@
|
||||
// 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 fix the interval of validity
|
||||
// of the Chebyshev approximation.
|
||||
// of the Chebyshev approximation.
|
||||
|
||||
G4ChebyshevApproximation::G4ChebyshevApproximation( function pFunction,
|
||||
G4int n,
|
||||
G4double a,
|
||||
G4double b )
|
||||
: fFunction(pFunction), fNumber(n),
|
||||
fChebyshevCof(new G4double[fNumber]),
|
||||
fMean(0.5*(b+a)), fDiff(0.5*(b-a))
|
||||
G4ChebyshevApproximation::G4ChebyshevApproximation(function pFunction, G4int n,
|
||||
G4double a, G4double b)
|
||||
: fFunction(pFunction)
|
||||
, fNumber(n)
|
||||
, fChebyshevCof(new G4double[fNumber])
|
||||
, fMean(0.5 * (b + a))
|
||||
, fDiff(0.5 * (b - a))
|
||||
{
|
||||
G4int i=0, j=0 ;
|
||||
G4double rootSum=0.0, cofj=0.0 ;
|
||||
G4double* tempFunction = new G4double[fNumber] ;
|
||||
G4double weight = 2.0/fNumber ;
|
||||
G4double cof = 0.5*weight*pi ; // pi/n
|
||||
|
||||
for (i=0;i<fNumber;i++)
|
||||
{
|
||||
rootSum = std::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]*std::cos(cofj*(i+0.5)) ;
|
||||
}
|
||||
fChebyshevCof[j] = weight*rootSum ;
|
||||
}
|
||||
delete[] tempFunction ;
|
||||
G4int i = 0, j = 0;
|
||||
G4double rootSum = 0.0, cofj = 0.0;
|
||||
G4double* tempFunction = new G4double[fNumber];
|
||||
G4double weight = 2.0 / fNumber;
|
||||
G4double cof = 0.5 * weight * pi; // pi/n
|
||||
|
||||
for(i = 0; i < fNumber; ++i)
|
||||
{
|
||||
rootSum = std::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] * std::cos(cofj * (i + 0.5));
|
||||
}
|
||||
fChebyshevCof[j] = weight * rootSum;
|
||||
}
|
||||
delete[] tempFunction;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -73,55 +75,56 @@ G4ChebyshevApproximation::G4ChebyshevApproximation( function pFunction,
|
||||
// Constructor for creation of Chebyshev coefficients for mx-derivative
|
||||
// from pFunction. The value of mx ! MUST BE ! < nx , because the result
|
||||
// array of fChebyshevCof will be of (nx-mx) size. The values a and b
|
||||
// fix the interval of validity of the Chebyshev approximation.
|
||||
// fix the interval of validity of the Chebyshev approximation.
|
||||
|
||||
G4ChebyshevApproximation::
|
||||
G4ChebyshevApproximation( function pFunction,
|
||||
G4int nx, G4int mx,
|
||||
G4double a, G4double b )
|
||||
: fFunction(pFunction), fNumber(nx),
|
||||
fChebyshevCof(new G4double[fNumber]),
|
||||
fMean(0.5*(b+a)), fDiff(0.5*(b-a))
|
||||
G4ChebyshevApproximation::G4ChebyshevApproximation(function pFunction, G4int nx,
|
||||
G4int mx, G4double a,
|
||||
G4double b)
|
||||
: fFunction(pFunction)
|
||||
, fNumber(nx)
|
||||
, fChebyshevCof(new G4double[fNumber])
|
||||
, fMean(0.5 * (b + a))
|
||||
, fDiff(0.5 * (b - a))
|
||||
{
|
||||
if(nx <= mx)
|
||||
{
|
||||
G4Exception("G4ChebyshevApproximation::G4ChebyshevApproximation()",
|
||||
"InvalidCall", FatalException, "Invalid arguments !") ;
|
||||
}
|
||||
G4int i=0, j=0 ;
|
||||
G4double rootSum = 0.0, cofj=0.0;
|
||||
G4double* tempFunction = new G4double[fNumber] ;
|
||||
G4double weight = 2.0/fNumber ;
|
||||
G4double cof = 0.5*weight*pi ; // pi/nx
|
||||
|
||||
for (i=0;i<fNumber;i++)
|
||||
{
|
||||
rootSum = std::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]*std::cos(cofj*(i+0.5)) ;
|
||||
}
|
||||
fChebyshevCof[j] = weight*rootSum ; // corresponds to pFunction
|
||||
}
|
||||
// Chebyshev coefficients for (mx)-derivative of pFunction
|
||||
|
||||
for(i=1;i<=mx;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
|
||||
if(nx <= mx)
|
||||
{
|
||||
G4Exception("G4ChebyshevApproximation::G4ChebyshevApproximation()",
|
||||
"InvalidCall", FatalException, "Invalid arguments !");
|
||||
}
|
||||
G4int i = 0, j = 0;
|
||||
G4double rootSum = 0.0, cofj = 0.0;
|
||||
G4double* tempFunction = new G4double[fNumber];
|
||||
G4double weight = 2.0 / fNumber;
|
||||
G4double cof = 0.5 * weight * pi; // pi/nx
|
||||
|
||||
for(i = 0; i < fNumber; ++i)
|
||||
{
|
||||
rootSum = std::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] * std::cos(cofj * (i + 0.5));
|
||||
}
|
||||
fChebyshevCof[j] = weight * rootSum; // corresponds to pFunction
|
||||
}
|
||||
// Chebyshev coefficients for (mx)-derivative of pFunction
|
||||
|
||||
for(i = 1; i <= mx; ++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
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
@@ -129,55 +132,54 @@ G4ChebyshevApproximation( function pFunction,
|
||||
// Constructor for creation of Chebyshev coefficients for integral
|
||||
// from pFunction.
|
||||
|
||||
G4ChebyshevApproximation::G4ChebyshevApproximation( function pFunction,
|
||||
G4double a,
|
||||
G4double b,
|
||||
G4int n )
|
||||
: fFunction(pFunction), fNumber(n),
|
||||
fChebyshevCof(new G4double[fNumber]),
|
||||
fMean(0.5*(b+a)), fDiff(0.5*(b-a))
|
||||
G4ChebyshevApproximation::G4ChebyshevApproximation(function pFunction,
|
||||
G4double a, G4double b,
|
||||
G4int n)
|
||||
: fFunction(pFunction)
|
||||
, fNumber(n)
|
||||
, fChebyshevCof(new G4double[fNumber])
|
||||
, fMean(0.5 * (b + a))
|
||||
, fDiff(0.5 * (b - a))
|
||||
{
|
||||
G4int i=0, j=0;
|
||||
G4double rootSum=0.0, cofj=0.0;
|
||||
G4double* tempFunction = new G4double[fNumber] ;
|
||||
G4double weight = 2.0/fNumber;
|
||||
G4double cof = 0.5*weight*pi ; // pi/n
|
||||
|
||||
for (i=0;i<fNumber;i++)
|
||||
{
|
||||
rootSum = std::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]*std::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
|
||||
G4int i = 0, j = 0;
|
||||
G4double rootSum = 0.0, cofj = 0.0;
|
||||
G4double* tempFunction = new G4double[fNumber];
|
||||
G4double weight = 2.0 / fNumber;
|
||||
G4double cof = 0.5 * weight * pi; // pi/n
|
||||
|
||||
for(i = 0; i < fNumber; ++i)
|
||||
{
|
||||
rootSum = std::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] * std::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 ;
|
||||
delete[] fChebyshevCof;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
@@ -185,16 +187,14 @@ G4ChebyshevApproximation::~G4ChebyshevApproximation()
|
||||
// Access function for Chebyshev coefficients
|
||||
//
|
||||
|
||||
|
||||
G4double
|
||||
G4ChebyshevApproximation::GetChebyshevCof(G4int number) const
|
||||
G4double G4ChebyshevApproximation::GetChebyshevCof(G4int number) const
|
||||
{
|
||||
if(number < 0 && number >= fNumber)
|
||||
{
|
||||
G4Exception("G4ChebyshevApproximation::GetChebyshevCof()",
|
||||
"InvalidCall", FatalException, "Argument out of range !") ;
|
||||
}
|
||||
return fChebyshevCof[number] ;
|
||||
if(number < 0 && number >= fNumber)
|
||||
{
|
||||
G4Exception("G4ChebyshevApproximation::GetChebyshevCof()", "InvalidCall",
|
||||
FatalException, "Argument out of range !");
|
||||
}
|
||||
return fChebyshevCof[number];
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
@@ -202,69 +202,67 @@ G4ChebyshevApproximation::GetChebyshevCof(G4int number) const
|
||||
// Evaluate the value of fFunction at the point x via the Chebyshev coefficients
|
||||
// fChebyshevCof[0,...,fNumber-1]
|
||||
|
||||
G4double
|
||||
G4ChebyshevApproximation::ChebyshevEvaluation(G4double x) const
|
||||
G4double G4ChebyshevApproximation::ChebyshevEvaluation(G4double x) const
|
||||
{
|
||||
G4double evaluate = 0.0, evaluate2 = 0.0, temp = 0.0,
|
||||
xReduced = 0.0, xReduced2 = 0.0 ;
|
||||
G4double evaluate = 0.0, evaluate2 = 0.0, temp = 0.0, xReduced = 0.0,
|
||||
xReduced2 = 0.0;
|
||||
|
||||
if ((x-fMean+fDiff)*(x-fMean-fDiff) > 0.0)
|
||||
{
|
||||
G4Exception("G4ChebyshevApproximation::ChebyshevEvaluation()",
|
||||
"InvalidCall", FatalException, "Invalid argument !") ;
|
||||
}
|
||||
xReduced = (x-fMean)/fDiff ;
|
||||
xReduced2 = 2.0*xReduced ;
|
||||
for (G4int i=fNumber-1;i>=1;i--)
|
||||
{
|
||||
temp = evaluate ;
|
||||
evaluate = xReduced2*evaluate - evaluate2 + fChebyshevCof[i] ;
|
||||
evaluate2 = temp ;
|
||||
}
|
||||
return xReduced*evaluate - evaluate2 + 0.5*fChebyshevCof[0] ;
|
||||
if((x - fMean + fDiff) * (x - fMean - fDiff) > 0.0)
|
||||
{
|
||||
G4Exception("G4ChebyshevApproximation::ChebyshevEvaluation()",
|
||||
"InvalidCall", FatalException, "Invalid argument !");
|
||||
}
|
||||
xReduced = (x - fMean) / fDiff;
|
||||
xReduced2 = 2.0 * xReduced;
|
||||
for(G4int 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
|
||||
// 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
|
||||
void G4ChebyshevApproximation::DerivativeChebyshevCof(G4double derCof[]) const
|
||||
{
|
||||
G4double cof = 1.0/fDiff ;
|
||||
derCof[fNumber-1] = 0.0 ;
|
||||
derCof[fNumber-2] = 2*(fNumber-1)*fChebyshevCof[fNumber-1] ;
|
||||
for(G4int i=fNumber-3;i>=0;i--)
|
||||
{
|
||||
derCof[i] = derCof[i+2] + 2*(i+1)*fChebyshevCof[i+1] ;
|
||||
}
|
||||
for(G4int j=0;j<fNumber;j++)
|
||||
{
|
||||
derCof[j] *= cof ;
|
||||
}
|
||||
G4double cof = 1.0 / fDiff;
|
||||
derCof[fNumber - 1] = 0.0;
|
||||
derCof[fNumber - 2] = 2 * (fNumber - 1) * fChebyshevCof[fNumber - 1];
|
||||
for(G4int i = fNumber - 3; i >= 0; --i)
|
||||
{
|
||||
derCof[i] = derCof[i + 2] + 2 * (i + 1) * fChebyshevCof[i + 1];
|
||||
}
|
||||
for(G4int j = 0; j < fNumber; ++j)
|
||||
{
|
||||
derCof[j] *= 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).
|
||||
// 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
|
||||
|
||||
void G4ChebyshevApproximation::IntegralChebyshevCof(
|
||||
G4double integralCof[]) const
|
||||
{
|
||||
G4double cof = 0.5*fDiff, sum = 0.0, factor = 1.0 ;
|
||||
for(G4int 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
|
||||
}
|
||||
G4double cof = 0.5 * fDiff, sum = 0.0, factor = 1.0;
|
||||
for(G4int 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
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,8 +23,11 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DataInterpolation class implementation
|
||||
//
|
||||
//
|
||||
// Author: V.Grichine, 03.04.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4DataInterpolation.hh"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -32,108 +35,108 @@
|
||||
// Constructor for initializing of fArgument, fFunction and fNumber
|
||||
// data members
|
||||
|
||||
G4DataInterpolation::G4DataInterpolation( G4double pX[],
|
||||
G4double pY[],
|
||||
G4int number )
|
||||
: fArgument(new G4double[number]),
|
||||
fFunction(new G4double[number]),
|
||||
fSecondDerivative(0),
|
||||
fNumber(number)
|
||||
G4DataInterpolation::G4DataInterpolation(G4double pX[], G4double pY[],
|
||||
G4int number)
|
||||
: fArgument(new G4double[number])
|
||||
, fFunction(new G4double[number])
|
||||
, fNumber(number)
|
||||
{
|
||||
for(G4int i=0;i<fNumber;i++)
|
||||
{
|
||||
fArgument[i] = pX[i] ;
|
||||
fFunction[i] = pY[i] ;
|
||||
}
|
||||
}
|
||||
for(G4int i = 0; i < fNumber; ++i)
|
||||
{
|
||||
fArgument[i] = pX[i];
|
||||
fFunction[i] = pY[i];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor for cubic spline interpolation. It creates the array
|
||||
// Constructor for cubic spline interpolation. It creates the array
|
||||
// fSecondDerivative[0,...fNumber-1] which is used in this interpolation by
|
||||
// the function
|
||||
// the function
|
||||
|
||||
|
||||
G4DataInterpolation::G4DataInterpolation( G4double pX[],
|
||||
G4double pY[],
|
||||
G4int number,
|
||||
G4double pFirstDerStart,
|
||||
G4double pFirstDerFinish )
|
||||
: fArgument(new G4double[number]),
|
||||
fFunction(new G4double[number]),
|
||||
fSecondDerivative(new G4double[number]),
|
||||
fNumber(number)
|
||||
G4DataInterpolation::G4DataInterpolation(G4double pX[], G4double pY[],
|
||||
G4int number, G4double pFirstDerStart,
|
||||
G4double pFirstDerFinish)
|
||||
: fArgument(new G4double[number])
|
||||
, fFunction(new G4double[number])
|
||||
, fSecondDerivative(new G4double[number])
|
||||
, fNumber(number)
|
||||
{
|
||||
G4int i=0 ;
|
||||
G4double p=0.0, qn=0.0, sig=0.0, un=0.0 ;
|
||||
const G4double maxDerivative = 0.99e30 ;
|
||||
G4double* u = new G4double[fNumber - 1] ;
|
||||
G4int i = 0;
|
||||
G4double p = 0.0, qn = 0.0, sig = 0.0, un = 0.0;
|
||||
const G4double maxDerivative = 0.99e30;
|
||||
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(G4int k=fNumber-2;k>=0;k--)
|
||||
{
|
||||
fSecondDerivative[k] = fSecondDerivative[k]*fSecondDerivative[k+1] + u[k];
|
||||
}
|
||||
delete[] u ;
|
||||
}
|
||||
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(G4int 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; }
|
||||
delete[] fArgument;
|
||||
delete[] fFunction;
|
||||
delete[] fSecondDerivative;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -143,50 +146,50 @@ G4DataInterpolation::~G4DataInterpolation()
|
||||
// This is Lagrange's form of interpolation and it is based on Neville's
|
||||
// algorithm
|
||||
|
||||
G4double
|
||||
G4DataInterpolation::PolynomInterpolation(G4double pX,
|
||||
G4double& deltaY ) const
|
||||
G4double G4DataInterpolation::PolynomInterpolation(G4double pX,
|
||||
G4double& deltaY) const
|
||||
{
|
||||
G4int i=0, j=1, k=0 ;
|
||||
G4double mult=0.0, difi=0.0, deltaLow=0.0, deltaUp=0.0, cd=0.0, y=0.0 ;
|
||||
G4double* c = new G4double[fNumber] ;
|
||||
G4double* d = new G4double[fNumber] ;
|
||||
G4double diff = std::fabs(pX-fArgument[0]) ;
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
difi = std::fabs(pX-fArgument[i]) ;
|
||||
if(difi <diff)
|
||||
G4int i = 0, j = 1, k = 0;
|
||||
G4double mult = 0.0, difi = 0.0, deltaLow = 0.0, deltaUp = 0.0, cd = 0.0,
|
||||
y = 0.0;
|
||||
G4double* c = new G4double[fNumber];
|
||||
G4double* d = new G4double[fNumber];
|
||||
G4double diff = std::fabs(pX - fArgument[0]);
|
||||
for(i = 0; i < fNumber; ++i)
|
||||
{
|
||||
difi = std::fabs(pX - fArgument[i]);
|
||||
if(difi < diff)
|
||||
{
|
||||
k = i;
|
||||
diff = difi;
|
||||
}
|
||||
c[i] = fFunction[i];
|
||||
d[i] = fFunction[i];
|
||||
}
|
||||
y = fFunction[k--];
|
||||
for(j = 1; j < fNumber; ++j)
|
||||
{
|
||||
for(i = 0; i < fNumber - j; ++i)
|
||||
{
|
||||
deltaLow = fArgument[i] - pX;
|
||||
deltaUp = fArgument[i + j] - pX;
|
||||
cd = c[i + 1] - d[i];
|
||||
mult = deltaLow - deltaUp;
|
||||
if(!(mult != 0.0))
|
||||
{
|
||||
k = i ;
|
||||
diff = difi ;
|
||||
G4Exception("G4DataInterpolation::PolynomInterpolation()", "Error",
|
||||
FatalException, "Coincident nodes !");
|
||||
}
|
||||
c[i] = fFunction[i] ;
|
||||
d[i] = fFunction[i] ;
|
||||
}
|
||||
y = fFunction[k--] ;
|
||||
for(j=1;j<fNumber;j++)
|
||||
{
|
||||
for(i=0;i<fNumber-j;i++)
|
||||
{
|
||||
deltaLow = fArgument[i] - pX ;
|
||||
deltaUp = fArgument[i+j] - pX ;
|
||||
cd = c[i+1] - d[i] ;
|
||||
mult = deltaLow - deltaUp ;
|
||||
if (!(mult != 0.0))
|
||||
{
|
||||
G4Exception("G4DataInterpolation::PolynomInterpolation()",
|
||||
"Error", FatalException, "Coincident nodes !") ;
|
||||
}
|
||||
mult = cd/mult ;
|
||||
d[i] = deltaUp*mult ;
|
||||
c[i] = deltaLow*mult ;
|
||||
}
|
||||
y += (deltaY = (2*k < (fNumber - j -1) ? c[k+1] : d[k--] )) ;
|
||||
}
|
||||
delete[] c ;
|
||||
delete[] d ;
|
||||
|
||||
return y ;
|
||||
mult = cd / mult;
|
||||
d[i] = deltaUp * mult;
|
||||
c[i] = deltaLow * mult;
|
||||
}
|
||||
y += (deltaY = (2 * k < (fNumber - j - 1) ? c[k + 1] : d[k--]));
|
||||
}
|
||||
delete[] c;
|
||||
delete[] d;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -194,47 +197,46 @@ G4DataInterpolation::PolynomInterpolation(G4double pX,
|
||||
// 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
|
||||
// with PolynomInterpolation function. They could be used instead for derivate
|
||||
// calculations and some other applications.
|
||||
|
||||
void
|
||||
G4DataInterpolation::PolIntCoefficient( G4double cof[]) const
|
||||
void G4DataInterpolation::PolIntCoefficient(G4double cof[]) const
|
||||
{
|
||||
G4int i=0, j=0 ;
|
||||
G4double factor;
|
||||
G4double reducedY=0.0, mult=1.0 ;
|
||||
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 ;
|
||||
G4int i = 0, j = 0;
|
||||
G4double factor;
|
||||
G4double reducedY = 0.0, mult = 1.0;
|
||||
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;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -244,59 +246,58 @@ G4DataInterpolation::PolIntCoefficient( G4double cof[]) const
|
||||
// Tests showed the method is not stable and hasn't advantage if compared
|
||||
// with polynomial interpolation ?!
|
||||
|
||||
G4double
|
||||
G4DataInterpolation::RationalPolInterpolation(G4double pX,
|
||||
G4double& deltaY ) const
|
||||
G4double G4DataInterpolation::RationalPolInterpolation(G4double pX,
|
||||
G4double& deltaY) const
|
||||
{
|
||||
G4int i=0, j=1, k=0 ;
|
||||
const G4double tolerance = 1.6e-24 ;
|
||||
G4double mult=0.0, difi=0.0, cd=0.0, y=0.0, cof=0.0 ;
|
||||
G4double* c = new G4double[fNumber] ;
|
||||
G4double* d = new G4double[fNumber] ;
|
||||
G4double diff = std::fabs(pX-fArgument[0]) ;
|
||||
for(i=0;i<fNumber;i++)
|
||||
{
|
||||
difi = std::fabs(pX-fArgument[i]) ;
|
||||
if (!(difi != 0.0))
|
||||
G4int i = 0, j = 1, k = 0;
|
||||
const G4double tolerance = 1.6e-24;
|
||||
G4double mult = 0.0, difi = 0.0, cd = 0.0, y = 0.0, cof = 0.0;
|
||||
G4double* c = new G4double[fNumber];
|
||||
G4double* d = new G4double[fNumber];
|
||||
G4double diff = std::fabs(pX - fArgument[0]);
|
||||
for(i = 0; i < fNumber; ++i)
|
||||
{
|
||||
difi = std::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(j = 1; j < fNumber; ++j)
|
||||
{
|
||||
for(i = 0; i < fNumber - j; ++i)
|
||||
{
|
||||
cd = c[i + 1] - d[i];
|
||||
difi = fArgument[i + j] - 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
|
||||
{
|
||||
y = fFunction[i] ;
|
||||
deltaY = 0.0 ;
|
||||
delete[] c ;
|
||||
delete[] d ;
|
||||
return y ;
|
||||
G4Exception("G4DataInterpolation::RationalPolInterpolation()", "Error",
|
||||
FatalException, "Coincident nodes !");
|
||||
}
|
||||
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(j=1;j<fNumber;j++)
|
||||
{
|
||||
for(i=0;i<fNumber-j;i++)
|
||||
{
|
||||
cd = c[i+1] - d[i] ;
|
||||
difi = fArgument[i+j] - 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("G4DataInterpolation::RationalPolInterpolation()",
|
||||
"Error", FatalException, "Coincident nodes !") ;
|
||||
}
|
||||
mult = cd/mult ;
|
||||
d[i] = c[i+1]*mult ;
|
||||
c[i] = cof*mult ;
|
||||
}
|
||||
y += (deltaY = (2*k < (fNumber - j - 1) ? c[k+1] : d[k--] )) ;
|
||||
}
|
||||
delete[] c ;
|
||||
delete[] d ;
|
||||
|
||||
return y ;
|
||||
mult = cd / mult;
|
||||
d[i] = c[i + 1] * mult;
|
||||
c[i] = cof * mult;
|
||||
}
|
||||
y += (deltaY = (2 * k < (fNumber - j - 1) ? c[k + 1] : d[k--]));
|
||||
}
|
||||
delete[] c;
|
||||
delete[] d;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -306,40 +307,40 @@ G4DataInterpolation::RationalPolInterpolation(G4double pX,
|
||||
// must be called before. The function works optimal, if sequential calls
|
||||
// are in random values of pX.
|
||||
|
||||
G4double
|
||||
G4DataInterpolation::CubicSplineInterpolation(G4double pX) const
|
||||
G4double G4DataInterpolation::CubicSplineInterpolation(G4double pX) const
|
||||
{
|
||||
G4int kLow=0, kHigh=fNumber-1, k=0 ;
|
||||
|
||||
// Searching in the table by means of bisection method.
|
||||
// fArgument must be monotonic, either increasing or decreasing
|
||||
|
||||
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
|
||||
G4double deltaHL = fArgument[kHigh] - fArgument[kLow] ;
|
||||
if (!(deltaHL != 0.0))
|
||||
{
|
||||
G4Exception("G4DataInterpolation::CubicSplineInterpolation()",
|
||||
"Error", FatalException, "Bad fArgument input !") ;
|
||||
}
|
||||
G4double a = (fArgument[kHigh] - pX)/deltaHL ;
|
||||
G4double 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 ;
|
||||
G4int kLow = 0, kHigh = fNumber - 1, k = 0;
|
||||
|
||||
// Searching in the table by means of bisection method.
|
||||
// fArgument must be monotonic, either increasing or decreasing
|
||||
|
||||
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
|
||||
G4double deltaHL = fArgument[kHigh] - fArgument[kLow];
|
||||
if(!(deltaHL != 0.0))
|
||||
{
|
||||
G4Exception("G4DataInterpolation::CubicSplineInterpolation()", "Error",
|
||||
FatalException, "Bad fArgument input !");
|
||||
}
|
||||
G4double a = (fArgument[kHigh] - pX) / deltaHL;
|
||||
G4double 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;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@@ -348,24 +349,23 @@ G4DataInterpolation::CubicSplineInterpolation(G4double pX) const
|
||||
// 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 G4DataInterpolation::FastCubicSpline(G4double pX, G4int index) const
|
||||
{
|
||||
G4double delta = fArgument[index+1] - fArgument[index] ;
|
||||
if (!(delta != 0.0))
|
||||
{
|
||||
G4Exception("G4DataInterpolation::FastCubicSpline()",
|
||||
"Error", FatalException, "Bad fArgument input !") ;
|
||||
}
|
||||
G4double a = (fArgument[index+1] - pX)/delta ;
|
||||
G4double 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 ;
|
||||
G4double delta = fArgument[index + 1] - fArgument[index];
|
||||
if(!(delta != 0.0))
|
||||
{
|
||||
G4Exception("G4DataInterpolation::FastCubicSpline()", "Error",
|
||||
FatalException, "Bad fArgument input !");
|
||||
}
|
||||
G4double a = (fArgument[index + 1] - pX) / delta;
|
||||
G4double 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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -373,32 +373,32 @@ G4DataInterpolation::FastCubicSpline(G4double pX,
|
||||
// Given argument pX, returns index k, so that pX bracketed by fArgument[k]
|
||||
// and fArgument[k+1]
|
||||
|
||||
G4int
|
||||
G4DataInterpolation::LocateArgument(G4double pX) const
|
||||
G4int G4DataInterpolation::LocateArgument(G4double pX) const
|
||||
{
|
||||
G4int kLow=-1, kHigh=fNumber, k=0 ;
|
||||
G4bool 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 ;
|
||||
G4int kLow = -1, kHigh = fNumber, k = 0;
|
||||
G4bool 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;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -409,88 +409,86 @@ G4DataInterpolation::LocateArgument(G4double pX) const
|
||||
// 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
|
||||
void G4DataInterpolation::CorrelatedSearch(G4double pX, G4int& index) const
|
||||
{
|
||||
G4int kHigh=0, k=0, Increment=0 ;
|
||||
// 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)
|
||||
G4int kHigh = 0, k = 0, Increment = 0;
|
||||
// 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)
|
||||
{
|
||||
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 ;
|
||||
}
|
||||
}
|
||||
index = fNumber;
|
||||
return;
|
||||
}
|
||||
else
|
||||
kHigh = index + 1;
|
||||
while((pX >= fArgument[kHigh]) == ascend)
|
||||
{
|
||||
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
|
||||
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 ;
|
||||
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;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -23,53 +23,51 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4GaussChebyshevQ class implementation
|
||||
//
|
||||
//
|
||||
// Author: V.Grichine, 13.05.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4GaussChebyshevQ.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
|
||||
// -----------------------------------------------------
|
||||
//
|
||||
// Constructor for Gauss-Chebyshev quadrature method
|
||||
|
||||
G4GaussChebyshevQ::G4GaussChebyshevQ( function pFunction ,
|
||||
G4int nChebyshev )
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
//
|
||||
G4GaussChebyshevQ::G4GaussChebyshevQ(function pFunction, G4int nChebyshev)
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
{
|
||||
fNumber = nChebyshev ; // Try to reduce fNumber twice ??
|
||||
G4double cof = pi/fNumber ;
|
||||
fAbscissa = new G4double[fNumber] ;
|
||||
fWeight = new G4double[fNumber] ;
|
||||
for(G4int i=0;i<fNumber;i++)
|
||||
{
|
||||
fAbscissa[i] = std::cos(cof*(i + 0.5)) ;
|
||||
fWeight[i] = cof*std::sqrt(1 - fAbscissa[i]*fAbscissa[i]) ;
|
||||
}
|
||||
fNumber = nChebyshev; // Try to reduce fNumber twice ??
|
||||
G4double cof = pi / fNumber;
|
||||
fAbscissa = new G4double[fNumber];
|
||||
fWeight = new G4double[fNumber];
|
||||
for(G4int i = 0; i < fNumber; ++i)
|
||||
{
|
||||
fAbscissa[i] = std::cos(cof * (i + 0.5));
|
||||
fWeight[i] = cof * std::sqrt(1 - fAbscissa[i] * fAbscissa[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
|
||||
G4GaussChebyshevQ::~G4GaussChebyshevQ()
|
||||
{
|
||||
}
|
||||
G4GaussChebyshevQ::~G4GaussChebyshevQ() {}
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
//
|
||||
// Integrates function pointed by fFunction from a to b by Gauss-Chebyshev
|
||||
// Integrates function pointed by fFunction from a to b by Gauss-Chebyshev
|
||||
// quadrature method
|
||||
|
||||
G4double
|
||||
G4GaussChebyshevQ::Integral(G4double a, G4double b) const
|
||||
//
|
||||
G4double G4GaussChebyshevQ::Integral(G4double a, G4double b) const
|
||||
{
|
||||
G4double xDiff=0.5*(b - a),
|
||||
xMean=0.5*(a + b),
|
||||
dx=0.0, integral=0.0 ;
|
||||
|
||||
for(G4int i=0;i<fNumber;i++)
|
||||
{
|
||||
dx = xDiff*fAbscissa[i] ;
|
||||
integral += fWeight[i]*fFunction(xMean + dx) ;
|
||||
}
|
||||
return integral *= xDiff ;
|
||||
G4double xDiff = 0.5 * (b - a), xMean = 0.5 * (a + b), dx = 0.0,
|
||||
integral = 0.0;
|
||||
|
||||
for(G4int i = 0; i < fNumber; ++i)
|
||||
{
|
||||
dx = xDiff * fAbscissa[i];
|
||||
integral += fWeight[i] * fFunction(xMean + dx);
|
||||
}
|
||||
return integral *= xDiff;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4GaussHermiteQ class implementation
|
||||
//
|
||||
//
|
||||
// Author: V.Grichine, 13.05.1997 V.Grichine
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4GaussHermiteQ.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
@@ -33,88 +35,87 @@
|
||||
//
|
||||
// Constructor for Gauss-Hermite
|
||||
|
||||
G4GaussHermiteQ::G4GaussHermiteQ ( function pFunction,
|
||||
G4int nHermite )
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
G4GaussHermiteQ::G4GaussHermiteQ(function pFunction, G4int nHermite)
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
{
|
||||
const G4double tolerance = 1.0e-12 ;
|
||||
const G4int maxNumber = 12 ;
|
||||
|
||||
G4int i=1, j=1, k=1 ;
|
||||
G4double newton0=0.;
|
||||
G4double newton1=0.0, temp1=0.0, temp2=0.0, temp3=0.0, temp=0.0 ;
|
||||
G4double piInMinusQ = std::pow(pi,-0.25) ; // 1.0/std::sqrt(std::sqrt(pi)) ??
|
||||
const G4double tolerance = 1.0e-12;
|
||||
const G4int maxNumber = 12;
|
||||
|
||||
fNumber = (nHermite +1)/2 ;
|
||||
fAbscissa = new G4double[fNumber] ;
|
||||
fWeight = new G4double[fNumber] ;
|
||||
G4int i = 1, j = 1, k = 1;
|
||||
G4double newton0 = 0.;
|
||||
G4double newton1 = 0.0, temp1 = 0.0, temp2 = 0.0, temp3 = 0.0, temp = 0.0;
|
||||
G4double piInMinusQ = std::pow(pi, -0.25); // 1.0/std::sqrt(std::sqrt(pi)) ??
|
||||
|
||||
for(i=1;i<=fNumber;i++)
|
||||
{
|
||||
if(i == 1)
|
||||
fNumber = (nHermite + 1) / 2;
|
||||
fAbscissa = new G4double[fNumber];
|
||||
fWeight = new G4double[fNumber];
|
||||
|
||||
for(i = 1; i <= fNumber; ++i)
|
||||
{
|
||||
if(i == 1)
|
||||
{
|
||||
newton0 =
|
||||
std::sqrt((G4double)(2 * nHermite + 1)) -
|
||||
1.85575001 * std::pow((G4double)(2 * nHermite + 1), -0.16666999);
|
||||
}
|
||||
else if(i == 2)
|
||||
{
|
||||
newton0 -= 1.14001 * std::pow((G4double) nHermite, 0.425999) / newton0;
|
||||
}
|
||||
else if(i == 3)
|
||||
{
|
||||
newton0 = 1.86002 * newton0 - 0.86002 * fAbscissa[0];
|
||||
}
|
||||
else if(i == 4)
|
||||
{
|
||||
newton0 = 1.91001 * newton0 - 0.91001 * fAbscissa[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
newton0 = 2.0 * newton0 - fAbscissa[i - 3];
|
||||
}
|
||||
for(k = 1; k <= maxNumber; ++k)
|
||||
{
|
||||
temp1 = piInMinusQ;
|
||||
temp2 = 0.0;
|
||||
for(j = 1; j <= nHermite; ++j)
|
||||
{
|
||||
newton0 = std::sqrt((G4double)(2*nHermite + 1)) -
|
||||
1.85575001*std::pow((G4double)(2*nHermite + 1),-0.16666999) ;
|
||||
temp3 = temp2;
|
||||
temp2 = temp1;
|
||||
temp1 = newton0 * std::sqrt(2.0 / j) * temp2 -
|
||||
std::sqrt(((G4double)(j - 1)) / j) * temp3;
|
||||
}
|
||||
else if(i == 2)
|
||||
temp = std::sqrt((G4double) 2 * nHermite) * temp2;
|
||||
newton1 = newton0;
|
||||
newton0 = newton1 - temp1 / temp;
|
||||
if(std::fabs(newton0 - newton1) <= tolerance)
|
||||
{
|
||||
newton0 -= 1.14001*std::pow((G4double)nHermite,0.425999)/newton0 ;
|
||||
break;
|
||||
}
|
||||
else if(i == 3)
|
||||
{
|
||||
newton0 = 1.86002*newton0 - 0.86002*fAbscissa[0] ;
|
||||
}
|
||||
else if(i == 4)
|
||||
{
|
||||
newton0 = 1.91001*newton0 - 0.91001*fAbscissa[1] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
newton0 = 2.0*newton0 - 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 = newton0*std::sqrt(2.0/j)*temp2
|
||||
- std::sqrt(((G4double)(j - 1))/j)*temp3 ;
|
||||
}
|
||||
temp = std::sqrt((G4double)2*nHermite)*temp2 ;
|
||||
newton1 = newton0 ;
|
||||
newton0 = newton1 - temp1/temp ;
|
||||
if(std::fabs(newton0 - newton1) <= tolerance)
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if(k > maxNumber)
|
||||
{
|
||||
G4Exception("G4GaussHermiteQ::G4GaussHermiteQ()",
|
||||
"OutOfRange", FatalException,
|
||||
"Too many iterations in Gauss-Hermite constructor.") ;
|
||||
}
|
||||
fAbscissa[i-1] = newton0 ;
|
||||
fWeight[i-1] = 2.0/(temp*temp) ;
|
||||
}
|
||||
}
|
||||
if(k > maxNumber)
|
||||
{
|
||||
G4Exception("G4GaussHermiteQ::G4GaussHermiteQ()", "OutOfRange",
|
||||
FatalException,
|
||||
"Too many iterations in Gauss-Hermite constructor.");
|
||||
}
|
||||
fAbscissa[i - 1] = newton0;
|
||||
fWeight[i - 1] = 2.0 / (temp * temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------
|
||||
//
|
||||
// Gauss-Hermite method for integration of std::exp(-x*x)*nFunction(x)
|
||||
// from minus infinity to plus infinity .
|
||||
// from minus infinity to plus infinity .
|
||||
|
||||
G4double G4GaussHermiteQ::Integral() const
|
||||
G4double G4GaussHermiteQ::Integral() const
|
||||
{
|
||||
G4double integral = 0.0 ;
|
||||
for(G4int i=0;i<fNumber;i++)
|
||||
{
|
||||
integral += fWeight[i]*(fFunction(fAbscissa[i])
|
||||
+ fFunction(-fAbscissa[i])) ;
|
||||
}
|
||||
return integral ;
|
||||
G4double integral = 0.0;
|
||||
for(G4int i = 0; i < fNumber; ++i)
|
||||
{
|
||||
integral +=
|
||||
fWeight[i] * (fFunction(fAbscissa[i]) + fFunction(-fAbscissa[i]));
|
||||
}
|
||||
return integral;
|
||||
}
|
||||
|
||||
@@ -23,138 +23,138 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4GaussJacobiQ class implementation
|
||||
//
|
||||
//
|
||||
#include "G4GaussJacobiQ.hh"
|
||||
// Author: V.Grichine, 13.05.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4GaussJacobiQ.hh"
|
||||
|
||||
// -------------------------------------------------------------
|
||||
//
|
||||
// Constructor for Gauss-Jacobi integration method.
|
||||
// Constructor for Gauss-Jacobi integration method.
|
||||
//
|
||||
|
||||
G4GaussJacobiQ::G4GaussJacobiQ( function pFunction,
|
||||
G4double alpha,
|
||||
G4double beta,
|
||||
G4int nJacobi )
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
G4GaussJacobiQ::G4GaussJacobiQ(function pFunction, G4double alpha,
|
||||
G4double beta, G4int nJacobi)
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
|
||||
{
|
||||
const G4double tolerance = 1.0e-12 ;
|
||||
const G4double maxNumber = 12 ;
|
||||
G4int i=1, k=1 ;
|
||||
G4double root=0.;
|
||||
G4double alphaBeta=0.0, alphaReduced=0.0, betaReduced=0.0,
|
||||
root1=0.0, root2=0.0, root3=0.0 ;
|
||||
G4double a=0.0, b=0.0, c=0.0,
|
||||
newton1=0.0, newton2=0.0, newton3=0.0, newton0=0.0,
|
||||
temp=0.0, rootTemp=0.0 ;
|
||||
const G4double tolerance = 1.0e-12;
|
||||
const G4double maxNumber = 12;
|
||||
G4int i = 1, k = 1;
|
||||
G4double root = 0.;
|
||||
G4double alphaBeta = 0.0, alphaReduced = 0.0, betaReduced = 0.0, root1 = 0.0,
|
||||
root2 = 0.0, root3 = 0.0;
|
||||
G4double a = 0.0, b = 0.0, c = 0.0, newton1 = 0.0, newton2 = 0.0,
|
||||
newton3 = 0.0, newton0 = 0.0, temp = 0.0, rootTemp = 0.0;
|
||||
|
||||
fNumber = nJacobi ;
|
||||
fAbscissa = new G4double[fNumber] ;
|
||||
fWeight = new G4double[fNumber] ;
|
||||
fNumber = nJacobi;
|
||||
fAbscissa = new G4double[fNumber];
|
||||
fWeight = new G4double[fNumber];
|
||||
|
||||
for (i=1;i<=nJacobi;i++)
|
||||
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*std::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 (G4int 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 ;
|
||||
}
|
||||
newton0 = (nJacobi*(alpha - beta - temp*root)*newton1 +
|
||||
2.0*(nJacobi + alpha)*(nJacobi + beta)*newton2)/
|
||||
(temp*(1.0 - root*root)) ;
|
||||
rootTemp = root ;
|
||||
root = rootTemp - newton1/newton0 ;
|
||||
if (std::fabs(root-rootTemp) <= tolerance)
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if (k > maxNumber)
|
||||
{
|
||||
G4Exception("G4GaussJacobiQ::G4GaussJacobiQ()", "OutOfRange",
|
||||
FatalException, "Too many iterations in constructor.") ;
|
||||
}
|
||||
fAbscissa[i-1] = root ;
|
||||
fWeight[i-1] = std::exp(GammaLogarithm((G4double)(alpha+nJacobi)) +
|
||||
GammaLogarithm((G4double)(beta+nJacobi)) -
|
||||
GammaLogarithm((G4double)(nJacobi+1.0)) -
|
||||
GammaLogarithm((G4double)(nJacobi + alphaBeta + 1.0)))
|
||||
*temp*std::pow(2.0,alphaBeta)/(newton0*newton2) ;
|
||||
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 * std::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(G4int 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;
|
||||
}
|
||||
newton0 = (nJacobi * (alpha - beta - temp * root) * newton1 +
|
||||
2.0 * (nJacobi + alpha) * (nJacobi + beta) * newton2) /
|
||||
(temp * (1.0 - root * root));
|
||||
rootTemp = root;
|
||||
root = rootTemp - newton1 / newton0;
|
||||
if(std::fabs(root - rootTemp) <= tolerance)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(k > maxNumber)
|
||||
{
|
||||
G4Exception("G4GaussJacobiQ::G4GaussJacobiQ()", "OutOfRange",
|
||||
FatalException, "Too many iterations in constructor.");
|
||||
}
|
||||
fAbscissa[i - 1] = root;
|
||||
fWeight[i - 1] =
|
||||
std::exp(GammaLogarithm((G4double)(alpha + nJacobi)) +
|
||||
GammaLogarithm((G4double)(beta + nJacobi)) -
|
||||
GammaLogarithm((G4double)(nJacobi + 1.0)) -
|
||||
GammaLogarithm((G4double)(nJacobi + alphaBeta + 1.0))) *
|
||||
temp * std::pow(2.0, alphaBeta) / (newton0 * 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
|
||||
G4double G4GaussJacobiQ::Integral() const
|
||||
{
|
||||
G4double integral = 0.0 ;
|
||||
for(G4int i=0;i<fNumber;i++)
|
||||
{
|
||||
integral += fWeight[i]*fFunction(fAbscissa[i]) ;
|
||||
}
|
||||
return integral ;
|
||||
G4double integral = 0.0;
|
||||
for(G4int i = 0; i < fNumber; ++i)
|
||||
{
|
||||
integral += fWeight[i] * fFunction(fAbscissa[i]);
|
||||
}
|
||||
return integral;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,84 +23,85 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4GaussLaguerreQ class implementation
|
||||
//
|
||||
//
|
||||
// Author: V.Grichine, 13.05.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4GaussLaguerreQ.hh"
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
//
|
||||
// Constructor for Gauss-Laguerre quadrature method: integral from zero to
|
||||
// infinity of std::pow(x,alpha)*std::exp(-x)*f(x).
|
||||
// The value of nLaguerre sets the accuracy.
|
||||
// The constructor creates arrays fAbscissa[0,..,nLaguerre-1] and
|
||||
// fWeight[0,..,nLaguerre-1] .
|
||||
// The constructor creates arrays fAbscissa[0,..,nLaguerre-1] and
|
||||
// fWeight[0,..,nLaguerre-1] .
|
||||
//
|
||||
|
||||
G4GaussLaguerreQ::G4GaussLaguerreQ( function pFunction,
|
||||
G4double alpha,
|
||||
G4int nLaguerre )
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
G4GaussLaguerreQ::G4GaussLaguerreQ(function pFunction, G4double alpha,
|
||||
G4int nLaguerre)
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
{
|
||||
const G4double tolerance = 1.0e-10 ;
|
||||
const G4int maxNumber = 12 ;
|
||||
G4int i=1, k=1 ;
|
||||
G4double newton0=0.0, newton1=0.0,
|
||||
temp1=0.0, temp2=0.0, temp3=0.0, temp=0.0, cofi=0.0 ;
|
||||
const G4double tolerance = 1.0e-10;
|
||||
const G4int maxNumber = 12;
|
||||
G4int i = 1, k = 1;
|
||||
G4double newton0 = 0.0, newton1 = 0.0, temp1 = 0.0, temp2 = 0.0, temp3 = 0.0,
|
||||
temp = 0.0, cofi = 0.0;
|
||||
|
||||
fNumber = nLaguerre ;
|
||||
fAbscissa = new G4double[fNumber] ;
|
||||
fWeight = new G4double[fNumber] ;
|
||||
|
||||
for(i=1;i<=fNumber;i++) // Loop over the desired roots
|
||||
{
|
||||
if(i == 1)
|
||||
fNumber = nLaguerre;
|
||||
fAbscissa = new G4double[fNumber];
|
||||
fWeight = new G4double[fNumber];
|
||||
|
||||
for(i = 1; i <= fNumber; ++i) // Loop over the desired roots
|
||||
{
|
||||
if(i == 1)
|
||||
{
|
||||
newton0 = (1.0 + alpha) * (3.0 + 0.92 * alpha) /
|
||||
(1.0 + 2.4 * fNumber + 1.8 * alpha);
|
||||
}
|
||||
else if(i == 2)
|
||||
{
|
||||
newton0 += (15.0 + 6.25 * alpha) / (1.0 + 0.9 * alpha + 2.5 * fNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
cofi = i - 2;
|
||||
newton0 += ((1.0 + 2.55 * cofi) / (1.9 * cofi) +
|
||||
1.26 * cofi * alpha / (1.0 + 3.5 * cofi)) *
|
||||
(newton0 - fAbscissa[i - 3]) / (1.0 + 0.3 * alpha);
|
||||
}
|
||||
for(k = 1; k <= maxNumber; ++k)
|
||||
{
|
||||
temp1 = 1.0;
|
||||
temp2 = 0.0;
|
||||
for(G4int j = 1; j <= fNumber; ++j)
|
||||
{
|
||||
newton0 = (1.0 + alpha)*(3.0 + 0.92*alpha)
|
||||
/ (1.0 + 2.4*fNumber + 1.8*alpha) ;
|
||||
temp3 = temp2;
|
||||
temp2 = temp1;
|
||||
temp1 =
|
||||
((2 * j - 1 + alpha - newton0) * temp2 - (j - 1 + alpha) * temp3) / j;
|
||||
}
|
||||
else if(i == 2)
|
||||
temp = (fNumber * temp1 - (fNumber + alpha) * temp2) / newton0;
|
||||
newton1 = newton0;
|
||||
newton0 = newton1 - temp1 / temp;
|
||||
if(std::fabs(newton0 - newton1) <= tolerance)
|
||||
{
|
||||
newton0 += (15.0 + 6.25*alpha)/(1.0 + 0.9*alpha + 2.5*fNumber) ;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
cofi = i - 2 ;
|
||||
newton0 += ((1.0+2.55*cofi)/(1.9*cofi)
|
||||
+ 1.26*cofi*alpha/(1.0+3.5*cofi))
|
||||
* (newton0 - fAbscissa[i-3])/(1.0 + 0.3*alpha) ;
|
||||
}
|
||||
for(k=1;k<=maxNumber;k++)
|
||||
{
|
||||
temp1 = 1.0 ;
|
||||
temp2 = 0.0 ;
|
||||
for(G4int j=1;j<=fNumber;j++)
|
||||
{
|
||||
temp3 = temp2 ;
|
||||
temp2 = temp1 ;
|
||||
temp1 = ((2*j - 1 + alpha - newton0)*temp2
|
||||
- (j - 1 + alpha)*temp3)/j ;
|
||||
}
|
||||
temp = (fNumber*temp1 - (fNumber +alpha)*temp2)/newton0 ;
|
||||
newton1 = newton0 ;
|
||||
newton0 = newton1 - temp1/temp ;
|
||||
if(std::fabs(newton0 - newton1) <= tolerance)
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if(k > maxNumber)
|
||||
{
|
||||
G4Exception("G4GaussLaguerreQ::G4GaussLaguerreQ()",
|
||||
"OutOfRange", FatalException,
|
||||
"Too many iterations in Gauss-Laguerre constructor") ;
|
||||
}
|
||||
|
||||
fAbscissa[i-1] = newton0 ;
|
||||
fWeight[i-1] = -std::exp(GammaLogarithm(alpha + fNumber)
|
||||
- GammaLogarithm((G4double)fNumber))/(temp*fNumber*temp2) ;
|
||||
}
|
||||
}
|
||||
if(k > maxNumber)
|
||||
{
|
||||
G4Exception("G4GaussLaguerreQ::G4GaussLaguerreQ()", "OutOfRange",
|
||||
FatalException,
|
||||
"Too many iterations in Gauss-Laguerre constructor");
|
||||
}
|
||||
|
||||
fAbscissa[i - 1] = newton0;
|
||||
fWeight[i - 1] = -std::exp(GammaLogarithm(alpha + fNumber) -
|
||||
GammaLogarithm((G4double) fNumber)) /
|
||||
(temp * fNumber * temp2);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
@@ -111,13 +112,12 @@ G4GaussLaguerreQ::G4GaussLaguerreQ( function pFunction,
|
||||
// for which fAbscissa[i] and fWeight[i] arrays were created in
|
||||
// G4VGaussianQuadrature(double,int) constructor
|
||||
|
||||
G4double
|
||||
G4GaussLaguerreQ::Integral() const
|
||||
G4double G4GaussLaguerreQ::Integral() const
|
||||
{
|
||||
G4double integral = 0.0 ;
|
||||
for(G4int i=0;i<fNumber;i++)
|
||||
{
|
||||
integral += fWeight[i]*fFunction(fAbscissa[i]) ;
|
||||
}
|
||||
return integral ;
|
||||
G4double integral = 0.0;
|
||||
for(G4int i = 0; i < fNumber; ++i)
|
||||
{
|
||||
integral += fWeight[i] * fFunction(fAbscissa[i]);
|
||||
}
|
||||
return integral;
|
||||
}
|
||||
|
||||
@@ -23,66 +23,65 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4GaussLegendreQ class implementation
|
||||
//
|
||||
//
|
||||
// Author: V.Grichine, 13.05.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4GaussLegendreQ.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
|
||||
G4GaussLegendreQ::G4GaussLegendreQ( function pFunction )
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
{
|
||||
}
|
||||
G4GaussLegendreQ::G4GaussLegendreQ(function pFunction)
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
{}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
//
|
||||
// Constructor for GaussLegendre quadrature method. The value nLegendre sets
|
||||
// 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 are used in Gauss-Legendre quadrature method.
|
||||
// abscissas and weights that are 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)
|
||||
G4GaussLegendreQ::G4GaussLegendreQ(function pFunction, G4int nLegendre)
|
||||
: G4VGaussianQuadrature(pFunction)
|
||||
{
|
||||
const G4double tolerance = 1.6e-10 ;
|
||||
G4int k = nLegendre ;
|
||||
fNumber = (nLegendre + 1)/2 ;
|
||||
if(2*fNumber != k)
|
||||
{
|
||||
G4Exception("G4GaussLegendreQ::G4GaussLegendreQ()", "InvalidCall",
|
||||
FatalException, "Invalid nLegendre argument !") ;
|
||||
}
|
||||
G4double newton0=0.0, newton1=0.0,
|
||||
temp1=0.0, temp2=0.0, temp3=0.0, temp=0.0 ;
|
||||
const G4double tolerance = 1.6e-10;
|
||||
G4int k = nLegendre;
|
||||
fNumber = (nLegendre + 1) / 2;
|
||||
if(2 * fNumber != k)
|
||||
{
|
||||
G4Exception("G4GaussLegendreQ::G4GaussLegendreQ()", "InvalidCall",
|
||||
FatalException, "Invalid nLegendre argument !");
|
||||
}
|
||||
G4double newton0 = 0.0, newton1 = 0.0, temp1 = 0.0, temp2 = 0.0, temp3 = 0.0,
|
||||
temp = 0.0;
|
||||
|
||||
fAbscissa = new G4double[fNumber] ;
|
||||
fWeight = new G4double[fNumber] ;
|
||||
|
||||
for(G4int i=1;i<=fNumber;i++) // Loop over the desired roots
|
||||
{
|
||||
newton0 = std::cos(pi*(i - 0.25)/(k + 0.5)) ; // Initial root
|
||||
do // approximation
|
||||
{ // loop of Newton's method
|
||||
temp1 = 1.0 ;
|
||||
temp2 = 0.0 ;
|
||||
for(G4int j=1;j<=k;j++)
|
||||
{
|
||||
temp3 = temp2 ;
|
||||
temp2 = temp1 ;
|
||||
temp1 = ((2.0*j - 1.0)*newton0*temp2 - (j - 1.0)*temp3)/j ;
|
||||
}
|
||||
temp = k*(newton0*temp1 - temp2)/(newton0*newton0 - 1.0) ;
|
||||
newton1 = newton0 ;
|
||||
newton0 = newton1 - temp1/temp ; // Newton's method
|
||||
fAbscissa = new G4double[fNumber];
|
||||
fWeight = new G4double[fNumber];
|
||||
|
||||
for(G4int i = 1; i <= fNumber; ++i) // Loop over the desired roots
|
||||
{
|
||||
newton0 = std::cos(pi * (i - 0.25) / (k + 0.5)); // Initial root
|
||||
do // approximation
|
||||
{ // loop of Newton's method
|
||||
temp1 = 1.0;
|
||||
temp2 = 0.0;
|
||||
for(G4int j = 1; j <= k; ++j)
|
||||
{
|
||||
temp3 = temp2;
|
||||
temp2 = temp1;
|
||||
temp1 = ((2.0 * j - 1.0) * newton0 * temp2 - (j - 1.0) * temp3) / j;
|
||||
}
|
||||
while(std::fabs(newton0 - newton1) > tolerance) ;
|
||||
temp = k * (newton0 * temp1 - temp2) / (newton0 * newton0 - 1.0);
|
||||
newton1 = newton0;
|
||||
newton0 = newton1 - temp1 / temp; // Newton's method
|
||||
} while(std::fabs(newton0 - newton1) > tolerance);
|
||||
|
||||
fAbscissa[fNumber-i] = newton0 ;
|
||||
fWeight[fNumber-i] = 2.0/((1.0 - newton0*newton0)*temp*temp) ;
|
||||
}
|
||||
fAbscissa[fNumber - i] = newton0;
|
||||
fWeight[fNumber - i] = 2.0 / ((1.0 - newton0 * newton0) * temp * temp);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -94,18 +93,16 @@ G4GaussLegendreQ::G4GaussLegendreQ( function pFunction,
|
||||
// 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
|
||||
G4double G4GaussLegendreQ::Integral(G4double a, G4double b) const
|
||||
{
|
||||
G4double xMean = 0.5*(a + b),
|
||||
xDiff = 0.5*(b - a),
|
||||
integral = 0.0, dx = 0.0 ;
|
||||
for(G4int i=0;i<fNumber;i++)
|
||||
{
|
||||
dx = xDiff*fAbscissa[i] ;
|
||||
integral += fWeight[i]*(fFunction(xMean + dx) + fFunction(xMean - dx)) ;
|
||||
}
|
||||
return integral *= xDiff ;
|
||||
G4double xMean = 0.5 * (a + b), xDiff = 0.5 * (b - a), integral = 0.0,
|
||||
dx = 0.0;
|
||||
for(G4int i = 0; i < fNumber; ++i)
|
||||
{
|
||||
dx = xDiff * fAbscissa[i];
|
||||
integral += fWeight[i] * (fFunction(xMean + dx) + fFunction(xMean - dx));
|
||||
}
|
||||
return integral *= xDiff;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -117,27 +114,25 @@ G4GaussLegendreQ::Integral(G4double a, G4double b) const
|
||||
// the range of integration, there are actually only five distinct values of
|
||||
// each.
|
||||
|
||||
G4double
|
||||
G4GaussLegendreQ::QuickIntegral(G4double a, G4double b) const
|
||||
G4double G4GaussLegendreQ::QuickIntegral(G4double a, G4double b) const
|
||||
{
|
||||
// From Abramowitz M., Stegan I.A. 1964 , Handbook of Math... , p. 916
|
||||
// From Abramowitz M., Stegan I.A. 1964 , Handbook of Math... , p. 916
|
||||
|
||||
static const G4double abscissa[] = { 0.148874338981631, 0.433395394129247,
|
||||
0.679409568299024, 0.865063366688985,
|
||||
0.973906528517172 } ;
|
||||
|
||||
static const G4double weight[] = { 0.295524224714753, 0.269266719309996,
|
||||
0.219086362515982, 0.149451349150581,
|
||||
0.066671344308688 } ;
|
||||
G4double xMean = 0.5*(a + b),
|
||||
xDiff = 0.5*(b - a),
|
||||
integral = 0.0, dx = 0.0 ;
|
||||
for(G4int i=0;i<5;i++)
|
||||
{
|
||||
dx = xDiff*abscissa[i] ;
|
||||
integral += weight[i]*(fFunction(xMean + dx) + fFunction(xMean - dx)) ;
|
||||
}
|
||||
return integral *= xDiff ;
|
||||
static const G4double abscissa[] = { 0.148874338981631, 0.433395394129247,
|
||||
0.679409568299024, 0.865063366688985,
|
||||
0.973906528517172 };
|
||||
|
||||
static const G4double weight[] = { 0.295524224714753, 0.269266719309996,
|
||||
0.219086362515982, 0.149451349150581,
|
||||
0.066671344308688 };
|
||||
G4double xMean = 0.5 * (a + b), xDiff = 0.5 * (b - a), integral = 0.0,
|
||||
dx = 0.0;
|
||||
for(G4int i = 0; i < 5; ++i)
|
||||
{
|
||||
dx = xDiff * abscissa[i];
|
||||
integral += weight[i] * (fFunction(xMean + dx) + fFunction(xMean - dx));
|
||||
}
|
||||
return integral *= xDiff;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -149,87 +144,83 @@ G4double
|
||||
// the range of integration, there are actually only five distinct values of
|
||||
// each.
|
||||
|
||||
G4double
|
||||
G4GaussLegendreQ::AccurateIntegral(G4double a, G4double b) const
|
||||
{
|
||||
// From Abramowitz M., Stegan I.A. 1964 , Handbook of Math... , p. 919
|
||||
|
||||
static const
|
||||
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 const
|
||||
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
|
||||
} ;
|
||||
G4double xMean = 0.5*(a + b),
|
||||
xDiff = 0.5*(b - a),
|
||||
integral = 0.0, dx = 0.0 ;
|
||||
for(G4int i=0;i<48;i++)
|
||||
{
|
||||
dx = xDiff*abscissa[i] ;
|
||||
integral += weight[i]*(fFunction(xMean + dx) + fFunction(xMean - dx)) ;
|
||||
}
|
||||
return integral *= xDiff ;
|
||||
G4double G4GaussLegendreQ::AccurateIntegral(G4double a, G4double b) const
|
||||
{
|
||||
// From Abramowitz M., Stegan I.A. 1964 , Handbook of Math... , p. 919
|
||||
|
||||
static const 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 const 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
|
||||
};
|
||||
G4double xMean = 0.5 * (a + b), xDiff = 0.5 * (b - a), integral = 0.0,
|
||||
dx = 0.0;
|
||||
for(G4int i = 0; i < 48; ++i)
|
||||
{
|
||||
dx = xDiff * abscissa[i];
|
||||
integral += weight[i] * (fFunction(xMean + dx) + fFunction(xMean - dx));
|
||||
}
|
||||
return integral *= xDiff;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,161 +23,134 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4SimpleIntegration class implementation
|
||||
//
|
||||
//
|
||||
// Implementation file for simple integration methods
|
||||
//
|
||||
// Author: V.Grichine, 26.03.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4SimpleIntegration.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
G4SimpleIntegration::G4SimpleIntegration(function pFunction)
|
||||
: fFunction(pFunction)
|
||||
{}
|
||||
|
||||
G4SimpleIntegration::G4SimpleIntegration( function pFunction )
|
||||
: fFunction(pFunction),
|
||||
fTolerance(.0001),
|
||||
fMaxDepth(100)
|
||||
G4SimpleIntegration::G4SimpleIntegration(function pFunction,
|
||||
G4double pTolerance)
|
||||
: fFunction(pFunction)
|
||||
, fTolerance(pTolerance)
|
||||
{}
|
||||
|
||||
G4SimpleIntegration::~G4SimpleIntegration() {}
|
||||
|
||||
// Simple integration methods
|
||||
|
||||
G4double G4SimpleIntegration::Trapezoidal(G4double xInitial, G4double xFinal,
|
||||
G4int iterationNumber)
|
||||
{
|
||||
G4double Step = (xFinal - xInitial) / iterationNumber;
|
||||
G4double mean = (fFunction(xInitial) + fFunction(xFinal)) * 0.5;
|
||||
G4double x = xInitial;
|
||||
for(G4int i = 1; i < iterationNumber; ++i)
|
||||
{
|
||||
x += Step;
|
||||
mean += fFunction(x);
|
||||
}
|
||||
return mean * Step;
|
||||
}
|
||||
|
||||
G4SimpleIntegration::G4SimpleIntegration( function pFunction,
|
||||
G4double pTolerance)
|
||||
: fFunction(pFunction),
|
||||
fTolerance(pTolerance),
|
||||
fMaxDepth(100)
|
||||
G4double G4SimpleIntegration::MidPoint(G4double xInitial, G4double xFinal,
|
||||
G4int iterationNumber)
|
||||
{
|
||||
G4double Step = (xFinal - xInitial) / iterationNumber;
|
||||
G4double x = xInitial + 0.5 * Step;
|
||||
G4double mean = fFunction(x);
|
||||
for(G4int i = 1; i < iterationNumber; ++i)
|
||||
{
|
||||
x += Step;
|
||||
mean += fFunction(x);
|
||||
}
|
||||
return mean * Step;
|
||||
}
|
||||
|
||||
|
||||
G4SimpleIntegration::~G4SimpleIntegration()
|
||||
G4double G4SimpleIntegration::Gauss(G4double xInitial, G4double xFinal,
|
||||
G4int iterationNumber)
|
||||
{
|
||||
}
|
||||
|
||||
// Simple integration methods
|
||||
|
||||
G4double
|
||||
G4SimpleIntegration::Trapezoidal(G4double xInitial,
|
||||
G4double xFinal,
|
||||
G4int iterationNumber )
|
||||
{
|
||||
G4double Step = (xFinal - xInitial)/iterationNumber ;
|
||||
G4double mean = (fFunction(xInitial) + fFunction(xFinal))*0.5 ;
|
||||
G4double x = xInitial ;
|
||||
for(G4int i=1;i<iterationNumber;i++)
|
||||
{
|
||||
x += Step ;
|
||||
mean += fFunction(x) ;
|
||||
}
|
||||
return mean*Step ;
|
||||
G4double x = 0.;
|
||||
static const G4double root = 1.0 / std::sqrt(3.0);
|
||||
G4double Step = (xFinal - xInitial) / (2.0 * iterationNumber);
|
||||
G4double delta = Step * root;
|
||||
G4double mean = 0.0;
|
||||
for(G4int i = 0; i < iterationNumber; ++i)
|
||||
{
|
||||
x = (2 * i + 1) * Step;
|
||||
mean += (fFunction(x + delta) + fFunction(x - delta));
|
||||
}
|
||||
return mean * Step;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4SimpleIntegration::MidPoint(G4double xInitial,
|
||||
G4double xFinal,
|
||||
G4int iterationNumber )
|
||||
G4double G4SimpleIntegration::Simpson(G4double xInitial, G4double xFinal,
|
||||
G4int iterationNumber)
|
||||
{
|
||||
G4double Step = (xFinal - xInitial)/iterationNumber ;
|
||||
G4double x = xInitial + 0.5*Step;
|
||||
G4double mean = fFunction(x) ;
|
||||
for(G4int i=1;i<iterationNumber;i++)
|
||||
{
|
||||
x += Step ;
|
||||
mean += fFunction(x) ;
|
||||
}
|
||||
return mean*Step ;
|
||||
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(G4int i = 1; i < iterationNumber; ++i)
|
||||
{
|
||||
x += Step;
|
||||
xPlus += Step;
|
||||
mean += fFunction(x);
|
||||
sum += fFunction(xPlus);
|
||||
}
|
||||
mean += 2.0 * sum;
|
||||
return mean * Step / 3.0;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4SimpleIntegration::Gauss(G4double xInitial,
|
||||
G4double xFinal,
|
||||
G4int iterationNumber )
|
||||
// Adaptive Gauss integration
|
||||
|
||||
G4double G4SimpleIntegration::AdaptGaussIntegration(G4double xInitial,
|
||||
G4double xFinal)
|
||||
{
|
||||
G4double x=0.;
|
||||
static const G4double root = 1.0/std::sqrt(3.0) ;
|
||||
G4double Step = (xFinal - xInitial)/(2.0*iterationNumber) ;
|
||||
G4double delta = Step*root ;
|
||||
G4double mean = 0.0 ;
|
||||
for(G4int i=0;i<iterationNumber;i++)
|
||||
{
|
||||
x = (2*i + 1)*Step ;
|
||||
mean += (fFunction(x+delta) + fFunction(x-delta)) ;
|
||||
}
|
||||
return mean*Step ;
|
||||
G4int depth = 0;
|
||||
G4double sum = 0.0;
|
||||
AdaptGauss(xInitial, xFinal, sum, depth);
|
||||
return sum;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4SimpleIntegration::Simpson(G4double xInitial,
|
||||
G4double xFinal,
|
||||
G4int iterationNumber )
|
||||
G4double G4SimpleIntegration::Gauss(G4double xInitial, G4double xFinal)
|
||||
{
|
||||
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(G4int i=1;i<iterationNumber;i++)
|
||||
{
|
||||
x += Step ;
|
||||
xPlus += Step ;
|
||||
mean += fFunction(x) ;
|
||||
sum += fFunction(xPlus) ;
|
||||
}
|
||||
mean += 2.0*sum ;
|
||||
return mean*Step/3.0 ;
|
||||
static const G4double root = 1.0 / std::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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Adaptive Gauss integration
|
||||
|
||||
G4double
|
||||
G4SimpleIntegration::AdaptGaussIntegration( G4double xInitial,
|
||||
G4double xFinal )
|
||||
void G4SimpleIntegration::AdaptGauss(G4double xInitial, G4double xFinal,
|
||||
G4double& sum, G4int& depth)
|
||||
{
|
||||
G4int depth = 0 ;
|
||||
G4double sum = 0.0 ;
|
||||
AdaptGauss(xInitial,xFinal,sum,depth) ;
|
||||
return sum ;
|
||||
}
|
||||
|
||||
|
||||
G4double
|
||||
G4SimpleIntegration::Gauss( G4double xInitial,
|
||||
G4double xFinal )
|
||||
{
|
||||
static const G4double root = 1.0/std::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("G4SimpleIntegration::AdaptGauss()", "Error",
|
||||
FatalException, "Function varies too rapidly !") ;
|
||||
}
|
||||
G4double xMean = (xInitial + xFinal)/2.0 ;
|
||||
G4double leftHalf = Gauss(xInitial,xMean) ;
|
||||
G4double rightHalf = Gauss(xMean,xFinal) ;
|
||||
G4double full = Gauss(xInitial,xFinal) ;
|
||||
if(std::fabs(leftHalf+rightHalf-full) < fTolerance)
|
||||
{
|
||||
sum += full ;
|
||||
}
|
||||
else
|
||||
{
|
||||
depth++ ;
|
||||
AdaptGauss(xInitial,xMean,sum,depth) ;
|
||||
AdaptGauss(xMean,xFinal,sum,depth) ;
|
||||
}
|
||||
if(depth > fMaxDepth)
|
||||
{
|
||||
G4Exception("G4SimpleIntegration::AdaptGauss()", "Error", FatalException,
|
||||
"Function varies too rapidly !");
|
||||
}
|
||||
G4double xMean = (xInitial + xFinal) / 2.0;
|
||||
G4double leftHalf = Gauss(xInitial, xMean);
|
||||
G4double rightHalf = Gauss(xMean, xFinal);
|
||||
G4double full = Gauss(xInitial, xFinal);
|
||||
if(std::fabs(leftHalf + rightHalf - full) < fTolerance)
|
||||
{
|
||||
sum += full;
|
||||
}
|
||||
else
|
||||
{
|
||||
++depth;
|
||||
AdaptGauss(xInitial, xMean, sum, depth);
|
||||
AdaptGauss(xMean, xFinal, sum, depth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,28 +23,16 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4StatDouble class implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
// class G4StatDouble
|
||||
//
|
||||
// Implementation.
|
||||
// Original Author: Giovanni Santin (ESA) - October 2005 in GRAS tool
|
||||
// Adapted by: John Apostolakis - November 2011
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
#include "G4StatDouble.hh"
|
||||
|
||||
G4StatDouble::G4StatDouble()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
G4StatDouble::G4StatDouble() { reset(); }
|
||||
|
||||
G4StatDouble::G4StatDouble(G4double x)
|
||||
{
|
||||
reset();
|
||||
fill(x);
|
||||
}
|
||||
G4StatDouble::G4StatDouble(G4double x) { fill(x); }
|
||||
|
||||
void G4StatDouble::reset()
|
||||
{
|
||||
@@ -56,33 +44,31 @@ void G4StatDouble::reset()
|
||||
m_scale = 1.;
|
||||
}
|
||||
|
||||
G4StatDouble::~G4StatDouble()
|
||||
{}
|
||||
G4StatDouble::~G4StatDouble() {}
|
||||
|
||||
void G4StatDouble::fill(G4double value, G4double weight)
|
||||
{
|
||||
m_sum_wx += value * weight;
|
||||
m_sum_wx += value * weight;
|
||||
m_sum_wx2 += value * value * weight;
|
||||
if(m_n < INT_MAX) { ++m_n; }
|
||||
m_sum_w += weight;
|
||||
m_sum_w2 += weight * weight;
|
||||
|
||||
if (weight <= 0.)
|
||||
if(m_n < INT_MAX)
|
||||
{
|
||||
G4cout << "[G4StatDouble::fill] WARNING: weight<=0. "
|
||||
<< weight << G4endl;
|
||||
++m_n;
|
||||
}
|
||||
m_sum_w += weight;
|
||||
m_sum_w2 += weight * weight;
|
||||
|
||||
if(weight <= 0.)
|
||||
{
|
||||
G4cout << "[G4StatDouble::fill] WARNING: weight<=0. " << weight << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
void G4StatDouble::scale(G4double value)
|
||||
{
|
||||
m_scale = m_scale * value;
|
||||
}
|
||||
void G4StatDouble::scale(G4double value) { m_scale = m_scale * value; }
|
||||
|
||||
G4double G4StatDouble::mean() const
|
||||
{
|
||||
G4double mean_val = 0.;
|
||||
if (m_sum_w > 0.)
|
||||
if(m_sum_w > 0.)
|
||||
{
|
||||
mean_val = m_sum_wx / m_sum_w;
|
||||
}
|
||||
@@ -92,52 +78,51 @@ G4double G4StatDouble::mean() const
|
||||
G4double G4StatDouble::mean(G4double ext_sum_w) const
|
||||
{
|
||||
G4double factor = 0.;
|
||||
// factor to rescale the Mean for the requested number
|
||||
// of events (or sum of weights) ext_sum_w
|
||||
// factor to rescale the Mean for the requested number
|
||||
// of events (or sum of weights) ext_sum_w
|
||||
|
||||
if (ext_sum_w > 0)
|
||||
if(ext_sum_w > 0)
|
||||
{
|
||||
factor = m_sum_w;
|
||||
factor = m_sum_w;
|
||||
factor /= ext_sum_w;
|
||||
}
|
||||
return mean() * factor;
|
||||
|
||||
}
|
||||
|
||||
G4double G4StatDouble::rms(G4double ssum_wx, G4double ssum_wx2,
|
||||
G4double ssum_w, G4int nn)
|
||||
G4double G4StatDouble::rms(G4double ssum_wx, G4double ssum_wx2, G4double ssum_w,
|
||||
G4int nn)
|
||||
{
|
||||
G4double vrms = 0.0;
|
||||
if (nn > 1)
|
||||
if(nn > 1)
|
||||
{
|
||||
G4double vmean = ssum_wx / ssum_w;
|
||||
G4double xn = nn;
|
||||
G4double tmp =
|
||||
G4double xn = nn;
|
||||
G4double tmp =
|
||||
// from GNU Scientific Library. This part is equivalent to N/(N-1)
|
||||
// when w_i = w
|
||||
// ((m_sum_w * m_sum_w) / (m_sum_w * m_sum_w - m_sum_w2))
|
||||
// ((m_sum_w * m_sum_w) / (m_sum_w * m_sum_w - m_sum_w2))
|
||||
|
||||
// from NIST "DATAPLOT Reference manual", Page 2-66
|
||||
// from NIST "DATAPLOT Reference manual", Page 2-66
|
||||
// http://www.itl.nist.gov/div898/software/dataplot/refman2/ch2/weightsd.pdf
|
||||
// rewritten based on: SUM[w(x-m)^2]/SUM[w] = SUM[wx^2]/SUM[w] - m^2
|
||||
// and dividing it by sqrt[n] to go from rms of distribution to the
|
||||
// rms of the mean value
|
||||
|
||||
(xn / (xn - 1))
|
||||
* ((ssum_wx2 / ssum_w) - (vmean * vmean));
|
||||
(xn / (xn - 1)) * ((ssum_wx2 / ssum_w) - (vmean * vmean));
|
||||
|
||||
tmp = std::max(tmp, 0.0); // this avoids observed computation problem
|
||||
vrms = std::sqrt( tmp );
|
||||
// G4cout << "[G4StatDoubleElement::rms] m_sum_wx: " << m_sum_wx
|
||||
// << " m_sum_wx2: " << m_sum_wx2 << " m_sum_w: " << m_sum_w
|
||||
// << " m_n: " << m_n << " tmp: " << tmp<< " rms: " << rms
|
||||
// << G4endl;
|
||||
// G4cout << "[G4StatDoubleElement::rms] (m_n / (m_n - 1)): " << (xn/(xn - 1))
|
||||
// << " (m_sum_wx2 / m_sum_w): " << (m_sum_wx2 / m_sum_w)
|
||||
// << " (mean * mean): " << (mean * mean)
|
||||
// << " ((m_sum_wx2 / m_sum_w) - (mean * mean)): "
|
||||
// << ((m_sum_wx2 / m_sum_w) - (mean * mean))
|
||||
// << G4endl;
|
||||
tmp = std::max(tmp, 0.0); // this avoids observed computation problem
|
||||
vrms = std::sqrt(tmp);
|
||||
// G4cout << "[G4StatDoubleElement::rms] m_sum_wx: " << m_sum_wx
|
||||
// << " m_sum_wx2: " << m_sum_wx2 << " m_sum_w: " << m_sum_w
|
||||
// << " m_n: " << m_n << " tmp: " << tmp<< " rms: " << rms
|
||||
// << G4endl;
|
||||
// G4cout << "[G4StatDoubleElement::rms] (m_n / (m_n - 1)): " << (xn/(xn -
|
||||
// 1))
|
||||
// << " (m_sum_wx2 / m_sum_w): " << (m_sum_wx2 / m_sum_w)
|
||||
// << " (mean * mean): " << (mean * mean)
|
||||
// << " ((m_sum_wx2 / m_sum_w) - (mean * mean)): "
|
||||
// << ((m_sum_wx2 / m_sum_w) - (mean * mean))
|
||||
// << G4endl;
|
||||
}
|
||||
return vrms * m_scale;
|
||||
}
|
||||
@@ -158,16 +143,16 @@ G4double G4StatDouble::rms(G4double ext_sum_w, G4int ext_n)
|
||||
// it is useful when, given a number ext_n of events with sum of the weights
|
||||
// ext_sum_w, only m_n (with sum of weights m_sum_w) are actually accumulated
|
||||
// in the internal summation (e.g. for a dose variable in a volume, because
|
||||
// only a few particles reach that volume)
|
||||
// only a few particles reach that volume)
|
||||
|
||||
return rms(m_sum_wx, m_sum_wx2, ext_sum_w, ext_n);
|
||||
}
|
||||
|
||||
void G4StatDouble::add(const G4StatDouble* ptr)
|
||||
{
|
||||
m_n += ptr->n();
|
||||
m_sum_w += ptr->sum_w();
|
||||
m_sum_w2 += ptr->sum_w2();
|
||||
m_sum_wx += ptr->sum_wx();
|
||||
m_n += ptr->n();
|
||||
m_sum_w += ptr->sum_w();
|
||||
m_sum_w2 += ptr->sum_w2();
|
||||
m_sum_wx += ptr->sum_wx();
|
||||
m_sum_wx2 += ptr->sum_wx2();
|
||||
}
|
||||
|
||||
@@ -23,75 +23,68 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4VGaussianQuadrature class implementation
|
||||
//
|
||||
//
|
||||
// Implementation file for G4VGaussianQuadrature virtual base class
|
||||
//
|
||||
// Author: V.Grichine, 18.04.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4VGaussianQuadrature.hh"
|
||||
#include "G4ios.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4VGaussianQuadrature.hh"
|
||||
|
||||
G4VGaussianQuadrature::G4VGaussianQuadrature( function pFunction )
|
||||
: fFunction(pFunction), fAbscissa(0), fWeight(0), fNumber(0)
|
||||
{
|
||||
}
|
||||
G4VGaussianQuadrature::G4VGaussianQuadrature(function pFunction)
|
||||
: fFunction(pFunction)
|
||||
{}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// Virtual destructor which deletes dynamically allocated memory
|
||||
//
|
||||
|
||||
G4VGaussianQuadrature::~G4VGaussianQuadrature()
|
||||
G4VGaussianQuadrature::~G4VGaussianQuadrature()
|
||||
{
|
||||
delete[] fAbscissa ;
|
||||
delete[] fWeight ;
|
||||
delete[] fAbscissa;
|
||||
delete[] fWeight;
|
||||
}
|
||||
|
||||
// -------------------------- Access functions ----------------------------------
|
||||
// -------------------------- Access functions
|
||||
// ----------------------------------
|
||||
|
||||
G4double
|
||||
G4VGaussianQuadrature::GetAbscissa(G4int index) const
|
||||
G4double G4VGaussianQuadrature::GetAbscissa(G4int index) const
|
||||
{
|
||||
return fAbscissa[index] ;
|
||||
return fAbscissa[index];
|
||||
}
|
||||
|
||||
G4double
|
||||
G4VGaussianQuadrature::GetWeight(G4int index) const
|
||||
G4double G4VGaussianQuadrature::GetWeight(G4int index) const
|
||||
{
|
||||
return fWeight[index] ;
|
||||
return fWeight[index];
|
||||
}
|
||||
|
||||
G4int G4VGaussianQuadrature::GetNumber() const
|
||||
{
|
||||
return fNumber ;
|
||||
}
|
||||
G4int G4VGaussianQuadrature::GetNumber() const { return fNumber; }
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Auxiliary function which returns the value of std::log(gamma-function(x))
|
||||
//
|
||||
|
||||
G4double
|
||||
G4VGaussianQuadrature::GammaLogarithm(G4double xx)
|
||||
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)
|
||||
// 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 const G4double cof[6] = { 76.18009172947146, -86.50532032941677,
|
||||
24.01409824083091, -1.231739572450155,
|
||||
24.01409824083091, -1.231739572450155,
|
||||
0.1208650973866179e-2, -0.5395239384953e-5 };
|
||||
G4double x = xx - 1.0;
|
||||
G4double tmp = x + 5.5;
|
||||
G4double x = xx - 1.0;
|
||||
G4double tmp = x + 5.5;
|
||||
tmp -= (x + 0.5) * std::log(tmp);
|
||||
G4double ser = 1.000000000190015;
|
||||
|
||||
for ( size_t j = 0; j <= 5; j++ )
|
||||
for(size_t j = 0; j <= 5; ++j)
|
||||
{
|
||||
x += 1.0;
|
||||
ser += cof[j]/x;
|
||||
ser += cof[j] / x;
|
||||
}
|
||||
return -tmp + std::log(2.5066282746310005*ser);
|
||||
return -tmp + std::log(2.5066282746310005 * ser);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user