CMS 3D CMS Logo

DataUtils.h
Go to the documentation of this file.
1 #ifndef L1Trigger_L1TMuonEndCapPhase2_DataUtils_h
2 #define L1Trigger_L1TMuonEndCapPhase2_DataUtils_h
3 
4 #include <array>
5 #include <vector>
6 #include <type_traits>
7 
11 
12 namespace emtf::phase2::data {
13 
14  // Merge-Sort
15  template <typename T, typename C>
16  void swapWires(T arr[], const unsigned int& wire_1, const unsigned int& wire_2, const C& comparator) {
17  int result = comparator(arr[wire_1], arr[wire_2]);
18 
19  if (result == 1) {
20  auto temp = arr[wire_1];
21  arr[wire_1] = arr[wire_2];
22  arr[wire_2] = temp;
23  }
24  }
25 
26  template <typename T, typename C>
27  void mergesortBlock(T arr[],
28  const unsigned int& offset,
29  const unsigned int& step,
30  const unsigned int& block_begin,
31  const unsigned int& block_end,
32  const unsigned int& first_n,
33  const C& comparator) {
34  auto wire_offset = offset + block_begin;
35  auto wire_cutoff = first_n + block_begin;
36  auto wire_1 = wire_offset;
37  auto wire_2 = wire_1 + step;
38 
39  // Loop pairs
40  while (wire_2 < block_end) {
41  // Trim results
42  if (first_n > 0 && wire_cutoff < block_end) {
43  bool wire_needed = (wire_offset <= wire_1) && (wire_1 <= wire_cutoff);
44 
45  if (!wire_needed) {
46  break;
47  }
48  }
49 
50  // Swap Wires
51  swapWires(arr, wire_1, wire_2, comparator);
52 
53  // Calculate next wire_1
54  if (step == 1) {
55  wire_1 = wire_2 + 1;
56  } else {
57  wire_1 = wire_1 + 1;
58  }
59 
60  // Calculate next wire_2
61  wire_2 = wire_1 + step;
62  }
63  }
64 
65  template <typename T, typename C>
66  void mergesort(T arr[], const unsigned int& arr_size, const unsigned int& first_n, const C& comparator) {
67  // Sort
68  auto n_pairs = static_cast<unsigned int>(arr_size / 2);
69 
70  for (unsigned int i = 0; i < n_pairs; ++i) {
71  swapWires(arr, 2 * i, 2 * i + 1, comparator);
72  }
73 
74  // Merge
75  auto offset = 0u;
76  auto step = 2u;
77  auto block_size = step * 2;
78 
79  // Loop block sizes
80  while (true) {
81  // Loop step sizes
82  // If the offset is greater than the amount of wires to keep
83  // there's no need to continue, since (offset)-wires are known
84  // to not contribute to the end result
85  while (true) {
86  // Loop blocks
87  auto block_begin = 0u;
88  auto block_end = block_size;
89 
90  while (block_begin < arr_size) {
91  // Constrain block_end
92  if (block_end > arr_size)
93  block_end = arr_size;
94 
95  // Merge block
96  mergesortBlock(arr, offset, step, block_begin, block_end, first_n, comparator);
97 
98  // Move to next block
99  block_begin = block_end;
100  block_end = block_end + block_size;
101  }
102 
103  // Decrease step
104  if (step > 2) {
105  // For each pass we are certain of the local min and max
106  // so skip 2 wires and reduce the step
107  offset = offset + 2;
108  step = step - 2;
109  } else if (step == 2) {
110  // For final pass we are certain of the global min and max
111  // so skip 1 wire and compare wires 1 to 1, the last value
112  // will be left without a partner; naturally since
113  // it's the global min
114  offset = 1;
115  step = 1;
116  } else {
117  // Short-Circuit: Done
118  break;
119  }
120  }
121 
122  // Short-Circuit: No more wires
123  if (block_size >= arr_size)
124  break;
125 
126  // Double the block size
127  offset = 0;
128  step = block_size;
129  block_size = step * 2;
130  }
131  }
132 
133  template <typename T, typename C>
134  void mergesort(T arr[], const unsigned int& arr_size, const C& comparator) {
135  mergesort(arr, arr_size, 0, comparator);
136  }
137 
138  // Median Calculation
139  template <typename T>
140  T getMedianOfSorted(T arr[], const unsigned int& arr_size) {
141  T mid;
142 
143  if ((arr_size % 2) == 0) {
144  const auto& top = arr[arr_size / 2];
145  const auto& bot = arr[arr_size / 2 - 1];
146  mid = (top + bot) >> 1; // Mid = (Top + Bot) / 2
147  } else {
148  mid = arr[(arr_size - 1) / 2];
149  }
150 
151  return mid;
152  }
153 } // namespace emtf::phase2::data
154 
155 #endif // L1Trigger_L1TMuonEndCapPhase2_DataUtils_h not defined
T getMedianOfSorted(T arr[], const unsigned int &arr_size)
Definition: DataUtils.h:140
void swapWires(T arr[], const unsigned int &wire_1, const unsigned int &wire_2, const C &comparator)
Definition: DataUtils.h:16
void mergesort(T arr[], const unsigned int &arr_size, const unsigned int &first_n, const C &comparator)
Definition: DataUtils.h:66
void mergesortBlock(T arr[], const unsigned int &offset, const unsigned int &step, const unsigned int &block_begin, const unsigned int &block_end, const unsigned int &first_n, const C &comparator)
Definition: DataUtils.h:27
step
Definition: StallMonitor.cc:83
long double T