46 fX1(x1), fX2(x2), fChanged(true), fTolerance(1.e-8)
72 G4cout <<
"G4PolynomialPDF::SetDomain(): Invalide domain! "
73 <<
"(x1 = " << x1 <<
", x2 = " << x2 <<
")." <<
G4endl;
98 G4cout <<
"G4PolynomialPDF::Normalize() PDF has non-positive area: "
116 if(ddxPower < -1 || ddxPower > 2) {
117 G4cout <<
"G4PolynomialPDF::GetX(): ddxPower " << ddxPower
118 <<
" not implemented" <<
G4endl;
131 else if(ddxPower == 1) {
134 else if(ddxPower == 2) {
147 if(x1 < fX1 || x2 >
fX2 || x2 < x1) {
148 G4cout <<
"G4PolynomialPDF::HasNegativeMinimum(): Invalid range "
149 << x1 <<
" - " << x2 <<
G4endl;
166 if(xMin < x1) xMin = x1;
167 if(xMin > x2) xMin = x2;
176 extremum >= x2-(x2-x1)*
fTolerance)
return false;
186 G4cout <<
"G4PolynomialPDF::GetRandomX(): PDF has negative values, returning 0..." <<
G4endl;
206 G4cout <<
"G4PolynomialPDF::GetX(): no PDF defined!" <<
G4endl;
209 if(ddxPower < -1 || ddxPower > 1) {
210 G4cout <<
"G4PolynomialPDF::GetX(): ddxPower " << ddxPower
211 <<
" not implemented" <<
G4endl;
214 if(ddxPower == -1 && (p<0 || p>1)) {
215 G4cout <<
"G4PolynomialPDF::GetX(): p is out of range" <<
G4endl;
220 if(x2 <= x1 || x1 < fX1 || x2 >
fX2) {
221 G4cout <<
"G4PolynomialPDF::GetX(): domain must have fX1 <= x1 < x2 <= fX2. "
222 <<
"You sent x1 = " << x1 <<
", x2 = " << x2 <<
"." <<
G4endl;
236 if(ddxPower == 1) slope *= 2.;
241 else if(value > x2) {
256 if(ddxPower == 1) b *= 2.;
258 if(ddxPower == 1) a *= 3;
259 else if(ddxPower == -1) a *= 0.5;
260 double sqrtFactor = b*b - 4.*a*c;
261 if(sqrtFactor < 0)
return x2;
262 sqrtFactor = sqrt(sqrtFactor)/2./fabs(a);
263 G4double valueMinus = -b/2./a - sqrtFactor;
264 if(valueMinus >= x1 && valueMinus <= x2)
return valueMinus;
265 else if(valueMinus > x2)
return x2;
266 G4double valuePlus = -b/2./a + sqrtFactor;
267 if(valuePlus >= x1 && valuePlus <= x2)
return valuePlus;
268 else if(valuePlus < x1)
return x2;
269 return (x1-valueMinus <= valuePlus-x2) ? x1 : x2;
274 if(guess < x1 || guess > x2) guess = (x2+x1)*0.5;
276 size_t iterations = 0;
289 else if(ddxPower == 0) {
299 if(f == 0)
return guess;
301 G4cout <<
"G4PolynomialPDF::GetX(): got f != 0 but slope = 0 for ddxPower = "
305 lastChange = - f/dfdx;
307 if(guess + lastChange < x1) {
308 lastChange = x1 - guess;
309 }
else if(guess + lastChange > x2) {
310 lastChange = x2 - guess;
314 lastChange /= (fX2-
fX1);
317 if(iterations > 50) {
319 G4cout <<
"G4PolynomialPDF::GetX(): got stuck searching for " << p
320 <<
" between " << x1 <<
" and " << x2 <<
" with ddxPower = "
322 <<
". Last guess was " << guess <<
"." <<
G4endl;
324 if(ddxPower==-1 && bisect) {
339 if(fz < 0)
return Bisect(p, z, x2);
345 G4cout <<
"G4PolynomialPDF::Dump() - PDF(x) = ";
350 if(i>1)
G4cout <<
"^" << i;
353 G4cout <<
"G4PolynomialPDF::Dump() - Interval: " <<
fX1 <<
" <= x < "
std::vector< G4double > fCoefficients
void SetCoefficients(const std::vector< G4double > &v)
void SetNCoefficients(size_t n)
G4PolynomialPDF(size_t n=0, const double *coeffs=nullptr, G4double x1=0, G4double x2=1)
G4double GetX(G4double p, G4double x1, G4double x2, G4int ddxPower=0, G4double guess=1.e99, G4bool bisect=true)
G4double Bisect(G4double p, G4double x1, G4double x2)
G4GLOB_DLL std::ostream G4cout
G4double GetCoefficient(size_t i) const
void SetDomain(G4double x1, G4double x2)
void SetCoefficient(size_t i, G4double value)
G4bool HasNegativeMinimum(G4double x1, G4double x2)
const G4double x[NPOINTSGL]
size_t GetNCoefficients() const
G4double EvalInverseCDF(G4double p)
G4double Evaluate(G4double x, G4int ddxPower=0)