npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
LOrPEWeightsLocalConvergence.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_LORPEWEIGHTSLOCALCONVERGENCE_HH_
2 #define NPSTAT_LORPEWEIGHTSLOCALCONVERGENCE_HH_
3 
4 /*!
5 // \file LOrPEWeightsLocalConvergence.hh
6 //
7 // \brief Class that decides whether the iterations of the LOrPE
8 // semiparametric mixture Fredholm equation have converged
9 //
10 // Author: I. Volobouev
11 //
12 // August 2022
13 */
14 
15 #include <cmath>
16 #include <cassert>
17 
18 namespace npstat {
20  {
21  public:
22  inline LOrPEWeightsLocalConvergence(const double i_tol,
23  const double i_normPower,
24  const bool i_useDensity)
25  : tol_(i_tol),
26  normPower_(i_normPower),
27  checkConVergenceForDensity_(i_useDensity)
28  {
29  assert(tol_ > 0.0);
30  assert(normPower_ > 0.0);
31  }
32 
33  inline double tol() const {return tol_;}
34  inline double normPower() const {return normPower_;}
35  inline bool checkingConVergenceForDensity() const
36  {return checkConVergenceForDensity_;}
37 
38  template<class Lorpe>
39  inline bool converged(const Lorpe& lorpe,
40  const double* previousWeights,
41  const double* currentWeights,
42  const double* previousBg,
43  const double* currentBg) const
44  {
45  if (checkConVergenceForDensity_)
46  return locallyConverged(lorpe, previousBg, currentBg);
47  else
48  return locallyConverged(lorpe, previousWeights, currentWeights);
49  }
50 
51  private:
52  template<class Lorpe>
53  inline bool locallyConverged(const Lorpe& lorpe,
54  const double* previous,
55  const double* current) const
56  {
57  assert(previous);
58  assert(current);
59 
60  const auto& sample = lorpe.coords();
61  const unsigned long sampleSize = sample.size();
62 
63  long double sum = 0.0L, wsum = 0.0L;
64  double p;
65  for (unsigned long i=0; i<sampleSize; ++i)
66  {
67  const double w = lorpe.cvLocalizingWeight(sample[i].first);
68  assert(w >= 0.0);
69  if (w > 0.0)
70  {
71  wsum += w;
72  const double ac = std::abs(current[i]);
73  const double ap = std::abs(previous[i]);
74  const double d = std::abs(current[i] - previous[i])*2.0/(ac + ap + 1.0);
75  if (normPower_ == 1.0)
76  p = d;
77  else if (normPower_ == 2.0)
78  p = d*d;
79  else
80  p = std::pow(d, normPower_);
81  sum += w*p;
82  }
83  }
84  assert(wsum > 0.0L);
85 
86  const double weightedDiff = sum/wsum;
87  const double norm = std::pow(weightedDiff, 1.0/normPower_);
88  return norm < tol_;
89  }
90 
91  double tol_;
92  double normPower_;
93  bool checkConVergenceForDensity_;
94  };
95 }
96 
97 #endif // NPSTAT_LORPEWEIGHTSLOCALCONVERGENCE_HH_
Definition: LOrPEWeightsLocalConvergence.hh:20
Definition: AbsArrayProjector.hh:14