npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
LOrPE1DFixedDegreeCVRunner.hh
1 #ifndef NPSTAT_LORPE1DFIXEDDEGREECVRUNNER_HH_
2 #define NPSTAT_LORPE1DFIXEDDEGREECVRUNNER_HH_
3 
4 /*!
5 // \file LOrPE1DFixedDegreeCVScanner.hh
6 //
7 // \brief Optimization of LOrPE bandwidth choice by cross-validation
8 // using the golden section search
9 //
10 // Author: I. Volobouev
11 //
12 // August 2022
13 */
14 
15 #include <cmath>
16 #include <cassert>
17 
19 #include "npstat/nm/MathUtils.hh"
20 
22 
23 namespace npstat {
25  {
26  public:
27  inline LOrPE1DFixedDegreeCVRunner(const double i_fixedDegree,
28  const double i_bwFactorGuess,
29  const double i_tol)
30  : fixedDegree_(i_fixedDegree),
31  bwFactorGuess_(i_bwFactorGuess),
32  tol_(i_tol)
33  {
34  assert(fixedDegree_ >= 0.0);
35  assert(bwFactorGuess_ > 0.0);
36  assert(tol_ > 0.0);
37  }
38 
39  inline double fixedDegree() const {return fixedDegree_;}
40  inline double bwFactorGuess() const {return bwFactorGuess_;}
41  inline double tol() const {return tol_;}
42 
43  template<class Lorpe>
44  inline LOrPE1DCVResult crossValidate(Lorpe& lorpe) const
45  {
46  const double oldDeg = lorpe.boundFilterDegree();
47  lorpe.bindFilterDegree(fixedDegree_);
48 
49  const double sqr2 = 1.414213562373095;
50  double bwFactor = 0.0, bestFcn, divider = 1.0;
51  bool bestBwFound = false;
52  auto fcn = MultiplyByConst(lorpe, -1.0);
53  const unsigned maxtries = 11; // divider can be increased up to
54  // the factor 2^((maxtries-1)/2)
55  for (unsigned itry=0; itry<maxtries && !bestBwFound; ++itry)
56  {
57  bestBwFound = goldenSectionSearchInLogSpace(
58  fcn, bwFactorGuess_/divider, tol_, &bwFactor, &bestFcn);
59  divider *= sqr2;
60  }
61  assert(bestBwFound);
62  assert(bwFactor > 0.0);
63 
64  // Construct parabolic approximation to the minimum
65  const double fstep = 1.0 + tol_;
66  const double bwMin = bwFactor/fstep;
67  const double bwMax = bwFactor*fstep;
68 
69  double extremumCoordinate, extremumValue;
70  const bool isMinimum = parabolicExtremum(
71  std::log(bwMin), fcn(bwMin),
72  std::log(bwFactor), bestFcn,
73  std::log(bwMax), fcn(bwMax),
74  &extremumCoordinate, &extremumValue);
75  assert(isMinimum);
76 
77  if (oldDeg < 0.0)
78  lorpe.unbindFilterDegree();
79  else
80  lorpe.bindFilterDegree(oldDeg);
81 
82  return LOrPE1DCVResult(
83  fixedDegree_, std::exp(extremumCoordinate), -extremumValue,
84  true, false);
85  }
86 
87  private:
88  double fixedDegree_;
89  double bwFactorGuess_;
90  double tol_;
91  };
92 }
93 
94 #endif // NPSTAT_LORPE1DFIXEDDEGREECVRUNNER_HH_
An object representing the result of the 1-d LOrPE cross-validation procedure.
Various simple mathematical utilities which did not end up inside dedicated headers.
Definition: LOrPE1DCVResult.hh:19
Definition: LOrPE1DFixedDegreeCVRunner.hh:25
Search for 1-d function minimum in log space using the golden section method.
Definition: AbsArrayProjector.hh:14
MultiplyByConstHelper< Result, Arg1 > MultiplyByConst(const Functor1< Result, Arg1 > &fcn, const Numeric &factor)
Definition: SimpleFunctors.hh:1015
bool parabolicExtremum(double x0, double y0, double x1, double y1, double x2, double y2, double *extremumCoordinate, double *extremumValue)
bool goldenSectionSearchInLogSpace(const Functor1< Result, Arg1 > &f, const Arg1 &x0, double tol, Arg1 *minimum, Result *fmin=0, double logstep=0.5)