ATLAS Offline Software
Loading...
Searching...
No Matches
Combinators.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4#include <algorithm>
5#include <numeric>
6#include <iostream>
7#include <iterator>
9
10
11using namespace HLT;
12CombinationGenerator::CombinationGenerator( const std::initializer_list<size_t>& collectionSizes )
13 : m_maxes( collectionSizes ),
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),
48 reset();
49 }
50
51
52CombinationGenerator::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
63UniqueCombinationGenerator::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
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
116NestedUniqueCombinationGenerator::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
127namespace {
128
129 void combMaker( const Index2DVec& indices, const std::function<void (const Index1DVec&) >& handle, const 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 }
146 } else {
147 combMaker( indices, handle, filter, rank+1, combination);
148 }
149 }
150 }
151 }
152}
153
154namespace HLT {
155 void elementsInUniqueCombinations( const Index2DVec& indices, std::set<size_t>& participants, const std::function<bool(const Index1DVec&)>& filter ) {
156 const auto handle = [&](const Index1DVec& combination ) { for ( auto el: combination ) participants.insert(participants.begin(), el); };
157 combMaker( indices, handle, filter );
158 }
159
160 void findUniqueCombinations( const Index2DVec& indices, std::vector<std::vector<size_t> >& combinations, const std::function<bool(const Index1DVec&)>& filter ) {
161 auto handle = [&](const Index1DVec& combination ) { combinations.push_back( combination ); };
162 combMaker( indices, handle, filter );
163 }
164}
static Double_t sz
int imax(int i, int j)
CombinationGenerator(const std::initializer_list< size_t > &collectionSizes)
construct combnations maker with the sizes of collection to which it should be applied
void operator++()
moves to the next combination
void add(const UniqueCombinationGenerator &gen)
Generator of unique combinations (no indices are repeated) API description.
UniqueCombinationGenerator(size_t nelems, size_t comblen)
bool exists(const std::string &filename)
does a file exist
virtual void handle(const Incident &inc)
Handle end of run incidents to save the metadata at that point.
It used to be useful piece of code for replacing actual SG with other store of similar functionality ...
void elementsInUniqueCombinations(const Index2DVec &indices, std::set< size_t > &participants, const std::function< bool(const Index1DVec &)> &filter)
std::vector< Index1DVec > Index2DVec
std::vector< size_t > Index1DVec
Unique combinations for case when one can not repeat the index (i.e.
void findUniqueCombinations(const Index2DVec &indices, std::vector< std::vector< size_t > > &combinations, const std::function< bool(const Index1DVec &)> &filter)
Creates unique combinations of elements.
std::pair< long int, long int > indices
const Amg::Vector3D & position() const
Method to retrieve the position of the Intersection.
void fill(H5::Group &out_file, size_t iterations)