BAT  0.9.4
The Bayesian analysis toolkit
 All Classes Namespaces Functions Variables Enumerations
BCMath.cxx
1 /*
2  * Copyright (C) 2007-2014, the BAT core developer team
3  * All rights reserved.
4  *
5  * For the licensing terms see doc/COPYING.
6  * For documentation see http://mpp.mpg.de/bat
7  */
8 
9 // ---------------------------------------------------------
10 
11 #include "BCMath.h"
12 #include "BCLog.h"
13 
14 #include <math.h>
15 #include <limits>
16 #include <set>
17 
18 #include <TMath.h>
19 #include <TF1.h>
20 #include <TH1D.h>
21 #include <TRandom3.h>
22 
23 #include <Math/PdfFuncMathCore.h>
24 #include <Math/QuantFuncMathCore.h>
25 
26 namespace BCMath {
27 
28 static unsigned int nCacheFact = 10000;
29 static double * logfact = 0;
30 
31 // ---------------------------------------------------------
32 
33 double LogGaus(double x, double mean, double sigma, bool norm)
34 {
35  // if we have a delta function, return fixed value
36  if (sigma == 0.)
37  return 0;
38 
39  // if sigma is negative use absolute value
40  if (sigma < 0.)
41  sigma *= -1.;
42 
43  double arg = (x - mean) / sigma;
44  double result = -.5 * arg * arg;
45 
46  // check if we should add the normalization constant
47  if (!norm)
48  return result;
49 
50  // subtract the log of the denominator of the normalization constant
51  // and return
52  return result - log(sqrt(2. * M_PI) * sigma);
53 }
54 
55 // ---------------------------------------------------------
56 
57 double LogPoisson(double x, double par)
58 {
59  if (par > 899)
60  return LogGaus(x, par, sqrt(par), true);
61 
62  if (x < 0)
63  return 0;
64 
65  if (x == 0.)
66  return -par;
67 
68  return x * log(par) - par - ApproxLogFact(x);
69 }
70 
71 // ---------------------------------------------------------
72 
73 double ApproxBinomial(int n, int k, double p)
74 {
75  return exp(LogApproxBinomial(n, k, p));
76 }
77 
78 // ---------------------------------------------------------
79 
80 double LogApproxBinomial(int n, int k, double p)
81 {
82  // check p
83  if (p == 0)
84  return -1e99;
85 
86  else if (p == 1)
87  return 0;
88 
89  // switch parameters if n < k
90  if (n < k) {
91  int a = n;
92  n = k;
93  k = a;
94  }
95 
96  return LogBinomFactor(n, k) + (double) k * log(p) + (double) (n - k) * log(1. - p);
97 }
98 
99 // ---------------------------------------------------------
100 
101 double LogBinomFactor(int n, int k)
102 {
103  // switch parameters if n < k
104  if (n < k) {
105  int a = n;
106  n = k;
107  k = a;
108  }
109 
110  if (n == k || k == 0)
111  return 0.;
112  if (k == 1 || k == n - 1)
113  return log((double) n);
114 
115  // if no approximation needed
116  if ( n < BCMATH_NFACT_ALIMIT || (n < (int) BCMath::nCacheFact && (n - k) < 10) )
117  return LogNoverK(n, k);
118 
119  // calculate final log(n over k) using approximations if necessary
120  return ApproxLogFact((double)n) - ApproxLogFact((double)k) - ApproxLogFact((double)(n - k));
121 }
122 
123 // ---------------------------------------------------------
124 
125 double ApproxLogFact(double x)
126 {
127  if (x > BCMath::nCacheFact)
128  return x * log(x) - x + log(x * (1. + 4. * x * (1. + 2. * x))) / 6. + log(M_PI) / 2.;
129 
130  else
131  return LogFact(static_cast<int>(floor(x + 0.5f)));
132 }
133 
134 // ---------------------------------------------------------
135 double LogFact(int n)
136 {
137  // return NaN for negative argument
138  if (n<0)
139  return std::numeric_limits<double>::quiet_NaN();
140 
141  // cache the factorials on first call
142  if ( !BCMath::logfact) {
143  BCMath::logfact = new double[BCMath::nCacheFact+1];
144  double tmplogfact = 0;
145  BCMath::logfact[0] = tmplogfact;
146  for (unsigned int i=1; i<=BCMath::nCacheFact; i++) {
147  tmplogfact += log((double) i);
148  BCMath::logfact[i] = tmplogfact;
149  }
150  }
151 
152  // return cached value if available
153  if (n <= (int) BCMath::nCacheFact)
154  return BCMath::logfact[n];
155 
156  // calculate factorial starting from the highest cached value
157  double ln(0.);
158  if (BCMath::logfact)
159  ln = BCMath::logfact[nCacheFact];
160 
161  for (int i = BCMath::nCacheFact+1; i <= n; i++)
162  ln += log((double) i);
163 
164  return ln;
165 }
166 
167 // ---------------------------------------------------------
168 
169 void CacheFactorial(unsigned int n)
170 {
171  nCacheFact = n;
172 }
173 
174 // ---------------------------------------------------------
175 
176 double LogNoverK(int n, int k)
177 {
178  // switch parameters if n < k
179  if (n < k) {
180  int a = n;
181  n = k;
182  k = a;
183  }
184 
185  if (n == k || k == 0)
186  return 0.;
187  if (k == 1 || k == n - 1)
188  return log((double) n);
189 
190  int lmax = std::max(k, n - k);
191  int lmin = std::min(k, n - k);
192 
193  double ln = 0.;
194 
195  for (int i = n; i > lmax; i--)
196  ln += log((double) i);
197  ln -= LogFact(lmin);
198 
199  return ln;
200 }
201 
202 // ---------------------------------------------------------
203 
204 int Nint(double x)
205 {
206  // round to integer
207  int i;
208 
209  if (x >= 0) {
210  i = (int) (x + .5);
211  if (x + .5 == (double) i && (i&1))
212  i--;
213  }
214  else {
215  i = int(x - 0.5);
216  if (x - 0.5 == double(i) && (i&1))
217  i++;
218  }
219 
220  return i;
221 }
222 
223 // ---------------------------------------------------------
224 
225 double LogBreitWignerNonRel(double x, double mean, double Gamma, bool norm)
226 {
227  double bw = log(Gamma) - log((x - mean) * (x - mean) + Gamma*Gamma / 4.);
228 
229  if (norm)
230  bw -= log(2. * M_PI);
231 
232  return bw;
233 }
234 
235 // ---------------------------------------------------------
236 
237 double LogBreitWignerRel(double x, double mean, double Gamma)
238 {
239  return -log((x*x - mean*mean) * (x*x - mean*mean) + mean*mean * Gamma*Gamma);
240 }
241 
242 // ---------------------------------------------------------
243 
244 double LogChi2(double x, int n)
245 {
246  if (x < 0) {
247  BCLog::OutWarning("BCMath::LogChi2 : parameter cannot be negative!");
248  return -1e99;
249  }
250 
251  if (x == 0 && n == 1) {
252  BCLog::OutWarning("BCMath::LogChi2 : returned value is infinity!");
253  return 1e99;
254  }
255 
256  double nOver2 = ((double) n) / 2.;
257 
258  return (nOver2 - 1.) * log(x) - x / 2. - nOver2 * log(2) - log(TMath::Gamma(nOver2));
259 }
260 
261 // ---------------------------------------------------------
262 double LogVoigtian(double x, double sigma, double gamma)
263 {
264  if (sigma <= 0 || gamma <= 0) {
265  BCLog::OutWarning("BCMath::LogVoigtian : widths are negative or zero!");
266  return -1e99;
267  }
268 
269  return log(TMath::Voigt(x, sigma, gamma));
270 }
271 
272 // ---------------------------------------------------------
273 double LogGammaPDF(double x, double alpha, double beta)
274 {
275  return alpha * log(beta) - TMath::LnGamma(alpha) + (alpha - 1) * log(x) - beta * x;
276 }
277 
278 // ---------------------------------------------------------
279 double LogLogNormal(double x, double mean, double sigma)
280 {
281  // if we have a delta function, return fixed value
282  if (sigma == 0.)
283  return 0;
284 
285  // if sigma is negative use absolute value
286  if (sigma < 0.)
287  sigma *= -1.;
288 
289  double arg = (log(x) - mean) / sigma;
290  double result = -.5 * arg * arg;
291 
292  return result - log(x * sqrt(2. * M_PI) * sigma);
293 }
294 
295 // ---------------------------------------------------------
296 double SplitGaussian(double* x, double* par)
297 {
298  double mean = par[0];
299  double sigmadown = par[1];
300  double sigmaup = par[2];
301 
302  double sigma = sigmadown;
303 
304  if (x[0] > mean)
305  sigma = sigmaup;
306 
307  return 1.0/sqrt(2.0*M_PI)/sigma * exp(- (x[0]-mean)*(x[0]-mean)/2./sigma/sigma);
308 }
309 
310 // ---------------------------------------------------------
311 // wrapper with signature to construct a TF1
312 double chi2(double *x, double *par)
313 {
314  return ROOT::Math::chisquared_pdf(x[0], par[0]);
315 }
316 
317 // ---------------------------------------------------------
318 void RandomChi2(std::vector<double> &randoms, int K)
319 {
320  // fixed upper cutoff to 1000, might be too small
321  TF1 *f = new TF1("chi2", chi2, 0.0, 1000, 1);
322  f->SetParameter(0, K);
323  f->SetNpx(500);
324  // uses inverse-transform method
325  // fortunately CDF only built once
326  for (unsigned int i = 0; i < randoms.size(); i++)
327  randoms.at(i) = f->GetRandom();
328 
329  delete f;
330 }
331 
332 // ---------------------------------------------------------
333 TH1D * ECDF(const std::vector<double> & data)
334 {
335  int N = data.size();
336 
337  std::set<double> uniqueObservations;
338  // sort and filter out multiple instances
339  for (int i = 0; i < N; ++i)
340  uniqueObservations.insert(data[i]);
341 
342  // extract lower edges for CDF histogram
343  unsigned nUnique = uniqueObservations.size();
344  std::vector<double> lowerEdges(nUnique);
345 
346  // traverse the set
347  std::set<double>::iterator iter;
348  int counter = 0;
349  for (iter = uniqueObservations.begin(); iter != uniqueObservations.end(); ++iter) {
350  lowerEdges[counter] = *iter;
351  counter++;
352  }
353 
354  // create histogram where
355  // lower edge of first bin = min. data
356  // upper edge of last bin = max. data
357  TH1D * ECDF = new TH1D("ECDF", "Empirical cumulative distribution function", nUnique - 1, &lowerEdges[0]);
358 
359  // fill the data in to find multiplicities
360  for (int i = 0; i < N; ++i)
361  ECDF -> Fill(data[i]);
362 
363  // just in case, empty the underflow
364  ECDF -> SetBinContent(0, 0.0);
365 
366  // construct the ecdf
367  for (int nBin = 1; nBin <= ECDF->GetNbinsX(); nBin++) {
368  double previousBin = ECDF -> GetBinContent(nBin - 1);
369  double thisBin = ECDF -> GetBinContent(nBin) / double(N);
370  ECDF -> SetBinContent(nBin, thisBin + previousBin);
371 
372  // the uncertainty is only correctly estimated in the model
373  ECDF -> SetBinError(nBin, 0.0);
374  }
375 
376  // set the endpoint to 1, so all larger values are at CDF=1
377  ECDF -> SetBinContent(ECDF->GetNbinsX() + 1, 1.);
378 
379  // adjust for nice plotting
380  ECDF -> SetMinimum(0.);
381  ECDF -> SetMaximum(1.);
382 
383  return ECDF;
384 }
385 
386 // ---------------------------------------------------------
387 
388 std::vector<int> longestRuns(const std::vector<bool> &bitStream)
389 {
390  // initialize counter variables
391  unsigned int maxRunAbove, maxRunBelow, currRun;
392  maxRunAbove = 0;
393  maxRunBelow = 0;
394  currRun = 1;
395  // set both entries to zero
396  std::vector<int> runs(2, 0);
397 
398  if (bitStream.empty())
399  return runs;
400 
401  // flag about kind of the currently considered run
402  bool aboveRun = bitStream.at(0);
403 
404  // start at second variable
405  std::vector<bool>::const_iterator iter = bitStream.begin();
406  ++iter;
407  while (iter != bitStream.end()) {
408 
409  // increase counter if run continues
410  if (*(iter - 1) == *iter)
411  currRun++;
412  else {
413  // compare terminated run to maximum
414  if (aboveRun)
415  maxRunAbove = std::max(maxRunAbove, currRun);
416  else
417  maxRunBelow = std::max(maxRunBelow, currRun);
418  // set flag to run of opposite kind
419  aboveRun = !aboveRun;
420  // restart at length one
421  currRun = 1;
422  }
423  // move to next bit
424  ++iter;
425  }
426 
427  // check last run
428  if (aboveRun)
429  maxRunAbove = std::max(maxRunAbove, currRun);
430  else
431  maxRunBelow = std::max(maxRunBelow, currRun);
432 
433  // save the longest runs
434  runs.at(0) = maxRunBelow;
435  runs.at(1) = maxRunAbove;
436 
437  return runs;
438 }
439 // ---------------------------------------------------------
440 
441 std::vector<double> longestRunsChi2(
442  const std::vector<double>& yMeasured,
443  const std::vector<double>& yExpected, const std::vector<double>& sigma)
444 {
445  //initialize counter variables
446  double maxRunAbove, maxRunBelow, currRun;
447  maxRunAbove = 0;
448  maxRunBelow = 0;
449  currRun = 0;
450  //set both entries to zero
451  std::vector<double> runs(2, 0);
452 
453  //check input size
454  if (yMeasured.size() != yExpected.size() || yMeasured.size() != sigma.size()
455  || yExpected.size() != sigma.size()) {
456  //should throw exception
457  return runs;
458  }
459 
460  //exclude zero uncertainty
461  //...
462 
463  int N = yMeasured.size();
464  if ( N<=0)
465  return runs;
466  //BCLog::OutDebug(Form("N = %d", N));
467 
468 
469  //flag about kind of the currently considered run
470  double residue = (yMeasured.at(0) - yExpected.at(0)) / sigma.at(0);
471  bool aboveRun = residue >= 0 ? true : false;
472  currRun = residue * residue;
473 
474  //start at second variable
475  for (int i = 1; i < N; i++) {
476  residue = (yMeasured.at(i) - yExpected.at(i)) / sigma.at(i);
477  //run continues
478  if ((residue >= 0) == aboveRun) {
479  currRun += residue * residue;
480  } else {
481  //compare terminated run to maximum
482  if (aboveRun)
483  maxRunAbove = std::max(maxRunAbove, currRun);
484  else
485  maxRunBelow = std::max(maxRunBelow, currRun);
486  //set flag to run of opposite kind
487  aboveRun = !aboveRun;
488  //restart at current residual
489  currRun = residue * residue;
490  }
491  }
492 
493  //check last run
494  if (aboveRun)
495  maxRunAbove = std::max(maxRunAbove, currRun);
496  else
497  maxRunBelow = std::max(maxRunBelow, currRun);
498 
499  //save the longest runs
500  runs.at(0) = maxRunBelow;
501  runs.at(1) = maxRunAbove;
502 
503  return runs;
504 }
505 // ---------------------------------------------------------
506 double longestRunFrequency(unsigned longestObserved, unsigned int nTrials)
507 {
508  // can't observe run that's longer than the whole sequence
509  if (longestObserved >= nTrials)
510  return 0.;
511 
512  // return value
513  double prob = 0.;
514 
515  // short cuts
516  typedef unsigned int uint;
517  uint Lobs = longestObserved;
518  uint n = nTrials;
519 
520  // the result of the inner loop is the cond. P given r successes
521  double conditionalProb;
522 
523  /* first method: use the gamma function for the factorials: bit slower and more inaccurate
524  * in fact may return NaN for n >= 1000.
525  * alternative using log factorial approximations, is faster and more accurate
526  */
527 
528  double tempLog = 0;
529  for (uint r = 0; r <= n; r++) {
530  conditionalProb = 0.0;
531 
532  for (uint i = 1; (i <= n - r + 1) && (i <= uint(r / double(Lobs + 1))); i++) {
533  tempLog = ApproxLogFact(n - i * (Lobs + 1)) - ApproxLogFact(i)
534  - ApproxLogFact(n - r - i + 1)
535  - ApproxLogFact(r - i * (Lobs + 1));
536  if (i % 2)
537  conditionalProb += exp(tempLog);
538  else
539  conditionalProb -= exp(tempLog);
540  }
541  prob += (1 + n - r) * conditionalProb;
542  }
543 
544  // Bernoulli probability of each permutation
545  prob *= pow(2., -double(n));
546 
547  return prob;
548 }
549 
550 // ---------------------------------------------------------
551 double Rvalue(const std::vector<double> & chain_means, const std::vector<double> & chain_variances,
552  const unsigned & chain_length, const bool & strict) throw (std::invalid_argument, std::domain_error)
553 {
554  if (chain_means.size() != chain_variances.size())
555  throw std::invalid_argument("BCMath::RValue: chain means and chain variances are not aligned!");
556 
557  const double n = chain_length;
558  const double m = chain_means.size();
559 
560  if (m <= 1)
561  throw std::invalid_argument("BCMath:RValue: Need at least two chains to compute R-value!");
562 
563  // init
564  double variance_of_means = 0.0;
565  double mean_of_means = 0.0;
566  double mean_of_variances = 0.0;
567  double variance_of_variances = 0.0;
568 
569  // use Welford's method here as well with temporary variables
570  double previous_mean_of_means = 0;
571  double previous_mean_of_variances = 0;
572  for (unsigned i = 0 ; i < m ; ++i)
573  {
574  if (0 == i)
575  {
576  mean_of_means = chain_means.front();
577  variance_of_means = 0;
578  mean_of_variances = chain_variances.front();
579  variance_of_variances = 0;
580 
581  continue;
582  }
583 
584  // temporarily store previous mean of step (i-1)
585  previous_mean_of_means = mean_of_means;
586  previous_mean_of_variances = mean_of_variances;
587 
588  // update step
589  mean_of_means += (chain_means[i] - previous_mean_of_means) / (i + 1.0);
590  variance_of_means += (chain_means[i] - previous_mean_of_means) * (chain_means[i] - mean_of_means);
591  mean_of_variances += (chain_variances[i] - previous_mean_of_variances) / (i + 1.0);
592  variance_of_variances += (chain_variances[i] - previous_mean_of_variances) * (chain_variances[i] - mean_of_variances);
593  }
594 
595  variance_of_means /= m - 1.0;
596  variance_of_variances /= m - 1.0;
597 
598  //use Gelman/Rubin notation
599  double B = variance_of_means * n;
600  double W = mean_of_variances;
601  double sigma_squared = (n - 1.0) / n * W + B / n;
602 
603  // avoid case with no variance whatsoever
604  if (0.0 == W && 0.0 == B)
605  {
606  BCLog::OutDebug("BCMath::Rvalue: All samples in all chains identical!");
607  return 1.0;
608  }
609  // avoid NaN due to divide by zero
610  if (0.0 == W)
611  {
612  BCLog::OutDebug("BCMath::Rvalue: W = 0. Avoiding R = NaN.");
613  return std::numeric_limits<double>::max();
614  }
615 
616  // the lax implementation stops here
617  if (!strict)
618  return sqrt(sigma_squared / W);
619 
620  //estimated scale reduction
621  double R = 0.0;
622 
623  // compute covariances using the means from above
624  double covariance_22 = 0.0; // cov(s_i^2, \bar{x_i}^2
625  double covariance_21 = 0.0; // cov(s_i^2, \bar{x_i}
626 
627  for (unsigned i = 0 ; i < m ; ++i)
628  {
629  covariance_21 += (chain_variances[i] - mean_of_variances) * (chain_means.at(i) - mean_of_means);
630  covariance_22 += (chain_variances[i] - mean_of_variances) * (chain_means[i] * chain_means[i] - mean_of_means * mean_of_means);
631  }
632 
633  covariance_21 /= m - 1.0;
634  covariance_22 /= m - 1.0;
635 
636  // scale of t-distribution
637  double V = sigma_squared + B / (m * n);
638 
639  // estimation of scale variance
640  double a = (n - 1.0) * (n - 1.0) / (n * n * m) * variance_of_variances;
641  double b = (m + 1) * (m + 1) / (m * n * m * n) * 2.0 / (m - 1) * B * B;
642  double c = 2.0 * (m + 1.0) * (n - 1.0) / (m * n * n) * n / m * (covariance_22 - 2.0 * mean_of_means * covariance_21);
643  double variance_of_V = a + b + c;
644 
645  // degrees of freedom of t-distribution
646  double df = 2.0 * V * V / variance_of_V;
647 
648  if (df <= 2)
649  {
650  BCLog::OutDebug(Form("BCMath::Rvalue: DoF (%g) below 2. Avoiding R = NaN.", df));
651  return std::numeric_limits<double>::max();;
652  }
653 
654  // sqrt of estimated scale reduction if sampling were continued
655  R = sqrt(V / W * df / (df - 2.0));
656 
657  // R smaller, but close to 1 is OK.
658  if (R < 0.99 && n > 100)
659  throw std::domain_error(Form("BCMath::Rvalue: %g < 0.99. Check for a bug in the implementation!", R));
660 
661  return R;
662 }
663 
664 // ---------------------------------------------------------
665 double CorrectPValue(const double & pvalue, const unsigned & npar, const unsigned & nobservations) throw (std::domain_error)
666 {
667  // avoid pathologies
668  if (pvalue < 0 or pvalue > 1)
669  throw std::domain_error(Form("BCMath::CorrectPValue: pvalue (%g) out of range", pvalue));
670 
671  if (pvalue < 1e-150)
672  return 0;
673 
674  // dof = nobs - npar
675  if (npar >= nobservations)
676  throw std::domain_error(Form("BCMath::CorrectPValue: "
677  "npar exceeds nobservations, %u vs %u", npar, nobservations));
678 
679  // convert upper-tail p value to a chi squared
680  const double chi2 = ROOT::Math::chisquared_quantile_c(pvalue, nobservations);
681 
682  // corrected degrees of freedom
683  const unsigned dof = nobservations - npar;
684 
685  // transform back to p value
686  return TMath::Prob(chi2, dof);
687 }
688 
689 // ---------------------------------------------------------
690 double FastPValue(const std::vector<unsigned> & observed, const std::vector<double> & expected,
691  unsigned nIterations, unsigned seed) throw (std::invalid_argument)
692 {
693  size_t nbins = observed.size();
694  if (nbins != expected.size())
695  {
696  throw std::invalid_argument(Form("BCMath::FastPValue: "
697  "size of expected and observed do not match, %u vs %u", unsigned(expected.size()), unsigned(nbins)));
698  }
699 
700  // temporary histogram to be modified in each MCMC step
701  std::vector<unsigned> histogram(nbins, 0);
702 
703  // fix seed to iterations for reproducible results
704  TRandom3 rng(seed);
705 
706  // keep track of log of probability and count data sets with larger value
707  double logp = 0;
708  double logp_start = 0;
709  int counter_pvalue = 0;
710 
711  // define starting distribution as histogram with most likely entries
712  for (size_t ibin = 0; ibin < nbins; ++ibin) {
713 
714  // get the number of expected events
715  double yexp = expected[ibin];
716 
717  //most likely observed value = int(expected value)
718  histogram[ibin] = size_t(yexp);
719 
720  // calculate test statistic (= likelihood of entire histogram) for starting distr.
721  logp += LogPoisson(size_t(yexp), yexp);
722 
723  //statistic of the observed data set
724  logp_start += LogPoisson(observed[ibin], yexp);
725  }
726 
727  // loop over iterations
728  for (unsigned iiter = 0; iiter < nIterations; ++iiter) {
729  // loop over bins
730  for (size_t ibin = 0; ibin < nbins; ++ibin) {
731  // random step up or down in statistics for this bin
732  double ptest = rng.Rndm() - 0.5;
733 
734  // increase statistics by 1
735  if (ptest > 0) {
736  // calculate factor of probability
737  double r = expected[ibin] / double(histogram[ibin] + 1);
738 
739  // walk, or don't (this is the Metropolis part)
740  if (rng.Rndm() < r) {
741  ++histogram[ibin];
742  logp += log(r);
743  }
744  }
745 
746  // decrease statistics by 1
747  else if (ptest <= 0 && histogram[ibin] > 0) {
748  // calculate factor of probability
749  double r = double(histogram[ibin]) / expected[ibin];
750 
751  // walk, or don't (this is the Metropolis part)
752  if (rng.Rndm() < r) {
753  --histogram[ibin];
754  logp += log(r);
755  }
756  }
757  } // end of looping over bins
758 
759  // increase counter
760  if (logp <= logp_start)
761  ++counter_pvalue;
762  // handle the case where a -b +b > a because of precision loss
763  else if (logp_start && logp != logp_start && fabs((logp - logp_start) / logp_start) < 1e-15)
764  ++counter_pvalue;
765 
766  } // end of looping over iterations
767 
768  // calculate p-value
769  return double(counter_pvalue) / nIterations;
770 }
771 } // end of namespace BCMath
double LogLogNormal(double x, double mean, double sigma)
Definition: BCMath.cxx:279
double FastPValue(const std::vector< unsigned > &observed, const std::vector< double > &expected, unsigned nIterations, unsigned seed)
Definition: BCMath.cxx:690
double SplitGaussian(double *x, double *par)
Definition: BCMath.cxx:296
double LogBreitWignerNonRel(double x, double mean, double Gamma, bool norm)
Definition: BCMath.cxx:225
double LogNoverK(int n, int k)
Definition: BCMath.cxx:176
double LogChi2(double x, int n)
Definition: BCMath.cxx:244
double LogGammaPDF(double x, double alpha, double beta)
Definition: BCMath.cxx:273
double CorrectPValue(const double &pvalue, const unsigned &npar, const unsigned &nobservations)
Definition: BCMath.cxx:665
std::vector< int > longestRuns(const std::vector< bool > &bitStream)
Definition: BCMath.cxx:388
double LogBinomFactor(int n, int k)
Definition: BCMath.cxx:101
double ApproxLogFact(double x)
Definition: BCMath.cxx:125
double LogVoigtian(double x, double sigma, double gamma)
Definition: BCMath.cxx:262
int Nint(double x)
Definition: BCMath.cxx:204
void RandomChi2(std::vector< double > &randoms, int K)
Definition: BCMath.cxx:318
void CacheFactorial(unsigned int n)
Definition: BCMath.cxx:169
double LogGaus(double x, double mean, double sigma, bool norm)
Definition: BCMath.cxx:33
double Rvalue(const std::vector< double > &chain_means, const std::vector< double > &chain_variances, const unsigned &chain_length, const bool &strict)
Definition: BCMath.cxx:551
double ApproxBinomial(int n, int k, double p)
Definition: BCMath.cxx:73
double LogApproxBinomial(int n, int k, double p)
Definition: BCMath.cxx:80
double LogPoisson(double x, double par)
Definition: BCMath.cxx:57
std::vector< double > longestRunsChi2(const std::vector< double > &yMeasured, const std::vector< double > &yExpected, const std::vector< double > &sigma)
Definition: BCMath.cxx:441
double LogFact(int n)
Definition: BCMath.cxx:135
TH1D * ECDF(const std::vector< double > &data)
Definition: BCMath.cxx:333