testQuadraticFitter.cc
Go to the documentation of this file.
1 
11 #include <utl/Histogram.h>
12 #include <utl/QuadraticFitter.h>
13 #include <tst/Verify.h>
14 #include <cppunit/extensions/HelperMacros.h>
15 #include <iostream>
16 
17 using namespace std;
18 using namespace utl;
19 using namespace tst;
20 
21 
22 #define EQUAL(_x_, _y_) CPPUNIT_ASSERT(Verify<Equal>(_x_, _y_))
23 #define CLOSE(_x_, _y_) CPPUNIT_ASSERT(Verify<CloseTo>(_x_, _y_))
24 #define CLOSEEPS(_x_, _y_, _eps_) CPPUNIT_ASSERT(Verify<CloseTo>(_x_, _y_, _eps_))
25 
26 
30 class TestQuadraticFitter : public CppUnit::TestFixture {
31 
32  CPPUNIT_TEST_SUITE(TestQuadraticFitter);
33  CPPUNIT_TEST(testHistogramExactFit);
34  CPPUNIT_TEST(testHistogramSemiRandomFit);
35  CPPUNIT_TEST(testFitRange);
36  CPPUNIT_TEST_SUITE_END();
37 
38 public:
39  void
41  {
42  fA = -3;
43  fB = 10000;
44  fExtreme = 20;
45 
46  fAExp = 600;
47  fDecay = 30;
48  fExtreme2 = 50;
49  fA2 = -1;
50  fB2 = 400;
51  }
52 
53  void tearDown() { }
54 
55  double quadraticFunction(const double x) const
56  { return fA * Sqr(x - fExtreme) + fB; }
57 
58  double
59  twoHumpFunction(const double x)
60  const
61  {
62  const double par = fA2 * Sqr(x - fExtreme2) + fB2;
63  const double dec = fAExp * exp(-x/fDecay);
64  return dec + (par >= 0 ? par : 0);
65  }
66 
67  void
69  {
70  const int n = 50;
71  vector<double> binEdges;
72  vector<double> counts;
73  for (int i = 0; i < n; ++i) {
74  binEdges.push_back(i);
75  counts.push_back(quadraticFunction(i+0.5));
76  }
77  binEdges.push_back(n);
78 
79  VariableBinHistogramWrap<double, double> h(binEdges, counts);
80 
81  const double pos =
82  MakeQuadraticFitter(h, FlatErrors()).GetExtremePosition();
83 
84  CLOSE(pos, fExtreme);
85 
86  double posErr;
87  int ndof;
88  const double pos2 =
89  MakeQuadraticFitter(h, FlatErrors()).GetExtremePosition(posErr, ndof);
90 
91  CLOSE(pos2, fExtreme);
92  EQUAL(ndof, 47);
93 
94  double chi2;
95  const double pos3 =
96  MakeQuadraticFitter(h, FlatErrors()).GetExtremePosition(posErr, chi2, ndof);
97 
98  CLOSE(pos3, fExtreme);
99  CLOSE(chi2, 0.);
100  EQUAL(ndof, 47);
101 
102  QuadraticFitData qf;
103  MakeQuadraticFitter(h, FlatErrors()).GetFitData(qf);
104 
105  CLOSE(qf.GetExtremePosition(), fExtreme);
106  CLOSE(qf.GetCoefficients()[0], fB);
107  CLOSE(qf.GetCoefficients()[1], 0.);
108  CLOSE(qf.GetCoefficients()[2], fA);
109 
110  CLOSE(qf(fExtreme), fB);
111  CLOSE(qf(fExtreme + 3), quadraticFunction(fExtreme + 3));
112  CLOSE(qf(fExtreme - 5), quadraticFunction(fExtreme - 5));
113  }
114 
115  void
117  {
118  const int n = 50;
119  vector<double> binEdges(n+1);
120  vector<double> counts(n);
121  for (int i = 0; i < n; ++i) {
122  binEdges[i] = i;
123  const double q = quadraticFunction(i+0.5);
124  const double sq = q > 0 ? sqrt(2*q) : 0;
125  const double qq = q + sq*sin(123456789.*i);
126  counts[i] = qq;
127  }
128  binEdges[n] = n;
129 
130  VariableBinHistogramWrap<double, double> h(binEdges, counts);
131 
132  double posErr;
133  int ndof;
134  double chi2;
135  const double pos =
136  MakeQuadraticFitter(h).GetExtremePosition(posErr, chi2, ndof);
137 
138  cout << "\n pos=" << pos << " posErr=" << posErr << " chi2=" << chi2 << " "
139  "ndof=" << ndof << endl;
140 
141  CLOSEEPS(pos, fExtreme, posErr);
142  CLOSEEPS(posErr, 0., 1.);
143  EQUAL(ndof, 47);
144 
145  const double omega = (chi2 - ndof) / sqrt(2.*ndof);
146 
147  CLOSEEPS(omega, 0., 0.5);
148  }
149 
150  void
152  {
153  typedef unsigned short int ushort;
154  const int n = 80;
155  vector<char> binEdges(n+1);
156  vector<ushort> counts(n);
157  for (char i = 0; i < n; ++i) {
158  binEdges[i] = i;
159  counts[i] = ushort(twoHumpFunction(i));
160  }
161  binEdges[n] = char(n);
162 
163  VariableBinHistogramWrap<char, ushort> h(binEdges, counts);
164 
165  const int start = 30;
166  const int stop = 70;
167 
168  double posErr;
169  int ndof;
170  double chi2;
171  const double pos =
172  MakeQuadraticFitter(h, start, stop).GetExtremePosition(posErr, chi2, ndof);
173 
174  cout << "\n pos=" << pos << " posErr=" << posErr << " chi2=" << chi2 << " "
175  "ndof=" << ndof << endl;
176 
177  double posErr2;
178  int ndof2;
179  double chi22;
180  const double pos2 =
181  MakeQuadraticFitter(h, double(start), double(stop)).GetExtremePosition(posErr2, chi22, ndof2);
182 
183  CLOSE(pos, pos2);
184  CLOSE(chi2, chi22);
185  CLOSE(pos, pos2);
186  EQUAL(ndof, ndof2);
187  const double numericalSolution = 47.979666;
188  CLOSEEPS(pos, numericalSolution + 0.5, posErr/10);
189 
190  cout << "\n pos=" << pos << " posErr=" << posErr << " chi2=" << chi2 << " "
191  "ndof=" << ndof << endl;
192 
193  cout << "start=" << h.GetBinIndex(30.) << " stop=" << h.GetBinIndex(70.) << endl;
194  }
195 
196 private:
197  double fA = 0;
198  double fB = 0;
199  double fExtreme = 0;
200 
201  double fAExp = 0;
202  double fDecay = 0;
203  double fExtreme2 = 0;
204  double fA2 = 0;
205  double fB2 = 0;
206 };
207 
208 
#define CLOSEEPS(_x_, _y_, _eps_)
constexpr T Sqr(const T &x)
Holds result of the quadratic fit.
#define CLOSE(_x_, _y_)
#define EQUAL(_x_, _y_)
CPPUNIT_TEST_SUITE_REGISTRATION(testAiresShowerFile)
const double * GetCoefficients() const
double quadraticFunction(const double x) const
QuadraticFitter< Histogram, ErrorPolicy > MakeQuadraticFitter(const Histogram &h, const ErrorPolicy)
unsigned short ushort
double GetExtremePosition() const

, generated on Tue Sep 26 2023.