npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
DensityAveScanND.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_DENSITYAVESCANND_HH_
2 #define NPSTAT_DENSITYAVESCANND_HH_
3 
4 /*!
5 // \file DensityAveScanND.hh
6 //
7 // \brief Fill multivariate arrays with multivariate density values by
8 // averaging inside the corresponding bins
9 //
10 // This class can be used with "functorFill" method of ArrayND (e.g., with
11 // histogram bin contents).
12 //
13 // Author: I. Volobouev
14 //
15 // June 2015
16 */
17 
18 #include <vector>
19 #include <cassert>
20 #include <stdexcept>
21 #include <memory>
22 #include <climits>
23 
26 
27 namespace npstat {
28  template<class Axis>
30  {
31  public:
32  /**
33  // This functor will NOT make a copy of the "fcn" parameter. This
34  // parameter will be used by reference only (aliased). It is up to
35  // the user of this class to ensure proper lifetime of this object.
36  //
37  // The density will be averaged over each bin using tensor
38  // product quadrature with "nIntegrationPoints" in each dimension.
39  */
41  const std::vector<Axis>& axes,
42  const unsigned nIntegrationPoints,
43  double normfactor=1.0)
44  : fcn_(fcn), axes_(new std::vector<Axis>(axes)), norm_(normfactor),
45  nInteg_(nIntegrationPoints), dim_(fcn.dim())
46  {
47  if (!(dim_ && dim_ == axes_->size())) throw std::invalid_argument(
48  "In npstat::DensityAveScanND constructor: incompatible arguments");
49  if (dim_ > CHAR_BIT*sizeof(unsigned long)) throw std::invalid_argument(
50  "In npstat::DensityAveScanND constructor: dimensionality is too high");
51  }
52 
53  inline void geBinCenter(const unsigned* index, const unsigned indexLen,
54  double* center) const
55  {
56  if (dim_ != indexLen) throw std::invalid_argument(
57  "In npstat::DensityAveScanND::getBinCenter: "
58  "incompatible index dimensionality");
59  assert(index);
60  assert(center);
61  const Axis* axes = &(*axes_)[0];
62  for (unsigned i=0; i<dim_; ++i)
63  center[i] = axes[i].binCenter(index[i]);
64  }
65 
66  inline double geBinSize(const unsigned* index, const unsigned indexLen,
67  double* size) const
68  {
69  if (dim_ != indexLen) throw std::invalid_argument(
70  "In npstat::DensityAveScanND::getBinSize: "
71  "incompatible index dimensionality");
72  assert(index);
73  assert(size);
74  double volume = 1.0;
75  const Axis* axes = &(*axes_)[0];
76  for (unsigned i=0; i<dim_; ++i)
77  {
78  const double width = axes[i].binWidth(index[i]);
79  volume *= width;
80  size[i] = width;
81  }
82  return volume;
83  }
84 
85  inline double operator()(const unsigned* index, const unsigned indexLen) const
86  {
87  if (dim_ != indexLen) throw std::invalid_argument(
88  "In npstat::DensityAveScanND::operator(): "
89  "incompatible input point dimensionality");
90  assert(index);
91 
92  double center[CHAR_BIT*sizeof(unsigned long)];
93  geBinCenter(index, indexLen, center);
94  if (nInteg_ > 1U)
95  {
96  double size[CHAR_BIT*sizeof(unsigned long)];
97  const double volume = geBinSize(index, indexLen, size);
98  const double integ = rectangleIntegralCenterAndSize(
99  fcn_, center, size, dim_, nInteg_);
100  return norm_*integ/volume;
101  }
102  else
103  return norm_*fcn_(center, dim_);
104  }
105 
106  private:
108 
109  DensityFunctorND fcn_;
110  std::shared_ptr<std::vector<Axis> > axes_;
111  double norm_;
112  unsigned nInteg_;
113  unsigned dim_;
114 
115 #ifdef SWIG
116  public:
117  inline void mapIndex(const unsigned* index, unsigned indexLen,
118  double* coords, unsigned lenCoords)
119  {
120  if (dim_ != lenCoords) throw std::invalid_argument(
121  "In npstat::DensityAveScanND::mapIndex: "
122  "incompatible coordinate dimensionality");
123  this->geBinCenter(index, indexLen, coords);
124  }
125 
126  inline double mapBinSize(const unsigned* index, unsigned indexLen,
127  double* coords, unsigned lenCoords)
128  {
129  if (dim_ != lenCoords) throw std::invalid_argument(
130  "In npstat::DensityAveScanND::mapBinSize: "
131  "incompatible coordinate dimensionality");
132  return this->geBinSize(index, indexLen, coords);
133  }
134 #endif // SWIG
135  };
136 
137  // Helper function for creating DensityAveScanND objects
138  template<class Axis>
139  inline DensityAveScanND<Axis> makeDensityAveScanND(
140  const AbsDistributionND& fcn, const std::vector<Axis>& axes,
141  const unsigned nIntegPoints, double normfactor=1.0)
142  {
143  return DensityAveScanND<Axis>(fcn, axes, nIntegPoints, normfactor);
144  }
145 
146  /**
147  // A helper functor to be used for the determination of multivariate
148  // density discretization errors (when the density is represented by
149  // a collection of values on a grid)
150  */
152  {
153  public:
155  const double normfactor,
156  const double discreteValue)
157  : fcn_(fcn), norm_(normfactor), h_(discreteValue) {}
158 
159  inline virtual ~DensityDiscretizationErrorND() {}
160 
161  inline virtual double operator()(const double* pt, unsigned dim) const
162  {
163  const double d = norm_*fcn_.density(pt, dim) - h_;
164  return d*d;
165  }
166 
167  inline virtual unsigned minDim() const {return fcn_.dim();}
168 
169  private:
171  const AbsDistributionND& fcn_;
172  const double norm_;
173  const double h_;
174  };
175 }
176 
177 #endif // NPSTAT_DENSITYAVESCANND_HH_
Interface definition for multivariate continuous statistical distributions.
Definition: AbsDistributionND.hh:26
Definition: DensityAveScanND.hh:30
DensityAveScanND(const AbsDistributionND &fcn, const std::vector< Axis > &axes, const unsigned nIntegrationPoints, double normfactor=1.0)
Definition: DensityAveScanND.hh:40
Definition: DensityAveScanND.hh:152
virtual double operator()(const double *pt, unsigned dim) const
Definition: DensityAveScanND.hh:161
virtual unsigned minDim() const
Definition: DensityAveScanND.hh:167
Definition: AbsArrayProjector.hh:14
double rectangleIntegralCenterAndSize(const AbsMultivariateFunctor &f, const double *rectangleCenter, const double *rectangleSize, unsigned dim, unsigned integrationPoints)
Gaussian quadratures on rectangles and hyperrectangles using tensor product integration.
Definition: AbsMultivariateFunctor.hh:19