ATLAS Offline Software
Combinators.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
4 #include <algorithm>
5 #include <numeric>
6 #include <iostream>
7 #include <iterator>
9 
10 
11 using namespace HLT;
12 CombinationGenerator::CombinationGenerator( const std::initializer_list<size_t>& collectionSizes )
13  : m_maxes( collectionSizes ),
14  m_current( m_maxes.size() ) {
15  reset();
16 
17 }
18 
20  // no combinations when at least one the sizes is 0 ( empty collection )
21  if ( std::any_of( m_maxes.begin(), m_maxes.end(),
22  []( size_t m ){ return m == 0; } ) )
23  m_current.clear();
24  else {
25  fill( m_current.begin(), m_current.end(), 0 );
26  }
27 }
28 
30  if ( m_current.empty() ) return;
31  for ( size_t i = 0, imax = m_current.size(); i < imax; ++i ) { // iterate over current indices and find the index which can be increased
32  if ( m_maxes[i] - m_current[i] == 1 ) { // reached end of the range of i-th collection, return to the beginning
33  m_current[i] = 0;
34  } else {
35  m_current[i]++;
36  return;
37  }
38  }
39 
40  // unsuccessful index increase == we need to make op bool returning false and next ++ should not happen
41  m_current.clear();
42 }
43 
45  : m_nElements(nelems),
46  m_combLen(comblen),
47  m_current(m_combLen) {
48  reset();
49  }
50 
51 
52 CombinationGenerator::operator bool() const {
53  return not m_current.empty();
54 }
55 
57  m_bitmask.resize(m_combLen, true);
58  m_bitmask.resize(m_nElements, false);
59  m_current.resize(m_combLen);
60  std::iota(m_current.begin(), m_current.end(), 0);
61 }
62 
63 UniqueCombinationGenerator::operator bool() const {
64  return not m_current.empty();
65 }
66 
68  if ( m_current.empty() ) return;
69 
70  const bool exists = std::prev_permutation( m_bitmask.begin(), m_bitmask.end());
71  if ( exists ) {
72  m_current.clear();
73  for (size_t i = 0; i < m_nElements; ++i) {
74  if ( m_bitmask[i] )
75  m_current.push_back(i);
76  }
77  return;
78  }
79  m_current.clear();
80 }
81 
82 
84  m_generators.push_back(gen);
85  reset();
86 }
88  m_current.clear();
89  for ( auto& gen: m_generators) {
90  gen.reset();
91  }
92  cache();
93 }
94 
96  size_t sz = 0;
97  for ( const auto& gen: m_generators) { sz += gen.size(); }
98  return sz;
99 }
100 
101 
103  m_current.clear();
104  for ( auto& gen: m_generators ) {
105  ++gen;
106  if ( gen ) {
107  cache();
108  return;
109  } else if ( &gen != &m_generators.back()) {
110  gen.reset();
111  }
112  }
113  m_current.clear();
114 }
115 
116 NestedUniqueCombinationGenerator::operator bool() const {
117  return not m_current.empty();
118 }
119 
121  m_current.clear();
122  for ( auto& gen: m_generators) {
123  m_current.insert(m_current.end(), gen.current().begin(), gen.current().end());
124  }
125 }
126 
127 namespace {
128 
129  void combMaker( const Index2DVec& indices, std::function<void (const Index1DVec&) >&& handle, std::function<bool (const Index1DVec&) >&& filter, size_t rank=0, Index1DVec combination={} ) {
130 
131  for ( auto position: indices[rank] ) {
132  // found an element matching to this combination
133  if ( std::find( combination.begin(), combination.end(), position ) == combination.end() ) {
134  // std::cout << "rank " << rank << " adding or replacing " << position << " to a combination containing so far ";
135  // std::copy( combination.begin(), combination.end(), std::ostream_iterator<size_t>(std::cout, " ") );
136  // std::cout << "\n";
137  if ( combination.size() == rank )
138  combination.push_back( position );
139  else
140  combination[rank] = position;
141 
142  if ( combination.size() == indices.size() ) { // end of recursion
143  if ( filter( combination ) )
144  handle( combination );
145  } else {
146  combMaker( indices, std::move(handle), std::move(filter), rank+1, combination);
147  }
148  }
149  }
150  }
151 }
152 
153 namespace HLT {
154  void elementsInUniqueCombinations( const Index2DVec& indices, std::set<size_t>& participants, std::function<bool(const Index1DVec&)>&& filter ) {
155  auto handle = [&](const Index1DVec& combination ) { for ( auto el: combination ) participants.insert(participants.begin(), el); };
156  combMaker( indices, std::move(handle), std::move(filter) );
157  }
158 
159  void findUniqueCombinations( const Index2DVec& indices, std::vector<std::vector<size_t> >& combinations, std::function<bool(const Index1DVec&)>&& filter ) {
160  auto handle = [&](const Index1DVec& combination ) { combinations.push_back( combination ); };
161  combMaker( indices, std::move(handle), std::move(filter) );
162  }
163 }
HLT::UniqueCombinationGenerator::m_nElements
size_t m_nElements
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:62
HLT::NestedUniqueCombinationGenerator::m_current
std::vector< size_t > m_current
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:86
fitman.sz
sz
Definition: fitman.py:527
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
HLT::UniqueCombinationGenerator::operator++
void operator++()
Definition: Combinators.cxx:67
HLT::NestedUniqueCombinationGenerator::reset
void reset()
Definition: Combinators.cxx:87
HLT::UniqueCombinationGenerator::reset
void reset()
Definition: Combinators.cxx:56
Trk::indices
std::pair< long int, long int > indices
Definition: AlSymMatBase.h:24
HLT::UniqueCombinationGenerator::UniqueCombinationGenerator
UniqueCombinationGenerator(size_t nelems, size_t comblen)
Definition: Combinators.cxx:44
HLT::findUniqueCombinations
void findUniqueCombinations(const Index2DVec &indices, std::vector< std::vector< size_t > > &combinations, std::function< bool(const Index1DVec &)> &&filter)
Creates unique combinations of elements.
Definition: Combinators.cxx:159
HLT::CombinationGenerator::operator++
void operator++()
moves to the next combination
Definition: Combinators.cxx:29
master.gen
gen
Definition: master.py:32
covarianceTool.filter
filter
Definition: covarianceTool.py:514
HLT::Index1DVec
std::vector< size_t > Index1DVec
Unique combinations for case when one can not repeat the index (i.e.
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:139
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
HLT::CombinationGenerator::CombinationGenerator
CombinationGenerator(const std::initializer_list< size_t > &collectionSizes)
construct combnations maker with the sizes of collection to which it should be applied
Definition: Combinators.cxx:12
HLT::UniqueCombinationGenerator::m_current
std::vector< size_t > m_current
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:64
HLT
It used to be useful piece of code for replacing actual SG with other store of similar functionality ...
Definition: HLTResultReader.h:26
lumiFormat.i
int i
Definition: lumiFormat.py:85
HLT::NestedUniqueCombinationGenerator::operator++
void operator++()
Definition: Combinators.cxx:102
HLT::CombinationGenerator::reset
void reset()
Definition: Combinators.cxx:19
plotIsoValidation.el
el
Definition: plotIsoValidation.py:197
HLT::NestedUniqueCombinationGenerator::add
void add(const UniqueCombinationGenerator &gen)
Definition: Combinators.cxx:83
imax
int imax(int i, int j)
Definition: TileLaserTimingTool.cxx:33
HLT::NestedUniqueCombinationGenerator::size
size_t size() const
Definition: Combinators.cxx:95
HLT::UniqueCombinationGenerator::m_combLen
size_t m_combLen
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:63
HLT::elementsInUniqueCombinations
void elementsInUniqueCombinations(const Index2DVec &indices, std::set< size_t > &participants, std::function< bool(const Index1DVec &)> &&filter)
Definition: Combinators.cxx:154
fill
void fill(H5::Group &out_file, size_t iterations)
Definition: test-hdf5-writer.cxx:95
HLT::NestedUniqueCombinationGenerator::cache
void cache()
Definition: Combinators.cxx:120
HLT::CombinationGenerator::m_current
std::vector< size_t > m_current
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:44
HLT::NestedUniqueCombinationGenerator::m_generators
std::vector< UniqueCombinationGenerator > m_generators
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:85
HLT::UniqueCombinationGenerator
Generator of unique combinations (no indices are repeated) API description.
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:51
python.combo.combinations
def combinations(items, n)
Definition: combo.py:85
HLT::CombinationGenerator::m_maxes
std::vector< size_t > m_maxes
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:43
Combinators.h
HLT::Index2DVec
std::vector< Index1DVec > Index2DVec
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:140
python.dummyaccess.exists
def exists(filename)
Definition: dummyaccess.py:9
HLT::UniqueCombinationGenerator::m_bitmask
std::vector< bool > m_bitmask
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:65
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60