npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
LocalPolyFilterND.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_LOCALPOLYFILTERND_HH_
2 #define NPSTAT_LOCALPOLYFILTERND_HH_
3 
4 /*!
5 // \file LocalPolyFilterND.hh
6 //
7 // \brief Local polynomial filtering (regression) on uniform
8 // hyperrectangular grids
9 //
10 // Author: I. Volobouev
11 //
12 // November 2009
13 */
14 
15 #include <map>
16 #include <vector>
17 
18 #include "geners/ClassId.hh"
19 #include "geners/CPP11_auto_ptr.hh"
20 
21 #include "npstat/nm/ArrayND.hh"
22 #include "npstat/nm/Matrix.hh"
23 
25 
26 namespace npstat {
27  typedef ArrayND<double> PolyFilterND;
28 
29  /** This class performs local polynomial filtering in multiple dimensions */
30  template <unsigned MaxDeg>
32  {
33  public:
34  enum {deg_size = MaxDeg};
35 
36  /**
37  // Main constructor. The arguments are as follows:
38  //
39  // taper -- Damping factors for each polynomial degree
40  // (starting with the 0th order term). This can be
41  // NULL in which case it is assumed that all
42  // factors are 1.
43  //
44  // maxDegree -- Maximum degree of the polynomials. The value
45  // must not exceed the "MaxDeg" template parameter.
46  // The length of the "taper" array (if not NULL)
47  // must be equal to maxDegree + 1. Note that, far
48  // away from the boundaries (where the situation is
49  // symmetric) the same filter will be produced using
50  // the same taper with an even degree N and with
51  // an odd degree N+1. Near the boundaries the filter
52  // coefficients will, of course, differ in these
53  // two cases.
54  //
55  // weight -- The array of weights.
56  //
57  // mirrorWeight -- If true, the "weight" argument represents
58  // just one hyperoctant corresponding to
59  // positive directions in all dimensions.
60  // The remaining part of the weight should
61  // be generated by reflections. If false,
62  // the "weight" argument will not be mirrored.
63  // In the latter case, the maximum of the weight
64  // should be in the array center.
65  //
66  // dataShape -- The shape of the data arrays which will be
67  // processed by this filter
68  */
69  template <class Array>
70  LocalPolyFilterND(const double* taper, unsigned maxDegree,
71  const Array& weight, bool mirrorWeight,
72  const ArrayShape& dataShape);
73 
75  LocalPolyFilterND& operator=(const LocalPolyFilterND&);
76 
77  virtual ~LocalPolyFilterND();
78 
79  //@{
80  /** Inspect object properties */
81  inline unsigned dim() const {return bins_.rank();}
82  inline unsigned maxDegree() const {return maxDegree_;}
83  inline ArrayShape dataShape() const {return bins_.shape();}
84  double taper(unsigned degree) const;
85  //@}
86 
87  /** Get the filter coefficients for the given grid point */
88  const PolyFilterND& getFilter(const unsigned* index,
89  unsigned lenIndex) const;
90 
91  /** Extract filter coefficients using linear grid index */
92  const PolyFilterND& linearGetFilter(unsigned long index) const;
93 
94  /** Get the complete effective filter matrix */
96 
97  /** Get the info needed to construct the sparse filter matrix */
98  template <class Triplet>
99  CPP11_auto_ptr<std::vector<Triplet> > sparseFilterTriplets() const;
100 
101  //@{
102  /**
103  // Contribution of a single point into the density estimate
104  // at that point (not normalized). This is needed for various
105  // leaving-one-out cross-validation procedures.
106  */
108  const unsigned* index, unsigned lenIndex) const;
109  double linearSelfContribution(unsigned long index) const;
110  //@}
111 
112  /** Check compatibility of an array with the filter */
113  template <class Array>
114  inline bool isCompatible(const Array& in) const
115  {return bins_.isShapeCompatible(in);}
116 
117  /** This method performs the filtering */
118  template <class ArrIn, class ArrOut>
119  void filter(const ArrIn& in, ArrOut* out) const;
120 
121  /**
122  // A diffent filtering method in which the shapes of the
123  // kernels are determined by the positions of the "sources"
124  // (i.e., sample points) instead of the positions at which
125  // the density (or response) is estimated. Note that elements
126  // of "out" array themselves are used as result accumulators.
127  */
128  template <class ArrIn, class ArrOut>
129  void convolve(const ArrIn& in, ArrOut* out) const;
130 
131  template <unsigned MaxDeg2>
132  bool operator==(const LocalPolyFilterND<MaxDeg2>& r) const;
133 
134  template <unsigned MaxDeg2>
135  inline bool operator!=(const LocalPolyFilterND<MaxDeg2>& r) const
136  {return !(*this == r);}
137 
138  // Methods needed for I/O
139  inline virtual gs::ClassId classId() const {return gs::ClassId(*this);}
140  virtual bool write(std::ostream& os) const;
141 
142  static const char* classname();
143  static inline unsigned version() {return 1;}
144  static LocalPolyFilterND* read(const gs::ClassId& id, std::istream& in);
145 
146  static inline unsigned classMaxDegree() {return MaxDeg;}
147 
148  private:
149  typedef std::map<ArrayRange, PolyFilterND*> PolyMap;
150 
152 
153  template <class Array>
154  void initialize(const double* itaper, unsigned maxDegree,
155  const Array& inweight, bool mirrorWeight);
156 
157  void cleanup();
158  void copyFilters(const LocalPolyFilterND& r);
159 
160  double* taper_;
161  PolyMap unique_;
162  ArrayShape wshape_;
163  ArrayND<PolyFilterND*> bins_;
164  std::vector<unsigned> filterCenters_;
165  PolyFilterND* centerFilter_;
166  unsigned maxDegree_;
167  mutable std::vector<unsigned> indexBuf_;
168 
169  template <unsigned StackLen, unsigned StackDim>
170  PolyFilterND* buildFilter(const ArrayND<double,StackLen,StackDim>& w,
171  const unsigned* center,
172  const double* steps, unsigned nSteps);
173 
174  template <unsigned StackLen, unsigned StackDim>
175  void createFiltersLoop(unsigned level, unsigned long idxData,
176  const ArrayND<double,StackLen,StackDim>& weight,
177  ArrayRange& range, unsigned* center,
178  const double* steps, unsigned nSteps);
179 
180  template <typename Tin, unsigned StackLen, unsigned StackDim,
181  typename Tout, unsigned StackLen2, unsigned StackDim2>
182  void filterLoop(unsigned level, unsigned long idxData,
183  const ArrayND<Tin,StackLen,StackDim>& in,
184  ArrayND<Tout,StackLen2,StackDim2>* out,
185  unsigned* shift) const;
186 
187  template <typename Tin, unsigned StackLen, unsigned StackDim>
188  long double filterInnerLoop(unsigned level,
189  const ArrayND<Tin,StackLen,StackDim>& in,
190  const PolyFilterND& poly,
191  const unsigned* shift,
192  unsigned long idxData,
193  unsigned long idxPoly) const;
194 
195  void matrixLoop(unsigned level, unsigned long idxData,
196  Matrix<double>* out, unsigned* shift) const;
197 
198  void matrixInnerLoop(unsigned level, Matrix<double>* out,
199  unsigned long rowNumber,
200  const PolyFilterND& poly, const unsigned* shift,
201  unsigned long idxData, unsigned long idxPoly) const;
202 
203  template <class Triplet>
204  void sparseMatrixLoop(unsigned level, unsigned long idxData,
205  std::vector<Triplet>* out, unsigned* shift) const;
206 
207  template <class Triplet>
208  void sparseMatrixInnerLoop(unsigned level, std::vector<Triplet>* out,
209  unsigned long rowNumber,
210  const PolyFilterND& poly, const unsigned* shift,
211  unsigned long idxData, unsigned long idxPoly) const;
212 
213  template <class ArrOut>
214  void runConvolution(double w, unsigned long linearBin,
215  ArrOut* out, unsigned* cornerBuf, unsigned* indexBuf,
216  const unsigned* zeroBuf) const;
217 
218  static std::string generateClassName();
219 
220 #ifdef SWIG
221  public:
222  inline LocalPolyFilterND(const double* itaper, unsigned maxDegree,
223  const ArrayND<double>& inweight,
224  bool mirrorWeight,
225  const ArrayShape& dataShape)
226  : taper_(0), wshape_(inweight.shape()), bins_(dataShape),
227  centerFilter_(0), maxDegree_(maxDegree)
228  {
229  initialize(itaper, maxDegree, inweight, mirrorWeight);
230  }
231 #endif //SWIG
232  };
233 }
234 
235 #include "npstat/stat/LocalPolyFilterND.icc"
236 
237 #endif // NPSTAT_LOCALPOLYFILTERND_HH_
Interface definition for multivariate smoothers that can be cross-validated.
Arbitrary-dimensional array template.
Template matrix class.
Definition: LocalPolyFilterND.hh:32
Matrix< double > getFilterMatrix() const
CPP11_auto_ptr< std::vector< Triplet > > sparseFilterTriplets() const
bool isCompatible(const Array &in) const
Definition: LocalPolyFilterND.hh:114
double selfContribution(const unsigned *index, unsigned lenIndex) const
unsigned dim() const
Definition: LocalPolyFilterND.hh:81
void convolve(const ArrIn &in, ArrOut *out) const
void filter(const ArrIn &in, ArrOut *out) const
const PolyFilterND & getFilter(const unsigned *index, unsigned lenIndex) const
const PolyFilterND & linearGetFilter(unsigned long index) const
ArrayShape dataShape() const
Definition: LocalPolyFilterND.hh:83
LocalPolyFilterND(const double *taper, unsigned maxDegree, const Array &weight, bool mirrorWeight, const ArrayShape &dataShape)
double linearSelfContribution(unsigned long index) const
Definition: AbsArrayProjector.hh:14
std::vector< unsigned > ArrayShape
Definition: ArrayShape.hh:21
Definition: AbsPolyFilterND.hh:27