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 +90 -132
- {pyqrackising-9.3.10.dist-info → pyqrackising-9.4.0.dist-info}/METADATA +1 -1
- {pyqrackising-9.3.10.dist-info → pyqrackising-9.4.0.dist-info}/RECORD +6 -6
- {pyqrackising-9.3.10.dist-info → pyqrackising-9.4.0.dist-info}/WHEEL +0 -0
- {pyqrackising-9.3.10.dist-info → pyqrackising-9.4.0.dist-info}/licenses/LICENSE.md +0 -0
- {pyqrackising-9.3.10.dist-info → pyqrackising-9.4.0.dist-info}/top_level.txt +0 -0
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
|
-
|
|
47
|
-
diff_y += diff_theta
|
|
42
|
+
diff_z += diff_phi
|
|
48
43
|
case 'Y':
|
|
49
|
-
diff_z += diff_theta
|
|
50
|
-
|
|
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
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
|
74
|
+
return row_len, col_len
|
|
82
75
|
|
|
83
76
|
|
|
84
|
-
|
|
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(
|
|
88
|
-
|
|
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
|
|
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
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
|
131
|
+
return inv_dist
|
|
131
132
|
|
|
132
133
|
|
|
133
|
-
def get_inv_dist(
|
|
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
|
-
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if
|
|
143
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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
|
|
@@ -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
|
|
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.
|
|
18
|
-
pyqrackising-9.
|
|
19
|
-
pyqrackising-9.
|
|
20
|
-
pyqrackising-9.
|
|
21
|
-
pyqrackising-9.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|