npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
NeymanOSDE1D.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_NEYMANOSDE1D_HH_
2 #define NPSTAT_NEYMANOSDE1D_HH_
3 
4 /*!
5 // \file NeymanOSDE1D.hh
6 //
7 // \brief OSDE based on minimizing the expected ISE of the empirical
8 // comparison density
9 //
10 // Author: I. Volobouev
11 //
12 // March 2023
13 */
14 
15 #include <vector>
16 
17 #include "npstat/nm/Matrix.hh"
19 
20 namespace npstat {
22  {
23  public:
24  template<typename Numeric>
25  NeymanOSDE1D(const Numeric* coords, unsigned long lenCoords,
26  double xmin, double xmax);
27 
28  inline double xmin() const {return xmin_;}
29  inline double xmax() const {return xmax_;}
30  inline unsigned long sampleSize() const {return nCoords_;}
31  inline double coord(unsigned long i) const
32  {return scale_*coords_.at(i) + shift_;}
33 
34  // coeffs -- array of coefficients, starting with degree 1.
35  // nCoeffs -- length of the array "coeffs".
36  //
37  // shrinkages -- shrinkage coefficients for constructing chi-square.
38  // nShrinkages -- length of the array "shrinkages". Should be at
39  // least as large as "nCoeffs".
40  //
41  // The function returns the chi-square value.
42  // Also, the following quantities are filled out on exit:
43  //
44  // polyStatistics -- scaled expansion coefficients of the
45  // comparison density, all these would have
46  // mean 0 and standard deviation 1 for oracle
47  // values of "coeffs". The length of this
48  // array should be at least "nShrinkages".
49  //
50  // gradient -- chi-square gradient w.r.t. coeffs. The length
51  // of this array should be at least "nCoeffs".
52  //
53  // hessian -- chi-square Hessian w.r.t. coeffs (if requested).
54  //
55  double chiSquare(const double* coeffs, unsigned nCoeffs,
56  const double* shrinkages, unsigned nShrinkages,
57  double* polyStatistics,
58  double* gradient,
59  Matrix<double>* hessian = nullptr) const;
60 
61  // "Sensitivity" matrix. The returned matrix will be
62  // dimensioned nShrinkages x nCoeffs.
63  Matrix<double> sensitivityMatrix(
64  const double* coeffs, unsigned nCoeffs,
65  unsigned nShrinkages) const;
66 
67  // Get the expectation values of the Legendre polynomials
68  // for the sample, starting with degree 1. The length of
69  // the array "coeffs" should be maxdeg.
70  void sampleCoeffs(double* coeffs, unsigned maxdeg) const;
71 
72  // Once the coefficients have been determined, get the
73  // density estimate for the original sample. Note that
74  // this density estimate will not be guaranteed positive.
75  // The coefficients start with degree 1.
76  LegendreDistro1D densityEstimate(const double* coeffs,
77  unsigned nCoeffs) const;
78 
79  // Check whether the given set of coefficients creates
80  // a series which can be used as a bona fide density.
81  // The coefficients start with degree 1.
82  inline bool isPositive(const double* coeffs,
83  const unsigned nCoeffs) const
84  {return densityEstimate(coeffs, nCoeffs).isPositive();}
85 
86  private:
87  void moveCoordsToStandardInterval();
88  void fillIntegralTable(unsigned maxdeg) const;
89  void fillDerivativeTables(unsigned maxdeg) const;
90 
91  // Coefficients start with degree 1 (not 0)
92  double cdf(const double* coeffs, unsigned ncoeffs,
93  unsigned long ipt) const;
94 
95  // Coordinates will be shifted and scaled to the [-1, 1] interval
96  std::vector<double> coords_;
97  unsigned long nCoords_;
98  double xmin_;
99  double xmax_;
100  double scale_;
101  double shift_;
102 
103  // integs_ is a table of integrals int_{-1}^coords_[i] P_m(x) dx,
104  // with m starting from 1. For the given m and i, use
105  // integs_[(m-1)*nCoords_ + i]. For m = 0, the corresponding
106  // integral is just coords_[i] + 1.0. The table should be grown
107  // as needed by the "fillIntegralTable" method.
108  mutable std::vector<double> integs_;
109  mutable unsigned currentMaxDeg_;
110 
111  // Series coefficients for the derivatives of the
112  // Legendre polynomials on [0, 1]
113  mutable std::vector<std::vector<double> > firstDeriv_;
114 
115  // Series coefficients for the second derivatives
116  // of the Legendre polynomials on [0, 1]
117  mutable std::vector<std::vector<double> > secondDeriv_;
118  };
119 }
120 
121 #include "npstat/stat/NeymanOSDE1D.icc"
122 
123 #endif // NPSTAT_NEYMANOSDE1D_HH_
Statistical distribution constructed using orthonormal Legendre polynomial series.
Template matrix class.
Definition: LegendreDistro1D.hh:26
Definition: NeymanOSDE1D.hh:22
Definition: AbsArrayProjector.hh:14