npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
AbsBandwidthGCV.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_ABSBANDWIDTHGCV_HH_
2 #define NPSTAT_ABSBANDWIDTHGCV_HH_
3 
4 /*!
5 // \file AbsBandwidthGCV.hh
6 //
7 // \brief Interface definitions for cross-validation with grouped data
8 //
9 // Implementations of these interfaces should calculate the quantity
10 // which is to be maximized (pseudo log likelihood, -AMISE, etc.)
11 //
12 // Author: I. Volobouev
13 //
14 // June 2015
15 */
16 
17 #include "npstat/stat/HistoND.hh"
18 
19 #ifdef SWIG
20 #include <stdexcept>
21 #include "npstat/wrap/arrayNDToNumpy.hh"
22 #include "npstat/wrap/numpyArrayUtils.hh"
23 #endif // SWIG
24 
25 namespace npstat {
26  // Forward declarations
27  struct AbsPolyFilter1D;
28  struct AbsPolyFilterND;
29 
30  /**
31  // Cross-validation for univariate densities.
32  // "Numeric" template parameter is the type of histogram bins.
33  // "Num2" is the type produced by the density estimation code
34  // (usually just double).
35  */
36  template<typename Numeric, typename Num2>
38  {
39  typedef Numeric bin_type;
40  typedef Num2 density_type;
41 
42  inline virtual ~AbsBandwidthGCV1D() {}
43 
44  /**
45  // It should be assumed that the "nFillsInRange" method of the
46  // argument histogram returns the actual number of fills (that is,
47  // the histogram represents an actual collection of points, has
48  // possible bin values of 0, 1, 2, ..., and it is not scaled).
49  */
50  virtual double operator()(
51  const HistoND<Numeric>& histo,
52  const Num2* densityEstimate,
53  const Num2* leaveOneOutEstimate,
54  unsigned lenEstimate,
55  const AbsPolyFilter1D& filterUsed) const = 0;
56 
57  /** Cross-validation for samples of univariate weighted points */
58  virtual double operator()(
59  const HistoND<Numeric>& histo,
60  double effectiveSampleSize,
61  const Num2* densityEstimate,
62  const Num2* leaveOneOutEstimate,
63  unsigned lenEstimate,
64  const AbsPolyFilter1D& filterUsed) const = 0;
65 
66 #ifdef SWIG
67  inline double cv(
68  const HistoND<Numeric,HistoAxis>& histo,
69  PyObject* input, PyObject* leaveOneOut,
70  const AbsPolyFilter1D& filterUsed) const
71  {
72  const int typenum = numpyArrayType(input);
73  const int typenum2 = numpyArrayType(leaveOneOut);
74  if (typenum != NumpyTypecode<double>::code ||
75  typenum2 != NumpyTypecode<double>::code)
76  throw std::invalid_argument("In npstat::AbsBandwidthGCV1D::cv: "
77  "unsupported input array type");
78  const unsigned datalen = histo.nBins();
79  if (!isNumpyShapeCompatible(input, &datalen, 1U) ||
80  !isNumpyShapeCompatible(leaveOneOut, &datalen, 1U)) throw std::invalid_argument(
81  "In npstat::AbsBandwidthCV1D::cv: incompatible array shape");
82  const Num2* in = (double*)PyArray_DATA((PyArrayObject*)input);
83  const Num2* leave = (double*)PyArray_DATA((PyArrayObject*)leaveOneOut);
84  return this->operator()(histo, in, leave, datalen, filterUsed);
85  }
86 
87  inline double cvWeighted(
88  const HistoND<Numeric,HistoAxis>& histo,
89  const double effectiveSampleSize,
90  PyObject* input, PyObject* leaveOneOut,
91  const AbsPolyFilter1D& filterUsed) const
92  {
93  const int typenum = numpyArrayType(input);
94  const int typenum2 = numpyArrayType(leaveOneOut);
95  if (typenum != NumpyTypecode<double>::code ||
96  typenum2 != NumpyTypecode<double>::code)
97  throw std::invalid_argument("In npstat::AbsBandwidthGCV1D::cvWeighted: "
98  "unsupported input array type");
99  const unsigned datalen = histo.nBins();
100  if (!isNumpyShapeCompatible(input, &datalen, 1U) ||
101  !isNumpyShapeCompatible(leaveOneOut, &datalen, 1U)) throw std::invalid_argument(
102  "In npstat::AbsBandwidthGCV1D::cvWeighted: incompatible array shape");
103  const Num2* in = (double*)PyArray_DATA((PyArrayObject*)input);
104  const Num2* leave = (double*)PyArray_DATA((PyArrayObject*)leaveOneOut);
105  return this->operator()(histo, effectiveSampleSize, in,
106  leave, datalen, filterUsed);
107  }
108 #endif // SWIG
109  };
110 
111  /**
112  // Cross-validation for multivariate densities.
113  // "Numeric" template parameter is the type of histogram bins.
114  // "Array" template parameter should be one of ArrayND types.
115  */
116  template<typename Numeric, class Array>
118  {
119  typedef Numeric bin_type;
120  typedef Array density_type;
121 
122  inline virtual ~AbsBandwidthGCVND() {}
123 
124  /**
125  // It should be assumed that the "nFillsInRange" method of the
126  // argument histogram returns the actual number of fills.
127  */
128  virtual double operator()(
129  const HistoND<Numeric>& histo,
130  const Array& densityEstimate,
131  const Array& leaveOneOutEstimate,
132  const AbsPolyFilterND& filterUsed) const = 0;
133 
134  /** Cross-validation for samples of multivariate weighted points */
135  virtual double operator()(
136  const HistoND<Numeric>& histo,
137  double effectiveSampleSize,
138  const Array& densityEstimate,
139  const Array& leaveOneOutEstimate,
140  const AbsPolyFilterND& filterUsed) const = 0;
141 
142 #ifdef SWIG
143  inline double cv(
144  const HistoND<Numeric,HistoAxis>& histo,
145  PyObject* input, PyObject* leaveOneOut,
146  const AbsPolyFilterND& filterUsed) const
147  {
148  const int typenum = numpyArrayType(input);
149  const int typenum2 = numpyArrayType(leaveOneOut);
150  if (typenum != NumpyTypecode<double>::code ||
151  typenum2 != NumpyTypecode<double>::code)
152  throw std::invalid_argument("In npstat::AbsBandwidthCVGND::cv: "
153  "unsupported input array type");
154  const unsigned* shape = histo.binContents().shapeData();
155  if (!isNumpyShapeCompatible(input, shape, histo.dim()) ||
156  !isNumpyShapeCompatible(leaveOneOut, shape, histo.dim()))
157  throw std::invalid_argument("In npstat::AbsBandwidthCVGND::cv: "
158  "incompatible array shape");
159  double* in = (double*)PyArray_DATA((PyArrayObject*)input);
160  double* leave = (double*)PyArray_DATA((PyArrayObject*)leaveOneOut);
161  const ArrayND<double>& wrap = externalMemArrayND(in, shape, histo.dim());
162  const ArrayND<double>& wrapL = externalMemArrayND(leave, shape, histo.dim());
163  return this->operator()(histo, wrap, wrapL, filterUsed);
164  }
165 
166  inline double cvWeighted(
167  const HistoND<Numeric,HistoAxis>& histo,
168  const double effectiveSampleSize,
169  PyObject* input, PyObject* leaveOneOut,
170  const AbsPolyFilterND& filterUsed) const
171  {
172  const int typenum = numpyArrayType(input);
173  const int typenum2 = numpyArrayType(leaveOneOut);
174  if (typenum != NumpyTypecode<double>::code ||
175  typenum2 != NumpyTypecode<double>::code)
176  throw std::invalid_argument("In npstat::AbsBandwidthCVGND::cvWeighted: "
177  "unsupported input array type");
178  const unsigned* shape = histo.binContents().shapeData();
179  if (!isNumpyShapeCompatible(input, shape, histo.dim()) ||
180  !isNumpyShapeCompatible(leaveOneOut, shape, histo.dim()))
181  throw std::invalid_argument("In npstat::AbsBandwidthCVGND::cvWeighted: "
182  "incompatible array shape");
183  double* in = (double*)PyArray_DATA((PyArrayObject*)input);
184  double* leave = (double*)PyArray_DATA((PyArrayObject*)leaveOneOut);
185  const ArrayND<double>& wrap = externalMemArrayND(in, shape, histo.dim());
186  const ArrayND<double>& wrapL = externalMemArrayND(leave, shape, histo.dim());
187  return this->operator()(histo, effectiveSampleSize, wrap, wrapL, filterUsed);
188  }
189 #endif // SWIG
190  };
191 }
192 
193 #endif // NPSTAT_ABSBANDWIDTHGCV_HH_
Arbitrary-dimensional histogram template.
const unsigned * shapeData() const
Definition: ArrayND.hh:335
Definition: HistoND.hh:46
const ArrayND< Numeric > & binContents() const
Definition: HistoND.hh:197
unsigned long nBins() const
Definition: HistoND.hh:226
unsigned dim() const
Definition: HistoND.hh:187
Definition: AbsArrayProjector.hh:14
ArrayND< Numeric > externalMemArrayND(Numeric *data, const unsigned *shape, unsigned dim)
Definition: AbsBandwidthGCV.hh:38
virtual double operator()(const HistoND< Numeric > &histo, double effectiveSampleSize, const Num2 *densityEstimate, const Num2 *leaveOneOutEstimate, unsigned lenEstimate, const AbsPolyFilter1D &filterUsed) const =0
virtual double operator()(const HistoND< Numeric > &histo, const Num2 *densityEstimate, const Num2 *leaveOneOutEstimate, unsigned lenEstimate, const AbsPolyFilter1D &filterUsed) const =0
Definition: AbsBandwidthGCV.hh:118
virtual double operator()(const HistoND< Numeric > &histo, const Array &densityEstimate, const Array &leaveOneOutEstimate, const AbsPolyFilterND &filterUsed) const =0
virtual double operator()(const HistoND< Numeric > &histo, double effectiveSampleSize, const Array &densityEstimate, const Array &leaveOneOutEstimate, const AbsPolyFilterND &filterUsed) const =0
Definition: AbsPolyFilter1D.hh:27
Definition: AbsPolyFilterND.hh:27