pyqrackising 9.5.11__py3-none-manylinux_2_39_x86_64.whl → 9.7.1__py3-none-manylinux_2_39_x86_64.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.
- pyqrackising/maxcut_tfim.py +65 -15
- pyqrackising/maxcut_tfim_sparse.py +75 -13
- pyqrackising/maxcut_tfim_streaming.py +63 -12
- pyqrackising/maxcut_tfim_util.py +16 -12
- pyqrackising/otoc.py +0 -2
- pyqrackising/spin_glass_solver.py +18 -4
- pyqrackising/spin_glass_solver_sparse.py +18 -4
- pyqrackising/spin_glass_solver_streaming.py +18 -4
- {pyqrackising-9.5.11.dist-info → pyqrackising-9.7.1.dist-info}/METADATA +1 -1
- pyqrackising-9.7.1.dist-info/RECORD +21 -0
- pyqrackising-9.5.11.dist-info/RECORD +0 -21
- {pyqrackising-9.5.11.dist-info → pyqrackising-9.7.1.dist-info}/WHEEL +0 -0
- {pyqrackising-9.5.11.dist-info → pyqrackising-9.7.1.dist-info}/licenses/LICENSE.md +0 -0
- {pyqrackising-9.5.11.dist-info → pyqrackising-9.7.1.dist-info}/top_level.txt +0 -0
pyqrackising/maxcut_tfim.py
CHANGED
|
@@ -3,7 +3,7 @@ import numpy as np
|
|
|
3
3
|
from numba import njit, prange
|
|
4
4
|
import os
|
|
5
5
|
|
|
6
|
-
from .maxcut_tfim_util import compute_cut, compute_energy, convert_bool_to_uint, get_cut, get_cut_base, init_thresholds, make_G_m_buf, make_theta_buf, maxcut_hamming_cdf, opencl_context, sample_mag, setup_opencl, bit_pick
|
|
6
|
+
from .maxcut_tfim_util import compute_cut, compute_energy, convert_bool_to_uint, get_cut, get_cut_base, heuristic_threshold, init_thresholds, make_G_m_buf, make_theta_buf, maxcut_hamming_cdf, opencl_context, sample_mag, setup_opencl, bit_pick
|
|
7
7
|
|
|
8
8
|
IS_OPENCL_AVAILABLE = True
|
|
9
9
|
try:
|
|
@@ -22,6 +22,9 @@ def update_repulsion_choice(G_m, weights, n, used, node, repulsion_base):
|
|
|
22
22
|
# Select node
|
|
23
23
|
used[node] = True
|
|
24
24
|
|
|
25
|
+
if abs(1.0 - repulsion_base) <= epsilon:
|
|
26
|
+
return
|
|
27
|
+
|
|
25
28
|
# Repulsion: penalize neighbors
|
|
26
29
|
for nbr in range(n):
|
|
27
30
|
if used[nbr]:
|
|
@@ -239,6 +242,60 @@ def run_cut_opencl(best_energy, samples, G_m_buf, is_segmented, local_size, glob
|
|
|
239
242
|
return samples[max_index_host[best_x]], energy
|
|
240
243
|
|
|
241
244
|
|
|
245
|
+
@njit
|
|
246
|
+
def exact_maxcut(G):
|
|
247
|
+
"""Brute-force exact MAXCUT solver using Numba JIT."""
|
|
248
|
+
n = G.shape[0]
|
|
249
|
+
max_cut = -1.0
|
|
250
|
+
best_mask = 0
|
|
251
|
+
|
|
252
|
+
# Enumerate all 2^n possible bitstrings
|
|
253
|
+
for mask in range(1 << n):
|
|
254
|
+
cut = 0.0
|
|
255
|
+
for i in range(n):
|
|
256
|
+
bi = (mask >> i) & 1
|
|
257
|
+
for j in range(i + 1, n):
|
|
258
|
+
if bi != ((mask >> j) & 1):
|
|
259
|
+
cut += G[i, j]
|
|
260
|
+
if cut > max_cut:
|
|
261
|
+
max_cut = cut
|
|
262
|
+
best_mask = mask
|
|
263
|
+
|
|
264
|
+
# Reconstruct best bitstring
|
|
265
|
+
best_bits = np.zeros(n, dtype=np.bool_)
|
|
266
|
+
for i in range(n):
|
|
267
|
+
best_bits[i] = (best_mask >> i) & 1
|
|
268
|
+
|
|
269
|
+
return best_bits, max_cut
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
@njit
|
|
273
|
+
def exact_spin_glass(G):
|
|
274
|
+
"""Brute-force exact spin-glass solver using Numba JIT."""
|
|
275
|
+
n = G.shape[0]
|
|
276
|
+
max_cut = -1.0
|
|
277
|
+
best_mask = 0
|
|
278
|
+
|
|
279
|
+
# Enumerate all 2^n possible bitstrings
|
|
280
|
+
for mask in range(1 << n):
|
|
281
|
+
cut = 0.0
|
|
282
|
+
for i in range(n):
|
|
283
|
+
bi = (mask >> i) & 1
|
|
284
|
+
for j in range(i + 1, n):
|
|
285
|
+
val = G[i, j]
|
|
286
|
+
cut += val if bi == ((mask >> j) & 1) else -val
|
|
287
|
+
if cut > max_cut:
|
|
288
|
+
max_cut = cut
|
|
289
|
+
best_mask = mask
|
|
290
|
+
|
|
291
|
+
# Reconstruct best bitstring
|
|
292
|
+
best_bits = np.zeros(n, dtype=np.bool_)
|
|
293
|
+
for i in range(n):
|
|
294
|
+
best_bits[i] = (best_mask >> i) & 1
|
|
295
|
+
|
|
296
|
+
return best_bits, max_cut
|
|
297
|
+
|
|
298
|
+
|
|
242
299
|
def maxcut_tfim(
|
|
243
300
|
G,
|
|
244
301
|
quality=None,
|
|
@@ -261,22 +318,15 @@ def maxcut_tfim(
|
|
|
261
318
|
|
|
262
319
|
n_qubits = len(G_m)
|
|
263
320
|
|
|
264
|
-
if n_qubits <
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if n_qubits == 0:
|
|
269
|
-
return "", 0, (empty, empty.copy())
|
|
270
|
-
|
|
271
|
-
if n_qubits == 1:
|
|
272
|
-
return "0", 0, (nodes, empty)
|
|
321
|
+
if n_qubits < heuristic_threshold:
|
|
322
|
+
best_solution, best_value = exact_spin_glass(G_m) if is_spin_glass else exact_maxcut(G_m)
|
|
323
|
+
bit_string, l, r = get_cut(best_solution, nodes, n_qubits)
|
|
273
324
|
|
|
274
|
-
if
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
return "00", 0, (nodes, empty)
|
|
325
|
+
if best_value < 0.0:
|
|
326
|
+
# Best cut is trivial partition, all/empty
|
|
327
|
+
return '0' * n_qubits, 0.0, (nodes, [])
|
|
278
328
|
|
|
279
|
-
|
|
329
|
+
return bit_string, best_value, (l, r)
|
|
280
330
|
|
|
281
331
|
if quality is None:
|
|
282
332
|
quality = 6
|
|
@@ -3,7 +3,7 @@ import numpy as np
|
|
|
3
3
|
from numba import njit, prange
|
|
4
4
|
import os
|
|
5
5
|
|
|
6
|
-
from .maxcut_tfim_util import binary_search, compute_cut_sparse, compute_energy_sparse, convert_bool_to_uint, get_cut, get_cut_base, init_thresholds, make_G_m_csr_buf, make_theta_buf, maxcut_hamming_cdf, opencl_context, sample_mag, setup_opencl, bit_pick, to_scipy_sparse_upper_triangular
|
|
6
|
+
from .maxcut_tfim_util import binary_search, compute_cut_sparse, compute_energy_sparse, convert_bool_to_uint, get_cut, get_cut_base, heuristic_threshold_sparse, init_thresholds, make_G_m_csr_buf, make_theta_buf, maxcut_hamming_cdf, opencl_context, sample_mag, setup_opencl, bit_pick, to_scipy_sparse_upper_triangular
|
|
7
7
|
|
|
8
8
|
IS_OPENCL_AVAILABLE = True
|
|
9
9
|
try:
|
|
@@ -22,6 +22,9 @@ def update_repulsion_choice(G_data, G_rows, G_cols, weights, n, used, node, repu
|
|
|
22
22
|
# Select node
|
|
23
23
|
used[node] = True
|
|
24
24
|
|
|
25
|
+
if abs(1.0 - repulsion_base) <= epsilon:
|
|
26
|
+
return
|
|
27
|
+
|
|
25
28
|
# Repulsion: penalize neighbors
|
|
26
29
|
for j in range(G_rows[node], G_rows[node + 1]):
|
|
27
30
|
nbr = G_cols[j]
|
|
@@ -253,6 +256,69 @@ def run_cut_opencl(best_energy, samples, G_data_buf, G_rows_buf, G_cols_buf, is_
|
|
|
253
256
|
return samples[max_index_host[best_x]], energy
|
|
254
257
|
|
|
255
258
|
|
|
259
|
+
@njit
|
|
260
|
+
def exact_maxcut(G_data, G_rows, G_cols):
|
|
261
|
+
"""Brute-force exact MAXCUT solver using Numba JIT."""
|
|
262
|
+
n = G_rows.shape[0] - 1
|
|
263
|
+
max_cut = -1.0
|
|
264
|
+
best_mask = 0
|
|
265
|
+
|
|
266
|
+
# Enumerate all 2^n possible bitstrings
|
|
267
|
+
for mask in range(1 << n):
|
|
268
|
+
cut = 0.0
|
|
269
|
+
for i in range(n):
|
|
270
|
+
bi = (mask >> i) & 1
|
|
271
|
+
for j in range(i + 1, n):
|
|
272
|
+
if bi != ((mask >> j) & 1):
|
|
273
|
+
u, v = (i, j) if i < j else (j, i)
|
|
274
|
+
start = G_rows[u]
|
|
275
|
+
end = G_rows[u + 1]
|
|
276
|
+
k = binary_search(G_cols[start:end], v) + start
|
|
277
|
+
if k < end:
|
|
278
|
+
cut += G_data[k]
|
|
279
|
+
if cut > max_cut:
|
|
280
|
+
max_cut = cut
|
|
281
|
+
best_mask = mask
|
|
282
|
+
|
|
283
|
+
# Reconstruct best bitstring
|
|
284
|
+
best_bits = np.zeros(n, dtype=np.bool_)
|
|
285
|
+
for i in range(n):
|
|
286
|
+
best_bits[i] = (best_mask >> i) & 1
|
|
287
|
+
|
|
288
|
+
return best_bits, max_cut
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
@njit
|
|
292
|
+
def exact_spin_glass(G_data, G_rows, G_cols):
|
|
293
|
+
"""Brute-force exact spin-glass solver using Numba JIT."""
|
|
294
|
+
n = G_rows.shape[0] - 1
|
|
295
|
+
max_cut = -1.0
|
|
296
|
+
best_mask = 0
|
|
297
|
+
|
|
298
|
+
# Enumerate all 2^n possible bitstrings
|
|
299
|
+
for mask in range(1 << n):
|
|
300
|
+
cut = 0.0
|
|
301
|
+
for i in range(n):
|
|
302
|
+
bi = (mask >> i) & 1
|
|
303
|
+
for j in range(i + 1, n):
|
|
304
|
+
u, v = (i, j) if i < j else (j, i)
|
|
305
|
+
start = G_rows[u]
|
|
306
|
+
end = G_rows[u + 1]
|
|
307
|
+
k = binary_search(G_cols[start:end], v) + start
|
|
308
|
+
if k < end:
|
|
309
|
+
val = G_data[k]
|
|
310
|
+
cut += val if bi == ((mask >> j) & 1) else -val
|
|
311
|
+
if cut > max_cut:
|
|
312
|
+
max_cut = cut
|
|
313
|
+
best_mask = mask
|
|
314
|
+
|
|
315
|
+
# Reconstruct best bitstring
|
|
316
|
+
best_bits = np.zeros(n, dtype=np.bool_)
|
|
317
|
+
for i in range(n):
|
|
318
|
+
best_bits[i] = (best_mask >> i) & 1
|
|
319
|
+
|
|
320
|
+
return best_bits, max_cut
|
|
321
|
+
|
|
256
322
|
|
|
257
323
|
def maxcut_tfim_sparse(
|
|
258
324
|
G,
|
|
@@ -278,19 +344,15 @@ def maxcut_tfim_sparse(
|
|
|
278
344
|
nodes = list(range(n_qubits))
|
|
279
345
|
G_m = G
|
|
280
346
|
|
|
281
|
-
if n_qubits <
|
|
282
|
-
if
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if n_qubits == 1:
|
|
286
|
-
return "0", 0, (nodes, [])
|
|
347
|
+
if n_qubits < heuristic_threshold_sparse:
|
|
348
|
+
best_solution, best_value = exact_spin_glass(G_m.data, G_m.indptr, G_m.indices) if is_spin_glass else exact_maxcut(G_m.data, G_m.indptr, G_m.indices)
|
|
349
|
+
bit_string, l, r = get_cut(best_solution, nodes, n_qubits)
|
|
287
350
|
|
|
288
|
-
if
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
return "00", 0, (nodes, [])
|
|
351
|
+
if best_value < 0.0:
|
|
352
|
+
# Best cut is trivial partition, all/empty
|
|
353
|
+
return '0' * n_qubits, 0.0, (nodes, [])
|
|
292
354
|
|
|
293
|
-
|
|
355
|
+
return bit_string, best_value, (l, r)
|
|
294
356
|
|
|
295
357
|
if quality is None:
|
|
296
358
|
quality = 6
|
|
@@ -324,7 +386,7 @@ def maxcut_tfim_sparse(
|
|
|
324
386
|
best_solution, best_value = sample_for_opencl(G_m.data, G_m.indptr, G_m.indices, G_data_buf, G_rows_buf, G_cols_buf, shots, cum_prob, repulsion_base, is_spin_glass, is_segmented, segment_size, theta_segment_size)
|
|
325
387
|
else:
|
|
326
388
|
thread_count = os.cpu_count() ** 2
|
|
327
|
-
best_solution, best_value = sample_measurement(
|
|
389
|
+
best_solution, best_value = sample_measurement(G_m.data, G_m.indptr, G_m.indices, shots, thread_count, cum_prob, repulsion_base, is_spin_glass)
|
|
328
390
|
|
|
329
391
|
bit_string, l, r = get_cut(best_solution, nodes, n_qubits)
|
|
330
392
|
|
|
@@ -3,7 +3,7 @@ import numpy as np
|
|
|
3
3
|
from numba import njit, prange
|
|
4
4
|
import os
|
|
5
5
|
|
|
6
|
-
from .maxcut_tfim_util import compute_cut_streaming, compute_energy_streaming, get_cut, get_cut_base, init_thresholds, maxcut_hamming_cdf, opencl_context, sample_mag, bit_pick
|
|
6
|
+
from .maxcut_tfim_util import compute_cut_streaming, compute_energy_streaming, get_cut, get_cut_base, heuristic_threshold, init_thresholds, maxcut_hamming_cdf, opencl_context, sample_mag, bit_pick
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
epsilon = opencl_context.epsilon
|
|
@@ -15,6 +15,9 @@ def update_repulsion_choice(G_func, nodes, weights, n, used, node, repulsion_bas
|
|
|
15
15
|
# Select node
|
|
16
16
|
used[node] = True
|
|
17
17
|
|
|
18
|
+
if abs(1.0 - repulsion_base) <= epsilon:
|
|
19
|
+
return
|
|
20
|
+
|
|
18
21
|
# Repulsion: penalize neighbors
|
|
19
22
|
for nbr in range(n):
|
|
20
23
|
if used[nbr]:
|
|
@@ -145,6 +148,58 @@ def find_G_min(G_func, nodes, n_nodes):
|
|
|
145
148
|
return G_min
|
|
146
149
|
|
|
147
150
|
|
|
151
|
+
@njit
|
|
152
|
+
def exact_maxcut(G_func, n):
|
|
153
|
+
"""Brute-force exact MAXCUT solver using Numba JIT."""
|
|
154
|
+
max_cut = -1.0
|
|
155
|
+
best_mask = 0
|
|
156
|
+
|
|
157
|
+
# Enumerate all 2^n possible bitstrings
|
|
158
|
+
for mask in range(1 << n):
|
|
159
|
+
cut = 0.0
|
|
160
|
+
for i in range(n):
|
|
161
|
+
bi = (mask >> i) & 1
|
|
162
|
+
for j in range(i + 1, n):
|
|
163
|
+
if bi != ((mask >> j) & 1):
|
|
164
|
+
cut += G_func(i, j)
|
|
165
|
+
if cut > max_cut:
|
|
166
|
+
max_cut = cut
|
|
167
|
+
best_mask = mask
|
|
168
|
+
|
|
169
|
+
# Reconstruct best bitstring
|
|
170
|
+
best_bits = np.zeros(n, dtype=np.bool_)
|
|
171
|
+
for i in range(n):
|
|
172
|
+
best_bits[i] = (best_mask >> i) & 1
|
|
173
|
+
|
|
174
|
+
return best_bits, max_cut
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@njit
|
|
178
|
+
def exact_spin_glass(G_func, n):
|
|
179
|
+
"""Brute-force exact spin-glass solver using Numba JIT."""
|
|
180
|
+
max_cut = -1.0
|
|
181
|
+
best_mask = 0
|
|
182
|
+
|
|
183
|
+
# Enumerate all 2^n possible bitstrings
|
|
184
|
+
for mask in range(1 << n):
|
|
185
|
+
cut = 0.0
|
|
186
|
+
for i in range(n):
|
|
187
|
+
bi = (mask >> i) & 1
|
|
188
|
+
for j in range(i + 1, n):
|
|
189
|
+
val = G_func(i, j)
|
|
190
|
+
cut += val if bi == ((mask >> j) & 1) else -val
|
|
191
|
+
if cut > max_cut:
|
|
192
|
+
max_cut = cut
|
|
193
|
+
best_mask = mask
|
|
194
|
+
|
|
195
|
+
# Reconstruct best bitstring
|
|
196
|
+
best_bits = np.zeros(n, dtype=np.bool_)
|
|
197
|
+
for i in range(n):
|
|
198
|
+
best_bits[i] = (best_mask >> i) & 1
|
|
199
|
+
|
|
200
|
+
return best_bits, max_cut
|
|
201
|
+
|
|
202
|
+
|
|
148
203
|
def maxcut_tfim_streaming(
|
|
149
204
|
G_func,
|
|
150
205
|
nodes,
|
|
@@ -158,19 +213,15 @@ def maxcut_tfim_streaming(
|
|
|
158
213
|
wgs = opencl_context.work_group_size
|
|
159
214
|
n_qubits = len(nodes)
|
|
160
215
|
|
|
161
|
-
if n_qubits <
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if n_qubits == 1:
|
|
166
|
-
return "0", 0, (nodes, [])
|
|
216
|
+
if n_qubits < heuristic_threshold:
|
|
217
|
+
best_solution, best_value = exact_spin_glass(G_func, n_qubits) if is_spin_glass else exact_maxcut(G_func, n_qubits)
|
|
218
|
+
bit_string, l, r = get_cut(best_solution, nodes, n_qubits)
|
|
167
219
|
|
|
168
|
-
if
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
return "00", 0, (nodes, [])
|
|
220
|
+
if best_value < 0.0:
|
|
221
|
+
# Best cut is trivial partition, all/empty
|
|
222
|
+
return '0' * n_qubits, 0.0, (nodes, [])
|
|
172
223
|
|
|
173
|
-
|
|
224
|
+
return bit_string, best_value, (l, r)
|
|
174
225
|
|
|
175
226
|
if quality is None:
|
|
176
227
|
quality = 6
|
pyqrackising/maxcut_tfim_util.py
CHANGED
|
@@ -121,6 +121,8 @@ except ImportError:
|
|
|
121
121
|
print("PyOpenCL not installed. (If you have any OpenCL accelerator devices with available ICDs, you might want to optionally install pyopencl.)")
|
|
122
122
|
|
|
123
123
|
opencl_context = OpenCLContext(compute_units, IS_OPENCL_AVAILABLE, work_group_size, dtype, epsilon, max_alloc, ctx, queue, calculate_cut_kernel, calculate_cut_sparse_kernel, calculate_cut_segmented_kernel, calculate_cut_sparse_segmented_kernel, single_bit_flips_kernel, single_bit_flips_sparse_kernel, single_bit_flips_segmented_kernel, single_bit_flips_sparse_segmented_kernel, double_bit_flips_kernel, double_bit_flips_sparse_kernel, double_bit_flips_segmented_kernel, double_bit_flips_sparse_segmented_kernel)
|
|
124
|
+
heuristic_threshold = 24
|
|
125
|
+
heuristic_threshold_sparse = 23
|
|
124
126
|
|
|
125
127
|
|
|
126
128
|
def setup_opencl(l, g, args_np):
|
|
@@ -390,19 +392,21 @@ def init_theta(h_mult, n_qubits, J_eff, degrees):
|
|
|
390
392
|
|
|
391
393
|
|
|
392
394
|
def init_thresholds(n_qubits):
|
|
393
|
-
n_bias = n_qubits
|
|
395
|
+
n_bias = n_qubits + 1
|
|
394
396
|
thresholds = np.empty(n_bias, dtype=np.float64)
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
397
|
+
normalizer = 0
|
|
398
|
+
for q in range(n_qubits >> 1):
|
|
399
|
+
normalizer += math.comb(n_qubits, q) << 1
|
|
400
|
+
if n_qubits & 1:
|
|
401
|
+
normalizer += math.comb(n_qubits, n_qubits >> 1)
|
|
402
|
+
p = 1
|
|
403
|
+
for q in range(n_qubits >> 1):
|
|
404
|
+
val = p / normalizer
|
|
405
|
+
thresholds[q] = val
|
|
406
|
+
thresholds[n_bias - (q + 1)] = val
|
|
401
407
|
p = math.comb(n_qubits, q + 1)
|
|
402
408
|
if n_qubits & 1:
|
|
403
|
-
thresholds[n_qubits >> 1] = p
|
|
404
|
-
tot_prob += p
|
|
405
|
-
thresholds /= tot_prob
|
|
409
|
+
thresholds[n_qubits >> 1] = p / normalizer
|
|
406
410
|
|
|
407
411
|
return thresholds
|
|
408
412
|
|
|
@@ -438,7 +442,7 @@ def probability_by_hamming_weight(J, h, z, theta, t, n_bias, normalized=True):
|
|
|
438
442
|
return bias
|
|
439
443
|
|
|
440
444
|
|
|
441
|
-
@njit
|
|
445
|
+
@njit
|
|
442
446
|
def maxcut_hamming_cdf(hamming_prob, n_qubits, J_func, degrees, quality, tot_t, h_mult):
|
|
443
447
|
n_steps = 1 << quality
|
|
444
448
|
delta_t = tot_t / n_steps
|
|
@@ -446,7 +450,7 @@ def maxcut_hamming_cdf(hamming_prob, n_qubits, J_func, degrees, quality, tot_t,
|
|
|
446
450
|
|
|
447
451
|
theta = init_theta(h_mult, n_qubits, J_func, degrees)
|
|
448
452
|
|
|
449
|
-
for qc in
|
|
453
|
+
for qc in range(n_qubits, n_steps * n_qubits):
|
|
450
454
|
step = qc // n_qubits
|
|
451
455
|
q = qc % n_qubits
|
|
452
456
|
J_eff = J_func[q]
|
pyqrackising/otoc.py
CHANGED
|
@@ -51,8 +51,6 @@ def get_otoc_hamming_distribution(J=-1.0, h=2.0, z=4, theta=0.0, t=5, n_qubits=6
|
|
|
51
51
|
rev = probability_by_hamming_weight(h, J, z, phi - np.pi, t, n_qubits + 1)
|
|
52
52
|
diff_phi = rev - fwd
|
|
53
53
|
|
|
54
|
-
diff_lam = (diff_theta + diff_phi) / 2
|
|
55
|
-
|
|
56
54
|
for b in pauli_string:
|
|
57
55
|
match b:
|
|
58
56
|
case 'X':
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from .maxcut_tfim import maxcut_tfim
|
|
2
|
-
from .maxcut_tfim_util import compute_cut, compute_energy, get_cut, gray_code_next, gray_mutation, int_to_bitstring, make_G_m_buf, make_best_theta_buf, opencl_context, setup_opencl
|
|
2
|
+
from .maxcut_tfim_util import compute_cut, compute_energy, get_cut, gray_code_next, gray_mutation, heuristic_threshold, int_to_bitstring, make_G_m_buf, make_best_theta_buf, opencl_context, setup_opencl
|
|
3
3
|
import networkx as nx
|
|
4
4
|
import numpy as np
|
|
5
5
|
from numba import njit, prange
|
|
@@ -296,6 +296,9 @@ def spin_glass_solver(
|
|
|
296
296
|
|
|
297
297
|
return "01", weight, ([nodes[0]], [nodes[1]]), -weight
|
|
298
298
|
|
|
299
|
+
if n_qubits < heuristic_threshold:
|
|
300
|
+
best_guess = None
|
|
301
|
+
|
|
299
302
|
bitstring = ""
|
|
300
303
|
if isinstance(best_guess, str):
|
|
301
304
|
bitstring = best_guess
|
|
@@ -305,16 +308,27 @@ def spin_glass_solver(
|
|
|
305
308
|
bitstring = "".join(["1" if b else "0" for b in best_guess])
|
|
306
309
|
else:
|
|
307
310
|
bitstring, cut_value, _ = maxcut_tfim(G_m, quality=quality, shots=shots, is_spin_glass=is_spin_glass, anneal_t=anneal_t, anneal_h=anneal_h, repulsion_base=repulsion_base, is_maxcut_gpu=is_maxcut_gpu, is_nested=True)
|
|
311
|
+
|
|
308
312
|
best_theta = np.array([b == "1" for b in list(bitstring)], dtype=np.bool_)
|
|
313
|
+
max_energy = compute_energy(best_theta, G_m, n_qubits) if is_spin_glass else cut_value
|
|
314
|
+
|
|
315
|
+
if n_qubits < heuristic_threshold:
|
|
316
|
+
bitstring, l, r = get_cut(best_theta, nodes, n_qubits)
|
|
317
|
+
if is_spin_glass:
|
|
318
|
+
cut_value = compute_cut(best_theta, G_m, n_qubits)
|
|
319
|
+
min_energy = -max_energy
|
|
320
|
+
else:
|
|
321
|
+
cut_value = max_energy
|
|
322
|
+
min_energy = compute_energy(best_theta, G_m, n_qubits)
|
|
323
|
+
|
|
324
|
+
return bitstring, float(cut_value), (l, r), float(min_energy)
|
|
309
325
|
|
|
310
326
|
if gray_iterations is None:
|
|
311
|
-
gray_iterations = n_qubits *
|
|
327
|
+
gray_iterations = n_qubits * n_qubits
|
|
312
328
|
|
|
313
329
|
if gray_seed_multiple is None:
|
|
314
330
|
gray_seed_multiple = os.cpu_count()
|
|
315
331
|
|
|
316
|
-
max_energy = compute_energy(best_theta, G_m, n_qubits) if is_spin_glass else cut_value
|
|
317
|
-
|
|
318
332
|
is_opencl = is_maxcut_gpu and IS_OPENCL_AVAILABLE
|
|
319
333
|
|
|
320
334
|
if is_opencl:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from .maxcut_tfim_sparse import maxcut_tfim_sparse
|
|
2
|
-
from .maxcut_tfim_util import compute_cut_sparse, compute_energy_sparse, get_cut, gray_code_next, gray_mutation, int_to_bitstring, make_G_m_csr_buf, make_best_theta_buf, opencl_context, setup_opencl, to_scipy_sparse_upper_triangular
|
|
2
|
+
from .maxcut_tfim_util import compute_cut_sparse, compute_energy_sparse, get_cut, gray_code_next, gray_mutation, heuristic_threshold_sparse, int_to_bitstring, make_G_m_csr_buf, make_best_theta_buf, opencl_context, setup_opencl, to_scipy_sparse_upper_triangular
|
|
3
3
|
import networkx as nx
|
|
4
4
|
import numpy as np
|
|
5
5
|
from numba import njit, prange
|
|
@@ -300,6 +300,9 @@ def spin_glass_solver_sparse(
|
|
|
300
300
|
|
|
301
301
|
return "01", weight, ([nodes[0]], [nodes[1]]), -weight
|
|
302
302
|
|
|
303
|
+
if n_qubits < heuristic_threshold_sparse:
|
|
304
|
+
best_guess = None
|
|
305
|
+
|
|
303
306
|
bitstring = ""
|
|
304
307
|
if isinstance(best_guess, str):
|
|
305
308
|
bitstring = best_guess
|
|
@@ -309,16 +312,27 @@ def spin_glass_solver_sparse(
|
|
|
309
312
|
bitstring = "".join(["1" if b else "0" for b in best_guess])
|
|
310
313
|
else:
|
|
311
314
|
bitstring, cut_value, _ = maxcut_tfim_sparse(G_m, quality=quality, shots=shots, is_spin_glass=is_spin_glass, anneal_t=anneal_t, anneal_h=anneal_h, repulsion_base=repulsion_base, is_maxcut_gpu=is_maxcut_gpu, is_nested=True)
|
|
315
|
+
|
|
312
316
|
best_theta = np.array([b == "1" for b in list(bitstring)], dtype=np.bool_)
|
|
317
|
+
max_energy = compute_energy(best_theta, G_m, n_qubits) if is_spin_glass else cut_value
|
|
318
|
+
|
|
319
|
+
if n_qubits < heuristic_threshold_sparse:
|
|
320
|
+
bitstring, l, r = get_cut(best_theta, nodes, n_qubits)
|
|
321
|
+
if is_spin_glass:
|
|
322
|
+
cut_value = compute_cut_sparse(best_theta, G_m.data, G_m.indptr, G_m.indices, n_qubits)
|
|
323
|
+
min_energy = -max_energy
|
|
324
|
+
else:
|
|
325
|
+
cut_value = max_energy
|
|
326
|
+
min_energy = compute_energy_sparse(best_theta, G_m.data, G_m.indptr, G_m.indices, n_qubits)
|
|
327
|
+
|
|
328
|
+
return bitstring, float(cut_value), (l, r), float(min_energy)
|
|
313
329
|
|
|
314
330
|
if gray_iterations is None:
|
|
315
|
-
gray_iterations = n_qubits *
|
|
331
|
+
gray_iterations = n_qubits * n_qubits
|
|
316
332
|
|
|
317
333
|
if gray_seed_multiple is None:
|
|
318
334
|
gray_seed_multiple = os.cpu_count()
|
|
319
335
|
|
|
320
|
-
max_energy = compute_energy_sparse(best_theta, G_m.data, G_m.indptr, G_m.indices, n_qubits) if is_spin_glass else cut_value
|
|
321
|
-
|
|
322
336
|
is_opencl = is_maxcut_gpu and IS_OPENCL_AVAILABLE
|
|
323
337
|
|
|
324
338
|
if is_opencl:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from .maxcut_tfim_streaming import maxcut_tfim_streaming
|
|
2
|
-
from .maxcut_tfim_util import compute_cut_streaming, compute_energy_streaming, get_cut, get_cut_base, gray_code_next, gray_mutation, int_to_bitstring, opencl_context
|
|
2
|
+
from .maxcut_tfim_util import compute_cut_streaming, compute_energy_streaming, get_cut, get_cut_base, gray_code_next, gray_mutation, heuristic_threshold, int_to_bitstring, opencl_context
|
|
3
3
|
import networkx as nx
|
|
4
4
|
import numpy as np
|
|
5
5
|
from numba import njit, prange
|
|
@@ -207,6 +207,9 @@ def spin_glass_solver_streaming(
|
|
|
207
207
|
|
|
208
208
|
return "01", weight, ([nodes[0]], [nodes[1]]), -weight
|
|
209
209
|
|
|
210
|
+
if n_qubits < heuristic_threshold:
|
|
211
|
+
best_guess = None
|
|
212
|
+
|
|
210
213
|
bitstring = ""
|
|
211
214
|
if isinstance(best_guess, str):
|
|
212
215
|
bitstring = best_guess
|
|
@@ -216,16 +219,27 @@ def spin_glass_solver_streaming(
|
|
|
216
219
|
bitstring = "".join(["1" if b else "0" for b in best_guess])
|
|
217
220
|
else:
|
|
218
221
|
bitstring, cut_value, _ = maxcut_tfim_streaming(G_func, nodes, quality=quality, shots=shots, is_spin_glass=is_spin_glass, anneal_t=anneal_t, anneal_h=anneal_h, repulsion_base=repulsion_base)
|
|
222
|
+
|
|
219
223
|
best_theta = np.array([b == "1" for b in list(bitstring)], dtype=np.bool_)
|
|
224
|
+
max_energy = compute_energy(best_theta, G_m, n_qubits) if is_spin_glass else cut_value
|
|
225
|
+
|
|
226
|
+
if n_qubits < heuristic_threshold:
|
|
227
|
+
bitstring, l, r = get_cut(best_theta, nodes, n_qubits)
|
|
228
|
+
if is_spin_glass:
|
|
229
|
+
cut_value = compute_cut_streaming(best_theta, G_func, nodes, n_qubits)
|
|
230
|
+
min_energy = -max_energy
|
|
231
|
+
else:
|
|
232
|
+
cut_value = max_energy
|
|
233
|
+
min_energy = compute_energy_streaming(best_theta, G_func, nodes, n_qubits)
|
|
234
|
+
|
|
235
|
+
return bitstring, float(cut_value), (l, r), float(min_energy)
|
|
220
236
|
|
|
221
237
|
if gray_iterations is None:
|
|
222
|
-
gray_iterations = n_qubits *
|
|
238
|
+
gray_iterations = n_qubits * n_qubits
|
|
223
239
|
|
|
224
240
|
if gray_seed_multiple is None:
|
|
225
241
|
gray_seed_multiple = os.cpu_count()
|
|
226
242
|
|
|
227
|
-
max_energy = compute_energy_streaming(best_theta, G_func, nodes, n_qubits) if is_spin_glass else cut_value
|
|
228
|
-
|
|
229
243
|
thread_count = os.cpu_count() ** 2
|
|
230
244
|
improved = True
|
|
231
245
|
while improved:
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
pyqrackising/__init__.py,sha256=Q-fHQRApRseeFnnO6VfD1LpjPHCVkWoz0Gnaqmv6lp0,884
|
|
2
|
+
pyqrackising/convert_tensor_network_to_tsp.py,sha256=IbZdPfHQ2bzYqDXUdHfwdZJh-pC8lri_cAgESaskQWI,3450
|
|
3
|
+
pyqrackising/generate_tfim_samples.py,sha256=IlAz1l8oLExO6wJBO8LCQKlU_4ZPlyGsNE8xUt_iTrg,4762
|
|
4
|
+
pyqrackising/kernels.cl,sha256=Q9LZ1oBOZ2A_VsQ8uRUGQKNVpzqVXYwhG6c27FO6ljI,27004
|
|
5
|
+
pyqrackising/maxcut_tfim.py,sha256=a2gbK_WypOQz8JTbMSXAtG5h-poumSTUNjK1jfNAF_c,11586
|
|
6
|
+
pyqrackising/maxcut_tfim_sparse.py,sha256=26Rv5yt_LC9OJRobCtOvEFgNphRfof9rduG7XoPehmQ,13361
|
|
7
|
+
pyqrackising/maxcut_tfim_streaming.py,sha256=ne0NH8_I6S9iYE6315UUCMlOtQyYuSJOjckRTIfkHH0,7893
|
|
8
|
+
pyqrackising/maxcut_tfim_util.py,sha256=I2iRXrrEr_YXKcmVlez8ZMwhmIQH3TegdepyM19J0CU,17062
|
|
9
|
+
pyqrackising/otoc.py,sha256=PKmpjwkGpMmwXGWmeqtvbVj1NfE35i9kkIdjQnDUZKE,7208
|
|
10
|
+
pyqrackising/spin_glass_solver.py,sha256=4CP4dTdxl2itZ9Iogth91LJY3DLVV9aXiVNpIYRgbxA,14289
|
|
11
|
+
pyqrackising/spin_glass_solver_sparse.py,sha256=p8w2it4reeqMRDoHvd7CeLkyV872oW1sUiIayEAM0ek,15295
|
|
12
|
+
pyqrackising/spin_glass_solver_streaming.py,sha256=pjn-XFPM4-rMEHVDzZHXzxK_c6tBmXzAVaVH6ujhFY0,10535
|
|
13
|
+
pyqrackising/tfim_magnetization.py,sha256=On1MhCNGGHRxJFRmCOpMcdqQJiy25gWkjz0Ka8i5f-Q,499
|
|
14
|
+
pyqrackising/tfim_square_magnetization.py,sha256=9uJCT8ytyufcGFrZiignjCkWJr9UcP44sAAy0BIBw34,531
|
|
15
|
+
pyqrackising/tsp.py,sha256=kqDxU2RCjad-T4tW_C9WO1I-COSwX7fHB6VhIuQsjfQ,62464
|
|
16
|
+
pyqrackising/tsp_maxcut.py,sha256=ngxfSJgePXVwJXfNXYdk4jv1ISznx8zHOqR-Vbf33B0,9772
|
|
17
|
+
pyqrackising-9.7.1.dist-info/licenses/LICENSE.md,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
18
|
+
pyqrackising-9.7.1.dist-info/METADATA,sha256=0hLsFLy5aO3y7j-S1qwCTn6GxKTl-v95V3oOClgn71I,1143
|
|
19
|
+
pyqrackising-9.7.1.dist-info/WHEEL,sha256=k8EuOMBHdXsN9XSTE5LrpwS4FtdLkoSlyO_7W-lE_zg,109
|
|
20
|
+
pyqrackising-9.7.1.dist-info/top_level.txt,sha256=bxlfGuLwzeVEI8Jm5D9HvC_WedgvvkSrpFwbGDjg-Ag,13
|
|
21
|
+
pyqrackising-9.7.1.dist-info/RECORD,,
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
pyqrackising/__init__.py,sha256=Q-fHQRApRseeFnnO6VfD1LpjPHCVkWoz0Gnaqmv6lp0,884
|
|
2
|
-
pyqrackising/convert_tensor_network_to_tsp.py,sha256=IbZdPfHQ2bzYqDXUdHfwdZJh-pC8lri_cAgESaskQWI,3450
|
|
3
|
-
pyqrackising/generate_tfim_samples.py,sha256=IlAz1l8oLExO6wJBO8LCQKlU_4ZPlyGsNE8xUt_iTrg,4762
|
|
4
|
-
pyqrackising/kernels.cl,sha256=Q9LZ1oBOZ2A_VsQ8uRUGQKNVpzqVXYwhG6c27FO6ljI,27004
|
|
5
|
-
pyqrackising/maxcut_tfim.py,sha256=05nRjk5hhEjNFjtXdKVObL0cYYuJ8URfcjrOGK5tGi4,10106
|
|
6
|
-
pyqrackising/maxcut_tfim_sparse.py,sha256=zMgaVmEgfZWL2tp728PuEg5Dc_jbQBUPsgbP3lXiMiA,11194
|
|
7
|
-
pyqrackising/maxcut_tfim_streaming.py,sha256=EcRXKurqLiQs6pMNz-rhMp2YQzRXD726RnkXsPt4IJ0,6346
|
|
8
|
-
pyqrackising/maxcut_tfim_util.py,sha256=2FSBcba8Ys8HEe_h-ayB68pAqeeJXeveEHGmZKg_tkI,16889
|
|
9
|
-
pyqrackising/otoc.py,sha256=Vq5tHy-XdV6O5qQGVN8E7xLkwHcXDhlWo6GNJTAd4dE,7258
|
|
10
|
-
pyqrackising/spin_glass_solver.py,sha256=YtsIfYfpwhEMQPVd_sbjqpz6nQcrv8p2mUBYZ-wRpnM,13792
|
|
11
|
-
pyqrackising/spin_glass_solver_sparse.py,sha256=E4Ft7H-uKXZyq1cS7Z77AgdkL5fMlKMK6DwnXgrgOhk,14740
|
|
12
|
-
pyqrackising/spin_glass_solver_streaming.py,sha256=xpWq63yODMzBPQQtpDuB1Tro6ta8pPbVwc0ZkDWVASk,10018
|
|
13
|
-
pyqrackising/tfim_magnetization.py,sha256=On1MhCNGGHRxJFRmCOpMcdqQJiy25gWkjz0Ka8i5f-Q,499
|
|
14
|
-
pyqrackising/tfim_square_magnetization.py,sha256=9uJCT8ytyufcGFrZiignjCkWJr9UcP44sAAy0BIBw34,531
|
|
15
|
-
pyqrackising/tsp.py,sha256=kqDxU2RCjad-T4tW_C9WO1I-COSwX7fHB6VhIuQsjfQ,62464
|
|
16
|
-
pyqrackising/tsp_maxcut.py,sha256=ngxfSJgePXVwJXfNXYdk4jv1ISznx8zHOqR-Vbf33B0,9772
|
|
17
|
-
pyqrackising-9.5.11.dist-info/licenses/LICENSE.md,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
18
|
-
pyqrackising-9.5.11.dist-info/METADATA,sha256=6Z3r5ubODul2NQjgGyg7M6l_nUBhntcpEI2mU18q81Q,1144
|
|
19
|
-
pyqrackising-9.5.11.dist-info/WHEEL,sha256=k8EuOMBHdXsN9XSTE5LrpwS4FtdLkoSlyO_7W-lE_zg,109
|
|
20
|
-
pyqrackising-9.5.11.dist-info/top_level.txt,sha256=bxlfGuLwzeVEI8Jm5D9HvC_WedgvvkSrpFwbGDjg-Ag,13
|
|
21
|
-
pyqrackising-9.5.11.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|