BCGaussianPrior.cxx
1 /*
2  * Copyright (C) 2007-2018, 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 #include "BCGaussianPrior.h"
10 #include "BCAux.h"
11 
12 #include <TMath.h>
13 
14 // ---------------------------------------------------------
15 BCGaussianPrior::BCGaussianPrior(double mean, double sigma)
16  : BCPrior()
17  , fMean(mean)
18  , fSigma(sigma)
19 {
20 }
21 
22 // ---------------------------------------------------------
23 double BCGaussianPrior::GetRawMoment(unsigned n, double xmin, double xmax)
24 {
25  if (n == 0)
26  return BCPrior::GetRawMoment(n, xmin, xmax);
27 
28  BCAux::BCRange r = BCAux::RangeType(xmin, xmax);
29 
30  if (r == BCAux::kReverseRange)
31  return GetRawMoment(n, xmax, xmin);
32 
33  if (r == BCAux::kInfiniteRange) {
34  if (n == 1)
35  return fMean;
36  if (n == 2)
37  return fMean * fMean + fSigma * fSigma;
38  if (n == 3)
39  return fMean * (fMean * fMean + 3 * fSigma * fSigma);
40  if (n == 4)
41  return pow(fMean, 4) + 6 * fMean * fMean * fSigma * fSigma + 3 * pow(fSigma, 4);
42  return BCPrior::GetRawMoment(n, xmin, xmax);
43  }
44 
45  if (r == BCAux::kEmptyRange)
46  return (n == 1) ? xmin : 0;
47 
48  if (n > 2)
49  return BCPrior::GetRawMoment(n, xmin, xmax);
50 
51  double amin = (xmin - fMean) / fSigma;
52  double amax = (xmax - fMean) / fSigma;
53  double Z = erf(amax / sqrt(2)) - erf(amin / sqrt(2));
54 
55  if (n == 1)
56  return fMean - fSigma * sqrt(2 / M_PI) * (exp(-amax * amax / 2) - exp(-amin * amin / 2)) / Z;
57 
58  // else n==2
59  double aphi_min = (r == BCAux::kNegativeInfiniteRange) ? 0 : (fMean + xmin) * exp(-amin * amin / 2);
60  double aphi_max = (r == BCAux::kPositiveInfiniteRange) ? 0 : (fMean + xmax) * exp(-amax * amax / 2);
61 
62  return fMean * fMean + fSigma * fSigma - fSigma * sqrt(2 / M_PI) * (aphi_max - aphi_min) / Z;
63 }
64 
65 // ---------------------------------------------------------
66 double BCGaussianPrior::GetIntegral(double xmin, double xmax)
67 {
68  switch (BCAux::RangeType(xmin, xmax)) {
69 
71  return -GetIntegral(xmax, xmin);
72 
74  return (TMath::Erf((xmax - fMean) / fSigma / sqrt(2)) - TMath::Erf((xmin - fMean) / fSigma / sqrt(2))) / 2;
75 
77  return (1 + TMath::Erf((xmax - fMean) / fSigma / sqrt(2))) / 2;
78 
80  return (1 - TMath::Erf((xmin - fMean) / fSigma / sqrt(2))) / 2;
81 
83  return 1;
84 
85  case BCAux::kEmptyRange:
86  return 0;
87 
88  default:
89  return std::numeric_limits<double>::quiet_NaN();
90  }
91 }
A class to represent the prior of a parameter.
Definition: BCPrior.h:49
BCGaussianPrior(double mean, double sigma)
Constructor.
BCRange
Range types.
Definition: BCAux.h:88
BCAux::BCRange RangeType(double xmin, double xmax)
Return type of range as a BCAux::BCRange enum.
Definition: BCAux.cxx:85
double fSigma
std dev of Gaussian
lower < upper, lower limit finite, upper limit infinite
Definition: BCAux.h:91
lower > upper
Definition: BCAux.h:94
lower limit == upper limit
Definition: BCAux.h:93
lower < upper, lower and upper limits finite
Definition: BCAux.h:89
lower < upper, lower limit infinite, upper limit finite
Definition: BCAux.h:90
lower < upper, lower and upper limits infinite
Definition: BCAux.h:92
virtual double GetIntegral(double xmin=-std::numeric_limits< double >::infinity(), double xmax=std::numeric_limits< double >::infinity())
Get integral of prior.
virtual double GetRawMoment(unsigned n, double xmin=-std::numeric_limits< double >::infinity(), double xmax=std::numeric_limits< double >::infinity())
Get raw moment of prior distrubion.
virtual double GetRawMoment(unsigned n, double xmin=-std::numeric_limits< double >::infinity(), double xmax=std::numeric_limits< double >::infinity())
Get raw moment of prior distrubion.
Definition: BCPrior.cxx:72