pyqrackising 9.3.10__py3-none-win_amd64.whl → 9.4.0__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyqrackising might be problematic. Click here for more details.

pyqrackising/otoc.py CHANGED
@@ -32,32 +32,23 @@ def get_otoc_hamming_distribution(J=-1.0, h=2.0, z=4, theta=0.174532925199432957
32
32
 
33
33
  diff_theta *= cycles
34
34
  diff_phi *= cycles
35
- # diff_lam = diff_phi
36
35
 
37
36
  diff_z = np.zeros(n_bias, dtype=np.float64)
38
- diff_x = np.zeros(n_bias, dtype=np.float64)
39
- diff_y = np.zeros(n_bias, dtype=np.float64)
40
37
  for b in pauli_string:
41
38
  match b:
42
39
  case 'X':
43
40
  diff_z += diff_theta
44
- diff_y += diff_phi
45
41
  case 'Z':
46
- diff_x += diff_phi
47
- diff_y += diff_theta
42
+ diff_z += diff_phi
48
43
  case 'Y':
49
- diff_z += diff_theta
50
- diff_x += diff_phi
44
+ diff_z += diff_theta + diff_phi
45
+ case _:
46
+ pass
51
47
 
52
48
  diff_z[0] += n_qubits
53
- diff_x[0] += n_qubits
54
- diff_y[0] += n_qubits
55
-
56
49
  diff_z /= diff_z.sum()
57
- diff_x /= diff_x.sum()
58
- diff_y /= diff_y.sum()
59
50
 
60
- return { 'X': diff_x, 'Y': diff_y, 'Z': diff_z }
51
+ return diff_z
61
52
 
62
53
 
63
54
  @njit
@@ -73,29 +64,46 @@ def fix_cdf(hamming_prob):
73
64
  return cum_prob
74
65
 
75
66
 
76
- def take_all(b, basis, sample):
77
- for i in range(len(basis)):
78
- if basis[i] == b:
79
- sample |= (1 << i)
67
+ @njit
68
+ def factor_width(width):
69
+ col_len = int(np.floor(np.sqrt(width)))
70
+ while ((width // col_len) * col_len) != width:
71
+ col_len -= 1
72
+ row_len = width // col_len
80
73
 
81
- return sample
74
+ return row_len, col_len
82
75
 
83
76
 
84
- def take_sample(b, basis, sample, m, inv_dist):
77
+ # Provided by Google search AI
78
+ def find_all_str_occurrences(main_string, sub_string):
85
79
  indices = []
80
+ start_index = 0
81
+ while True:
82
+ index = main_string.find(sub_string, start_index)
83
+ if index == -1:
84
+ break
85
+ indices.append(index)
86
+ start_index = index + 1 # Start searching after the found occurrence
87
+
88
+ return indices
89
+
90
+
91
+ def take_sample(n_qubits, sample, m, inv_dist):
92
+ indices = [i for i in range(n_qubits)]
86
93
  tot_inv_dist = 0.0
87
- for i in range(len(basis)):
88
- if basis[i] == b:
89
- indices.append(i)
90
- tot_inv_dist += inv_dist[i]
94
+ for i in range(n_qubits):
95
+ tot_inv_dist += inv_dist[i]
91
96
  selected = []
92
97
  for i in range(m):
93
98
  r = tot_inv_dist * np.random.random()
94
- p = 0.0
99
+ p = inv_dist[indices[0]]
95
100
  idx = 0
96
101
  while p < r:
97
- p += inv_dist[indices[idx]]
98
102
  idx += 1
103
+ if idx >= len(indices):
104
+ idx = len(indices) - 1
105
+ break
106
+ p += inv_dist[indices[idx]]
99
107
  i = indices[idx]
100
108
  del indices[idx]
101
109
  selected.append(i)
@@ -106,133 +114,83 @@ def take_sample(b, basis, sample, m, inv_dist):
106
114
  return sample
107
115
 
108
116
 
109
- @njit
110
- def factor_width(width):
111
- col_len = np.floor(np.sqrt(width))
112
- while ((width // col_len) * col_len) != width:
113
- col_len -= 1
114
- row_len = width // col_len
115
-
116
- return row_len, col_len
117
-
118
-
119
- # Provided by Google search AI
120
- def find_all_str_occurrences(main_string, sub_string):
121
- indices = []
122
- start_index = 0
123
- while True:
124
- index = main_string.find(sub_string, start_index)
125
- if index == -1:
126
- break
127
- indices.append(index)
128
- start_index = index + 1 # Start searching after the found occurrence
117
+ def get_willow_inv_dist(butterfly_idx_x, butterfly_idx_z, n_qubits, row_len, col_len):
118
+ inv_dist = np.zeros(n_qubits, dtype=np.float64)
119
+ for idx in butterfly_idx_x:
120
+ b_row, b_col = divmod(idx, row_len)
121
+ for q in range(n_qubits):
122
+ q_row, q_col = divmod(q, row_len)
123
+ inv_dist[q] -= abs(q_row - b_row) + abs(q_col - b_col)
124
+ for idx in butterfly_idx_z:
125
+ b_row, b_col = divmod(idx, row_len)
126
+ for q in range(n_qubits):
127
+ q_row, q_col = divmod(q, row_len)
128
+ inv_dist[q] += abs(q_row - b_row) + abs(q_col - b_col)
129
+ inv_dist += 1.0 - inv_dist.min()
129
130
 
130
- return indices
131
+ return inv_dist
131
132
 
132
133
 
133
- def get_inv_dist(butterfly_idx, n_qubits, row_len):
134
+ def get_inv_dist(butterfly_idx_x, butterfly_idx_z, n_qubits, row_len, col_len):
134
135
  inv_dist = np.zeros(n_qubits, dtype=np.float64)
135
- for idx in butterfly_idx:
136
+ half_row = row_len >> 1
137
+ half_col = col_len >> 1
138
+ for idx in butterfly_idx_x:
139
+ b_row, b_col = divmod(idx, row_len)
140
+ for q in range(n_qubits):
141
+ q_row, q_col = divmod(q, row_len)
142
+ row_d = abs(q_row - b_row)
143
+ if row_d > half_row:
144
+ row_d = row_len - row_d
145
+ col_d = abs(q_col - b_col)
146
+ if col_d > half_col:
147
+ col_d = col_len - col_d
148
+ inv_dist[q] -= row_d + col_d
149
+ for idx in butterfly_idx_z:
150
+ b_row, b_col = divmod(idx, row_len)
136
151
  for q in range(n_qubits):
137
- b_row = idx // row_len
138
- b_col = idx % row_len
139
- q_row = q // row_len
140
- q_col = q % row_len
141
- dist = (q_row - b_row) ** 2 + (q_col - b_col) ** 2
142
- if dist > 0:
143
- inv_dist[q] += 1.0 / dist
152
+ q_row, q_col = divmod(q, row_len)
153
+ row_d = abs(q_row - b_row)
154
+ if row_d > half_row:
155
+ row_d = row_len - row_d
156
+ col_d = abs(q_col - b_col)
157
+ if col_d > half_col:
158
+ col_d = col_len - col_d
159
+ inv_dist[q] += row_d + col_d
160
+ inv_dist += 1.0 - inv_dist.min()
144
161
 
145
162
  return inv_dist
146
163
 
147
164
 
148
- def generate_otoc_samples(J=-1.0, h=2.0, z=4, theta=0.174532925199432957, t=5, n_qubits=56, cycles=1, pauli_string = 'X' + 'I' * 55, shots=100, measurement_basis='Z' * 56):
165
+ def generate_otoc_samples(J=-1.0, h=2.0, z=4, theta=0.174532925199432957, t=5, n_qubits=56, cycles=1, pauli_string = 'X' + 'I' * 55, shots=100, is_orbifold=True):
149
166
  pauli_string = list(pauli_string)
150
167
  if len(pauli_string) != n_qubits:
151
168
  raise ValueError("OTOC pauli_string must be same length as n_qubits! (Use 'I' for qubits that aren't changed.)")
152
169
 
153
- measurement_basis = list(measurement_basis)
154
- if len(measurement_basis) != n_qubits:
155
- raise ValueError("OTOC measurement_basis must be same length as n_qubits! (Use 'I' for excluded qubits.)")
156
-
157
- basis_x, basis_y, basis_z = [], [], []
158
- for b in pauli_string:
159
- if b == 'Z':
160
- basis_z.append('X')
161
- basis_y.append('I')
162
- basis_x.append('Z')
163
- elif b == 'X':
164
- basis_z.append('Z')
165
- basis_y.append('I')
166
- basis_x.append('X')
167
- elif b == 'Y':
168
- basis_z.append('I')
169
- basis_y.append('Z')
170
- basis_x.append('I')
171
- else:
172
- basis_z.append('I')
173
- basis_y.append('I')
174
- basis_x.append('I')
175
-
176
- bases = { 'X': basis_x, 'Y': basis_y, 'Z': basis_z }
177
- thresholds = { key: fix_cdf(value) for key, value in get_otoc_hamming_distribution(J, h, z, theta, t, n_qubits, cycles, pauli_string).items() }
170
+ thresholds = fix_cdf(get_otoc_hamming_distribution(J, h, z, theta, t, n_qubits, cycles, pauli_string))
178
171
 
179
172
  row_len, col_len = factor_width(n_qubits)
180
173
  p_string = "".join(pauli_string)
181
174
  butterfly_idx_x = find_all_str_occurrences(p_string, 'X')
182
- butterfly_idx_y = find_all_str_occurrences(p_string, 'Y')
183
175
  butterfly_idx_z = find_all_str_occurrences(p_string, 'Z')
184
176
 
185
- inv_dist_x = get_inv_dist(butterfly_idx_x, n_qubits, row_len)
186
- inv_dist_y = get_inv_dist(butterfly_idx_y, n_qubits, row_len)
187
- inv_dist_z = get_inv_dist(butterfly_idx_z, n_qubits, row_len)
188
-
189
- inv_dist = { 'X': inv_dist_x, 'Y': inv_dist_y, 'Z': inv_dist_z }
177
+ if is_orbifold:
178
+ inv_dist = get_inv_dist(butterfly_idx_x, butterfly_idx_z, n_qubits, row_len, col_len)
179
+ else:
180
+ inv_dist = get_willow_inv_dist(butterfly_idx_x, butterfly_idx_z, n_qubits, row_len, col_len)
190
181
 
191
182
  samples = []
192
183
  for _ in range(shots):
193
- sample_3_axis = { 'X': 0, 'Y': 0, 'Z': 0 }
194
- for key, value in thresholds.items():
195
- basis = bases[key]
196
-
197
- # First dimension: Hamming weight
198
- m = sample_mag(value)
199
- if m == 0:
200
- continue
201
- if m >= n_qubits:
202
- sample_3_axis[key] = (1 << n_qubits) - 1
203
- continue
204
-
205
- # Second dimension: permutation within Hamming weight
206
- z_count = basis.count('Z')
207
- if z_count > m:
208
- sample_3_axis[key] = take_sample('Z', basis, sample_3_axis[key], m, inv_dist[key])
209
- continue
210
- m -= z_count
211
- sample_3_axis[key] = take_all('Z', basis, sample_3_axis[key])
212
- if m == 0:
213
- continue
214
-
215
- i_count = basis.count('I')
216
- if i_count > m:
217
- sample_3_axis[key] = take_sample('I', basis, sample_3_axis[key], m, inv_dist[key])
218
- continue
219
- m -= i_count
220
- sample_3_axis[key] = take_all('I', basis, sample_3_axis[key])
221
- if m == 0:
222
- continue
223
-
224
- sample_3_axis[key] = take_sample('X', basis, sample_3_axis[key], m, inv_dist[key])
225
-
226
- sample = 0
227
- j = 0
228
- for i in range(n_qubits):
229
- base = measurement_basis[i]
230
- if base not in ['X', 'Y', 'Z']:
231
- continue
232
- if (sample_3_axis[base] >> i) & 1:
233
- sample |= 1 << j
234
- j += 1
235
-
236
- samples.append(sample)
184
+ # First dimension: Hamming weight
185
+ m = sample_mag(thresholds)
186
+ if m == 0:
187
+ samples.append(0)
188
+ continue
189
+ if m >= n_qubits:
190
+ samples.append((1 << n_qubits) - 1)
191
+ continue
192
+
193
+ # Second dimension: permutation within Hamming weight
194
+ samples.append(take_sample(n_qubits, 0, m, inv_dist))
237
195
 
238
196
  return samples
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqrackising
3
- Version: 9.3.10
3
+ Version: 9.4.0
4
4
  Summary: Fast MAXCUT, TSP, and sampling heuristics from near-ideal transverse field Ising model (TFIM)
5
5
  Home-page: https://github.com/vm6502q/PyQrackIsing
6
6
  Author: Dan Strano
@@ -6,7 +6,7 @@ pyqrackising/maxcut_tfim.py,sha256=U1nNjyfMS48TtTQk7TRf5_VF3pVPfAcZEa2awc2nR8k,1
6
6
  pyqrackising/maxcut_tfim_sparse.py,sha256=eenJNSEwRvgwACfKoH0tj6rpn7uqH6nNTBuxUPh_lDg,11941
7
7
  pyqrackising/maxcut_tfim_streaming.py,sha256=FkBsRoXSRhv4gUeN9O7Ivx54oxq_SqiCDKnYsyxU4bs,6664
8
8
  pyqrackising/maxcut_tfim_util.py,sha256=nMLrbvDMsCtVgbS4vbRNSZYpdne5YzdifjlQbbWmKjU,16935
9
- pyqrackising/otoc.py,sha256=-SGs5Y2slNsqEURGPQv-uI5bIz2JOejY4iEckMRf0Sw,7674
9
+ pyqrackising/otoc.py,sha256=YGDjsM5J6p_tmKTaeeZMfxcV9rJ1k7oWfT22w7DgAXk,6428
10
10
  pyqrackising/spin_glass_solver.py,sha256=tgmdJ6b1TetnFM--QEzOZFsNkquQYRVYiHVSzIGYvMI,14207
11
11
  pyqrackising/spin_glass_solver_sparse.py,sha256=cmXfAR43n1beRk4LaQbwfrQWkkhMPzPXpdK2T1HhQrk,15159
12
12
  pyqrackising/spin_glass_solver_streaming.py,sha256=joQLMKotgjQMwbG0msv_AookiWva_AiVBIR0Xr1Unho,10310
@@ -14,8 +14,8 @@ pyqrackising/tfim_magnetization.py,sha256=On1MhCNGGHRxJFRmCOpMcdqQJiy25gWkjz0Ka8
14
14
  pyqrackising/tfim_square_magnetization.py,sha256=9uJCT8ytyufcGFrZiignjCkWJr9UcP44sAAy0BIBw34,531
15
15
  pyqrackising/tsp.py,sha256=k8VK6fKw_niR-dVz8MyOT7LedABIwTzcSkhTOircYBg,64290
16
16
  pyqrackising/tsp_maxcut.py,sha256=lEDruz5lhjVu0ufvH5VaMJW3_nohO-rEijJJabEtuSU,10084
17
- pyqrackising-9.3.10.dist-info/licenses/LICENSE.md,sha256=fTqV5eBpeAZO0_jit8j4Ref9ikBSlHJ8xwj5TLg7gFk,7817
18
- pyqrackising-9.3.10.dist-info/METADATA,sha256=MjpwA4DmpEtEYrlPAYXCe1ixGcAz629s44q095-tRIo,1171
19
- pyqrackising-9.3.10.dist-info/WHEEL,sha256=ZjXRCNaQ9YSypEK2TE0LRB0sy2OVXSszb4Sx1XjM99k,97
20
- pyqrackising-9.3.10.dist-info/top_level.txt,sha256=bxlfGuLwzeVEI8Jm5D9HvC_WedgvvkSrpFwbGDjg-Ag,13
21
- pyqrackising-9.3.10.dist-info/RECORD,,
17
+ pyqrackising-9.4.0.dist-info/licenses/LICENSE.md,sha256=fTqV5eBpeAZO0_jit8j4Ref9ikBSlHJ8xwj5TLg7gFk,7817
18
+ pyqrackising-9.4.0.dist-info/METADATA,sha256=4JhSdjeWRNgMpmJF78y5JupPS-V_6CWl8bzL3sEr5xE,1170
19
+ pyqrackising-9.4.0.dist-info/WHEEL,sha256=ZjXRCNaQ9YSypEK2TE0LRB0sy2OVXSszb4Sx1XjM99k,97
20
+ pyqrackising-9.4.0.dist-info/top_level.txt,sha256=bxlfGuLwzeVEI8Jm5D9HvC_WedgvvkSrpFwbGDjg-Ag,13
21
+ pyqrackising-9.4.0.dist-info/RECORD,,