StatCollector_test.cc
Go to the documentation of this file.
1 /**
2  * @file StatCollector_test.cc
3  * @brief Tests the classes in StatCollector.h
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date 20141229
6  * @version 1.0
7  * @see StatCollector.h
8  *
9  * See http://www.boost.org/libs/test for the Boost test library home page.
10  *
11  * Timing:
12  * not given yet
13  */
14 
15 // C/C++ standard libraries
16 #include <array>
17 #include <valarray>
18 #include <utility> // std::pair<>
19 #include <memory> // std::unique_ptr<>
20 #include <initializer_list>
21 #include <tuple>
22 #include <stdexcept> // std::range_error
23 
24 // Boost libraries
25 /*
26  * Boost Magic: define the name of the module;
27  * and do that before the inclusion of Boost unit test headers
28  * because it will change what they provide.
29  * Among the those, there is a main() function and some wrapping catching
30  * unhandled exceptions and considering them test failures, and probably more.
31  * This also makes fairly complicate to receive parameters from the command line
32  * (for example, a random seed).
33  */
34 #define BOOST_TEST_MODULE ( StatCollector_test )
35 #include <boost/test/unit_test.hpp>
36 
37 // LArSoft libraries
39 
40 
42 
43 //------------------------------------------------------------------------------
44 //--- Test code
45 //
46 
47 template <typename T, typename W>
49  lar::util::StatCollector<T, W> const& stats,
50  int n,
51  W weights,
52  W sum,
53  W sumsq,
54  W rms // might as well compute it myself...
55 ) {
56 
57  using Weight_t = W;
58 
59  BOOST_TEST(stats.N() == n);
60  if (n == 0) {
61  BOOST_CHECK_THROW(stats.AverageWeight(), std::range_error);
62  }
63  else {
64  const Weight_t average = weights / n;
65  BOOST_TEST(double(stats.AverageWeight()) == double(average), 0.1% tolerance());
66  }
67  if (weights == 0.) {
68  BOOST_TEST(double(stats.Weights()) == 0, 0.01% tolerance());
69  BOOST_TEST(double(stats.Sum()) == 0, 0.01% tolerance());
70  BOOST_TEST(double(stats.SumSq()) == 0, 0.01% tolerance());
71  BOOST_CHECK_THROW(stats.Average(), std::range_error);
72  BOOST_CHECK_THROW(stats.Variance(), std::range_error);
73  BOOST_CHECK_THROW(stats.RMS(), std::range_error);
74  }
75  else {
76  const Weight_t average = sum / weights;
77  // check at precision 0.01% or 0.1%
78  BOOST_TEST(double(stats.Weights()) == double(weights), 0.01% tolerance());
79  BOOST_TEST(double(stats.Sum()) == double(sum), 0.01% tolerance());
80  BOOST_TEST(double(stats.SumSq()) == double(sumsq), 0.01% tolerance());
81  BOOST_TEST(double(stats.Average()) == double(average), 0.1% tolerance());
82  BOOST_TEST(double(stats.Variance()) == double(rms*rms), 0.1% tolerance());
83  BOOST_TEST(double(stats.RMS()) == double(rms), 0.1% tolerance());
84  }
85 } // CheckStats<>(StatCollector)
86 
87 template <typename T, typename W>
90  int n,
91  W weights,
92  W sumX,
93  W sumsqX,
94  W rmsX, // might as well compute it myself...
95  W sumY,
96  W sumsqY,
97  W rmsY, // might as well compute it myself...
98  W sumXY,
99  W cov,
100  W lin_corr
101 ) {
102 
103  using Weight_t = W;
104 
105  BOOST_TEST(stats.N() == n);
106  if (n == 0) {
107  BOOST_CHECK_THROW(stats.AverageWeight(), std::range_error);
108  }
109  else {
110  const Weight_t average = weights / n;
111  BOOST_TEST(double(stats.AverageWeight()) == double(average), 0.1% tolerance());
112  }
113 
114  if (weights == 0.) {
115  BOOST_TEST(double(stats.Weights()) == 0, 0.01% tolerance());
116  BOOST_TEST(double(stats.SumX()) == 0, 0.01% tolerance());
117  BOOST_TEST(double(stats.SumSqX()) == 0, 0.01% tolerance());
118  BOOST_CHECK_THROW(stats.AverageX(), std::range_error);
119  BOOST_CHECK_THROW(stats.VarianceX(), std::range_error);
120  BOOST_CHECK_THROW(stats.RMSx(), std::range_error);
121  BOOST_TEST(double(stats.SumY()) == 0, 0.01% tolerance());
122  BOOST_TEST(double(stats.SumSqY()) == 0, 0.01% tolerance());
123  BOOST_CHECK_THROW(stats.AverageY(), std::range_error);
124  BOOST_CHECK_THROW(stats.VarianceY(), std::range_error);
125  BOOST_CHECK_THROW(stats.RMSy(), std::range_error);
126  BOOST_TEST(double(stats.SumXY()) == 0, 0.01% tolerance());
127  BOOST_CHECK_THROW(stats.Covariance(), std::range_error);
128  BOOST_CHECK_THROW(stats.LinearCorrelation(), std::range_error);
129  }
130  else {
131  const Weight_t averageX = sumX / weights;
132  const Weight_t averageY = sumY / weights;
133  // check at precision 0.01% or 0.1%
134 
135  BOOST_TEST(double(stats.Weights()) == double(weights), 0.01% tolerance());
136  BOOST_TEST(double(stats.SumX()) == double(sumX), 0.01% tolerance());
137  BOOST_TEST(double(stats.SumSqX()) == double(sumsqX), 0.01% tolerance());
138  BOOST_TEST(double(stats.AverageX()) == double(averageX), 0.1% tolerance());
139  BOOST_TEST(double(stats.VarianceX()) == double(rmsX*rmsX), 0.1% tolerance());
140  BOOST_TEST(double(stats.RMSx()) == double(rmsX), 0.1% tolerance());
141  BOOST_TEST(double(stats.SumY()) == double(sumY), 0.01% tolerance());
142  BOOST_TEST(double(stats.SumSqY()) == double(sumsqY), 0.01% tolerance());
143  BOOST_TEST(double(stats.AverageY()) == double(averageY), 0.1% tolerance());
144  BOOST_TEST(double(stats.VarianceY()) == double(rmsY*rmsY), 0.1% tolerance());
145  BOOST_TEST(double(stats.RMSy()) == double(rmsY), 0.1% tolerance());
146  BOOST_TEST(double(stats.SumXY()) == double(sumXY), 0.01% tolerance());
147  BOOST_TEST(double(stats.Covariance()) == double(cov), 0.1% tolerance());
148  BOOST_TEST(double(stats.LinearCorrelation()) == double(lin_corr), 0.1% tolerance());
149  }
150 
151 } // CheckStats<>(StatCollector2D)
152 
153 
154 /**
155  * @brief Tests StatCollector object with a known input
156  * @tparam T type of the stat collector data
157  * @tparam W type of the stat collector weight
158  */
159 template <typename T, typename W = T>
161 
162  using Data_t = T;
163  using Weight_t = W;
164 
165  using WeightedData_t = std::vector<std::pair<Data_t, Weight_t>>;
166 
167  // prepare input data
168  std::valarray<Data_t> unweighted_data{
169  Data_t(5), Data_t(7), Data_t(7), Data_t(13)
170  };
171  WeightedData_t unweighted_data_weight({
172  { Data_t(5), Weight_t(1) },
173  { Data_t(7), Weight_t(1) },
174  { Data_t(7), Weight_t(1) },
175  { Data_t(13), Weight_t(1) }
176  });
177  int uw_n = 4;
178  Weight_t uw_weights = Weight_t( 4.);
179  Weight_t uw_sum = Weight_t( 32.);
180  Weight_t uw_sumsq = Weight_t(292.);
181  Weight_t uw_rms = Weight_t( 3.);
182 
183  WeightedData_t weighted_data({
184  { Data_t(5), Weight_t(1) },
185  { Data_t(7), Weight_t(2) },
186  { Data_t(13), Weight_t(1) }
187  });
188  int w_n = 3;
189  Weight_t w_weights = Weight_t( 4.);
190  Weight_t w_sum = Weight_t( 32.);
191  Weight_t w_sumsq = Weight_t(292.);
192  Weight_t w_rms = Weight_t( 3.);
193 
194  //
195  // part I: construction
196  //
198 
199  // check that everything is 0 or NaN-like
200  CheckStats<Data_t, Weight_t>(stats, 0, 0., 0., 0., 0. /* should not be used */);
201 
202  //
203  // part II: add elements one by one
204  //
205  // data set: { 5, 7, 7, 13 }
206  stats.add(5); // w = 1 sum = 5 sum2 = 25
207  stats.add(7, 2); // w = 3 sum = 19 sum2 = 123
208  stats.add(13); // w = 4 sum = 32 sum2 = 292
209 
210  CheckStats<Data_t, Weight_t>(stats, w_n, w_weights, w_sum, w_sumsq, w_rms);
211 
212 
213  //
214  // part III: add unweighted elements by bulk
215  //
216 
217  // - III.1: clear the statistics
218  stats.clear();
219  CheckStats<Data_t, Weight_t>(stats, 0, 0., 0., 0., 0. /* should not be used */);
220 
221  // - III.2: fill by iterators
222  stats.add_unweighted(std::begin(unweighted_data), std::end(unweighted_data));
223  CheckStats(stats, uw_n, uw_weights, uw_sum, uw_sumsq, uw_rms);
224 
225  // - III.3: fill by container
226  stats.clear();
227  stats.add_unweighted(unweighted_data);
228  CheckStats(stats, uw_n, uw_weights, uw_sum, uw_sumsq, uw_rms);
229 
230  // - III.4: fill by iterators and extractor
231  stats.clear();
232  stats.add_unweighted(
233  unweighted_data_weight.begin(), unweighted_data_weight.end(),
234  [](std::pair<Data_t, Weight_t> d){ return d.first; }
235  );
236  CheckStats(stats, uw_n, uw_weights, uw_sum, uw_sumsq, uw_rms);
237 
238  // - III.5: fill by container and extractor
239  stats.clear();
240  stats.add_unweighted(unweighted_data_weight,
241  [](std::pair<Data_t, Weight_t> d){ return d.first; }
242  );
243  CheckStats(stats, uw_n, uw_weights, uw_sum, uw_sumsq, uw_rms);
244 
245 
246  //
247  // part IV: add weighted elements by bulk
248  //
249 
250  // - IV.1: fill by iterators
251  stats.clear();
252  stats.add_weighted(weighted_data.begin(), weighted_data.end());
253  CheckStats(stats, w_n, w_weights, w_sum, w_sumsq, w_rms);
254 
255  // - IV.2: fill by container
256  stats.clear();
257  stats.add_weighted(weighted_data);
258  CheckStats(stats, w_n, w_weights, w_sum, w_sumsq, w_rms);
259 
260 
261 } // StatCollectorTest()
262 
263 
264 /**
265  * @brief Tests StatCollector2D object with a known input
266  * @tparam T type of the stat collector data
267  * @tparam W type of the stat collector weight
268  */
269 template <typename T, typename W = T>
271 
272  using Data_t = T;
273  using Weight_t = W;
274 
275 
276  using UnweightedItem_t = std::pair<Data_t, Data_t>;
277  using WeightedItem_t = std::tuple<Data_t, Data_t, Weight_t>;
278 
279 // using UnweightedData_t = std::vector<std::pair<Data_t, Data_t>>;
280  using WeightedData_t = std::vector<WeightedItem_t>;
281 
282  // prepare input data
283  std::vector<UnweightedItem_t> unweighted_data{
284  { Data_t(5), Data_t(10) },
285  { Data_t(7), Data_t(14) },
286  { Data_t(7), Data_t(14) },
287  { Data_t(13), Data_t(26) }
288  };
289  WeightedData_t unweighted_data_weight({
290  WeightedItem_t{ Data_t(5), Data_t(10), Weight_t(1) }, // w = 1 sumX = 5 sumX2 = 25
291  WeightedItem_t{ Data_t(7), Data_t(14), Weight_t(1) }, // w = 2 sumX = 12 sumX2 = 74
292  WeightedItem_t{ Data_t(7), Data_t(14), Weight_t(1) }, // w = 3 sumX = 19 sumX2 = 123
293  WeightedItem_t{ Data_t(13), Data_t(26), Weight_t(1) } // w = 4 sumX = 32 sumX2 = 292
294  });
295  // sumY = 2 sumX, sumsqY = 4 sumsqY, sumXY = 2 sumsqX
296  // covariance = aveXY - aveX aveY = 2 sumsqX/N - 2 aveX^2 = 2 varX
297  // linear correlation = sumXY / (rmsX rmsY) = 1
298  int uw_n = 4;
299  Weight_t uw_weights = Weight_t( 4.);
300  Weight_t uw_sumX = Weight_t( 32.);
301  Weight_t uw_sumsqX = Weight_t( 292.);
302  Weight_t uw_rmsX = Weight_t( 3.);
303  Weight_t uw_sumY = Weight_t( 64.);
304  Weight_t uw_sumsqY = Weight_t( 1168.);
305  Weight_t uw_rmsY = Weight_t( 6.);
306  Weight_t uw_sumXY = Weight_t( 584.);
307  Weight_t uw_cov = Weight_t( 18.);
308  Weight_t uw_lin_corr = Weight_t( 1.);
309 
310  WeightedData_t weighted_data({
311  WeightedItem_t{ Data_t(5), Data_t(10), Weight_t(1) },
312  WeightedItem_t{ Data_t(7), Data_t(14), Weight_t(2) },
313  WeightedItem_t{ Data_t(13), Data_t(26), Weight_t(1) }
314  });
315  int w_n = 3;
316  Weight_t w_weights = Weight_t( 4.);
317  Weight_t w_sumX = Weight_t( 32.);
318  Weight_t w_sumsqX = Weight_t( 292.);
319  Weight_t w_rmsX = Weight_t( 3.);
320  Weight_t w_sumY = Weight_t( 64.);
321  Weight_t w_sumsqY = Weight_t( 1168.);
322  Weight_t w_rmsY = Weight_t( 6.);
323  Weight_t w_sumXY = Weight_t( 584.);
324  Weight_t w_cov = Weight_t( 18.);
325  Weight_t w_lin_corr = Weight_t( 1.);
326 
327  //
328  // part I: construction
329  //
331 
332  // check that everything is 0 or NaN-like
333  CheckStats<Data_t, Weight_t>(stats, 0, 0.,
334  0., 0., 0. /* should not be used */,
335  0., 0., 0. /* should not be used */,
336  0., 0. /* should not be used */, 0. /* should not be used */
337  );
338 
339  //
340  // part II: add elements one by one
341  //
342  // the data is the same as weighted_data, just inserted one by one
343  // and exercising both weighted and unweighted addition;
344  // this part deliberately ignores directly interfaces adding pairs and tuples
345  for (auto const& data: weighted_data) {
346  if (std::get<2>(data) == Weight_t(1))
347  stats.add(std::get<0>(data), std::get<1>(data));
348  else
349  stats.add(std::get<0>(data), std::get<1>(data), std::get<2>(data));
350  } // for
351 
352  // by construction of the input, the statistics for X and Y are the same
353  CheckStats<Data_t, Weight_t>(stats, w_n, w_weights,
354  w_sumX, w_sumsqX, w_rmsX,
355  w_sumY, w_sumsqY, w_rmsY,
356  w_sumXY, w_cov, w_lin_corr
357  );
358 
359 
360  //
361  // part III: add unweighted elements by bulk
362  //
363 
364  // - III.1: clear the statistics
365  stats.clear();
366  CheckStats<Data_t, Weight_t>(stats, 0, 0.,
367  0., 0., 0. /* should not be used */,
368  0., 0., 0. /* should not be used */,
369  0., 0. /* should not be used */, 0. /* should not be used */
370  );
371 
372  // - III.2: fill by iterators
373  stats.add_unweighted(std::begin(unweighted_data), std::end(unweighted_data));
374  CheckStats<Data_t, Weight_t>(stats, uw_n, uw_weights,
375  uw_sumX, uw_sumsqX, uw_rmsX,
376  uw_sumY, uw_sumsqY, uw_rmsY,
377  uw_sumXY, uw_cov, uw_lin_corr
378  );
379 
380  // - III.3: fill by container
381  stats.clear();
382  stats.add_unweighted(unweighted_data);
383  CheckStats<Data_t, Weight_t>(stats, uw_n, uw_weights,
384  uw_sumX, uw_sumsqX, uw_rmsX,
385  uw_sumY, uw_sumsqY, uw_rmsY,
386  uw_sumXY, uw_cov, uw_lin_corr
387  );
388 
389  // - III.4: fill by iterators and extractor
390  stats.clear();
391  stats.add_unweighted(
392  unweighted_data_weight.begin(), unweighted_data_weight.end(),
393  [](WeightedItem_t const& d)
394  { return UnweightedItem_t{ std::get<0>(d), std::get<1>(d) }; }
395  );
396  CheckStats<Data_t, Weight_t>(stats, uw_n, uw_weights,
397  uw_sumX, uw_sumsqX, uw_rmsX,
398  uw_sumY, uw_sumsqY, uw_rmsY,
399  uw_sumXY, uw_cov, uw_lin_corr
400  );
401 
402  // - III.5: fill by container and extractor
403  stats.clear();
404  stats.add_unweighted(unweighted_data_weight,
405  [](WeightedItem_t const& d)
406  { return UnweightedItem_t{ std::get<0>(d), std::get<1>(d) }; }
407  );
408  CheckStats<Data_t, Weight_t>(stats, uw_n, uw_weights,
409  uw_sumX, uw_sumsqX, uw_rmsX,
410  uw_sumY, uw_sumsqY, uw_rmsY,
411  uw_sumXY, uw_cov, uw_lin_corr
412  );
413 
414 
415  //
416  // part IV: add weighted elements by bulk
417  //
418 
419  // - IV.1: fill by iterators
420  stats.clear();
421  stats.add_weighted(weighted_data.begin(), weighted_data.end());
422  CheckStats(stats, w_n, w_weights,
423  w_sumX, w_sumsqX, w_rmsX,
424  w_sumY, w_sumsqY, w_rmsY,
425  w_sumXY, w_cov, w_lin_corr
426  );
427 
428  // - IV.2: fill by container
429  stats.clear();
430  stats.add_weighted(weighted_data);
431  CheckStats(stats, w_n, w_weights,
432  w_sumX, w_sumsqX, w_rmsX,
433  w_sumY, w_sumsqY, w_rmsY,
434  w_sumXY, w_cov, w_lin_corr
435  );
436 
437 
438 } // StatCollectorTest2D()
439 
440 
441 /**
442  * @brief Tests MinMaxCollector object with a known input
443  *
444  */
445 template <typename T>
447 
448  using Data_t = T;
449 
450  std::initializer_list<Data_t> more_data{ 7, -20, 44, 78, 121 }; // [-20,121]
451  // BUG the double brace syntax is required to work around clang bug 21629
452  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
453  std::array<Data_t, 5> even_more_data {{ 7, -2, 123, 78, 121 }}; // [-2,123]
454 
455  // for easier notation
456  std::unique_ptr<lar::util::MinMaxCollector<Data_t>> collector;
457 
458  //
459  // 1. from default constructor
460  //
461  collector.reset(new lar::util::MinMaxCollector<Data_t>);
462 
463  // there should be no data now
464  BOOST_TEST(!collector->has_data());
465 
466  collector->add(Data_t(10));
467  // there should be some data now
468  BOOST_TEST(collector->has_data());
469 
470  BOOST_TEST(collector->min() == Data_t( 10));
471  BOOST_TEST(collector->max() == Data_t( 10));
472 
473  collector->add(more_data);
474  BOOST_TEST(collector->min() == Data_t( -20));
475  BOOST_TEST(collector->max() == Data_t( 121));
476 
477  collector->add(even_more_data.begin(), even_more_data.end());
478  BOOST_TEST(collector->min() == Data_t( -20));
479  BOOST_TEST(collector->max() == Data_t( 123));
480 
481  //
482  // 2. from initializer list constructor
483  //
484  collector.reset(new lar::util::MinMaxCollector<Data_t>{ -25, 3, 1 });
485 
486  // there should be data already
487  BOOST_TEST(collector->has_data());
488 
489  collector->add(Data_t(10));
490  // there should still be some data
491  BOOST_TEST(collector->has_data());
492 
493  BOOST_TEST(collector->min() == Data_t( -25));
494  BOOST_TEST(collector->max() == Data_t( 10));
495 
496  collector->add(more_data);
497  BOOST_TEST(collector->min() == Data_t( -25));
498  BOOST_TEST(collector->max() == Data_t( 121));
499 
500  collector->add(even_more_data.begin(), even_more_data.end());
501  BOOST_TEST(collector->min() == Data_t( -25));
502  BOOST_TEST(collector->max() == Data_t( 123));
503 
504 
505  //
506  // 3. from initializer list constructor
507  //
508  // BUG the double brace syntax is required to work around clang bug 21629
509  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
510  std::array<Data_t, 3> init_data{{ -25, 3, 1 }};
511  collector.reset(
512  new lar::util::MinMaxCollector<Data_t>(init_data.begin(), init_data.end())
513  );
514 
515  // there should be data already
516  BOOST_TEST(collector->has_data());
517 
518  collector->add(Data_t(10));
519  // there should still be some data
520  BOOST_TEST(collector->has_data());
521 
522  BOOST_TEST(collector->min() == Data_t( -25));
523  BOOST_TEST(collector->max() == Data_t( 10));
524 
525  collector->add(more_data);
526  BOOST_TEST(collector->min() == Data_t( -25));
527  BOOST_TEST(collector->max() == Data_t( 121));
528 
529  collector->add(even_more_data.begin(), even_more_data.end());
530  BOOST_TEST(collector->min() == Data_t( -25));
531  BOOST_TEST(collector->max() == Data_t( 123));
532 
533 } // MinMaxCollectorTest()
534 
535 
536 //------------------------------------------------------------------------------
537 //--- registration of tests
538 //
539 // Boost needs now to know which tests we want to run.
540 // Tests are "automatically" registered, hence the BOOST_AUTO_TEST_CASE()
541 // macro name. The argument is a name for the test; each test will have a
542 // number of checks and it will fail if any of them does.
543 //
544 
545 //
546 // stat collector tests
547 //
548 BOOST_AUTO_TEST_CASE(StatCollectorPureIntegerTest) {
549  StatCollectorTest<int, int>();
550 }
551 
552 BOOST_AUTO_TEST_CASE(StatCollectorIntegerTest) {
553  StatCollectorTest<int, float>();
554 }
555 
556 BOOST_AUTO_TEST_CASE(StatCollectorIntegerWeightsTest) {
557  StatCollectorTest<float, int>();
558 }
559 
560 BOOST_AUTO_TEST_CASE(StatCollectorRealTest) {
561  StatCollectorTest<double, double>();
562 }
563 
564 
565 //
566 // stat collector 2D tests
567 //
568 BOOST_AUTO_TEST_CASE(StatCollector2DPureIntegerTest) {
569  StatCollector2DTest<int, int>();
570 }
571 
572 BOOST_AUTO_TEST_CASE(StatCollector2DIntegerTest) {
573  StatCollector2DTest<int, float>();
574 }
575 
576 BOOST_AUTO_TEST_CASE(StatCollector2DIntegerWeightsTest) {
577  StatCollector2DTest<float, int>();
578 }
579 
580 BOOST_AUTO_TEST_CASE(StatCollector2DRealTest) {
581  StatCollector2DTest<double, double>();
582 }
583 
584 
585 //
586 // Minimum/maximum collector tests
587 //
588 BOOST_AUTO_TEST_CASE(MinMaxCollectorIntegerTest) {
589  MinMaxCollectorTest<int>();
590 }
591 
592 BOOST_AUTO_TEST_CASE(MinMaxCollectorRealTest) {
593  MinMaxCollectorTest<double>();
594 }
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
void MinMaxCollectorTest()
Tests MinMaxCollector object with a known input.
void CheckStats(lar::util::StatCollector< T, W > const &stats, int n, W weights, W sum, W sumsq, W rms)
Weight_t SumSqY() const
Returns the weighted sum of the square of the y values.
double rms(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:40
void add(Data_t x, Data_t y, Weight_t weight=Weight_t(1.0))
Adds one entry with specified values and weight.
Weight_t AverageWeight() const
Returns the arithmetic average of the weights.
auto const tolerance
Weight_t SumXY() const
Returns the weighted sum of the product of x and y values.
Weight_t Covariance() const
Returns the covariance of the (x, y) pair.
Classes gathering simple statistics.
Weight_t RMS() const
Returns the root mean square.
Weight_t VarianceY() const
Returns the variance of the y values.
Weight_t Average() const
Returns the value average.
Keeps track of the minimum and maximum value we observed.
Weight_t Variance() const
Returns the square of the RMS of the values.
Weight_t Sum() const
Returns the weighted sum of the values.
int N() const
Returns the number of entries added.
Weight_t AverageWeight() const
Returns the arithmetic average of the weights.
Weight_t AverageY() const
Returns the y value average.
std::void_t< T > n
Weight_t SumSqX() const
Returns the weighted sum of the square of the x values.
Weight_t AverageX() const
Returns the x value average.
Weight_t SumSq() const
Returns the weighted sum of the square of the values.
int N() const
Returns the number of entries added.
Weight_t SumX() const
Returns the weighted sum of the x values.
BOOST_AUTO_TEST_CASE(StatCollectorPureIntegerTest)
Weight_t SumY() const
Returns the weighted sum of the y values.
void StatCollector2DTest()
Tests StatCollector2D object with a known input.
Collects statistics on two homogeneous quantities (weighted)
Weight_t LinearCorrelation() const
Returns the linear correlation.
Weight_t RMSy() const
Returns the standard deviation of the y sample.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
Weight_t RMSx() const
Returns the standard deviation of the x sample.
Weight_t Weights() const
Returns the sum of the weights.
Weight_t VarianceX() const
Returns the variance of the x values.
Collects statistics on a single quantity (weighted)
void StatCollectorTest()
Tests StatCollector object with a known input.
Weight_t Weights() const
Returns the sum of the weights.
void add(Data_t value, Weight_t weight=Weight_t(1.0))
Adds one entry with specified value and weight.