npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
MinuitLOrPEBgCVFcn1D.hh
Go to the documentation of this file.
1 #ifndef NPSI_MINUITLORPEBGCVFCN1D_HH_
2 #define NPSI_MINUITLORPEBGCVFCN1D_HH_
3 
4 /*!
5 // \file MinuitLOrPEBgCVFcn1D.hh
6 //
7 // \brief Fit of LOrPE bandwidth and maximum poly degree in the mixed
8 // signal/background model
9 //
10 // Author: I. Volobouev
11 //
12 // October 2013
13 */
14 
15 #include <iostream>
16 #include <sstream>
17 #include <stdexcept>
18 #include <cmath>
19 
22 
23 #include "Minuit2/FCNBase.h"
24 
25 namespace npsi {
26  template <class Numeric, class NumIn=double>
27  class MinuitLOrPEBgCVFcn1D : public ROOT::Minuit2::FCNBase
28  {
29  public:
30  /**
31  // Most arguments of this constructor are the same as the arguments
32  // of the npstat::lorpeBackground1D function. See the description
33  // of that function for more detail. The two arguments not of this
34  // kind are:
35  //
36  // up -- This parameter regulates Minuit convergence.
37  // See Minuit manual for details.
38  //
39  // minlog -- Infrequently, LOrPE creates a density estimate
40  // which is exactly 0 for some histogram bin which
41  // is not empty; the value of this parameter limits
42  // the contribution of such bins into the overall
43  // likelihood.
44  //
45  // An internal copy of "initialApproximation" will be made
46  // if such an approximation is provided (initialApproximation
47  // can also be specified as NULL to use the uniform background
48  // density as a starting point for iterations).
49  //
50  // This class will not assume ownership of any references
51  // or pointers
52  */
55  const npstat::AbsDistribution1D& signal,
56  const double signalFraction,
57  const unsigned nIntegrationPoints,
58  const NumIn* initialApproximation,
59  const unsigned lenApproximation,
60  const int symmetricBetaPower,
61  const double minimumBgFeatureSize,
62  const double effectiveNumBgEvents,
63  const double convergenceEpsilon,
64  const unsigned maxIterations,
65  const npstat::BoundaryHandling& bm,
66  const bool useLeastSquaresCV,
67  const bool verbose,
68  const bool bandwidthIsAbsolute,
69  const unsigned cvmode,
70  const double regularizationParameter,
71  const double minlog,
72  const double up)
73  : histo_(histo),
74  fbuilder_(fbuilder),
75  signal_(signal),
76  initialApproximation_(initialApproximation),
77  signalFraction_(signalFraction),
78  minlog_(minlog),
79  up_(up),
80  convergenceEpsilon_(convergenceEpsilon),
81  regularizationParameter_(regularizationParameter),
82  minimumBgFeatureSize_(minimumBgFeatureSize),
83  effectiveNumBgEvents_(effectiveNumBgEvents),
84  callCount_(0),
85  lenApproximation_(lenApproximation),
86  nIntegrationPoints_(nIntegrationPoints),
87  maxIterations_(maxIterations),
88  cvmode_(cvmode),
89  m_(symmetricBetaPower),
90  bm_(bm),
91  verbose_(verbose),
92  bandwidthIsAbsolute_(bandwidthIsAbsolute),
93  useLeastSquaresCV_(useLeastSquaresCV)
94  {
95  densityBuffer_.resize(3*histo_.nBins());
96  }
97 
98  inline virtual ~MinuitLOrPEBgCVFcn1D() {}
99 
100  inline unsigned long callCount() const {return callCount_;}
101 
102  inline npstat::AbsSymbetaFilterProvider& getFilterProvider() const
103  {return fbuilder_;}
104 
105  inline double getActualBandwidth(const double bwParameter,
106  const double maxDegree) const
107  {
108  double bandwidth = bwParameter;
109  if (!bandwidthIsAbsolute_)
110  {
111  // The bandwidth parameter is actually the logarithm
112  // of the ratio between the actual bandwidth and the
113  // minimum acceptable bandwidth
114  const double minbw = minHistoBandwidth1D(
115  histo_, minimumBgFeatureSize_, maxDegree,
116  effectiveNumBgEvents_, m_);
117  bandwidth = minbw*exp(bwParameter);
118  }
119  return bandwidth;
120  }
121 
122  /**
123  // This method returns either the negative log likelihood or
124  // the cross validation approximation of MISE.
125  //
126  // It is assumed that bandwidth is the first parameter while
127  // degree of the LOrPE polynomial is the second.
128  */
129  virtual double operator()(const std::vector<double>& x) const
130  {
131  if (x.size() < 2U) throw std::invalid_argument(
132  "In npsi::MinuitLOrPEBgCVFcn1D::operator() : "
133  "at least two parameters needed");
134 
135  const double maxDegree = x[1];
136  const double bandwidth = getActualBandwidth(x[0], maxDegree);
137 
138  const unsigned nbins = histo_.nBins();
139  double* signalDensity = &densityBuffer_[0];
140  double* bgDensity = signalDensity + nbins;
141  double* densityMinusOne = bgDensity + nbins;
142 
143  double convergenceDelta = 0.0;
144  const unsigned niter = npstat::lorpeBackground1D(
145  histo_, fbuilder_, bm_, signal_, signalFraction_,
146  nIntegrationPoints_,
147  initialApproximation_, lenApproximation_,
148  m_, bandwidth, maxDegree,
149  convergenceEpsilon_, maxIterations_,
150  signalDensity, nbins, bgDensity, nbins,
151  workspace_, densityMinusOne, nbins,
152  cvmode_, regularizationParameter_, &convergenceDelta);
153 
154  if (niter >= maxIterations_)
155  {
156  std::ostringstream os;
157  os << "In npsi::MinuitLOrPEBgCVFcn1D::operator() : "
158  << "background determination algorithm failed to converge.";
159  if (fabs(convergenceDelta) > convergenceEpsilon_)
160  os << " Requested divergence <= " << convergenceEpsilon_
161  << ", achieved only " << convergenceDelta << '.';
162  throw std::runtime_error(os.str());
163  }
164 
165  double cv = 0.0;
166  if (useLeastSquaresCV_)
168  histo_, signalFraction_,
169  signalDensity, nbins, bgDensity, nbins,
170  densityMinusOne, nbins);
171  else
173  histo_, signalFraction_,
174  signalDensity, nbins, bgDensity, nbins,
175  densityMinusOne, nbins, minlog_);
176 
177  if (verbose_)
178  {
179  std::cout << "MinuitLOrPEBgCVFcn1D " << callCount_
180  << ", bw " << bandwidth
181  << ", deg " << maxDegree;
182  if (useLeastSquaresCV_)
183  std::cout << ", lscv " << cv;
184  else
185  std::cout << ", pll " << -cv;
186  std::cout << '\n';
187  std::cout.flush();
188  }
189 
190  ++callCount_;
191  return cv;
192  }
193 
194  inline double Up() const {return up_;}
195 
196  private:
197  mutable std::vector<double> densityBuffer_;
198  mutable std::vector<double> workspace_;
199 
200  const npstat::HistoND<Numeric>& histo_;
202  const npstat::AbsDistribution1D& signal_;
203  const NumIn* initialApproximation_;
204 
205  double signalFraction_;
206  double minlog_;
207  double up_;
208  double convergenceEpsilon_;
209  double regularizationParameter_;
210  double minimumBgFeatureSize_;
211  double effectiveNumBgEvents_;
212 
213  mutable unsigned long callCount_;
214  unsigned lenApproximation_;
215  unsigned nIntegrationPoints_;
216  unsigned maxIterations_;
217  unsigned cvmode_;
218  int m_;
219 
221 
222  bool verbose_;
223  bool bandwidthIsAbsolute_;
224  bool useLeastSquaresCV_;
225  };
226 }
227 
228 #endif // NPSI_MINUITLORPEBGCVFCN1D_HH_
Utilities for semiparametric fitting of signal/backround mixtures.
Definition: MinuitLOrPEBgCVFcn1D.hh:28
virtual double operator()(const std::vector< double > &x) const
Definition: MinuitLOrPEBgCVFcn1D.hh:129
MinuitLOrPEBgCVFcn1D(const npstat::HistoND< Numeric > &histo, npstat::AbsSymbetaFilterProvider &fbuilder, const npstat::AbsDistribution1D &signal, const double signalFraction, const unsigned nIntegrationPoints, const NumIn *initialApproximation, const unsigned lenApproximation, const int symmetricBetaPower, const double minimumBgFeatureSize, const double effectiveNumBgEvents, const double convergenceEpsilon, const unsigned maxIterations, const npstat::BoundaryHandling &bm, const bool useLeastSquaresCV, const bool verbose, const bool bandwidthIsAbsolute, const unsigned cvmode, const double regularizationParameter, const double minlog, const double up)
Definition: MinuitLOrPEBgCVFcn1D.hh:53
Definition: AbsSymbetaFilterProvider.hh:28
Definition: BoundaryHandling.hh:21
Definition: HistoND.hh:46
A driver function for 1-d density estimation by LOrPE in a composite signal plus background model.
Definition: fitCompositeJohnson.hh:16
double lorpeBgCVLeastSquares1D(const HistoND< Numeric > &histo, double signalFraction, const NumOut *signalDensity, unsigned lenSignalDensity, const NumOut *bgDensity, unsigned lenBgDensity, const NumOut *densityMinusOne, unsigned lenDensityMinusOne)
double lorpeBgCVPseudoLogli1D(const HistoND< Numeric > &histo, double signalFraction, const NumOut *signalDensity, unsigned lenSignalDensity, const NumOut *bgDensity, unsigned lenBgDensity, const NumOut *densityMinusOne, unsigned lenDensityMinusOne, double minlog=log(DBL_MIN))
unsigned lorpeBackground1D(const HistoND< Numeric > &histo, AbsSymbetaFilterProvider &fbuilder, const BoundaryHandling &bm, const AbsDistribution1D &signal, double signalFraction, unsigned nIntegrationPoints, const NumIn *initialApproximation, unsigned lenApproximation, int m, double bandwidth, double maxDegree, double convergenceEpsilon, unsigned maxIterations, NumOut *signalDensity, unsigned lenSignalDensity, NumOut *bgDensity, unsigned lenBgDensity, std::vector< double > &workspace, NumOut *densityMinusOne=0, unsigned lenDensityMinusOne=0, unsigned cvmode=CV_MODE_LINEARIZED, double regularizationParameter=-1.0, double *lastDivergence=0)
Definition: AbsDistribution1D.hh:31