Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
n_aryGrayCodeCounter.cpp
Go to the documentation of this file.
1 
17 #include "n_aryGrayCodeCounter.h"
18 #include <cstring>
19 #include <iostream>
20 
21 
22 
28 
29 
30  offset_max = 0;
31  offset = 0;
32 
33 }
34 
35 
41 
42  n_ary_limits = n_ary_limits_in.copy();
43 
44  if ( n_ary_limits.size() == 0 ) {
45  offset_max = 0;
46  offset = 0;
47  return;
48  }
49 
51  for (size_t idx=1; idx<n_ary_limits.size(); idx++) {
52  offset_max *= n_ary_limits[idx];
53  }
54 
55  offset_max--;
56  offset = 0;
57 
58  // initialize the counter
59  initialize(0);
60 
61 }
62 
63 
69 n_aryGrayCodeCounter::n_aryGrayCodeCounter( matrix_base<int>& n_ary_limits_in, int64_t initial_offset) {
70 
71  n_ary_limits = n_ary_limits_in.copy();
72 
73  if ( n_ary_limits.size() == 0 ) {
74  offset_max = 0;
75  offset = 0;
76  return;
77  }
78 
80  for (size_t idx=1; idx<n_ary_limits.size(); idx++) {
81  offset_max *= n_ary_limits[idx];
82  }
83 
84  offset_max--;
85  offset = initial_offset;
86 
87  // initialize the counter
88  initialize(initial_offset);
89 
90 }
91 
92 
93 
94 
98 void
100 
101  initialize(0);
102 
103 }
104 
105 
110 void
111 n_aryGrayCodeCounter::initialize( int64_t initial_offset ) {
112 
113  if ( initial_offset < 0 || initial_offset > offset_max ) {
114  std::string error("n_aryGrayCodeCounter::initialize: Wrong value of initial_offset");
115  throw error;
116  }
117 
118  // generate counter chain
120 
121  for (size_t idx = 0; idx < n_ary_limits.size(); idx++) {
122  counter_chain[idx] = initial_offset % n_ary_limits[idx];
123  initial_offset /= n_ary_limits[idx];
124  }
125 
126  // determine the initial gray code corresponding to the given offset
128  int parity = 0;
129  for (unsigned long long jdx = n_ary_limits.size()-1; jdx != ~0ULL; jdx--) {
130  gray_code[jdx] = parity ? n_ary_limits[jdx] - 1 - counter_chain[jdx] : counter_chain[jdx];
131  parity = parity ^ (gray_code[jdx] & 1);
132  }
133 
134 
135 
136 }
137 
138 
139 
144 GrayCode
146 
147 
148  return gray_code.copy();
149 
150 }
151 
152 
156 int
158 
159  int changed_index;
160 
161  int&& ret = next(changed_index);
162  return ret;
163 
164 }
165 
166 
171 int
172 n_aryGrayCodeCounter::next( int& changed_index) {
173 
174 
175  int value_prev, value;
176  int&& ret = next( changed_index, value_prev, value);
177  return ret;
178 
179 }
180 
187 int
188 n_aryGrayCodeCounter::next( int& changed_index, int& value_prev, int& value) {
189 
190 
191  // determine the index which is about to modify
192  changed_index = 0;
193 
194  if ( offset >= offset_max ) {
195  return 1;
196  }
197 
198 
199  bool update_counter = true;
200  int counter_chain_idx = 0;
201  while( update_counter ) {
202 
203  if ( counter_chain[counter_chain_idx] < n_ary_limits[counter_chain_idx]-1 ) {
204  counter_chain[counter_chain_idx]++;
205  update_counter = false;
206  }
207  else if ( counter_chain[counter_chain_idx] == n_ary_limits[counter_chain_idx]-1 ) {
208  counter_chain[counter_chain_idx] = 0;
209  update_counter = true;
210  }
211 
212  counter_chain_idx++;
213 
214  }
215 
216 
217  // determine the updated gray code
218  int parity = 0;
219  for (size_t jdx = n_ary_limits.size()-1; jdx != ~0ULL; jdx--) {
220  int gray_code_new_val = parity ? n_ary_limits[jdx] - 1 - counter_chain[jdx] : counter_chain[jdx];
221  parity = parity ^ (gray_code_new_val & 1);
222 
223  if ( gray_code_new_val != gray_code[jdx] ) {
224  value_prev = gray_code[jdx];
225  value = gray_code_new_val;
226  gray_code[jdx] = gray_code_new_val;
227  changed_index = jdx;
228  break;
229  }
230  }
231 
232  offset++;
233 
234  return 0;
235 
236 }
237 
238 
239 
240 void
241 n_aryGrayCodeCounter::set_offset_max( const int64_t& value ) {
242 
243 
244  offset_max = value;
245 
246 }
247 
248 
249 
GrayCode gray_code
the current gray code associated to the offset value
int64_t offset_max
the maximal offset in the counter offset = prod( n_ary_limits[i] )
n_aryGrayCodeCounter()
Default constructor of the class.
int64_t offset
the current offset in the counter 0<= offset <= offset_max
matrix_base< scalar > copy() const
Call to create a copy of the matrix.
void set_offset_max(const int64_t &value)
int next()
Iterate the counter to the next value.
void initialize()
Initialize the gray counter by zero offset.
GrayCode_base< int > GrayCode
alias for Piquassoboost state with values of type int64_t
Definition: GrayCode.h:40
int size() const
Call to get the number of the allocated elements.
GrayCode_base copy() const
Call to create a copy of the state.
GrayCode get()
Get the current gray code counter value.
matrix_base< int > n_ary_limits
The maximal value of the individual gray code elements.
matrix_base< int > counter_chain
The incremental counter chain associated to the gray code.