pyqrackising 9.5.3__tar.gz → 9.5.5__tar.gz

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.

Files changed (28) hide show
  1. {pyqrackising-9.5.3/pyqrackising.egg-info → pyqrackising-9.5.5}/PKG-INFO +1 -1
  2. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyproject.toml +1 -1
  3. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/maxcut_tfim.py +12 -36
  4. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/maxcut_tfim_sparse.py +12 -35
  5. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/maxcut_tfim_streaming.py +11 -18
  6. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/maxcut_tfim_util.py +4 -44
  7. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/otoc.py +24 -20
  8. {pyqrackising-9.5.3 → pyqrackising-9.5.5/pyqrackising.egg-info}/PKG-INFO +1 -1
  9. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/setup.py +1 -1
  10. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/LICENSE.md +0 -0
  11. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/MANIFEST.in +0 -0
  12. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/README.md +0 -0
  13. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/__init__.py +0 -0
  14. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/convert_tensor_network_to_tsp.py +0 -0
  15. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/generate_tfim_samples.py +0 -0
  16. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/kernels.cl +0 -0
  17. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/spin_glass_solver.py +0 -0
  18. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/spin_glass_solver_sparse.py +0 -0
  19. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/spin_glass_solver_streaming.py +0 -0
  20. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/tfim_magnetization.py +0 -0
  21. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/tfim_square_magnetization.py +0 -0
  22. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/tsp.py +0 -0
  23. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising/tsp_maxcut.py +0 -0
  24. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising.egg-info/SOURCES.txt +0 -0
  25. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising.egg-info/dependency_links.txt +0 -0
  26. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising.egg-info/not-zip-safe +0 -0
  27. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/pyqrackising.egg-info/top_level.txt +0 -0
  28. {pyqrackising-9.5.3 → pyqrackising-9.5.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqrackising
3
- Version: 9.5.3
3
+ Version: 9.5.5
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
@@ -10,7 +10,7 @@ build-backend = "setuptools.build_meta"
10
10
 
11
11
  [project]
12
12
  name = "pyqrackising"
13
- version = "9.5.3"
13
+ version = "9.5.5"
14
14
  requires-python = ">=3.8"
15
15
  description = "Fast MAXCUT, TSP, and sampling heuristics from near-ideal transverse field Ising model (TFIM)"
16
16
  readme = {file = "README.txt", content-type = "text/markdown"}
@@ -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, 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, 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:
@@ -177,21 +177,6 @@ def init_J_and_z(G_m, repulsion_base):
177
177
  return J_eff, degrees
178
178
 
179
179
 
180
- @njit
181
- def cpu_footer(shots, thread_count, quality, n_qubits, G_m, nodes, is_spin_glass, anneal_t, anneal_h, repulsion_base):
182
- J_eff, degrees = init_J_and_z(G_m, repulsion_base)
183
- hamming_prob = maxcut_hamming_cdf(n_qubits, J_eff, degrees, quality, anneal_t, anneal_h)
184
-
185
- degrees = None
186
- J_eff = None
187
-
188
- best_solution, best_value = sample_measurement(G_m, shots, thread_count, hamming_prob, repulsion_base, is_spin_glass)
189
-
190
- bit_string, l, r = get_cut(best_solution, nodes, n_qubits)
191
-
192
- return bit_string, best_value, (l, r)
193
-
194
-
195
180
  def run_cut_opencl(best_energy, samples, G_m_buf, is_segmented, local_size, global_size, args_buf, local_energy_buf, local_index_buf, max_energy_host, max_index_host, max_energy_buf, max_index_buf):
196
181
  queue = opencl_context.queue
197
182
  calculate_cut_kernel = opencl_context.calculate_cut_segmented_kernel if is_segmented else opencl_context.calculate_cut_kernel
@@ -253,6 +238,7 @@ def run_cut_opencl(best_energy, samples, G_m_buf, is_segmented, local_size, glob
253
238
 
254
239
  return samples[max_index_host[best_x]], energy
255
240
 
241
+
256
242
  def maxcut_tfim(
257
243
  G,
258
244
  quality=None,
@@ -308,31 +294,21 @@ def maxcut_tfim(
308
294
  if repulsion_base is None:
309
295
  repulsion_base = 5.0
310
296
 
311
- is_opencl = is_maxcut_gpu and IS_OPENCL_AVAILABLE
312
-
313
- if not is_opencl:
314
- thread_count = os.cpu_count() ** 2
315
-
316
- bit_string, best_value, partition = cpu_footer(shots, thread_count, quality, n_qubits, G_m, nodes, is_spin_glass, anneal_t, anneal_h, repulsion_base)
317
-
318
- if best_value < 0.0:
319
- # Best cut is trivial partition, all/empty
320
- return '0' * n_qubits, 0.0, (nodes, [])
321
-
322
- return bit_string, best_value, partition
323
-
324
- segment_size = (G_m.shape[0] * G_m.shape[1] + 3) >> 2
325
- theta_segment_size = (((n_qubits + 31) >> 5) * (((shots + wgs - 1) // wgs) * wgs) + 3) >> 2
326
- is_segmented = ((G_m.nbytes << 1) > opencl_context.max_alloc) or ((theta_segment_size << 3) > opencl_context.max_alloc)
327
- G_m_buf = make_G_m_buf(G_m, is_segmented, segment_size)
328
-
329
297
  J_eff, degrees = init_J_and_z(G_m, repulsion_base)
330
- hamming_prob = maxcut_hamming_cdf(n_qubits, J_eff, degrees, quality, anneal_t, anneal_h)
298
+ cum_prob = maxcut_hamming_cdf(init_thresholds(n_qubits), n_qubits, J_eff, degrees, quality, anneal_t, anneal_h)
331
299
 
332
300
  degrees = None
333
301
  J_eff = None
334
302
 
335
- best_solution, best_value = sample_for_opencl(G_m, G_m_buf, shots, hamming_prob, repulsion_base, is_spin_glass, is_segmented, segment_size, theta_segment_size)
303
+ if is_maxcut_gpu and IS_OPENCL_AVAILABLE:
304
+ segment_size = (G_m.shape[0] * G_m.shape[1] + 3) >> 2
305
+ theta_segment_size = (((n_qubits + 31) >> 5) * (((shots + wgs - 1) // wgs) * wgs) + 3) >> 2
306
+ is_segmented = ((G_m.nbytes << 1) > opencl_context.max_alloc) or ((theta_segment_size << 3) > opencl_context.max_alloc)
307
+ G_m_buf = make_G_m_buf(G_m, is_segmented, segment_size)
308
+ best_solution, best_value = sample_for_opencl(G_m, G_m_buf, shots, cum_prob, repulsion_base, is_spin_glass, is_segmented, segment_size, theta_segment_size)
309
+ else:
310
+ thread_count = os.cpu_count() ** 2
311
+ best_solution, best_value = sample_measurement(G_m, shots, thread_count, cum_prob, repulsion_base, is_spin_glass)
336
312
 
337
313
  bit_string, l, r = get_cut(best_solution, nodes, n_qubits)
338
314
 
@@ -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, 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, 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:
@@ -187,17 +187,6 @@ def init_J_and_z(G_m, repulsion_base):
187
187
  return J_eff, degrees
188
188
 
189
189
 
190
- @njit
191
- def cpu_footer(J_eff, degrees, shots, thread_count, quality, n_qubits, G_data, G_rows, G_cols, nodes, is_spin_glass, anneal_t, anneal_h, repulsion_base):
192
- hamming_prob = maxcut_hamming_cdf(n_qubits, J_eff, degrees, quality, anneal_t, anneal_h)
193
-
194
- best_solution, best_value = sample_measurement(G_data, G_rows, G_cols, shots, thread_count, hamming_prob, repulsion_base, is_spin_glass)
195
-
196
- bit_string, l, r = get_cut(best_solution, nodes, n_qubits)
197
-
198
- return bit_string, best_value, (l, r)
199
-
200
-
201
190
  def run_cut_opencl(best_energy, samples, G_data_buf, G_rows_buf, G_cols_buf, is_segmented, local_size, global_size, args_buf, local_energy_buf, local_index_buf, max_energy_host, max_index_host, max_energy_buf, max_index_buf):
202
191
  queue = opencl_context.queue
203
192
  calculate_cut_kernel = opencl_context.calculate_cut_sparse_segmented_kernel if is_segmented else opencl_context.calculate_cut_sparse_kernel
@@ -319,35 +308,23 @@ def maxcut_tfim_sparse(
319
308
  if repulsion_base is None:
320
309
  repulsion_base = 5.0
321
310
 
322
- J_eff, degrees = init_J_and_z(G_m, repulsion_base)
323
-
324
311
  n_qubits = G_m.shape[0]
325
312
 
326
- is_opencl = is_maxcut_gpu and IS_OPENCL_AVAILABLE
327
-
328
- if not is_opencl:
329
- thread_count = os.cpu_count() ** 2
330
-
331
- bit_string, best_value, partition = cpu_footer(J_eff, degrees, shots, thread_count, quality, n_qubits, G_m.data, G_m.indptr, G_m.indices, nodes, is_spin_glass, anneal_t, anneal_h, repulsion_base)
332
-
333
- if best_value < 0.0:
334
- # Best cut is trivial partition, all/empty
335
- return '0' * n_qubits, 0.0, (nodes, [])
336
-
337
- return bit_string, best_value, partition
338
-
339
- segment_size = (G_m.data.shape[0] + 3) >> 2
340
- theta_segment_size = (((n_qubits + 31) >> 5) * (((shots + wgs - 1) // wgs) * wgs) + 3) >> 2
341
- is_segmented = (G_m.data.nbytes << 1) > opencl_context.max_alloc or ((theta_segment_size << 3) > opencl_context.max_alloc)
342
-
343
- G_data_buf, G_rows_buf, G_cols_buf = make_G_m_csr_buf(G_m, is_segmented, segment_size)
344
-
345
- hamming_prob = maxcut_hamming_cdf(n_qubits, J_eff, degrees, quality, anneal_t, anneal_h)
313
+ J_eff, degrees = init_J_and_z(G_m, repulsion_base)
314
+ cum_prob = maxcut_hamming_cdf(init_thresholds(n_qubits), n_qubits, J_eff, degrees, quality, anneal_t, anneal_h)
346
315
 
347
316
  degrees = None
348
317
  J_eff = None
349
318
 
350
- 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, hamming_prob, repulsion_base, is_spin_glass, is_segmented, segment_size, theta_segment_size)
319
+ if is_maxcut_gpu and IS_OPENCL_AVAILABLE:
320
+ segment_size = (G_m.data.shape[0] + 3) >> 2
321
+ theta_segment_size = (((n_qubits + 31) >> 5) * (((shots + wgs - 1) // wgs) * wgs) + 3) >> 2
322
+ is_segmented = (G_m.data.nbytes << 1) > opencl_context.max_alloc or ((theta_segment_size << 3) > opencl_context.max_alloc)
323
+ G_data_buf, G_rows_buf, G_cols_buf = make_G_m_csr_buf(G_m, is_segmented, segment_size)
324
+ 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
+ else:
326
+ thread_count = os.cpu_count() ** 2
327
+ best_solution, best_value = sample_measurement(G_data, G_rows, G_cols, shots, thread_count, cum_prob, repulsion_base, is_spin_glass)
351
328
 
352
329
  bit_string, l, r = get_cut(best_solution, nodes, n_qubits)
353
330
 
@@ -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, 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, init_thresholds, maxcut_hamming_cdf, opencl_context, sample_mag, bit_pick
7
7
 
8
8
 
9
9
  epsilon = opencl_context.epsilon
@@ -145,21 +145,6 @@ def find_G_min(G_func, nodes, n_nodes):
145
145
  return G_min
146
146
 
147
147
 
148
- @njit
149
- def cpu_footer(shots, thread_count, quality, n_qubits, G_min, G_func, nodes, is_spin_glass, anneal_t, anneal_h, repulsion_base):
150
- J_eff, degrees = init_J_and_z(G_func, nodes, G_min, repulsion_base)
151
- hamming_prob = maxcut_hamming_cdf(n_qubits, J_eff, degrees, quality, anneal_t, anneal_h)
152
-
153
- degrees = None
154
- J_eff = None
155
-
156
- best_solution, best_value = sample_measurement(G_func, nodes, shots, thread_count, hamming_prob, n_qubits, repulsion_base, is_spin_glass)
157
-
158
- bit_string, l, r = get_cut(best_solution, nodes, n_qubits)
159
-
160
- return bit_string, best_value, (l, r)
161
-
162
-
163
148
  def maxcut_tfim_streaming(
164
149
  G_func,
165
150
  nodes,
@@ -207,10 +192,18 @@ def maxcut_tfim_streaming(
207
192
 
208
193
  thread_count = os.cpu_count() ** 2
209
194
 
210
- bit_string, best_value, partition = cpu_footer(shots, thread_count, quality, n_qubits, G_min, G_func, nodes, is_spin_glass, anneal_t, anneal_h, repulsion_base)
195
+ J_eff, degrees = init_J_and_z(G_func, nodes, G_min, repulsion_base)
196
+ cum_prob = maxcut_hamming_cdf(init_thresholds(n_qubits), n_qubits, J_eff, degrees, quality, anneal_t, anneal_h)
197
+
198
+ degrees = None
199
+ J_eff = None
200
+
201
+ best_solution, best_value = sample_measurement(G_func, nodes, shots, thread_count, cum_prob, n_qubits, repulsion_base, is_spin_glass)
202
+
203
+ bit_string, l, r = get_cut(best_solution, nodes, n_qubits)
211
204
 
212
205
  if best_value < 0.0:
213
206
  # Best cut is trivial partition, all/empty
214
207
  return '0' * n_qubits, 0.0, (nodes, [])
215
208
 
216
- return bit_string, best_value, partition
209
+ return bit_string, best_value, (l, r)
@@ -389,56 +389,18 @@ def init_theta(h_mult, n_qubits, J_eff, degrees):
389
389
  return theta
390
390
 
391
391
 
392
- # From Google Search AI
393
- @njit
394
- def factorial(num):
395
- """Calculates the factorial of a non-negative integer."""
396
- if num == 0:
397
- return 1
398
-
399
- result = 1
400
- for i in range(1, num + 1):
401
- result *= i
402
-
403
- return result
404
-
405
-
406
- # From Google Search AI
407
- @njit
408
- def comb(n, k):
409
- """
410
- Calculates the number of combinations (n choose k) from scratch.
411
- n: The total number of items.
412
- k: The number of items to choose.
413
- """
414
- # Optimize by choosing the smaller of k and (n-k)
415
- # This reduces the number of multiplications in the factorial calculation
416
- k = min(k, n - k)
417
-
418
- # Calculate the numerator: n * (n-1) * ... * (n-k+1)
419
- numerator = 1
420
- for i in range(k):
421
- numerator *= (n - i)
422
-
423
- # Calculate the denominator: k!
424
- denominator = factorial(k)
425
-
426
- return numerator // denominator
427
-
428
-
429
- @njit
430
392
  def init_thresholds(n_qubits):
431
393
  n_bias = n_qubits - 1
432
394
  thresholds = np.empty(n_bias, dtype=np.float64)
433
395
  tot_prob = 0
434
396
  p = n_qubits
435
- for q in range(1, n_qubits // 2):
397
+ for q in range(1, n_qubits >> 1):
436
398
  thresholds[q - 1] = p
437
399
  thresholds[n_bias - q] = p
438
400
  tot_prob += 2 * p
439
- p = comb(n_qubits, q + 1)
401
+ p = math.comb(n_qubits, q + 1)
440
402
  if n_qubits & 1:
441
- thresholds[q - 1] = p
403
+ thresholds[n_qubits >> 1] = p
442
404
  tot_prob += p
443
405
  thresholds /= tot_prob
444
406
 
@@ -477,9 +439,7 @@ def probability_by_hamming_weight(J, h, z, theta, t, n_bias, normalized=True):
477
439
 
478
440
 
479
441
  @njit(parallel=True)
480
- def maxcut_hamming_cdf(n_qubits, J_func, degrees, quality, tot_t, h_mult):
481
- hamming_prob = init_thresholds(n_qubits)
482
-
442
+ def maxcut_hamming_cdf(hamming_prob, n_qubits, J_func, degrees, quality, tot_t, h_mult):
483
443
  n_steps = 1 << quality
484
444
  delta_t = tot_t / n_steps
485
445
  n_bias = n_qubits + 1
@@ -15,25 +15,15 @@ def get_otoc_hamming_distribution(J=-1.0, h=2.0, z=4, theta=0.0, t=5, n_qubits=6
15
15
  bias[0] = 1.0
16
16
  return bias
17
17
 
18
- max_entropy = np.empty(n_bias, dtype=np.float64)
19
- tot_prob = 0
20
- p = 1.0
21
- for q in range(n_qubits // 2):
22
- max_entropy[q] = p
23
- max_entropy[n_bias - (q + 1)] = p
24
- tot_prob += 2 * p
25
- p = math.comb(n_qubits, q + 1)
26
- if n_qubits & 1:
27
- max_entropy[q - 1] = p
28
- tot_prob += p
29
- max_entropy /= tot_prob
30
-
18
+ entropy_frac = 0.0
31
19
  diff_z = np.zeros(n_bias, dtype=np.float64)
32
20
  for pauli_string in pauli_strings:
33
21
  pauli_string = list(pauli_string)
34
22
  if len(pauli_string) != n_qubits:
35
23
  raise ValueError("OTOCS pauli_string must be same length as n_qubits! (Use 'I' for qubits that aren't changed.)")
36
24
 
25
+ entropy_frac += pauli_string.count('X') + pauli_string.count('Y') + pauli_string.count('Z')
26
+
37
27
  fwd = probability_by_hamming_weight(J, h, z, theta, t, n_qubits + 1)
38
28
  rev = probability_by_hamming_weight(-J, -h, z, theta + np.pi, t, n_qubits + 1)
39
29
  diff_theta = rev - fwd
@@ -49,10 +39,6 @@ def get_otoc_hamming_distribution(J=-1.0, h=2.0, z=4, theta=0.0, t=5, n_qubits=6
49
39
  diff_phi[0] += 1.0
50
40
  diff_lam[0] += 1.0
51
41
 
52
- diff_theta += max_entropy
53
- diff_phi += max_entropy
54
- diff_lam += max_entropy
55
-
56
42
  for b in pauli_string:
57
43
  match b:
58
44
  case 'X':
@@ -67,6 +53,24 @@ def get_otoc_hamming_distribution(J=-1.0, h=2.0, z=4, theta=0.0, t=5, n_qubits=6
67
53
  # Normalize:
68
54
  diff_z /= diff_z.sum()
69
55
 
56
+ entropy_frac = np.atan2(entropy_frac, math.sqrt(n_qubits))
57
+ max_entropy = np.empty(n_bias, dtype=np.float64)
58
+ tot_prob = 0
59
+ p = 1.0
60
+ for q in range(n_qubits >> 1):
61
+ max_entropy[q] = p
62
+ max_entropy[n_bias - (q + 1)] = p
63
+ tot_prob += 2 * p
64
+ p = math.comb(n_qubits, q + 1)
65
+ if n_qubits & 1:
66
+ max_entropy[n_qubits >> 1] = p
67
+ tot_prob += p
68
+ max_entropy *= entropy_frac / tot_prob
69
+ diff_z = max_entropy + (1 - entropy_frac) * diff_z
70
+
71
+ # Normalize:
72
+ diff_z /= diff_z.sum()
73
+
70
74
  return diff_z
71
75
 
72
76
 
@@ -145,7 +149,7 @@ def get_willow_inv_dist(butterfly_idx_x, butterfly_idx_z, n_qubits, row_len, col
145
149
  for q in range(n_qubits):
146
150
  q_row, q_col = divmod(q, row_len)
147
151
  inv_dist[q] += abs(q_row - b_row) + abs(q_col - b_col)
148
- inv_dist += 1.0 - inv_dist.min()
152
+ inv_dist -= inv_dist.min()
149
153
 
150
154
  return inv_dist
151
155
 
@@ -176,7 +180,7 @@ def get_inv_dist(butterfly_idx_x, butterfly_idx_z, n_qubits, row_len, col_len):
176
180
  if col_d > half_col:
177
181
  col_d = col_len - col_d
178
182
  inv_dist[q] += row_d + col_d
179
- inv_dist += 1.0 - inv_dist.min()
183
+ inv_dist -= inv_dist.min()
180
184
 
181
185
  return inv_dist
182
186
 
@@ -188,7 +192,7 @@ def generate_otoc_samples(J=-1.0, h=2.0, z=4, theta=0.0, t=5, n_qubits=65, pauli
188
192
  for pauli_string in pauli_strings:
189
193
  pauli_string = list(pauli_string)
190
194
  entropy_frac += pauli_string.count('X') + pauli_string.count('Y') + pauli_string.count('Z')
191
- entropy_frac /= n_qubits * len(pauli_strings)
195
+ entropy_frac = np.atan2(entropy_frac, math.sqrt(n_qubits))
192
196
 
193
197
  row_len, col_len = factor_width(n_qubits)
194
198
  inv_dist = np.zeros(n_qubits, dtype=np.float64)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqrackising
3
- Version: 9.5.3
3
+ Version: 9.5.5
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
@@ -7,7 +7,7 @@ with open(README_PATH) as readme_file:
7
7
 
8
8
  setup(
9
9
  name='pyqrackising',
10
- version='9.5.3',
10
+ version='9.5.5',
11
11
  author='Dan Strano',
12
12
  author_email='stranoj@gmail.com',
13
13
  description='Fast MAXCUT, TSP, and sampling heuristics from near-ideal transverse field Ising model (TFIM)',
File without changes
File without changes
File without changes
File without changes