Kernel Quantum Probability Library
The KQP library aims at providing tools for working with quantums probabilities
intervals.hpp
1 /*
2  This file is part of the Kernel Quantum Probability library (KQP).
3 
4  KQP is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  KQP is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with KQP. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef __KQP_INTERVALS_H__
19 #define __KQP_INTERVALS_H__
20 
21 #include <vector>
22 namespace kqp {
23  # include <kqp/define_header_logger.hpp>
24  DEFINE_KQP_HLOGGER("kqp.intervals");
25 
28  const std::vector<bool> *which;
29  size_t size;
30  std::pair<size_t, size_t> current;
31 
32  void find(size_t fromInclusive) {
33  if (which) {
34  // Find the first "true" bit from current position
35  current.first = std::find(which->begin() + fromInclusive, which->end(), true) - which->begin();
36 
37  // Find the first "false" bit from start
38  current.second = current.first == size ? size : std::find(which->begin() + current.first + 1, which->end(), false) - which->begin() - 1;
39  } else {
40  if (fromInclusive > 0)
41  current.first = current.second = size;
42  else {
43  current.first = 0;
44  current.second = size - 1;
45  }
46  }
47 
48  }
49 
50  IntervalsIterator &operator++(int) {
51  find(current.second+1);
52  return *this;
53  }
54 
55  IntervalsIterator(const std::vector<bool> *which, size_t size) : which(which), size(size) {
56  find(0);
57  }
58 
59  IntervalsIterator(const std::vector<bool> *which, size_t size, size_t begin, size_t end) : which(which), size(size), current(begin,end) {
60  }
61 
62  const std::pair<size_t, size_t> & operator*() const {
63  return current;
64  }
65  const std::pair<size_t, size_t> *operator->() const {
66  return &current;
67  }
68  bool operator!=(const IntervalsIterator &other) {
69  return which != other.which || current != other.current;
70  }
71 };
72 
73 
74 class Intervals {
75 public:
77 
78  Intervals(const std::vector<bool> &which) : m_which(&which), m_size(which.size()), m_end(m_which, m_size, m_size, m_size) {
79  m_selected = std::accumulate(which.begin(), which.end(), 0);
80  }
81 
82  Intervals(const std::vector<bool> *which, size_t size) : m_which(which), m_size(size), m_end(m_which, m_size, m_size, m_size) {
83  assert(!which || which->size() == m_size);
84  if (which) m_selected = std::accumulate(which->begin(), which->end(), 0);
85  else m_selected = m_size;
86  }
87 
88  size_t size() const { return m_size;}
89  size_t selected() const { return m_selected; }
90 
91  Iterator begin() {
92  return Iterator(m_which, m_size);
93  }
94  const Iterator &end() {
95  return m_end;
96  }
97 
98  private:
99  // Vector of selected entries
100  const std::vector<bool> *m_which;
101 
102  // Number of entries
103  size_t m_size;
104 
105  // End for the iterator
106  const Iterator m_end;
107 
108  // Number of selected entries
109  size_t m_selected;
110 
111 
112 };
113 }
114 #endif