Belle II Software  release-08-01-10
Algorithms.h
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 #pragma once
9 
10 #include <tracking/trackFindingCDC/utilities/Range.h>
11 
12 #include <algorithm>
13 #include <iterator>
14 #include <optional>
15 #include <vector>
16 
17 namespace Belle2 {
22  namespace TrackFindingCDC {
23 
28  template <class Ts, class ACategoryFunction, class ACategory>
29  ACategory common(const Ts& items, const ACategoryFunction& catFunc, const ACategory defaultCat)
30  {
31  auto it = std::begin(items);
32  auto itEnd = std::end(items);
33  return common(it, itEnd, catFunc, defaultCat);
34  }
35 
40  template <class It, class ACategoryFunction, class ACategory>
41  ACategory common(It itBegin, It itEnd, const ACategoryFunction& catFunc, const ACategory defaultCat)
42  {
43  if (itBegin == itEnd) return defaultCat; // empty case
44  const ACategory cat = catFunc(*itBegin);
45  for (It it = itBegin; it != itEnd; ++it) {
46  if (cat != catFunc(*it)) {
47  return defaultCat;
48  };
49  }
50  return cat;
51  }
52 
56  template <class Ts, class APredicate>
57  void erase_remove_if(Ts& ts, const APredicate& predicate)
58  {
59  ts.erase(std::remove_if(std::begin(ts), std::end(ts), predicate), std::end(ts));
60  }
61 
62  template<class Ts>
63  void only_best_N(Ts& ts, const size_t N)
64  {
65  auto newEnd = std::next(ts.begin(), std::min(N, ts.size()));
66  ts.erase(newEnd, ts.end());
67  }
68 
72  template <class Ts>
73  void erase_unique(Ts& ts)
74  {
75  ts.erase(std::unique(std::begin(ts), std::end(ts)), std::end(ts));
76  }
77 
81  template <class Ts, class AEqual>
82  void erase_unique(Ts& ts, const AEqual& equal)
83  {
84  ts.erase(std::unique(std::begin(ts), std::end(ts), equal), std::end(ts));
85  }
86 
90  template <class It>
91  std::vector<std::pair<It, int> > unique_count(It itBegin, It itEnd)
92  {
93  std::vector<std::pair<It, int> > result;
94  if (itBegin == itEnd) return result;
95  It it = itBegin;
96  result.emplace_back(it, 1);
97  ++it;
98  for (; it != itEnd; ++it) {
99  if (*it == *result.back().first) {
100  ++result.back().second;
101  } else {
102  result.emplace_back(it, 1);
103  }
104  }
105  return result;
106  }
107 
111  template <class It, class AEqual>
112  std::vector<std::pair<It, int> > unique_count(It itBegin, It itEnd, const AEqual& equal)
113  {
114  std::vector<std::pair<It, int> > result;
115  if (itBegin == itEnd) return result;
116  It it = itBegin;
117  result.emplace_back(it, 1);
118  ++it;
119  for (; it != itEnd; ++it) {
120  if (equal(*it, *result.back().first)) {
121  ++result.back().second;
122  } else {
123  result.emplace_back(it, 1);
124  }
125  }
126  return result;
127  }
128 
132  template <class It>
133  std::vector<Range<It> > unique_ranges(It itBegin, It itEnd)
134  {
135  std::vector<std::pair<It, It> > result;
136  if (itBegin == itEnd) return result;
137  It it1 = itBegin;
138  It it2 = itBegin + 1;
139  result.emplace_back(it1, it2);
140  for (; it2 != itEnd; ++it1, ++it2) {
141  if (not(*it1 == *it2)) {
142  result.emplace_back(it2, it2);
143  }
144  ++result.back().second;
145  }
146  return result;
147  }
148 
152  template <class It, class AEqual>
153  std::vector<Range<It> > unique_ranges(It itBegin, It itEnd, const AEqual& equal)
154  {
155  std::vector<Range<It> > result;
156  if (itBegin == itEnd) return result;
157  It it1 = itBegin;
158  It it2 = itBegin + 1;
159  result.emplace_back(it1, it2);
160  for (; it2 != itEnd; ++it1, ++it2) {
161  if (not equal(*it1, *it2)) {
162  result.emplace_back(it2, it2);
163  }
164  ++result.back().second;
165  }
166  return result;
167  }
168 
172  template <class It, class ACategoryFunction>
173  std::vector<Range<It>> adjacent_groupby(It itBegin, It itEnd, const ACategoryFunction& catFunc)
174  {
175  std::vector<Range<It>> result;
176  if (itBegin == itEnd) return result; // empty case
177 
178  It itFirstOfGroup = itBegin;
179  auto catOfGroup = catFunc(*itBegin);
180 
181  for (It it = itBegin; it != itEnd; ++it) {
182  auto cat = catFunc(*it);
183  if (catOfGroup != cat) {
184  result.emplace_back(itFirstOfGroup, it);
185  itFirstOfGroup = it;
186  catOfGroup = cat;
187  }
188  }
189  result.emplace_back(itFirstOfGroup, itEnd);
190  return result;
191  }
192 
197  template <class AInputIterator, class AOutputIterator, class ABinaryOperation>
198  AOutputIterator transform_adjacent_pairs(AInputIterator itBegin,
199  AInputIterator itEnd,
200  AOutputIterator result,
201  const ABinaryOperation& map)
202  {
203  if (itBegin == itEnd) return result;
204 
205  AInputIterator second = itBegin;
206  ++second;
207  while (second != itEnd) {
208  *result = map(*itBegin, *second);
209  ++result;
210  ++itBegin;
211  ++second;
212  }
213  return result;
214  }
215 
220  template <class AInputIterator, class AOutputIterator, class ATrinaryOperation>
221  AOutputIterator transform_adjacent_triples(AInputIterator itBegin,
222  AInputIterator itEnd,
223  AOutputIterator result,
224  const ATrinaryOperation& map)
225  {
226  if (not(itBegin != itEnd)) return result;
227 
228  AInputIterator second = itBegin;
229  ++second;
230  if (not(second != itEnd)) return result;
231 
232  AInputIterator third = second;
233  ++third;
234  while (third != itEnd) {
235  *result = map(*itBegin, *second, *third);
236  ++result;
237  ++itBegin;
238  ++second;
239  ++third;
240  }
241  return result;
242  }
243 
248  template <class Ts, class TCopyIfPredicate>
249  Ts copy_if(Ts const& inputContainer, TCopyIfPredicate pred)
250  {
251  Ts outputContainer;
252 
253  // copy only if predicate is true
254  std::copy_if(inputContainer.begin(), inputContainer.end(), std::back_inserter(outputContainer), pred);
255  return outputContainer;
256  }
257 
258 
262  template <class Ts, class AUnaryPredicate>
263  bool any(const Ts& ts, const AUnaryPredicate& comparator)
264  {
265  return std::any_of(std::begin(ts), std::end(ts), comparator);
266  }
267 
271  template <class Ts, class AItem>
272  bool is_in(const AItem& item, const Ts& ts)
273  {
274  return std::find(std::begin(ts), std::end(ts), item) != std::end(ts);
275  };
276 
280  template <class T, class Ts>
281  std::vector<T*> as_pointers(Ts& ts)
282  {
283  using std::begin;
284  using std::end;
285  std::size_t vsize = end(ts) - begin(ts);
286  std::vector<T*> result(vsize, nullptr);
287  std::transform(begin(ts), end(ts), result.begin(), [](T & t) { return std::addressof<T>(t);});
288  return result;
289  }
290  }
292 }
Abstract base class for different kinds of events.
def equal(a, b)
Definition: bitstring.py:292