npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
QuadraticOrthoPolyND.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_QUADRATICORTHOPOLYND_HH_
2 #define NPSTAT_QUADRATICORTHOPOLYND_HH_
3 
4 /*!
5 // \file QuadraticOrthoPolyND.hh
6 //
7 // \brief Multivariate quadratic orthogonal polynomials with arbitrary
8 // weight functions
9 //
10 // Author: I. Volobouev
11 //
12 // March 2010
13 */
14 
15 #include "npstat/nm/BoxND.hh"
17 
18 namespace npstat {
19  /**
20  // Class for figuring out the coefficients of multivariate quadratic
21  // orthogonal polynomials generated with an arbitrary weight functions
22  */
24  {
25  public:
26  /**
27  // "weight" is the weigh function used to build the orthogonal
28  // polynomials. "nSteps" is the number of integration intervals
29  // in each dimension (numerical integration is used for
30  // orthogonalization of the basis polynomials and for subsequent
31  // construction of polynomial series). "nStepsDim" is the number
32  // of elements in the "nSteps" array and also the dimensionality
33  // of the coordinate space. The integration region is defined by
34  // the "boundingBox" argument whose dimensionality must be consistent
35  // with "nStepsDim".
36  //
37  // Integration will be performed by simply evaluating the functions
38  // at the interval centers. Use a sufficiently large number of
39  // integration points if high precision is desired.
40  */
42  const BoxND<double>& boundingBox,
43  const unsigned* nSteps, unsigned nStepsDim);
45 
46  // Copy constructor and the assignment operator
48  QuadraticOrthoPolyND& operator=(const QuadraticOrthoPolyND&);
49 
50  //@{
51  /** Inspect object properties */
52  inline unsigned dim() const {return dim_;}
53  inline unsigned nTerms() const {return ((dim_+1U)*(dim_+2U))/2U;}
54  inline const AbsDistributionND* weight() const {return weight_;}
55  inline const BoxND<double>& boundingBox() const {return box_;}
56  inline const std::vector<unsigned>& nSteps() const {return numSteps_;}
57  //@}
58 
59  /**
60  // Coefficient in the expansion of the orthogonal series
61  // polynomial in the monomial basis. The order of the monomials
62  // is 1, x0, x1, ..., xN, x0^2, x0*x1, ..., x0*xN, x1^2, x1*x2, ...
63  // The number of the polynomials is, of course, the same as the
64  // number of monomials and equals "nTerms()".
65  */
66  double monomialCoefficient(unsigned iPoly, unsigned iMono) const;
67 
68  /**
69  // Value of a certain polynomial at the given coordinate "x".
70  // The argument "polyN" is the polynomial number which
71  // should be less than "nTerms()". Note that the code does not
72  // check whether the coordinate is inside the original box.
73  */
74  double value(unsigned polyN, const double* x, unsigned lenX) const;
75 
76  /**
77  // Series expansion at the given coordinate "x". The number
78  // of coefficients provided, nCoeffs, is allowed to take the
79  // following values:
80  //
81  // 1 -- just return the constant term
82  // dim() + 1 -- use linear terms only
83  // nTerms() -- use the full expansion
84  //
85  // Note that the code does not check whether the coordinate
86  // is inside the original box.
87  //
88  // If the "individualPolynomials" array is not 0, the values
89  // of the individual polynomials will be stored there. They
90  // represent the gradient of the series expansion at the given
91  // point with respect to the series coefficients. There must be
92  // at least nCoeffs elements in the "individualPolynomials" array.
93  */
94  double series(const double* x, unsigned lenX,
95  const double* coeffs, unsigned nCoeffs,
96  double* individualPolynomials=0) const;
97 
98  /**
99  // The gradient of the series expansion. The size of the result
100  // array must be equal to "dim()". Note that the code does not
101  // check whether the coordinate is inside the original box.
102  */
103  void gradient(const double* x, unsigned lenX,
104  const double* coeffs, unsigned nCoeffs,
105  double* result, unsigned lenResult) const;
106 
107  /**
108  // The hessian of the series expansion. The size of the
109  // result array must be equal to "dim()*(dim()+1)/2".
110  // Hessian matrix is returned in the upper-trangular form.
111  // The result is, of course, coordinate-independent.
112  */
113  void hessian(const double* coeffs, unsigned nCoeffs,
114  double* result, unsigned lenResult) const;
115 
116  /**
117  // The following method fits orthogonal polynomial series
118  // to an object which has its own method with signature
119  // "Numeric method(const double* x, unsigned dimX) const".
120  // The arguments which will be fed into this method will be
121  // shifted and scaled from the box coordinates according to
122  // x[i] = (boxCoordinate[i] - location[i])/scale[i].
123  // It must be possible to perform a static cast from
124  // "Numeric" to double.
125  //
126  // "nCoeffs" can have multiple values, as in the "series"
127  // method. The bounding box and the number of integration
128  // intervals are assumed to be the same as in the constructor.
129  */
130  template <class T, typename Numeric>
131  void fit(const T& obj, Numeric (T::*)(const double*, unsigned) const,
132  const double* location, const double* scale, unsigned nScales,
133  double* coeffs, unsigned nCoeffs) const;
134 
135  private:
137 
138  void integrationLoop(unsigned level, long double *gram);
139  void gramSchmidt(const long double *gram);
140 
141  template <class T, typename Numeric>
142  void fitLoop(const T& obj,
143  Numeric (T::*)(const double*, unsigned) const,
144  unsigned level,
145  const double* location, const double* scale,
146  double* methodCoords,
147  long double *sum, unsigned nCoeffs) const;
148 
149  AbsDistributionND* weight_;
150  BoxND<double> box_;
151  std::vector<unsigned> numSteps_;
152  std::vector<double> coeffM_;
153  mutable std::vector<double> work_;
154  mutable std::vector<double> buf_;
155  mutable std::vector<long double> sprod_;
156  long double cellSize_;
157  unsigned dim_;
158  };
159 }
160 
161 #include "npstat/stat/QuadraticOrthoPolyND.icc"
162 
163 #endif // NPSTAT_QUADRATICORTHOPOLYND_HH_
Interface definition for multivariate continuous statistical distributions.
Template to represent rectangles, boxes, and hyperboxes.
Definition: AbsDistributionND.hh:26
Definition: QuadraticOrthoPolyND.hh:24
double series(const double *x, unsigned lenX, const double *coeffs, unsigned nCoeffs, double *individualPolynomials=0) const
unsigned dim() const
Definition: QuadraticOrthoPolyND.hh:52
void hessian(const double *coeffs, unsigned nCoeffs, double *result, unsigned lenResult) const
void gradient(const double *x, unsigned lenX, const double *coeffs, unsigned nCoeffs, double *result, unsigned lenResult) const
double monomialCoefficient(unsigned iPoly, unsigned iMono) const
void fit(const T &obj, Numeric(T::*)(const double *, unsigned) const, const double *location, const double *scale, unsigned nScales, double *coeffs, unsigned nCoeffs) const
double value(unsigned polyN, const double *x, unsigned lenX) const
QuadraticOrthoPolyND(const AbsDistributionND &weight, const BoxND< double > &boundingBox, const unsigned *nSteps, unsigned nStepsDim)
Definition: AbsArrayProjector.hh:14