pyqrackising 9.3.11__py3-none-win_amd64.whl → 9.5.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 +122 -117
- {pyqrackising-9.3.11.dist-info → pyqrackising-9.5.0.dist-info}/METADATA +1 -1
- {pyqrackising-9.3.11.dist-info → pyqrackising-9.5.0.dist-info}/RECORD +6 -6
- {pyqrackising-9.3.11.dist-info → pyqrackising-9.5.0.dist-info}/WHEEL +0 -0
- {pyqrackising-9.3.11.dist-info → pyqrackising-9.5.0.dist-info}/licenses/LICENSE.md +0 -0
- {pyqrackising-9.3.11.dist-info → pyqrackising-9.5.0.dist-info}/top_level.txt +0 -0
pyqrackising/otoc.py
CHANGED
|
@@ -7,57 +7,47 @@ import sys
|
|
|
7
7
|
epsilon = opencl_context.epsilon
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
def get_otoc_hamming_distribution(J=-1.0, h=2.0, z=4, theta=0.
|
|
11
|
-
pauli_string = list(pauli_string)
|
|
12
|
-
if len(pauli_string) != n_qubits:
|
|
13
|
-
raise ValueError("OTOCS pauli_string must be same length as n_qubits! (Use 'I' for qubits that aren't changed.)")
|
|
14
|
-
|
|
10
|
+
def get_otoc_hamming_distribution(J=-1.0, h=2.0, z=4, theta=0.0, t=5, n_qubits=65, pauli_strings = ['X' + 'I' * 64]):
|
|
15
11
|
n_bias = n_qubits + 1
|
|
16
12
|
if h <= epsilon:
|
|
17
13
|
bias = np.empty(n_bias, dtype=np.float64)
|
|
18
14
|
bias[0] = 1.0
|
|
19
|
-
return
|
|
20
|
-
|
|
21
|
-
fwd = probability_by_hamming_weight(J, h, z, theta, t, n_qubits + 1)
|
|
22
|
-
rev = probability_by_hamming_weight(-J, -h, z, theta + np.pi, t, n_qubits + 1)
|
|
23
|
-
diff_theta = rev - fwd
|
|
24
|
-
|
|
25
|
-
phi = theta + np.pi / 2
|
|
26
|
-
fwd = probability_by_hamming_weight(-h, -J, z, phi, t, n_qubits + 1)
|
|
27
|
-
rev = probability_by_hamming_weight(h, J, z, phi + np.pi, t, n_qubits + 1)
|
|
28
|
-
diff_phi = rev - fwd
|
|
29
|
-
|
|
30
|
-
# Lambda (Y-axis) is at a right angle to both J and h,
|
|
31
|
-
# so there is no difference in this dimension.
|
|
32
|
-
|
|
33
|
-
diff_theta *= cycles
|
|
34
|
-
diff_phi *= cycles
|
|
35
|
-
# diff_lam = diff_phi
|
|
15
|
+
return bias
|
|
36
16
|
|
|
37
17
|
diff_z = np.zeros(n_bias, dtype=np.float64)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
18
|
+
for pauli_string in pauli_strings:
|
|
19
|
+
pauli_string = list(pauli_string)
|
|
20
|
+
if len(pauli_string) != n_qubits:
|
|
21
|
+
raise ValueError("OTOCS pauli_string must be same length as n_qubits! (Use 'I' for qubits that aren't changed.)")
|
|
22
|
+
|
|
23
|
+
fwd = probability_by_hamming_weight(J, h, z, theta, t, n_qubits + 1)
|
|
24
|
+
rev = probability_by_hamming_weight(-J, -h, z, theta + np.pi, t, n_qubits + 1)
|
|
25
|
+
diff_theta = rev - fwd
|
|
26
|
+
|
|
27
|
+
phi = theta + np.pi / 2
|
|
28
|
+
fwd = probability_by_hamming_weight(-h, -J, z, phi, t, n_qubits + 1)
|
|
29
|
+
rev = probability_by_hamming_weight(h, J, z, phi + np.pi, t, n_qubits + 1)
|
|
30
|
+
diff_phi = rev - fwd
|
|
31
|
+
|
|
32
|
+
# Lambda (Y-axis) is at a right angle to both J and h,
|
|
33
|
+
# so there is no difference in this dimension.
|
|
34
|
+
|
|
35
|
+
diff_z[0] += n_qubits
|
|
36
|
+
for b in pauli_string:
|
|
37
|
+
match b:
|
|
38
|
+
case 'X':
|
|
39
|
+
diff_z += diff_theta
|
|
40
|
+
case 'Z':
|
|
41
|
+
diff_z += diff_phi
|
|
42
|
+
case 'Y':
|
|
43
|
+
diff_z += diff_theta + diff_phi
|
|
44
|
+
case _:
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
# Normalize:
|
|
56
48
|
diff_z /= diff_z.sum()
|
|
57
|
-
diff_x /= diff_x.sum()
|
|
58
|
-
diff_y /= diff_y.sum()
|
|
59
49
|
|
|
60
|
-
return
|
|
50
|
+
return diff_z
|
|
61
51
|
|
|
62
52
|
|
|
63
53
|
@njit
|
|
@@ -73,32 +63,9 @@ def fix_cdf(hamming_prob):
|
|
|
73
63
|
return cum_prob
|
|
74
64
|
|
|
75
65
|
|
|
76
|
-
def take_sample(n_qubits, sample, m, inv_dist):
|
|
77
|
-
indices = [i for i in range(n_qubits)]
|
|
78
|
-
tot_inv_dist = 0.0
|
|
79
|
-
for i in range(n_qubits):
|
|
80
|
-
tot_inv_dist += inv_dist[i]
|
|
81
|
-
selected = []
|
|
82
|
-
for i in range(m):
|
|
83
|
-
r = tot_inv_dist * np.random.random()
|
|
84
|
-
p = 0.0
|
|
85
|
-
idx = 0
|
|
86
|
-
while p < r:
|
|
87
|
-
p += inv_dist[indices[idx]]
|
|
88
|
-
idx += 1
|
|
89
|
-
i = indices[idx]
|
|
90
|
-
del indices[idx]
|
|
91
|
-
selected.append(i)
|
|
92
|
-
tot_inv_dist -= inv_dist[i]
|
|
93
|
-
for i in selected:
|
|
94
|
-
sample |= 1 << i
|
|
95
|
-
|
|
96
|
-
return sample
|
|
97
|
-
|
|
98
|
-
|
|
99
66
|
@njit
|
|
100
67
|
def factor_width(width):
|
|
101
|
-
col_len = np.floor(np.sqrt(width))
|
|
68
|
+
col_len = int(np.floor(np.sqrt(width)))
|
|
102
69
|
while ((width // col_len) * col_len) != width:
|
|
103
70
|
col_len -= 1
|
|
104
71
|
row_len = width // col_len
|
|
@@ -120,68 +87,106 @@ def find_all_str_occurrences(main_string, sub_string):
|
|
|
120
87
|
return indices
|
|
121
88
|
|
|
122
89
|
|
|
123
|
-
def
|
|
90
|
+
def take_sample(n_qubits, sample, m, inv_dist):
|
|
91
|
+
indices = [i for i in range(n_qubits)]
|
|
92
|
+
tot_inv_dist = 0.0
|
|
93
|
+
for i in range(n_qubits):
|
|
94
|
+
tot_inv_dist += inv_dist[i]
|
|
95
|
+
selected = []
|
|
96
|
+
for i in range(m):
|
|
97
|
+
r = tot_inv_dist * np.random.random()
|
|
98
|
+
p = inv_dist[indices[0]]
|
|
99
|
+
idx = 0
|
|
100
|
+
while p < r:
|
|
101
|
+
idx += 1
|
|
102
|
+
if idx >= len(indices):
|
|
103
|
+
idx = len(indices) - 1
|
|
104
|
+
break
|
|
105
|
+
p += inv_dist[indices[idx]]
|
|
106
|
+
i = indices[idx]
|
|
107
|
+
del indices[idx]
|
|
108
|
+
selected.append(i)
|
|
109
|
+
tot_inv_dist -= inv_dist[i]
|
|
110
|
+
for i in selected:
|
|
111
|
+
sample |= 1 << i
|
|
112
|
+
|
|
113
|
+
return sample
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def get_willow_inv_dist(butterfly_idx_x, butterfly_idx_z, n_qubits, row_len, col_len):
|
|
124
117
|
inv_dist = np.zeros(n_qubits, dtype=np.float64)
|
|
125
|
-
for idx in
|
|
118
|
+
for idx in butterfly_idx_x:
|
|
119
|
+
b_row, b_col = divmod(idx, row_len)
|
|
120
|
+
for q in range(n_qubits):
|
|
121
|
+
q_row, q_col = divmod(q, row_len)
|
|
122
|
+
inv_dist[q] -= abs(q_row - b_row) + abs(q_col - b_col)
|
|
123
|
+
for idx in butterfly_idx_z:
|
|
124
|
+
b_row, b_col = divmod(idx, row_len)
|
|
126
125
|
for q in range(n_qubits):
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
q_col = q % row_len
|
|
131
|
-
dist = (q_row - b_row) ** 2 + (q_col - b_col) ** 2
|
|
132
|
-
inv_dist[q] += 1.0 / (1.0 + dist)
|
|
126
|
+
q_row, q_col = divmod(q, row_len)
|
|
127
|
+
inv_dist[q] += abs(q_row - b_row) + abs(q_col - b_col)
|
|
128
|
+
inv_dist += 1.0 - inv_dist.min()
|
|
133
129
|
|
|
134
130
|
return inv_dist
|
|
135
131
|
|
|
136
132
|
|
|
137
|
-
def
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
133
|
+
def get_inv_dist(butterfly_idx_x, butterfly_idx_z, n_qubits, row_len, col_len):
|
|
134
|
+
inv_dist = np.zeros(n_qubits, dtype=np.float64)
|
|
135
|
+
half_row = row_len >> 1
|
|
136
|
+
half_col = col_len >> 1
|
|
137
|
+
for idx in butterfly_idx_x:
|
|
138
|
+
b_row, b_col = divmod(idx, row_len)
|
|
139
|
+
for q in range(n_qubits):
|
|
140
|
+
q_row, q_col = divmod(q, row_len)
|
|
141
|
+
row_d = abs(q_row - b_row)
|
|
142
|
+
if row_d > half_row:
|
|
143
|
+
row_d = row_len - row_d
|
|
144
|
+
col_d = abs(q_col - b_col)
|
|
145
|
+
if col_d > half_col:
|
|
146
|
+
col_d = col_len - col_d
|
|
147
|
+
inv_dist[q] -= row_d + col_d
|
|
148
|
+
for idx in butterfly_idx_z:
|
|
149
|
+
b_row, b_col = divmod(idx, row_len)
|
|
150
|
+
for q in range(n_qubits):
|
|
151
|
+
q_row, q_col = divmod(q, row_len)
|
|
152
|
+
row_d = abs(q_row - b_row)
|
|
153
|
+
if row_d > half_row:
|
|
154
|
+
row_d = row_len - row_d
|
|
155
|
+
col_d = abs(q_col - b_col)
|
|
156
|
+
if col_d > half_col:
|
|
157
|
+
col_d = col_len - col_d
|
|
158
|
+
inv_dist[q] += row_d + col_d
|
|
159
|
+
inv_dist += 1.0 - inv_dist.min()
|
|
145
160
|
|
|
146
|
-
|
|
161
|
+
return inv_dist
|
|
147
162
|
|
|
148
|
-
row_len, col_len = factor_width(n_qubits)
|
|
149
|
-
p_string = "".join(pauli_string)
|
|
150
|
-
butterfly_idx_x = find_all_str_occurrences(p_string, 'X')
|
|
151
|
-
butterfly_idx_y = find_all_str_occurrences(p_string, 'Y')
|
|
152
|
-
butterfly_idx_z = find_all_str_occurrences(p_string, 'Z')
|
|
153
163
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
inv_dist_z = get_inv_dist(butterfly_idx_z, n_qubits, row_len)
|
|
164
|
+
def generate_otoc_samples(J=-1.0, h=2.0, z=4, theta=0.0, t=5, n_qubits=65, pauli_strings = ['X' + 'I' * 64], shots=100, is_orbifold=True):
|
|
165
|
+
thresholds = fix_cdf(get_otoc_hamming_distribution(J, h, z, theta, t, n_qubits, pauli_strings))
|
|
157
166
|
|
|
158
|
-
|
|
167
|
+
row_len, col_len = factor_width(n_qubits)
|
|
168
|
+
inv_dist = np.zeros(n_qubits, dtype=np.float64)
|
|
169
|
+
for pauli_string in pauli_strings:
|
|
170
|
+
butterfly_idx_x = find_all_str_occurrences(pauli_string, 'X')
|
|
171
|
+
butterfly_idx_z = find_all_str_occurrences(pauli_string, 'Z')
|
|
172
|
+
if is_orbifold:
|
|
173
|
+
inv_dist += get_inv_dist(butterfly_idx_x, butterfly_idx_z, n_qubits, row_len, col_len)
|
|
174
|
+
else:
|
|
175
|
+
inv_dist += get_willow_inv_dist(butterfly_idx_x, butterfly_idx_z, n_qubits, row_len, col_len)
|
|
176
|
+
inv_dist /= 2.0
|
|
159
177
|
|
|
160
178
|
samples = []
|
|
161
179
|
for _ in range(shots):
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
sample_3_axis[key] = take_sample(n_qubits, sample_3_axis[key], m, inv_dist[key])
|
|
174
|
-
|
|
175
|
-
sample = 0
|
|
176
|
-
j = 0
|
|
177
|
-
for i in range(n_qubits):
|
|
178
|
-
base = measurement_basis[i]
|
|
179
|
-
if base not in ['X', 'Y', 'Z']:
|
|
180
|
-
continue
|
|
181
|
-
if (sample_3_axis[base] >> i) & 1:
|
|
182
|
-
sample |= 1 << j
|
|
183
|
-
j += 1
|
|
184
|
-
|
|
185
|
-
samples.append(sample)
|
|
180
|
+
# First dimension: Hamming weight
|
|
181
|
+
m = sample_mag(thresholds)
|
|
182
|
+
if m == 0:
|
|
183
|
+
samples.append(0)
|
|
184
|
+
continue
|
|
185
|
+
if m >= n_qubits:
|
|
186
|
+
samples.append((1 << n_qubits) - 1)
|
|
187
|
+
continue
|
|
188
|
+
|
|
189
|
+
# Second dimension: permutation within Hamming weight
|
|
190
|
+
samples.append(take_sample(n_qubits, 0, m, inv_dist))
|
|
186
191
|
|
|
187
192
|
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=B70mFX7GDBR0VPAjIUFCJfqJig6QjvrPfkSyJ5w6vo0,6350
|
|
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.5.0.dist-info/licenses/LICENSE.md,sha256=fTqV5eBpeAZO0_jit8j4Ref9ikBSlHJ8xwj5TLg7gFk,7817
|
|
18
|
+
pyqrackising-9.5.0.dist-info/METADATA,sha256=bx799MMc3V0fTNSj_Yi-xs3mwJOGkZ0yat1SxxheDlE,1170
|
|
19
|
+
pyqrackising-9.5.0.dist-info/WHEEL,sha256=ZjXRCNaQ9YSypEK2TE0LRB0sy2OVXSszb4Sx1XjM99k,97
|
|
20
|
+
pyqrackising-9.5.0.dist-info/top_level.txt,sha256=bxlfGuLwzeVEI8Jm5D9HvC_WedgvvkSrpFwbGDjg-Ag,13
|
|
21
|
+
pyqrackising-9.5.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|