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