npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
HistoNDCdf.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_HISTONDCDF_HH_
2 #define NPSTAT_HISTONDCDF_HH_
3 
4 /*!
5 // \file HistoNDCdf.hh
6 //
7 // \brief Construct multivariate cumulative density out of a histogram
8 //
9 // Author: I. Volobouev
10 //
11 // November 2011
12 */
13 
14 #include <cassert>
15 #include <stdexcept>
16 
17 #include "npstat/stat/HistoND.hh"
18 
19 namespace npstat {
20  /**
21  // Multivariate cumulative density for a histogram of some scalar type.
22  // This class is mainly useful for its ability to come up with boxes
23  // that cover a certain predefined fraction of the distribution.
24  */
25  class HistoNDCdf
26  {
27  public:
28  /**
29  // The argument histogram can not have negative bins
30  // and also can not be empty
31  //
32  // The "iniScales" parameter in the following constructor
33  // specifies the proportions for the sides of the boxes
34  // which will be returned by the "coveringBox" method.
35  // For example, if for a 3-d histogram these proportions
36  // are 1, 2, and 3 then the sides of the returned boxes
37  // will be two times longer in the second dimension in
38  // comparison with the first dimension, and three times
39  // longer in the third dimension. All scales must be positive.
40  //
41  // The "eps" parameter specifies the tolerance within which
42  // the sizes of the boxes returned by the "coveringBox" method
43  // will be calculated. Their linear sizes will be within
44  // the factor (1 +- eps) of the correct ones. Naturally,
45  // this number must be larger than DBL_EPSILON.
46  */
47  template <typename Numeric>
49  const double* iniScales, const unsigned lenScales,
50  const double eps=1.0e-12)
51  : cdf_(ArrayND<double>(histo.binContents()).template
52  cdfArray<long double>()),
53  axes_(histo.axes()),
54  startBox_(BoxND<double>::sizeTwoBox(lenScales)),
55  buf_(lenScales),
56  tol_(eps),
57  dim_(lenScales)
58  {
59  if (histo.dim() == 0) throw std::invalid_argument(
60  "In npstat::HistoNDCdf constructor: "
61  "can not use zero-dimensional histograms");
62  if (!arrayIsDensity(histo.binContents())) throw std::invalid_argument(
63  "In npstat::HistoNDCdf constructor: histogram is not a density");
64  if (lenScales != histo.dim()) throw std::invalid_argument(
65  "In npstat::HistoNDCdf constructor: incompatible number of scales");
66  assert(iniScales);
67  for (unsigned i=0; i<dim_; ++i)
68  {
69  if (iniScales[i] <= 0.0) throw std::invalid_argument(
70  "In npstat::HistoNDCdf constructor: all scales must be positive");
71  startBox_[i].expand(iniScales[i]);
72  }
73  const double mx = cdf_.linearValue(cdf_.length() - 1U);
74  assert(mx > 0.0);
75  cdf_ /= mx;
76  }
77 
78  /** Histogram dimensionality */
79  inline unsigned dim() const {return dim_;}
80 
81  /** Bounding box of the histogram from which this object was created */
83 
84  /** Multivariate cumulative density function */
85  double cdf(const double* x, unsigned dim) const;
86 
87  /** Fraction of the distribution inside the given box */
88  double boxCoverage(const BoxND<double>& box) const;
89 
90  /**
91  // The box that is centered at the given position and covers
92  // the given fraction of the distribution
93  */
94  void coveringBox(double coveredFraction, const double* boxCenter,
95  unsigned dimCenter, BoxND<double>* coverBox) const;
96  private:
97  HistoNDCdf();
98 
99  ArrayND<double> cdf_;
100  std::vector<HistoAxis> axes_;
101  BoxND<double> startBox_;
102  mutable std::vector<double> buf_;
103  double tol_;
104  unsigned dim_;
105  };
106 }
107 
108 #endif // NPSTAT_HISTONDCDF_HH_
Arbitrary-dimensional histogram template.
Definition: ArrayND.hh:93
unsigned long length() const
Definition: ArrayND.hh:320
Numeric & linearValue(unsigned long index)
Definition: HistoNDCdf.hh:26
unsigned dim() const
Definition: HistoNDCdf.hh:79
BoxND< double > boundingBox() const
void coveringBox(double coveredFraction, const double *boxCenter, unsigned dimCenter, BoxND< double > *coverBox) const
double boxCoverage(const BoxND< double > &box) const
HistoNDCdf(const HistoND< Numeric > &histo, const double *iniScales, const unsigned lenScales, const double eps=1.0e-12)
Definition: HistoNDCdf.hh:48
double cdf(const double *x, unsigned dim) const
Definition: HistoND.hh:46
const ArrayND< Numeric > & binContents() const
Definition: HistoND.hh:197
unsigned dim() const
Definition: HistoND.hh:187
Definition: AbsArrayProjector.hh:14
bool arrayIsDensity(const Arr &arr)
Definition: BoxND.hh:25
BoxND & expand(double r)