BCPrior.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 // ---------------------------------------------------------
10 
11 #include "BCAux.h"
12 #include "BCLog.h"
13 #include "BCPrior.h"
14 #include "BCConstantPrior.h"
15 
16 #include <TMath.h>
17 #include <TF1.h>
18 #include <TH1.h>
19 #include <TH2.h>
20 #include <TRandom.h>
21 
22 // ---------------------------------------------------------
24  : fPriorFunction("prior_interal_f1", this, &BCPrior::GetPriorForROOT, 0, 0, 1) //-std::numeric_limits<double>::max(),std::numeric_limits<double>::max()))
25  , fLogIntegral(0)
26 {
27 }
28 
29 // ---------------------------------------------------------
31  : fPriorFunction("prior_interal_f1", this, &BCPrior::GetPriorForROOT, 0, 0, 1) //-std::numeric_limits<double>::max(),std::numeric_limits<double>::max()))
32  , fLogIntegral(other.fLogIntegral)
33 {
34 }
35 
36 // ---------------------------------------------------------
38 {
39 }
40 
41 // ---------------------------------------------------------
42 void swap(BCPrior& A, BCPrior& B)
43 {
44  TF1 temp = A.fPriorFunction;
46  B.fPriorFunction = temp;
47  std::swap(A.fLogIntegral, B.fLogIntegral);
48 }
49 
50 // ---------------------------------------------------------
51 double BCPrior::GetPrior(double x, bool normalize)
52 {
53  double lp = GetLogPrior(x);
54  if (normalize)
55  lp -= fLogIntegral;
56 
57  if (std::isfinite(lp))
58  return exp(lp);
59  if (lp < 0)
60  return 0; // exp(-inf)
61  return std::numeric_limits<double>::infinity(); // exp(inf)
62 }
63 
64 // ---------------------------------------------------------
65 double BCPrior::GetMode(double xmin, double xmax)
66 {
67  BCAux::MakeFinite(xmin, xmax);
68  return fPriorFunction.GetMaximumX(xmin, xmax);
69 }
70 
71 // ---------------------------------------------------------
72 double BCPrior::GetRawMoment(unsigned n, double xmin, double xmax)
73 {
74  if (n == 0)
75  return 1;
76  BCAux::MakeFinite(xmin, xmax);
77  return fPriorFunction.Moment(static_cast<double>(n), xmin, xmax);
78 }
79 
80 // ---------------------------------------------------------
81 double BCPrior::GetIntegral(double xmin, double xmax)
82 {
83  BCAux::MakeFinite(xmin, xmax);
84  return fPriorFunction.Integral(xmin, xmax);
85 }
86 
87 // ---------------------------------------------------------
88 double BCPrior::GetCentralMoment(unsigned n, double xmin, double xmax)
89 {
90  if (n == 0)
91  return std::numeric_limits<double>::infinity();
92 
93  if (n == 1)
94  return 0;
95 
96  double mean = GetRawMoment(1, xmin, xmax);
97  if (!std::isfinite(mean))
98  return std::numeric_limits<double>::infinity();
99 
100  double cm = 0;
101  for (unsigned i = n; i > 1; --i) {
102  double rm = GetRawMoment(i, xmin, xmax);
103  if (!std::isfinite(rm))
104  return std::numeric_limits<double>::infinity();
105  cm += TMath::Binomial(n, i) * rm * pow(-mean, n - i);
106  }
107  cm -= (n - 1) * pow(-mean, n);
108  return cm;
109 }
110 
111 // ---------------------------------------------------------
112 double BCPrior::GetStandardizedMoment(unsigned n, double xmin, double xmax)
113 {
114  double variance = GetVariance(xmin, xmax);
115  if (!std::isfinite(variance))
116  return std::numeric_limits<double>::infinity();
117 
118  double cm = GetCentralMoment(n, xmin, xmax);
119  if (!std::isfinite(cm))
120  return std::numeric_limits<double>::infinity();
121 
122  return cm / pow(variance, n / 2.);
123 }
124 
125 // ---------------------------------------------------------
126 double BCPrior::GetRandomValue(double xmin, double xmax, TRandom* const R)
127 {
128  (void)R;
129  return fPriorFunction.GetRandom(xmin, xmax);
130 }
131 
132 // ---------------------------------------------------------
133 void BCPrior::SetFunctionRange(double xmin, double xmax)
134 {
135  fPriorFunction.SetRange(xmin, xmax);
136  CalculateAndStoreIntegral(xmin, xmax);
137 }
138 
139 // ---------------------------------------------------------
141 {
142  if (!h)
143  return;
144  for (int i = 1; i <= h->GetNbinsX(); ++i)
145  h -> SetBinContent(i, GetPrior(h->GetXaxis()->GetBinCenter(i)));
146 }
147 
148 // ---------------------------------------------------------
150 {
151  if (!h)
152  return;
153  for (int i = 1; i <= h->GetNbinsX(); ++i)
154  if (h->GetXaxis()->GetBinWidth(i) > 0)
155  h -> SetBinContent(i, GetIntegral(h->GetXaxis()->GetBinLowEdge(i), h->GetXaxis()->GetBinUpEdge(i)) / h->GetXaxis()->GetBinWidth(i));
156 }
157 
158 // ---------------------------------------------------------
159 BCH1D BCPrior::GetBCH1D(TH1* bins, const std::string& name)
160 {
161  BCH1D bch1;
162  if (!IsValid())
163  return bch1;
164 
165  TH1* h = BCAux::OwnClone(bins, name);
166 
167  h->Add(&GetFunction(), 1, "I");
168 
169  bch1 = h;
170  bch1.SetLocalMode(GetMode(h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax()));
171 
172  return bch1;
173 }
174 
175 // ---------------------------------------------------------
176 BCH2D BCPrior::GetBCH2D(BCPrior* ordinate, TH2* bins, const std::string& name)
177 {
178  BCH2D bch2;
179 
180  if (!ordinate || !ordinate->IsValid())
181  return bch2;
182 
183  BCH1D bch_x = GetBCH1D(bins->ProjectionX(), "tempx");
184  if (!bch_x.Valid())
185  return bch2;
186 
187  BCH1D bch_y = ordinate->GetBCH1D(bins->ProjectionY(), "tempy");
188  if (!bch_y.Valid())
189  return bch2;
190 
191  TH2* h = BCAux::OwnClone(bins, name);
192 
193  // get x bins:
194  std::vector<double> bin_edges_x(bch_x.GetHistogram()->GetNbinsX() + 1, 0);
195  bch_x.GetHistogram()->GetXaxis()->GetLowEdge(&bin_edges_x[0]);
196  bin_edges_x.back() = bch_x.GetHistogram()->GetXaxis()->GetXmax();
197  // get y bins
198  std::vector<double> bin_edges_y(bch_y.GetHistogram()->GetNbinsX() + 1, 0);
199  bch_y.GetHistogram()->GetXaxis()->GetLowEdge(&bin_edges_y[0]);
200  bin_edges_y.back() = bch_y.GetHistogram()->GetXaxis()->GetXmax();
201  // set into bins histogram
202  bins->SetBins(bin_edges_x.size() - 1, &bin_edges_x[0], bin_edges_y.size() - 1, &bin_edges_y[0]);
203 
204  // set content
205  for (int x = 1; x <= bch_x.GetHistogram()->GetNbinsX(); ++x)
206  for (int y = 1; y <= bch_y.GetHistogram()->GetNbinsX(); ++y)
207  h->SetBinContent(x, y, bch_x.GetHistogram()->GetBinContent(x) * bch_x.GetHistogram()->GetBinContent(y));
208 
209  bch2 = h;
210 
211  return bch2;
212 }
A class to represent the prior of a parameter.
Definition: BCPrior.h:49
void MakeFinite(double &xmin, double &xmax)
Make an infinite range finite by setting inf values to max.
Definition: BCAux.cxx:102
virtual double GetPriorForROOT(double *x, double *)
For accessing prior as ROOT TF1.
Definition: BCPrior.h:222
virtual void FillHistogramByCenterValue(TH1 *h)
Fill histogram by prior evaluated at bin center.
Definition: BCPrior.cxx:140
T * OwnClone(const T *o)
Create a clone of the input but avoid registering the object with ROOT so it cannot be deleted twice...
Definition: BCAux.h:189
virtual void SetFunctionRange(double xmin, double xmax)
Set range of ROOT TF1 function.
Definition: BCPrior.cxx:133
virtual TF1 & GetFunction()
Return back ROOT TF1 evaluating BCPrior::GetPrior.
Definition: BCPrior.h:118
A class for handling 2D distributions.
Definition: BCH2D.h:37
TF1 fPriorFunction
Definition: BCPrior.h:291
BCPrior()
Empty constructor.
Definition: BCPrior.cxx:23
friend void swap(BCPrior &A, BCPrior &B)
swap
Definition: BCPrior.cxx:42
virtual double GetMode(double xmin=-std::numeric_limits< double >::infinity(), double xmax=std::numeric_limits< double >::infinity())
Return mode of prior (in range).
Definition: BCPrior.cxx:65
virtual double GetPrior(double x, bool normalize=false)
Get prior.
Definition: BCPrior.cxx:51
virtual bool Valid() const
Whether histogram has been set and filled.
virtual double CalculateAndStoreIntegral(double xmin=-std::numeric_limits< double >::infinity(), double xmax=std::numeric_limits< double >::infinity())
Calculate and store integral for use in normalized TF1s.
Definition: BCPrior.h:242
A class for handling 1D distributions.
Definition: BCH1D.h:34
virtual BCH2D GetBCH2D(BCPrior *ordinate, TH2 *bins, const std::string &name="prior")
Get BCH2D object for prior.
Definition: BCPrior.cxx:176
virtual double GetLogPrior(double x)=0
Get log of prior.
virtual double GetIntegral(double xmin=-std::numeric_limits< double >::infinity(), double xmax=std::numeric_limits< double >::infinity())
Get integral of prior.
Definition: BCPrior.cxx:81
virtual BCH1D GetBCH1D(TH1 *bins, const std::string &name="prior")
Get BCH1D object for prior.
Definition: BCPrior.cxx:159
virtual double GetRandomValue(double xmin, double xmax, TRandom *const R=NULL)
Definition: BCPrior.cxx:126
double fLogIntegral
Log of integral of unnormalized pdf over the range.
Definition: BCPrior.h:293
virtual double GetCentralMoment(unsigned n, double xmin=-std::numeric_limits< double >::infinity(), double xmax=std::numeric_limits< double >::infinity())
Get central moment of prior distrubion.
Definition: BCPrior.cxx:88
void SetLocalMode(double mode)
Set local mode.
Definition: BCH1D.h:158
virtual void FillHistogramByIntegral(TH1 *h)
Fill histogram by integrating prior over bin and dividing by bin width.
Definition: BCPrior.cxx:149
virtual double GetStandardizedMoment(unsigned n, double xmin=-std::numeric_limits< double >::infinity(), double xmax=std::numeric_limits< double >::infinity())
Get standardised moment of prior distrubion.
Definition: BCPrior.cxx:112
virtual double GetVariance(double xmin=-std::numeric_limits< double >::infinity(), double xmax=std::numeric_limits< double >::infinity())
Get variance of prior.
Definition: BCPrior.h:181
virtual bool IsValid() const =0
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
virtual ~BCPrior()
Destructor.
Definition: BCPrior.cxx:37