15 #include <Math/PdfFuncMathCore.h> 16 #include <Math/QuantFuncMathCore.h> 27 return (fabs(x - mean) < std::numeric_limits<double>::epsilon()) ? std::numeric_limits<double>::infinity() : 0;
32 double arg = (x - mean) / sigma;
33 double result = -.5 * arg * arg;
40 return result - 0.5 * log(2 * M_PI) - log(sigma);
46 double norm_const = (norm) ? 0.5 * log(2 / M_PI) - log(sigma_below + sigma_above) : 0;
48 return LogGaus(x, mode, sigma_above,
false) + norm_const;
49 return LogGaus(x, mode, sigma_below,
false) + norm_const;
56 return -std::numeric_limits<double>::infinity();
60 return (x == 0.0) ? 0.0 : -std::numeric_limits<double>::infinity();
64 BCLog::OutWarning(
"BCMath::LogPoisson : expectation value (lambda) cannot be negative.");
65 return std::numeric_limits<double>::quiet_NaN();
69 return LogGaus(x, lambda, sqrt(lambda),
true);
82 return std::numeric_limits<double>::quiet_NaN();
86 return std::numeric_limits<double>::quiet_NaN();
89 return (k == 0) ? 0 : -std::numeric_limits<double>::infinity();
91 return (k == n) ? 0 : -std::numeric_limits<double>::infinity();
107 static std::vector<double> CachedLogFactorials;
114 return std::numeric_limits<double>::quiet_NaN();
116 if (k == 0 || k == n)
118 if (k == 1 || k == n - 1)
119 return log((
double)n);
122 if (n < CachedLogFactorials.size() && (n - k) < 10)
133 return std::numeric_limits<double>::quiet_NaN();
134 unsigned n =
static_cast<unsigned>(floor(x + 0.5));
135 if (n < CachedLogFactorials.size())
136 return CachedLogFactorials[n];
137 return x * log(x) - x + log(x * (1 + 4 * x * (1 + 2 * x))) / 6 + log(M_PI) / 2;
144 if (n < CachedLogFactorials.size())
145 return CachedLogFactorials[n];
148 double logfact = (CachedLogFactorials.empty()) ? 0 : CachedLogFactorials.back();
149 for (
unsigned i = CachedLogFactorials.size(); i <= n; ++i)
150 logfact += log((
double)i);
158 if (n < CachedLogFactorials.size())
160 return CachedLogFactorials.size();
163 CachedLogFactorials.reserve(n);
166 if (CachedLogFactorials.empty())
167 CachedLogFactorials.push_back(0);
170 for (
unsigned i = CachedLogFactorials.size(); i <= n; ++i)
171 CachedLogFactorials.push_back(CachedLogFactorials.back() + log(static_cast<double>(i)));
173 return CachedLogFactorials.size();
187 return static_cast<int>(((x > 0) ? 1 : -1) * floor(fabs(x) + 0.5));
194 return std::numeric_limits<double>::quiet_NaN();
196 if ( k == 0 || k == n )
198 if ( k == 1 || k == n - 1)
199 return log((
double)n);
201 int lmax = std::max(k, n - k);
202 int lmin = std::min(k, n - k);
206 for (
int i = n; i > lmax; --i)
207 log_bf += log((
double)i);
216 double bw = log(Gamma) - log((x - mean) * (x - mean) + Gamma * Gamma / 4.);
219 bw -= log(2. * M_PI);
228 return -log((x * x - mean * mean) * (x * x - mean * mean) + mean * mean * Gamma * Gamma);
236 BCLog::OutWarning(
"BCMath::LogChi2 : parameter cannot be negative!");
237 return std::numeric_limits<double>::quiet_NaN();
240 if (x == 0 && n == 1) {
241 BCLog::OutWarning(
"BCMath::LogChi2 : returned value is infinity!");
242 return std::numeric_limits<double>::infinity();
245 double nOver2 = ((double) n) / 2.;
247 return (nOver2 - 1.) * log(x) - x / 2. - nOver2 * log(2) - log(TMath::Gamma(nOver2));
253 if (sigma <= 0 || gamma <= 0) {
254 BCLog::OutWarning(
"BCMath::LogVoigtian : widths are negative or zero!");
255 return std::numeric_limits<double>::quiet_NaN();
258 return log(TMath::Voigt(x, sigma, gamma));
264 return alpha * log(beta) - TMath::LnGamma(alpha) + (alpha - 1) * log(x) - beta * x;
278 double arg = (log(x) - mean) / sigma;
279 double result = -.5 * arg * arg;
281 return result - log(x * sqrt(2. * M_PI) * sigma);
288 if (pvalue < 0 || pvalue > 1)
289 throw std::domain_error(Form(
"BCMath::CorrectPValue: pvalue (%g) out of range", pvalue));
291 if (pvalue < std::numeric_limits<double>::epsilon())
295 if (npar >= nobservations)
296 throw std::domain_error(Form(
"BCMath::CorrectPValue: " 297 "npar exceeds nobservations, %u vs %u", npar, nobservations));
300 const double chi2 = ROOT::Math::chisquared_quantile_c(pvalue, nobservations);
303 const unsigned dof = nobservations - npar;
306 return TMath::Prob(chi2, dof);
310 double BCMath::FastPValue(
const std::vector<unsigned>& observed,
const std::vector<double>& expected,
311 unsigned nIterations,
unsigned seed)
313 size_t nbins = observed.size();
314 if (nbins != expected.size()) {
315 throw std::invalid_argument(Form(
"BCMath::FastPValue: " 316 "size of expected and observed do not match, %u vs %u",
unsigned(expected.size()),
unsigned(nbins)));
320 std::vector<unsigned> histogram(nbins, 0);
327 double logp_start = 0;
328 int counter_pvalue = 0;
331 for (
size_t ibin = 0; ibin < nbins; ++ibin) {
334 double yexp = expected[ibin];
337 histogram[ibin] = size_t(yexp);
343 logp_start +=
LogPoisson(observed[ibin], yexp);
347 for (
unsigned iiter = 0; iiter < nIterations; ++iiter) {
349 for (
size_t ibin = 0; ibin < nbins; ++ibin) {
351 double ptest = rng.Rndm() - 0.5;
356 double r = expected[ibin] / double(histogram[ibin] + 1);
359 if (rng.Rndm() < r) {
366 else if (ptest <= 0 && histogram[ibin] > 0) {
368 double r = double(histogram[ibin]) / expected[ibin];
371 if (rng.Rndm() < r) {
379 if (logp <= logp_start)
382 else if (logp_start && logp != logp_start && fabs((logp - logp_start) / logp_start) < 1e-15)
388 return double(counter_pvalue) / nIterations;
391 double BCMath::Random::Chi2(TRandom* rng,
double dof)
393 return 2.0 * Gamma(rng, dof / 2.0, 1.0);
396 double BCMath::Random::Gamma(TRandom* rng,
double a,
double b)
402 double u = rng->Uniform(1);
403 return Gamma(rng, 1.0 + a, b) * std::pow(u, 1.0 / a);
407 double d = a - 1.0 / 3.0;
408 double c = (1.0 / 3.0) / sqrt (d);
420 if (u < 1 - 0.0331 * x * x * x * x)
423 if (log (u) < 0.5 * x * x + d * (1 - v + log (v)))
double LogApproxBinomial(unsigned n, unsigned k, double p)
Calculates natural logarithm of the Binomial probability using approximations for factorial calculati...
double LogFact(unsigned n)
Calculates natural logarithm of the n-factorial (n!)
double LogBinomFactorExact(unsigned n, unsigned k)
Calculates natural logarithm of the Binomial factor "n over k".
double FastPValue(const std::vector< unsigned > &observed, const std::vector< double > &expected, unsigned nIterations=1e5, unsigned seed=0)
Calculate the p value using fast MCMC for a histogram and the likelihood as test statistic.
double LogBreitWignerNonRel(double x, double mean, double Gamma, bool norm=false)
Calculates the logarithm of the nonrelativistic Breit-Wigner distribution.
double LogBreitWignerRel(double x, double mean, double Gamma)
Calculates the logarithm of the relativistic Breit-Wigner distribution.
double LogBinomFactor(unsigned n, unsigned k)
Calculates natural logarithm of the Binomial factor "n over k" using approximations for factorial cal...
double LogLogNormal(double x, double mean=0, double sigma=1)
Return the log of the log normal distribution.
double LogChi2(double x, int n)
Calculates the logarithm of chi square function: chi2(double x; size_t n)
double LogGammaPDF(double x, double alpha, double beta)
Returns the log of the Gamma PDF.
double CorrectPValue(const double &pvalue, const unsigned &npar, const unsigned &nobservations)
Correct a p value by transforming to a chi^2 with dof=nobservations, then back to a pvalue with dof r...
double ApproxLogFact(double x)
Calculates natural logarithm of the n-factorial (n!) using Srinivasa Ramanujan approximation log(n!) ...
double LogVoigtian(double x, double sigma, double gamma)
Calculates the logarithm of normalized voigtian function: voigtian(double x, double sigma...
int Nint(double x)
Returns the nearest integer of a double number.
double LogSplitGaus(double x, double mode, double sigma_below, double sigma_above, bool norm=false)
Calculate the natural logarithm of a normal distribution function with different variances below and ...
double LogGaus(double x, double mean=0, double sigma=1, bool norm=false)
Calculate the natural logarithm of a normal distribution function.
double ApproxBinomial(unsigned n, unsigned k, double p)
Calculates Binomial probability using approximations for factorial calculations if calculation for nu...
double LogPoisson(double x, double lambda)
Calculate the natural logarithm of a poisson distribution.
unsigned CacheFactorials(unsigned n)
Cache factorials for first.