npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
LOrPE1DFixedDegreeCVScanner.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_LORPE1DFIXEDDEGREECVSCANNER_HH_
2 #define NPSTAT_LORPE1DFIXEDDEGREECVSCANNER_HH_
3 
4 /*!
5 // \file LOrPE1DFixedDegreeCVScanner.hh
6 //
7 // \brief Optimization of LOrPE bandwidth choice by cross-validation
8 // by simply scanning a predefined set of bandwidth values
9 //
10 // Author: I. Volobouev
11 //
12 // August 2022
13 */
14 
15 #include <cmath>
16 #include <cassert>
17 #include <vector>
18 #include <stdexcept>
19 
22 
24 
25 namespace npstat {
27  {
28  public:
29  inline LOrPE1DFixedDegreeCVScanner(const double degree,
30  const std::vector<double>& bandwidthFactors)
31  : bandwidthFactors_(bandwidthFactors),
32  logBw_(bandwidthFactors.size()),
33  fixedDegree_(degree)
34  {
35  if (fixedDegree_ < 0.0) throw std::invalid_argument(
36  "In npstat::LOrPE1DFixedDegreeCVScanner constructor: "
37  "degree argument must be non-negative");
38  const unsigned nscan = bandwidthFactors_.size();
39  if (nscan < 2U) throw std::invalid_argument(
40  "In npstat::LOrPE1DFixedDegreeCVScanner constructor: "
41  "insufficient number of bandwidth factors");
42  if (!isStrictlyIncreasing(bandwidthFactors_.begin(), bandwidthFactors_.end()))
43  throw std::invalid_argument(
44  "In npstat::LOrPE1DFixedDegreeCVScanner constructor: "
45  "sequence of bandwidth factors must be strictly increasing");
46  for (unsigned i=0; i<nscan; ++i)
47  {
48  if (bandwidthFactors_[i] <= 0.0) throw std::invalid_argument(
49  "In npstat::LOrPE1DFixedDegreeCVScanner constructor: "
50  "all bandwidth factors must be positive");
51  logBw_[i] = std::log(bandwidthFactors_[i]);
52  }
53  }
54 
55  inline unsigned nBwFactors() const {return bandwidthFactors_.size();}
56  inline double getBwFactor(const unsigned i) const {return bandwidthFactors_.at(i);}
57 
58  template<class Lorpe>
59  inline LOrPE1DCVResult crossValidate(Lorpe& lorpe) const
60  {
61  const unsigned nscan = bandwidthFactors_.size();
62  std::vector<double> cvValues(nscan);
63  for (unsigned i=0; i<nscan; ++i)
64  cvValues[i] = lorpe(fixedDegree_, bandwidthFactors_[i]);
65  const ScanExtremum1D& scanMax = findScanMaximum1D(&logBw_[0], nscan,
66  &cvValues[0], nscan);
67  return LOrPE1DCVResult(
68  fixedDegree_, std::exp(scanMax.location()), scanMax.value(),
69  true, scanMax.isOnTheBoundary());
70  }
71 
72  private:
73  std::vector<double> bandwidthFactors_;
74  std::vector<double> logBw_;
75  double fixedDegree_;
76  };
77 }
78 
79 #endif // NPSTAT_LORPE1DFIXEDDEGREECVSCANNER_HH_
An object representing the result of the 1-d LOrPE cross-validation procedure.
Finding extrema of scanned 1-d curves.
Definition: LOrPE1DCVResult.hh:19
Definition: LOrPE1DFixedDegreeCVScanner.hh:27
Definition: ScanExtremum1D.hh:16
A few simple template functions for checking monotonicity of container values.
Definition: AbsArrayProjector.hh:14
bool isStrictlyIncreasing(Iter begin, Iter const end)
Definition: isMonotonous.hh:18