npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
AbsDistributionND.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_ABSDISTRIBUTIONND_HH_
2 #define NPSTAT_ABSDISTRIBUTIONND_HH_
3 
4 /*!
5 // \file AbsDistributionND.hh
6 //
7 // \brief Interface definition for multivariate continuous statistical
8 // distributions
9 //
10 // Author: I. Volobouev
11 //
12 // March 2010
13 */
14 
15 #include <vector>
16 #include <typeinfo>
17 
19 #include "geners/ClassId.hh"
20 
21 namespace npstat {
22  struct AbsRandomGenerator;
23 
24  /** All classes derived from this base should have copy constructors */
26  {
27  public:
28  explicit AbsDistributionND(const unsigned dim);
30  AbsDistributionND& operator=(const AbsDistributionND& r);
31 
32  inline virtual ~AbsDistributionND() {}
33 
34  /** "Virtual copy constructor" */
35  virtual AbsDistributionND* clone() const = 0;
36 
37  /**
38  // The comparison operator is needed mostly in order to
39  // support I/O testing. Because of this, do not expect
40  // it to work well for classes which do not implement
41  // the "isEqual" method. Moreover, derived classes should
42  // not implement "operator==", provide only "isEqual" if needed.
43  */
44  bool operator==(const AbsDistributionND& r) const;
45 
46  /** Logical negation of operator== */
47  inline bool operator!=(const AbsDistributionND& r) const
48  {return !(*this == r);}
49 
50  /** Dimensionality of the density */
51  inline unsigned dim() const {return dim_;}
52 
53  /** Probability density */
54  virtual double density(const double* x, unsigned dim) const = 0;
55 
56  /**
57  // Mapping from the unit hypercube into the density support
58  // region. Note that "bufLen" does not have to be equal to
59  // the dimensionality of the function. There may be an
60  // efficient way to generate just the leading dimensions
61  // in case "bufLen" is smaller than the dimensionality.
62  */
63  virtual void unitMap(const double* rnd,
64  unsigned bufLen, double* x) const = 0;
65 
66  /**
67  // The following method should return "true" in case the
68  // "unitMap" method is implemented by a sequence of conditional
69  // quantile functions. Distributions with such maps permit
70  // quantile-based interpolation procedures.
71  */
72  virtual bool mappedByQuantiles() const = 0;
73 
74  /**
75  // Random number generator according to the given distribution.
76  // Should return the number of random points used up from the
77  // generator. Length of the provided buffer "x" should be equal
78  // to the function dimensionality.
79  */
80  virtual unsigned random(AbsRandomGenerator& g,
81  double* x, unsigned lenX) const;
82 
83  //@{
84  /** Prototype needed for I/O */
85  virtual gs::ClassId classId() const = 0;
86  virtual bool write(std::ostream&) const {return false;}
87  //@}
88 
89  static inline const char* classname() {return "npstat::AbsDistributionND";}
90  static inline unsigned version() {return 1;}
91  static AbsDistributionND* read(const gs::ClassId& id, std::istream&);
92 
93  protected:
94  virtual bool isEqual(const AbsDistributionND&) const = 0;
95 
96  // Distribution dimensionality
97  const unsigned dim_;
98 
99  private:
100  AbsDistributionND();
101 
102  // Memory buffer for generating random numbers
103  std::vector<double> temp_;
104  double* ws_;
105 
106 #ifdef SWIG
107  public:
108  inline std::vector<double> random2(AbsRandomGenerator& g) const
109  {
110  std::vector<double> buffer(dim_);
111  this->random(g, &buffer[0], dim_);
112  return buffer;
113  }
114 
115  inline std::vector<double> unitMap2(const double* x, unsigned dim) const
116  {
117  std::vector<double> buffer(dim);
118  this->unitMap(x, dim, &buffer[0]);
119  return buffer;
120  }
121 #endif // SWIG
122  };
123 
124  /**
125  // Distribution which is scalable and shiftable in each
126  // direction separately (but can not be rotated)
127  */
129  {
130  public:
131  /**
132  // Location and scale parameters must be provided.
133  // The length of the location and scale arrays must be
134  // equal to the dimensionality of the density support.
135  */
137  const double* scale, unsigned dim);
138  inline virtual ~AbsScalableDistributionND() {}
139 
140  /** Get the location parameter for the given coordinate */
141  inline double location(unsigned i) const {return location_.at(i);}
142 
143  /** Get the scale parameter for the given coordinate */
144  inline double scale(unsigned i) const {return scale_.at(i);}
145 
146  /** Set the location parameter for the given coordinate */
147  inline void setLocation(unsigned i, double v) {location_.at(i) = v;}
148 
149  /** Set the scale parameter for the given coordinate */
150  void setScale(unsigned i, double v);
151 
152  //@{
153  /** Method overriden from the AbsDistributionND base class */
154  double density(const double* x, unsigned dim) const;
155  void unitMap(const double* rnd, unsigned dim, double* x) const;
156  //@}
157 
158  /** "Virtual copy constructor" */
159  virtual AbsScalableDistributionND* clone() const = 0;
160 
161  /**
162  // Is the mappling from the unit cube to the support region
163  // performed by the conditional quantile functions?
164  */
165  virtual bool mappedByQuantiles() const = 0;
166 
167  //@{
168  /** Method related to "geners" I/O */
169  virtual gs::ClassId classId() const = 0;
170  virtual bool write(std::ostream& os) const;
171  //@}
172 
173  /**
174  // Pseudo-read function for I/O. Note that this class is abstract,
175  // so its instance can not be created.
176  */
177  static bool read(std::istream& is, unsigned* dim,
178  std::vector<double>* locations,
179  std::vector<double>* scales);
180  protected:
181  /**
182  // Derived classes should override the following method as long as
183  // they have at least one additional data member. Don't forget to
184  // call "isEqual" of the base class inside the derived class.
185  */
186  virtual bool isEqual(const AbsDistributionND&) const;
187 
188  private:
189  virtual double unscaledDensity(const double* x) const = 0;
190  virtual void unscaledUnitMap(const double* rnd, unsigned bufLen,
191  double* x) const = 0;
192  std::vector<double> location_;
193  std::vector<double> scale_;
194  mutable std::vector<double> work_;
195  double scaleProd_;
196 
197 #ifdef SWIG
198  public:
200  const double* location, unsigned lenLocation,
201  const double* scale, unsigned lenScale);
202 #endif // SWIG
203  };
204 
205  /**
206  // Product distribution in which every marginal is represented by
207  // the same class. In the template below, Distro1D should be derived
208  // from AbsDistribution1D.
209  */
210  template<class Distro1D>
212  {
213  public:
214  /**
215  // The marginals_ vector should be filled by the constructors
216  // of the derived classes
217  */
218  inline explicit HomogeneousProductDistroND(unsigned dim)
219  : AbsDistributionND(dim) {marginals_.reserve(dim);}
220 
221  inline virtual ~HomogeneousProductDistroND() {}
222 
223  virtual HomogeneousProductDistroND* clone() const = 0;
224 
225  inline bool mappedByQuantiles() const {return true;}
226 
227  double density(const double* x, unsigned dim) const;
228  void unitMap(const double* rnd, unsigned bufLen, double* x) const;
229 
230  protected:
231  virtual bool isEqual(const AbsDistributionND& r) const;
232 
233  protected:
234  std::vector<Distro1D> marginals_;
235  };
236 
237  /**
238  // A functor for the density function of the given multivariate
239  // distribution which implements AbsMultivariateFunctor interface
240  */
242  {
243  public:
244  inline explicit DensityFunctorND(const AbsDistributionND& fcn)
245  : fcn_(fcn) {}
246 
247  inline virtual ~DensityFunctorND() {}
248 
249  inline virtual double operator()(const double* x, unsigned dim) const
250  {return fcn_.density(x, dim);}
251 
252  inline virtual unsigned minDim() const {return fcn_.dim();}
253 
254  private:
256  const AbsDistributionND& fcn_;
257  };
258 }
259 
260 #include "npstat/stat/AbsDistributionND.icc"
261 
262 #endif // NPSTAT_ABSDISTRIBUTIONND_HH_
Interface definition for multidimensional functors.
Definition: AbsDistributionND.hh:26
virtual unsigned random(AbsRandomGenerator &g, double *x, unsigned lenX) const
bool operator!=(const AbsDistributionND &r) const
Definition: AbsDistributionND.hh:47
virtual gs::ClassId classId() const =0
virtual void unitMap(const double *rnd, unsigned bufLen, double *x) const =0
virtual AbsDistributionND * clone() const =0
bool operator==(const AbsDistributionND &r) const
virtual bool mappedByQuantiles() const =0
unsigned dim() const
Definition: AbsDistributionND.hh:51
virtual double density(const double *x, unsigned dim) const =0
Definition: AbsDistributionND.hh:129
AbsScalableDistributionND(const double *location, const double *scale, unsigned dim)
static bool read(std::istream &is, unsigned *dim, std::vector< double > *locations, std::vector< double > *scales)
void setLocation(unsigned i, double v)
Definition: AbsDistributionND.hh:147
virtual bool isEqual(const AbsDistributionND &) const
void unitMap(const double *rnd, unsigned dim, double *x) const
virtual gs::ClassId classId() const =0
void setScale(unsigned i, double v)
virtual AbsScalableDistributionND * clone() const =0
virtual bool mappedByQuantiles() const =0
double location(unsigned i) const
Definition: AbsDistributionND.hh:141
double scale(unsigned i) const
Definition: AbsDistributionND.hh:144
double density(const double *x, unsigned dim) const
Definition: AbsDistributionND.hh:242
virtual double operator()(const double *x, unsigned dim) const
Definition: AbsDistributionND.hh:249
virtual unsigned minDim() const
Definition: AbsDistributionND.hh:252
Definition: AbsDistributionND.hh:212
void unitMap(const double *rnd, unsigned bufLen, double *x) const
virtual HomogeneousProductDistroND * clone() const =0
bool mappedByQuantiles() const
Definition: AbsDistributionND.hh:225
HomogeneousProductDistroND(unsigned dim)
Definition: AbsDistributionND.hh:218
double density(const double *x, unsigned dim) const
Definition: AbsArrayProjector.hh:14
Definition: AbsMultivariateFunctor.hh:19
Definition: AbsRandomGenerator.hh:27