Belle II Software  release-08-01-10
Median.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include <tracking/trackFindingCDC/numerics/Median.h>
9 
10 #include <tracking/trackFindingCDC/numerics/WeightComperator.h>
11 #include <tracking/trackFindingCDC/utilities/Algorithms.h>
12 
13 #include <cmath>
14 
15 using namespace Belle2;
16 
17 double TrackFindingCDC::median(std::vector<double> values)
18 {
19  auto notfinite = [](double v) { return not std::isfinite(v); };
20  erase_remove_if(values, notfinite);
21 
22  int n = values.size();
23 
24  if (n == 0) return NAN;
25 
26  std::nth_element(values.begin(), values.begin() + n / 2, values.end());
27  if (n % 2 == 0) {
28  // For an even number of values the median is the average of the two central values.
29  double upper = values[n / 2];
30  double lower = *std::max_element(values.begin(), values.begin() + n / 2);
31  return (lower + upper) / 2;
32  } else {
33  return values[n / 2];
34  }
35 }
36 
37 double TrackFindingCDC::weightedMedian(std::vector<WithWeight<double> > weightedValues)
38 {
39  auto notfinite = [](const WithWeight<double>& weightedValue) {
40  return not std::isfinite(weightedValue) or not std::isfinite(weightedValue.getWeight());
41  };
42  erase_remove_if(weightedValues, notfinite);
43 
44  if (weightedValues.empty()) return NAN;
45 
46  std::sort(weightedValues.begin(), weightedValues.end());
47 
49  Weight totalWeight = 0;
50  for (WithWeight<double>& weightedValue : weightedValues) {
51  totalWeight += weightedValue.getWeight();
52  weightedValue.setWeight(totalWeight);
53  }
54 
55  auto it = std::partition_point(weightedValues.begin(),
56  weightedValues.end(),
57  GetWeight() < totalWeight / 2.0);
58  return it == weightedValues.end() ? weightedValues.back() : *it;
59 }
Abstract base class for different kinds of events.