File indexing completed on 2024-04-06 12:27:45
0001 #ifndef RecoTauTag_RecoTau_CombinatoricGenerator_h
0002 #define RecoTauTag_RecoTau_CombinatoricGenerator_h
0003
0004 #include <boost/iterator/iterator_facade.hpp>
0005 #include <boost/iterator/filter_iterator.hpp>
0006 #include <boost/iterator/transform_iterator.hpp>
0007 #include <vector>
0008 #include <set>
0009 #include <memory>
0010 #include <iostream>
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 namespace reco {
0048 namespace tau {
0049
0050 template <typename T>
0051 class Combinatoric {
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 typedef typename T::const_iterator value_iter;
0066 typedef typename T::value_type value_type;
0067 typedef size_t index_type;
0068 typedef typename std::vector<index_type> indices_collection;
0069 typedef typename indices_collection::const_iterator index_iter;
0070 typedef typename std::set<index_type> indices_set;
0071
0072 class IndexInSet {
0073
0074 public:
0075 IndexInSet(const indices_set& combo, bool negate) : combo_(combo), negate_(negate) {}
0076 bool operator()(const index_type& index) const {
0077 return (negate_) ? !combo_.count(index) : combo_.count(index);
0078 }
0079
0080 private:
0081 indices_set combo_;
0082 bool negate_;
0083 };
0084
0085 class ValueAccessor {
0086
0087
0088 public:
0089 ValueAccessor(const value_iter& begin) : begin_(begin) {}
0090 const value_type& operator()(index_type const& index) const { return *(begin_ + index); }
0091
0092 private:
0093 value_iter begin_;
0094 };
0095
0096 public:
0097 Combinatoric(const value_iter& begin,
0098 const indices_collection& indices,
0099 const indices_collection& combo,
0100 bool done)
0101 : begin_(begin),
0102 combo_(combo.begin(), combo.end()),
0103 comboSet_(combo.begin(), combo.end()),
0104 indices_(indices),
0105 done_(done),
0106 valueAccessor_(begin),
0107 inChoice_(comboSet_, false),
0108 notInChoice_(comboSet_, true) {}
0109
0110 typedef typename boost::filter_iterator<IndexInSet, index_iter> ComboIter;
0111 typedef typename boost::transform_iterator<ValueAccessor, ComboIter> ValueIter;
0112
0113
0114 ValueIter combo_begin() const {
0115 return ValueIter(ComboIter(inChoice_, indices_.begin(), indices_.end()), valueAccessor_);
0116 }
0117
0118 ValueIter combo_end() const {
0119 return ValueIter(ComboIter(inChoice_, indices_.end(), indices_.end()), valueAccessor_);
0120 }
0121
0122
0123 ValueIter remainder_end() const {
0124 return ValueIter(ComboIter(notInChoice_, indices_.end(), indices_.end()), valueAccessor_);
0125 }
0126
0127 ValueIter remainder_begin() const {
0128 return ValueIter(ComboIter(notInChoice_, indices_.begin(), indices_.end()), valueAccessor_);
0129 }
0130
0131
0132 Combinatoric<T> next() const {
0133
0134
0135
0136
0137
0138 indices_collection newCombo(combo_);
0139
0140
0141
0142
0143
0144
0145
0146 size_t distanceFromEnd = 0;
0147 size_t nElements = indices_.size();
0148 indices_collection::reverse_iterator pos = newCombo.rbegin();
0149 for (; pos != newCombo.rend(); ++pos, ++distanceFromEnd) {
0150
0151
0152 if (*pos < (nElements - 1 - distanceFromEnd)) {
0153 (*pos)++;
0154 break;
0155 } else {
0156
0157 (*pos) = nElements;
0158 }
0159 }
0160
0161
0162
0163
0164
0165
0166 indices_collection::iterator forward_pos = pos.base();
0167
0168
0169
0170 bool done = true;
0171 if (forward_pos != newCombo.begin()) {
0172
0173 index_type next_pos_value = (*pos) + 1;
0174
0175 done = false;
0176 for (; forward_pos != newCombo.end(); ++forward_pos, ++next_pos_value) {
0177 *forward_pos = next_pos_value;
0178 }
0179 }
0180
0181
0182
0183
0184
0185
0186 return Combinatoric<T>(begin_, indices_, newCombo, done);
0187 }
0188
0189
0190 bool done() const { return done_; }
0191
0192
0193 const indices_set& combo() const { return comboSet_; }
0194
0195
0196 bool operator==(const Combinatoric<T>& rhs) const {
0197 return (this->combo() == rhs.combo() && this->done() == rhs.done());
0198 }
0199
0200 private:
0201
0202
0203 value_iter begin_;
0204 indices_collection combo_;
0205 indices_set comboSet_;
0206 indices_collection indices_;
0207 bool done_;
0208 ValueAccessor valueAccessor_;
0209 IndexInSet inChoice_;
0210 IndexInSet notInChoice_;
0211 };
0212
0213 template <typename T>
0214 class CombinatoricIterator
0215 : public boost::iterator_facade<CombinatoricIterator<T>, const Combinatoric<T>, boost::forward_traversal_tag> {
0216
0217 public:
0218 typedef Combinatoric<T> value_type;
0219 explicit CombinatoricIterator(const Combinatoric<T>& c) : node_(c) {}
0220
0221 private:
0222 friend class boost::iterator_core_access;
0223
0224 bool equal(CombinatoricIterator const& other) const { return this->node_ == other.node_; }
0225
0226 void increment() { node_ = node_.next(); }
0227
0228 const Combinatoric<T>& dereference() const { return node_; }
0229
0230 Combinatoric<T> node_;
0231 };
0232
0233 template <typename T>
0234 class CombinatoricGenerator {
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245 typedef typename T::const_iterator value_iter;
0246 typedef typename T::value_type value_type;
0247 typedef size_t index_type;
0248 typedef typename std::vector<index_type> indices_collection;
0249 typedef typename indices_collection::iterator index_iter;
0250 typedef typename std::set<index_type> indices_set;
0251
0252 public:
0253 typedef std::unique_ptr<CombinatoricIterator<T> > CombIterPtr;
0254 typedef CombinatoricIterator<T> iterator;
0255 typedef typename iterator::value_type::ValueIter combo_iterator;
0256
0257 explicit CombinatoricGenerator(const value_iter& begin, const value_iter& end, size_t choose) {
0258
0259 indices_collection initialCombo(choose);
0260 indices_collection finalCombo(choose);
0261
0262 size_t totalElements = end - begin;
0263
0264 if (choose <= totalElements) {
0265 indices_collection allIndices(totalElements);
0266 for (size_t i = 0; i < totalElements; ++i) {
0267 allIndices[i] = i;
0268 }
0269
0270 for (size_t i = 0; i < choose; ++i) {
0271 initialCombo[i] = i;
0272
0273 finalCombo[i] = totalElements;
0274 }
0275
0276 beginning_ =
0277 CombIterPtr(new CombinatoricIterator<T>(Combinatoric<T>(begin, allIndices, initialCombo, false)));
0278
0279 ending_ = CombIterPtr(new CombinatoricIterator<T>(Combinatoric<T>(begin, allIndices, finalCombo, true)));
0280 } else {
0281
0282
0283 beginning_ = CombIterPtr(
0284 new CombinatoricIterator<T>(Combinatoric<T>(begin, indices_collection(), indices_collection(), true)));
0285
0286 ending_ = CombIterPtr(
0287 new CombinatoricIterator<T>(Combinatoric<T>(begin, indices_collection(), indices_collection(), true)));
0288 }
0289 }
0290
0291 CombinatoricIterator<T> begin() { return *beginning_; }
0292
0293 CombinatoricIterator<T> end() { return *ending_; }
0294
0295 private:
0296 CombIterPtr beginning_;
0297 CombIterPtr ending_;
0298 };
0299
0300 }
0301 }
0302 #endif