Belle II Software development
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
15using namespace Belle2;
16
17double 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
37double 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.