pyqrackising 9.7.0__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 +62 -15
- pyqrackising/maxcut_tfim_sparse.py +71 -12
- pyqrackising/maxcut_tfim_streaming.py +60 -12
- pyqrackising/maxcut_tfim_util.py +2 -0
- pyqrackising/spin_glass_solver.py +17 -3
- pyqrackising/spin_glass_solver_sparse.py +17 -3
- pyqrackising/spin_glass_solver_streaming.py +17 -3
- {pyqrackising-9.7.0.dist-info → pyqrackising-9.7.1.dist-info}/METADATA +1 -1
- pyqrackising-9.7.1.dist-info/RECORD +21 -0
- pyqrackising-9.7.0.dist-info/RECORD +0 -21
- {pyqrackising-9.7.0.dist-info → pyqrackising-9.7.1.dist-info}/WHEEL +0 -0
- {pyqrackising-9.7.0.dist-info → pyqrackising-9.7.1.dist-info}/licenses/LICENSE.md +0 -0
- {pyqrackising-9.7.0.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:
|
|
@@ -242,6 +242,60 @@ def run_cut_opencl(best_energy, samples, G_m_buf, is_segmented, local_size, glob
|
|
|
242
242
|
return samples[max_index_host[best_x]], energy
|
|
243
243
|
|
|
244
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
|
+
|
|
245
299
|
def maxcut_tfim(
|
|
246
300
|
G,
|
|
247
301
|
quality=None,
|
|
@@ -264,22 +318,15 @@ def maxcut_tfim(
|
|
|
264
318
|
|
|
265
319
|
n_qubits = len(G_m)
|
|
266
320
|
|
|
267
|
-
if n_qubits <
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if n_qubits == 0:
|
|
272
|
-
return "", 0, (empty, empty.copy())
|
|
273
|
-
|
|
274
|
-
if n_qubits == 1:
|
|
275
|
-
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)
|
|
276
324
|
|
|
277
|
-
if
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
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, [])
|
|
281
328
|
|
|
282
|
-
|
|
329
|
+
return bit_string, best_value, (l, r)
|
|
283
330
|
|
|
284
331
|
if quality is None:
|
|
285
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:
|
|
@@ -256,6 +256,69 @@ def run_cut_opencl(best_energy, samples, G_data_buf, G_rows_buf, G_cols_buf, is_
|
|
|
256
256
|
return samples[max_index_host[best_x]], energy
|
|
257
257
|
|
|
258
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
|
+
|
|
259
322
|
|
|
260
323
|
def maxcut_tfim_sparse(
|
|
261
324
|
G,
|
|
@@ -281,19 +344,15 @@ def maxcut_tfim_sparse(
|
|
|
281
344
|
nodes = list(range(n_qubits))
|
|
282
345
|
G_m = G
|
|
283
346
|
|
|
284
|
-
if n_qubits <
|
|
285
|
-
if
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
if n_qubits == 1:
|
|
289
|
-
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)
|
|
290
350
|
|
|
291
|
-
if
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
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, [])
|
|
295
354
|
|
|
296
|
-
|
|
355
|
+
return bit_string, best_value, (l, r)
|
|
297
356
|
|
|
298
357
|
if quality is None:
|
|
299
358
|
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 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
|
|
@@ -148,6 +148,58 @@ def find_G_min(G_func, nodes, n_nodes):
|
|
|
148
148
|
return G_min
|
|
149
149
|
|
|
150
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
|
+
|
|
151
203
|
def maxcut_tfim_streaming(
|
|
152
204
|
G_func,
|
|
153
205
|
nodes,
|
|
@@ -161,19 +213,15 @@ def maxcut_tfim_streaming(
|
|
|
161
213
|
wgs = opencl_context.work_group_size
|
|
162
214
|
n_qubits = len(nodes)
|
|
163
215
|
|
|
164
|
-
if n_qubits <
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if n_qubits == 1:
|
|
169
|
-
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)
|
|
170
219
|
|
|
171
|
-
if
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
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, [])
|
|
175
223
|
|
|
176
|
-
|
|
224
|
+
return bit_string, best_value, (l, r)
|
|
177
225
|
|
|
178
226
|
if quality is None:
|
|
179
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):
|
|
@@ -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,7 +308,20 @@ 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
327
|
gray_iterations = n_qubits * n_qubits
|
|
@@ -313,8 +329,6 @@ def spin_glass_solver(
|
|
|
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,7 +312,20 @@ 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
331
|
gray_iterations = n_qubits * n_qubits
|
|
@@ -317,8 +333,6 @@ def spin_glass_solver_sparse(
|
|
|
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,7 +219,20 @@ 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
238
|
gray_iterations = n_qubits * n_qubits
|
|
@@ -224,8 +240,6 @@ def spin_glass_solver_streaming(
|
|
|
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=uqC7Ryw1ikehGfG4OFV7rHojWlx5u8wL2l8yxsmNkWY,10170
|
|
6
|
-
pyqrackising/maxcut_tfim_sparse.py,sha256=YyenDVmXR46Pf9LClvpNEWjziToE6U7WOy68mKseTkk,11269
|
|
7
|
-
pyqrackising/maxcut_tfim_streaming.py,sha256=7vPKulDRcQ-YvPacCNT11Ba-CXhBYggjpu_aDMov6NE,6410
|
|
8
|
-
pyqrackising/maxcut_tfim_util.py,sha256=Ye8kNEunHQLdbTdyT8hTFlsRy0f3QCnKUDIwZXAm0rM,17003
|
|
9
|
-
pyqrackising/otoc.py,sha256=PKmpjwkGpMmwXGWmeqtvbVj1NfE35i9kkIdjQnDUZKE,7208
|
|
10
|
-
pyqrackising/spin_glass_solver.py,sha256=-hQAyTCRpadYhH4E8cT9kBFK9vdSDNK22XESXGSnfjc,13786
|
|
11
|
-
pyqrackising/spin_glass_solver_sparse.py,sha256=F07Y92FCaUJHX1h1ydTFp6HjWLgo_A2buPErIvtYM7g,14734
|
|
12
|
-
pyqrackising/spin_glass_solver_streaming.py,sha256=dDl7VYeu7BkJlLHTCCovaT3z6-Zx4RGwTVcNGzwxTXY,10012
|
|
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.0.dist-info/licenses/LICENSE.md,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
18
|
-
pyqrackising-9.7.0.dist-info/METADATA,sha256=OWfrA57TEpL09F0zzFdKL5UmCBTvihkTGF739CIUFcU,1143
|
|
19
|
-
pyqrackising-9.7.0.dist-info/WHEEL,sha256=k8EuOMBHdXsN9XSTE5LrpwS4FtdLkoSlyO_7W-lE_zg,109
|
|
20
|
-
pyqrackising-9.7.0.dist-info/top_level.txt,sha256=bxlfGuLwzeVEI8Jm5D9HvC_WedgvvkSrpFwbGDjg-Ag,13
|
|
21
|
-
pyqrackising-9.7.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|