pyqrack-cpu-complex128 2.25.4__tar.gz → 2.26.0__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.
- {pyqrack_cpu_complex128-2.25.4/pyqrack_cpu_complex128.egg-info → pyqrack_cpu_complex128-2.26.0}/PKG-INFO +1 -1
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/qrack_ace_backend.py +214 -215
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/qrack_simulator.py +16 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0/pyqrack_cpu_complex128.egg-info}/PKG-INFO +1 -1
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/setup.py +1 -1
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/LICENSE +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/MANIFEST.in +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/Makefile +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/README.md +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyproject.toml +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/__init__.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/neuron_activation_fn.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/pauli.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/qrack_circuit.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/qrack_near_clifford_qec_backend.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/qrack_neuron.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/qrack_neuron_torch_layer.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/qrack_stabilizer.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/qrack_system/qrack_system.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/stats/load_quantized_data.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/stats/quantize_by_range.py +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack_cpu_complex128.egg-info/SOURCES.txt +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack_cpu_complex128.egg-info/dependency_links.txt +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack_cpu_complex128.egg-info/not-zip-safe +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack_cpu_complex128.egg-info/requires.txt +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack_cpu_complex128.egg-info/top_level.txt +0 -0
- {pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/setup.cfg +0 -0
{pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/qrack_ace_backend.py
RENAMED
|
@@ -334,18 +334,19 @@ class QrackAceBackend:
|
|
|
334
334
|
self._is_row_long_range[-1] = False
|
|
335
335
|
sim_count = col_patch_count * row_patch_count
|
|
336
336
|
|
|
337
|
-
#
|
|
338
|
-
#
|
|
339
|
-
#
|
|
340
|
-
#
|
|
341
|
-
# automatically factor apart whatever boundary sites
|
|
342
|
-
#
|
|
343
|
-
#
|
|
344
|
-
#
|
|
345
|
-
#
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
337
|
+
# The shared boundary "crossbar" QrackSimulator has been removed.
|
|
338
|
+
# It used to give every boundary site (row- and/or column-boundary
|
|
339
|
+
# alike) one extra real replica in a single simulator shared by ALL
|
|
340
|
+
# boundary qubits, trusting that simulator's own greedy elision
|
|
341
|
+
# (set_sdrp) to automatically factor apart whatever boundary sites
|
|
342
|
+
# turned out to be separable, rather than hand-coding "crossbar
|
|
343
|
+
# intersection" logic. Measurement showed it adds real, and
|
|
344
|
+
# growing-with-patch-count, connectivity value -- but per explicit
|
|
345
|
+
# instruction, it is being ripped out cleanly regardless, to get an
|
|
346
|
+
# empirical read on XEB without it. Every boundary qubit already
|
|
347
|
+
# carries a classical LHVQubit proxy (self._lhv, below) in
|
|
348
|
+
# parallel; _correct() now falls back to that proxy for tie-
|
|
349
|
+
# breaking wherever the crossbar replica used to be consulted.
|
|
349
350
|
self._qubits = []
|
|
350
351
|
self._lhv = {}
|
|
351
352
|
sim_counts = [0] * sim_count
|
|
@@ -361,9 +362,6 @@ class QrackAceBackend:
|
|
|
361
362
|
qubit.append((t_sim_id, sim_counts[t_sim_id]))
|
|
362
363
|
sim_counts[t_sim_id] += 1
|
|
363
364
|
|
|
364
|
-
qubit.append((boundary_sim_id, boundary_count))
|
|
365
|
-
boundary_count += 1
|
|
366
|
-
|
|
367
365
|
if (not to_clone) or (tot_qubits in to_clone._lhv):
|
|
368
366
|
self._lhv[tot_qubits] = LHVQubit(
|
|
369
367
|
to_clone=(to_clone._lhv[tot_qubits] if to_clone else None)
|
|
@@ -386,22 +384,10 @@ class QrackAceBackend:
|
|
|
386
384
|
)
|
|
387
385
|
tot_qubits += 1
|
|
388
386
|
|
|
389
|
-
# The crossbar's size is fixed by how many boundary sites exist.
|
|
390
|
-
# When there are none (e.g. a grid small enough, relative to
|
|
391
|
-
# long_range_rows/columns, that the whole thing is "fully
|
|
392
|
-
# connected" with no QEC boundary at all), we must NOT allocate a
|
|
393
|
-
# 0-qubit QrackSimulator for the crossbar. The boundary sim is only
|
|
394
|
-
# created when boundary_count > 0, exactly mirroring how the original
|
|
395
|
-
# LHV-based code never instantiated anything for the boundary case
|
|
396
|
-
# when there were no boundary sites.
|
|
397
|
-
has_boundary = boundary_count > 0
|
|
398
|
-
if has_boundary:
|
|
399
|
-
sim_counts.append(boundary_count)
|
|
400
|
-
|
|
401
387
|
# Error-detection gadget (IBM-style detect-and-post-select, not
|
|
402
|
-
# correction): two shared ancillae per simulator --
|
|
403
|
-
#
|
|
404
|
-
#
|
|
388
|
+
# correction): two shared ancillae per simulator -- one per patch,
|
|
389
|
+
# "a single ancilla per patch, overall" -- reused across every real
|
|
390
|
+
# (same-simulator) coupling
|
|
405
391
|
# gate that touches it, never allocated per-gate or per-qubit.
|
|
406
392
|
# See _apply_coupling for the actual gadget; this block only does
|
|
407
393
|
# the qubit-index bookkeeping, in the same style as every other
|
|
@@ -483,7 +469,7 @@ class QrackAceBackend:
|
|
|
483
469
|
self._sdrp = 0.0
|
|
484
470
|
|
|
485
471
|
self.sim = []
|
|
486
|
-
for i in range(sim_count
|
|
472
|
+
for i in range(sim_count):
|
|
487
473
|
self.sim.append(
|
|
488
474
|
to_clone.sim[i].clone()
|
|
489
475
|
if to_clone
|
|
@@ -499,8 +485,6 @@ class QrackAceBackend:
|
|
|
499
485
|
)
|
|
500
486
|
)
|
|
501
487
|
|
|
502
|
-
self._boundary_sim_id = boundary_sim_id if has_boundary else None
|
|
503
|
-
|
|
504
488
|
def clone(self):
|
|
505
489
|
return QrackAceBackend(to_clone=self)
|
|
506
490
|
|
|
@@ -753,19 +737,17 @@ class QrackAceBackend:
|
|
|
753
737
|
|
|
754
738
|
@staticmethod
|
|
755
739
|
def _get_qb_lhv_indices(hq):
|
|
756
|
-
#
|
|
757
|
-
#
|
|
758
|
-
#
|
|
759
|
-
#
|
|
760
|
-
#
|
|
761
|
-
#
|
|
762
|
-
#
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
else:
|
|
768
|
-
qb = [0, 1, 2, 3, 4]
|
|
740
|
+
# With the shared boundary "crossbar" QrackSimulator removed,
|
|
741
|
+
# every entry of hq is again an ordinary (sim_id, idx) tuple into a
|
|
742
|
+
# real physical replica: 1 for a bulk qubit, 2 for an edge-boundary
|
|
743
|
+
# qubit (home + adjacent-patch), or 4 for a corner-boundary qubit
|
|
744
|
+
# (home + adjacent-patch + 2 diagonal-patch). None of them are
|
|
745
|
+
# virtual/LHV-backed slots any more -- the classical LHVQubit
|
|
746
|
+
# proxy (self._lhv) is tracked entirely separately from hq, not as
|
|
747
|
+
# one of its indices -- so qb is simply every index, in order. We
|
|
748
|
+
# keep this helper's name and signature for minimal call-site
|
|
749
|
+
# churn; "lhv" is always -1 (no index needs special-casing).
|
|
750
|
+
qb = list(range(len(hq)))
|
|
769
751
|
lhv = -1
|
|
770
752
|
|
|
771
753
|
return qb, lhv
|
|
@@ -857,26 +839,22 @@ class QrackAceBackend:
|
|
|
857
839
|
if lq in self._lhv:
|
|
858
840
|
self._lhv[lq].h()
|
|
859
841
|
|
|
860
|
-
if len(hq) ==
|
|
842
|
+
if len(hq) == 4:
|
|
843
|
+
# Corner-boundary qubit: 4 real replicas remain (home,
|
|
844
|
+
# adjacent-patch, and the 2 diagonal-patch shadows) now that
|
|
845
|
+
# the crossbar replica that used to sit at old-index-2 is
|
|
846
|
+
# gone. These are exactly the old "end-cap" set
|
|
847
|
+
# [p0, p1, p3, p4] from before removal -- vote via their own
|
|
848
|
+
# RMS pool first, and consult the LHV proxy only as the
|
|
849
|
+
# last-resort tie-breaker on a genuine 2-2 split (the role the
|
|
850
|
+
# crossbar replica used to fill).
|
|
861
851
|
p0 = self.sim[hq[0][0]].prob(hq[0][1])
|
|
862
852
|
p1 = self.sim[hq[1][0]].prob(hq[1][1])
|
|
863
853
|
p2 = self.sim[hq[2][0]].prob(hq[2][1])
|
|
864
854
|
p3 = self.sim[hq[3][0]].prob(hq[3][1])
|
|
865
|
-
p4 = self.sim[hq[4][0]].prob(hq[4][1])
|
|
866
855
|
lhv = self._lhv.get(lq)
|
|
867
856
|
|
|
868
|
-
|
|
869
|
-
# shadow replicas), by analogy with the 3-replica case's
|
|
870
|
-
# slot1/slot2: vote first via their own RMS pool, UNLESS they
|
|
871
|
-
# are in a genuine 2-vs-2 tie, in which case the crossbar
|
|
872
|
-
# replica (hq[2], already weighted specially in the prior
|
|
873
|
-
# flat-pool code) breaks the tie; the LHV is consulted only
|
|
874
|
-
# as a last-resort fallback if the crossbar itself is
|
|
875
|
-
# ambiguous. This is a direct structural analogy to the
|
|
876
|
-
# validated 3-replica cascade, not independently re-derived
|
|
877
|
-
# for this topology -- carried only as far as that cheap
|
|
878
|
-
# analogy supports, per explicit guidance.
|
|
879
|
-
end_caps = [p0, p1, p3, p4]
|
|
857
|
+
end_caps = [p0, p1, p2, p3]
|
|
880
858
|
# Classify each end-cap as decisively high / decisively low /
|
|
881
859
|
# undecided (within epsilon of 0.5), rather than a bare >=0.5
|
|
882
860
|
# check -- a replica reading EXACTLY 0.5 was previously always
|
|
@@ -884,9 +862,9 @@ class QrackAceBackend:
|
|
|
884
862
|
high_count = sum(1 for x in end_caps if x > (0.5 + self._epsilon))
|
|
885
863
|
low_count = sum(1 for x in end_caps if x < (0.5 - self._epsilon))
|
|
886
864
|
undecided_count = len(end_caps) - high_count - low_count
|
|
887
|
-
# Ambiguous (defer to the
|
|
888
|
-
#
|
|
889
|
-
#
|
|
865
|
+
# Ambiguous (defer to the LHV tie-breaker) on a genuine 2-2
|
|
866
|
+
# split, OR if any end-cap is undecided -- an undecided value
|
|
867
|
+
# can't safely be counted toward either side.
|
|
890
868
|
end_caps_tied = (high_count == 2 and low_count == 2) or (undecided_count > 0)
|
|
891
869
|
|
|
892
870
|
if not end_caps_tied:
|
|
@@ -898,8 +876,6 @@ class QrackAceBackend:
|
|
|
898
876
|
if abs(eff_prob - 0.5) <= self._epsilon
|
|
899
877
|
else (eff_prob >= 0.5)
|
|
900
878
|
)
|
|
901
|
-
elif abs(p2 - 0.5) > self._epsilon:
|
|
902
|
-
result = p2 >= 0.5
|
|
903
879
|
elif lhv is not None:
|
|
904
880
|
p_lhv = lhv.prob()
|
|
905
881
|
result = (
|
|
@@ -910,42 +886,41 @@ class QrackAceBackend:
|
|
|
910
886
|
else:
|
|
911
887
|
result = random.random() < 0.5
|
|
912
888
|
|
|
913
|
-
p = [p0, p1, p2, p3
|
|
889
|
+
p = [p0, p1, p2, p3]
|
|
914
890
|
syndrome = [1 - x for x in p] if result else list(p)
|
|
915
|
-
for q in range(
|
|
891
|
+
for q in range(4):
|
|
916
892
|
if syndrome[q] > (0.5 + self._epsilon):
|
|
917
893
|
self.sim[hq[q][0]].x(hq[q][1])
|
|
918
894
|
|
|
919
895
|
if not skip_rotation:
|
|
920
|
-
a, i, w = [0, 0, 0, 0
|
|
896
|
+
a, i, w = [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]
|
|
921
897
|
a[0], i[0], r0 = self._get_bloch_angles(hq[0])
|
|
922
898
|
a[1], i[1], r1 = self._get_bloch_angles(hq[1])
|
|
923
899
|
a[2], i[2], r2 = self._get_bloch_angles(hq[2])
|
|
924
900
|
a[3], i[3], r3 = self._get_bloch_angles(hq[3])
|
|
925
|
-
|
|
926
|
-
w = [1 - r0, 1 - r1, 1 - r2, 1 - r3, 1 - r4]
|
|
901
|
+
w = [1 - r0, 1 - r1, 1 - r2, 1 - r3]
|
|
927
902
|
|
|
928
903
|
w_total = sum(w)
|
|
929
904
|
if w_total > self._epsilon:
|
|
930
905
|
a_target = sum(wx * ax for wx, ax in zip(w, a)) / w_total
|
|
931
906
|
i_target = sum(wx * ix for wx, ix in zip(w, i)) / w_total
|
|
932
907
|
# hq[0] is excluded from the rotation itself, by the
|
|
933
|
-
# same reasoning as the
|
|
908
|
+
# same reasoning as the 2-replica case below: it's
|
|
934
909
|
# allocated identically (unconditionally, first, in
|
|
935
910
|
# the qubit's home-patch simulator) before any
|
|
936
|
-
# boundary
|
|
937
|
-
#
|
|
938
|
-
#
|
|
939
|
-
#
|
|
940
|
-
#
|
|
941
|
-
#
|
|
911
|
+
# boundary-extension logic runs, so it's the replica
|
|
912
|
+
# most likely to carry real, same-simulator coherent
|
|
913
|
+
# entanglement worth protecting from the decoherence a
|
|
914
|
+
# physical rotation would cost it. Indices 1-3 are all
|
|
915
|
+
# boundary-extension slots with no comparable real
|
|
916
|
+
# entanglement to lose.
|
|
942
917
|
# Only rotate a replica that is itself reasonably
|
|
943
918
|
# separable (its own reduced state still has a
|
|
944
919
|
# meaningfully-defined Bloch direction). A replica
|
|
945
920
|
# that's picked up genuine entanglement with another
|
|
946
921
|
# logical qubit's replica (e.g. via a real gate_fn
|
|
947
922
|
# coupling in _apply_coupling -- not just slot0; any
|
|
948
|
-
# of slots 1-
|
|
923
|
+
# of slots 1-3 can end up real-coupled depending on
|
|
949
924
|
# geometry) reads a Bloch vector dominated by
|
|
950
925
|
# simulator floating-point noise, not real
|
|
951
926
|
# information. Rotating it "toward consensus" in that
|
|
@@ -970,8 +945,8 @@ class QrackAceBackend:
|
|
|
970
945
|
# replica is "more entangled than separable" and is
|
|
971
946
|
# left alone; short of it, the rotation still does
|
|
972
947
|
# real, useful reconciliation work.
|
|
973
|
-
for x in range(1,
|
|
974
|
-
if [r0, r1, r2, r3
|
|
948
|
+
for x in range(1, 4):
|
|
949
|
+
if [r0, r1, r2, r3][x] <= self._rot_epsilon:
|
|
975
950
|
self._rotate_to_bloch(hq[x], a_target - a[x], i_target - i[x])
|
|
976
951
|
# If every replica reads as maximally mixed (w_total ~ 0),
|
|
977
952
|
# there is no well-defined direction to rotate toward at
|
|
@@ -979,62 +954,61 @@ class QrackAceBackend:
|
|
|
979
954
|
# arbitrary/undefined target derived from noise.
|
|
980
955
|
|
|
981
956
|
else:
|
|
957
|
+
# Edge-boundary qubit: only 2 real replicas remain (home +
|
|
958
|
+
# adjacent-patch) now that the crossbar replica that used to
|
|
959
|
+
# sit at old-index-2 is gone. The classical LHV proxy takes
|
|
960
|
+
# over the crossbar's old role as "slot2" in the conditional
|
|
961
|
+
# tie-breaking cascade below.
|
|
982
962
|
lhv = self._lhv.get(lq)
|
|
963
|
+
p0 = self.sim[hq[0][0]].prob(hq[0][1])
|
|
964
|
+
p1 = self.sim[hq[1][0]].prob(hq[1][1])
|
|
965
|
+
|
|
983
966
|
if lhv is None:
|
|
984
|
-
#
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
# Balancing suggestion from Elara (the custom OpenAI GPT)
|
|
991
|
-
prms = math.sqrt((p[0] ** 2 + p[1] ** 2 + p[2] ** 2) / 3)
|
|
992
|
-
qrms = math.sqrt(((1 - p[0]) ** 2 + (1 - p[1]) ** 2 + (1 - p[2]) ** 2) / 3)
|
|
967
|
+
# No LHV proxy exists (shouldn't normally happen for a
|
|
968
|
+
# boundary qubit, since the constructor always creates
|
|
969
|
+
# one -- handled defensively anyway): fall back to a
|
|
970
|
+
# plain 2-way RMS pool over the two real replicas.
|
|
971
|
+
prms = math.sqrt((p0**2 + p1**2) / 2)
|
|
972
|
+
qrms = math.sqrt(((1 - p0) ** 2 + (1 - p1) ** 2) / 2)
|
|
993
973
|
eff_prob = (prms + (1 - qrms)) / 2
|
|
994
974
|
result = (
|
|
995
975
|
(random.random() < 0.5)
|
|
996
976
|
if abs(eff_prob - 0.5) <= self._epsilon
|
|
997
977
|
else (eff_prob >= 0.5)
|
|
998
978
|
)
|
|
999
|
-
syndrome = [1 -
|
|
1000
|
-
for q in range(
|
|
979
|
+
syndrome = [1 - p0, 1 - p1] if result else [p0, p1]
|
|
980
|
+
for q in range(2):
|
|
1001
981
|
if syndrome[q] > (0.5 + self._epsilon):
|
|
1002
982
|
self.sim[hq[q][0]].x(hq[q][1])
|
|
1003
983
|
# end_caps_agree is referenced unconditionally below (to
|
|
1004
984
|
# decide whether the rotation step is worth doing at all);
|
|
1005
985
|
# this branch has no separate "end-caps vs slot0" concept
|
|
1006
986
|
# the way the has-LHV branch does, so the analogous check
|
|
1007
|
-
# is simply whether
|
|
987
|
+
# is simply whether both replicas already decisively
|
|
1008
988
|
# agree with each other.
|
|
1009
|
-
all_high =
|
|
1010
|
-
all_low =
|
|
989
|
+
all_high = p0 > (0.5 + self._epsilon) and p1 > (0.5 + self._epsilon)
|
|
990
|
+
all_low = p0 < (0.5 - self._epsilon) and p1 < (0.5 - self._epsilon)
|
|
1011
991
|
end_caps_agree = all_high or all_low
|
|
1012
992
|
else:
|
|
1013
|
-
# Conditional tie-breaking cascade, NOT a fixed-weight pool
|
|
1014
|
-
#
|
|
1015
|
-
#
|
|
1016
|
-
#
|
|
1017
|
-
#
|
|
1018
|
-
#
|
|
1019
|
-
# 0
|
|
1020
|
-
#
|
|
1021
|
-
# only
|
|
1022
|
-
# weight: trust slot1/slot2 alone whenever they agree, and
|
|
1023
|
-
# only consult slot0, then lhv, when they genuinely don't.
|
|
1024
|
-
#
|
|
1025
|
-
p0 = self.sim[hq[0][0]].prob(hq[0][1])
|
|
1026
|
-
p1 = self.sim[hq[1][0]].prob(hq[1][1])
|
|
1027
|
-
p2 = self.sim[hq[2][0]].prob(hq[2][1])
|
|
993
|
+
# Conditional tie-breaking cascade, NOT a fixed-weight pool
|
|
994
|
+
# -- same structure as before the crossbar was removed,
|
|
995
|
+
# with the (now-removed) crossbar replica's old role as
|
|
996
|
+
# "slot2" taken over by the classical LHV proxy: trust
|
|
997
|
+
# slot1 (hq[1], the real adjacent-patch replica) and the
|
|
998
|
+
# LHV together whenever they agree; fall back to slot0
|
|
999
|
+
# (hq[0], home) when they disagree and it has a decisive
|
|
1000
|
+
# opinion; consult the LHV alone, as an absolute last
|
|
1001
|
+
# resort, only when slot0 is also ambiguous.
|
|
1028
1002
|
p_lhv = lhv.prob()
|
|
1029
1003
|
|
|
1030
|
-
# Same fix as the
|
|
1031
|
-
# decisively high / low / undecided rather than a bare
|
|
1004
|
+
# Same fix as the 4-replica branch above: classify p1/lhv
|
|
1005
|
+
# as decisively high / low / undecided rather than a bare
|
|
1032
1006
|
# >=0.5 check.
|
|
1033
1007
|
p1_high = p1 > (0.5 + self._epsilon)
|
|
1034
1008
|
p1_low = p1 < (0.5 - self._epsilon)
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
end_caps_agree = (p1_high and
|
|
1009
|
+
lhv_high = p_lhv > (0.5 + self._epsilon)
|
|
1010
|
+
lhv_low = p_lhv < (0.5 - self._epsilon)
|
|
1011
|
+
end_caps_agree = (p1_high and lhv_high) or (p1_low and lhv_low)
|
|
1038
1012
|
slot0_disagrees_with_end_caps = (
|
|
1039
1013
|
end_caps_agree
|
|
1040
1014
|
and (abs(p0 - 0.5) > self._epsilon)
|
|
@@ -1055,8 +1029,8 @@ class QrackAceBackend:
|
|
|
1055
1029
|
# itself default below.
|
|
1056
1030
|
result = p0 >= 0.5
|
|
1057
1031
|
elif end_caps_agree:
|
|
1058
|
-
prms = math.sqrt((p1**2 +
|
|
1059
|
-
qrms = math.sqrt(((1 - p1) ** 2 + (1 -
|
|
1032
|
+
prms = math.sqrt((p1**2 + p_lhv**2) / 2)
|
|
1033
|
+
qrms = math.sqrt(((1 - p1) ** 2 + (1 - p_lhv) ** 2) / 2)
|
|
1060
1034
|
eff_prob = (prms + (1 - qrms)) / 2
|
|
1061
1035
|
result = (
|
|
1062
1036
|
(random.random() < 0.5)
|
|
@@ -1064,9 +1038,9 @@ class QrackAceBackend:
|
|
|
1064
1038
|
else (eff_prob >= 0.5)
|
|
1065
1039
|
)
|
|
1066
1040
|
elif abs(p0 - 0.5) > self._epsilon:
|
|
1067
|
-
# Genuine deadlock between slot1
|
|
1068
|
-
# exactly-entangled qubit in this common
|
|
1069
|
-
# a real opinion, so it breaks the tie.
|
|
1041
|
+
# Genuine deadlock between slot1 and the LHV; slot0 (a
|
|
1042
|
+
# real, exactly-entangled qubit in this common
|
|
1043
|
+
# topology) has a real opinion, so it breaks the tie.
|
|
1070
1044
|
result = p0 >= 0.5
|
|
1071
1045
|
else:
|
|
1072
1046
|
# slot0 is itself ambiguous; only now does the LHV's
|
|
@@ -1077,9 +1051,9 @@ class QrackAceBackend:
|
|
|
1077
1051
|
else (p_lhv >= 0.5)
|
|
1078
1052
|
)
|
|
1079
1053
|
|
|
1080
|
-
p = [p0, p1
|
|
1054
|
+
p = [p0, p1]
|
|
1081
1055
|
syndrome = [1 - x for x in p] if result else list(p)
|
|
1082
|
-
for q in range(
|
|
1056
|
+
for q in range(2):
|
|
1083
1057
|
if syndrome[q] > (0.5 + self._epsilon):
|
|
1084
1058
|
self.sim[hq[q][0]].x(hq[q][1])
|
|
1085
1059
|
# The LHV proxy is never hard-collapsed via x(); it is only
|
|
@@ -1088,11 +1062,10 @@ class QrackAceBackend:
|
|
|
1088
1062
|
# as a non-collapsing tie-breaker of last resort.
|
|
1089
1063
|
|
|
1090
1064
|
if (not skip_rotation) and (not end_caps_agree):
|
|
1091
|
-
a, i, w = [0, 0
|
|
1065
|
+
a, i, w = [0, 0], [0, 0], [0, 0]
|
|
1092
1066
|
a[0], i[0], r0 = self._get_bloch_angles(hq[0])
|
|
1093
1067
|
a[1], i[1], r1 = self._get_bloch_angles(hq[1])
|
|
1094
|
-
|
|
1095
|
-
w = [1 - r0, 1 - r1, 1 - r2]
|
|
1068
|
+
w = [1 - r0, 1 - r1]
|
|
1096
1069
|
|
|
1097
1070
|
w_total = sum(w)
|
|
1098
1071
|
if w_total > self._epsilon:
|
|
@@ -1106,14 +1079,14 @@ class QrackAceBackend:
|
|
|
1106
1079
|
# well-intentioned averaged target -- is a real
|
|
1107
1080
|
# decoherence event on that relationship. slot0's
|
|
1108
1081
|
# Bloch angles still inform the target above (so
|
|
1109
|
-
# slot1
|
|
1110
|
-
#
|
|
1111
|
-
#
|
|
1112
|
-
#
|
|
1113
|
-
# rotated
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1082
|
+
# slot1 reconciles toward a value that accounts for
|
|
1083
|
+
# what slot0 currently shows), but only slot1 (the
|
|
1084
|
+
# lossy shadow replica, which has no comparable real
|
|
1085
|
+
# entanglement to lose) is actually rotated -- the
|
|
1086
|
+
# LHV proxy is never physically rotated either, since
|
|
1087
|
+
# it isn't a real qubit.
|
|
1088
|
+
if r1 <= self._rot_epsilon:
|
|
1089
|
+
self._rotate_to_bloch(hq[1], a_target - a[1], i_target - i[1])
|
|
1117
1090
|
|
|
1118
1091
|
if phase:
|
|
1119
1092
|
for q in qb:
|
|
@@ -1438,7 +1411,13 @@ class QrackAceBackend:
|
|
|
1438
1411
|
# the single-replica CZ dual-check elsewhere.
|
|
1439
1412
|
anc2 = None
|
|
1440
1413
|
if self.is_error_detection and not self._in_gadget_capture and (len(hq1) > 1):
|
|
1441
|
-
|
|
1414
|
+
anc_sim = hq1[0][0]
|
|
1415
|
+
t_sims = {y[0] for y in hq2 if y[0] >= 0}
|
|
1416
|
+
for x in hq1:
|
|
1417
|
+
if x[0] in t_sims:
|
|
1418
|
+
anc_sim = x[0]
|
|
1419
|
+
break
|
|
1420
|
+
anc2 = self._detect_ancilla2_lq[anc_sim]
|
|
1442
1421
|
self._in_gadget_capture = True
|
|
1443
1422
|
# XOR on target
|
|
1444
1423
|
self.cx(lq2, anc2)
|
|
@@ -1562,9 +1541,9 @@ class QrackAceBackend:
|
|
|
1562
1541
|
|
|
1563
1542
|
qb1, _ = QrackAceBackend._get_qb_lhv_indices(hq1)
|
|
1564
1543
|
|
|
1565
|
-
# Apply cross coupling on every
|
|
1566
|
-
#
|
|
1567
|
-
# Also apply across target repetition.
|
|
1544
|
+
# Apply cross coupling on every real replica in hq1/h2 (the LHV
|
|
1545
|
+
# proxy is coupled separately, just below, via _cpauli_lhv -- it
|
|
1546
|
+
# is not one of hq's indices). Also apply across target repetition.
|
|
1568
1547
|
for l2 in t2:
|
|
1569
1548
|
h2 = self._unpack(l2)
|
|
1570
1549
|
qb2, _ = QrackAceBackend._get_qb_lhv_indices(h2)
|
|
@@ -1910,12 +1889,14 @@ class QrackAceBackend:
|
|
|
1910
1889
|
|
|
1911
1890
|
anc1, anc2 = None, None
|
|
1912
1891
|
if self.is_error_detection and not self._in_gadget_capture and ((len(hq1) > 1) or (len(hq2) > 1)):
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1892
|
+
t_sims = {y[0] for y in hq2 if y[0] >= 0}
|
|
1893
|
+
anc_sim = hq1[0][0]
|
|
1894
|
+
for x in hq1:
|
|
1895
|
+
if x[0] in t_sims:
|
|
1896
|
+
anc_sim = x[0]
|
|
1897
|
+
break
|
|
1898
|
+
anc1 = self._detect_ancilla1_lq[anc_sim]
|
|
1899
|
+
anc2 = self._detect_ancilla2_lq[anc_sim]
|
|
1919
1900
|
self._in_gadget_capture = True
|
|
1920
1901
|
self.cx(lq1, anc1)
|
|
1921
1902
|
self.cx(lq2, anc2)
|
|
@@ -2020,25 +2001,6 @@ class QrackAceBackend:
|
|
|
2020
2001
|
self.mcx([c1, c2], t)
|
|
2021
2002
|
return
|
|
2022
2003
|
|
|
2023
|
-
if len(hqt) > 1:
|
|
2024
|
-
self.h(t)
|
|
2025
|
-
self.cx(c2, t)
|
|
2026
|
-
self.adjt(t)
|
|
2027
|
-
self.cx(c1, t)
|
|
2028
|
-
self.t(t)
|
|
2029
|
-
self.cx(c2, t)
|
|
2030
|
-
self.adjt(t)
|
|
2031
|
-
self.cx(c1, t)
|
|
2032
|
-
self.t(t)
|
|
2033
|
-
self.h(t)
|
|
2034
|
-
self.t(c2)
|
|
2035
|
-
self.cx(c1, c2)
|
|
2036
|
-
self.t(c1)
|
|
2037
|
-
self.adjt(c2)
|
|
2038
|
-
self.cx(c1, c2)
|
|
2039
|
-
return
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
2004
|
if not self._in_gadget_capture:
|
|
2043
2005
|
self._correct(c1)
|
|
2044
2006
|
self._correct(c2)
|
|
@@ -2066,9 +2028,24 @@ class QrackAceBackend:
|
|
|
2066
2028
|
# bulk on this path (the len(hqt) > 1 case returns earlier,
|
|
2067
2029
|
# above) and nothing else in this method uses that array anymore.
|
|
2068
2030
|
anc_and = None
|
|
2069
|
-
if self.is_error_detection and not self._in_gadget_capture and ((len(hq1) > 1) or (len(hq2) > 1)):
|
|
2031
|
+
if self.is_error_detection and not self._in_gadget_capture and ((len(hq1) > 1) or (len(hq2) > 1) or (len(hqt) > 1)):
|
|
2032
|
+
found = False
|
|
2033
|
+
anc_sim = hq1[0][0]
|
|
2034
|
+
t_sims = {y[0] for y in hqt if y[0] >= 0}
|
|
2035
|
+
for x in hq1:
|
|
2036
|
+
if (x[0] < 0) or (x[0] not in t_sims):
|
|
2037
|
+
continue
|
|
2038
|
+
anc_sim = x[0]
|
|
2039
|
+
for y in hq2:
|
|
2040
|
+
if (y[0] < 0) or (y[0] not in t_sims):
|
|
2041
|
+
continue
|
|
2042
|
+
if anc_sim == y[0]:
|
|
2043
|
+
found = True
|
|
2044
|
+
break
|
|
2045
|
+
if found:
|
|
2046
|
+
break
|
|
2070
2047
|
self._in_gadget_capture = True
|
|
2071
|
-
anc_and = self._detect_ancilla2_lq[
|
|
2048
|
+
anc_and = self._detect_ancilla2_lq[anc_sim]
|
|
2072
2049
|
self.cx(t, anc_and)
|
|
2073
2050
|
# self.mcx() only supports a single control at the logical
|
|
2074
2051
|
# level (a syntax-convenience wrapper, confirmed directly --
|
|
@@ -2084,7 +2061,6 @@ class QrackAceBackend:
|
|
|
2084
2061
|
# skips setting up a second anc_and, and just performs the
|
|
2085
2062
|
# ordinary native-witness-or-shadow Toffoli computation on
|
|
2086
2063
|
# anc_and instead.
|
|
2087
|
-
anc_sim = hqt[0][0]
|
|
2088
2064
|
c1_idx = next((r[1] for r in hq1 if r[0] == anc_sim), None)
|
|
2089
2065
|
c2_idx = next((r[1] for r in hq2 if r[0] == anc_sim), None)
|
|
2090
2066
|
if (c1_idx is not None) and (c2_idx is not None):
|
|
@@ -2098,26 +2074,67 @@ class QrackAceBackend:
|
|
|
2098
2074
|
qb2, _ = QrackAceBackend._get_qb_lhv_indices(hq2)
|
|
2099
2075
|
qbt, _ = QrackAceBackend._get_qb_lhv_indices(hqt)
|
|
2100
2076
|
|
|
2077
|
+
witnesses = []
|
|
2078
|
+
needs_shadow = False
|
|
2101
2079
|
for qt in qbt:
|
|
2102
|
-
witness = None
|
|
2103
2080
|
bt = hqt[qt]
|
|
2081
|
+
witness = None
|
|
2104
2082
|
for q1 in qb1:
|
|
2105
2083
|
b1 = hq1[q1]
|
|
2106
2084
|
for q2 in qb2:
|
|
2107
2085
|
b2 = hq2[q2]
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
if bt[0] == b1[0] and bt[0] == b2[0]:
|
|
2111
|
-
witness = bt
|
|
2112
|
-
break
|
|
2113
|
-
if witness is not None:
|
|
2086
|
+
if bt[0] == b1[0] and bt[0] == b2[0]:
|
|
2087
|
+
witness = (b1, b2, bt)
|
|
2114
2088
|
break
|
|
2115
2089
|
if witness is not None:
|
|
2116
2090
|
break
|
|
2117
|
-
if witness:
|
|
2091
|
+
if witness is None:
|
|
2092
|
+
needs_shadow = True
|
|
2093
|
+
break
|
|
2094
|
+
witnesses.append(witness)
|
|
2095
|
+
|
|
2096
|
+
if needs_shadow:
|
|
2097
|
+
# Confirmed directly: whenever even one replica of t lacks a
|
|
2098
|
+
# native witness shared with c1 and c2, the per-replica
|
|
2099
|
+
# fallback to _ccx_shadow craters fidelity specifically when
|
|
2100
|
+
# either control is in genuine superposition -- 0.64-0.68
|
|
2101
|
+
# vs. 0.999+ for every other input tested, stable from 100 to
|
|
2102
|
+
# 2500 shots, so not shot noise. Diverting the WHOLE
|
|
2103
|
+
# operation (not just the unwitnessed replica) to the general
|
|
2104
|
+
# 6-CX decomposition instead: every step here is a genuine
|
|
2105
|
+
# logical cx()/h()/t()/adjt() call, which updates every
|
|
2106
|
+
# replica of t through the same _apply_coupling boundary-
|
|
2107
|
+
# crossing machinery already validated elsewhere in this
|
|
2108
|
+
# file, rather than the lower-level per-replica _cx_shadow
|
|
2109
|
+
# calls _ccx_shadow uses for just the unwitnessed ones.
|
|
2110
|
+
#
|
|
2111
|
+
# Wrapped in _in_gadget_capture, same as established earlier:
|
|
2112
|
+
# without it, each individual cx() here would independently
|
|
2113
|
+
# trigger its own XOR-invariant gadget setup, which corrupts
|
|
2114
|
+
# the precise T/Tdg phase relationships this decomposition
|
|
2115
|
+
# depends on (confirmed directly, the first time this
|
|
2116
|
+
# decomposition was used unconditionally -- corrupted even
|
|
2117
|
+
# c1/c2, which the per-replica path never touched at all).
|
|
2118
|
+
self._in_gadget_capture = True
|
|
2119
|
+
self.h(t)
|
|
2120
|
+
self.cx(c2, t)
|
|
2121
|
+
self.adjt(t)
|
|
2122
|
+
self.cx(c1, t)
|
|
2123
|
+
self.t(t)
|
|
2124
|
+
self.cx(c2, t)
|
|
2125
|
+
self.adjt(t)
|
|
2126
|
+
self.cx(c1, t)
|
|
2127
|
+
self.t(t)
|
|
2128
|
+
self.h(t)
|
|
2129
|
+
self.t(c2)
|
|
2130
|
+
self.cx(c1, c2)
|
|
2131
|
+
self.t(c1)
|
|
2132
|
+
self.adjt(c2)
|
|
2133
|
+
self.cx(c1, c2)
|
|
2134
|
+
self._in_gadget_capture = False
|
|
2135
|
+
else:
|
|
2136
|
+
for (b1, b2, bt) in witnesses:
|
|
2118
2137
|
self.sim[b1[0]].mcx([b1[1], b2[1]], bt[1])
|
|
2119
|
-
else:
|
|
2120
|
-
self._ccx_shadow(b1, b2, bt, c1, c2, t)
|
|
2121
2138
|
|
|
2122
2139
|
self._in_gadget_capture = True
|
|
2123
2140
|
|
|
@@ -2156,54 +2173,36 @@ class QrackAceBackend:
|
|
|
2156
2173
|
return self.sim[b[0]].prob(b[1])
|
|
2157
2174
|
|
|
2158
2175
|
self._correct(lq)
|
|
2159
|
-
if len(hq) ==
|
|
2160
|
-
#
|
|
2176
|
+
if len(hq) == 4:
|
|
2177
|
+
# The 4 real replicas are already mutually consistent here
|
|
2178
|
+
# (the _correct() call above already ran the tie-breaking
|
|
2179
|
+
# cascade, using the LHV proxy as needed, and forced
|
|
2180
|
+
# agreement via x()). A plain, unweighted RMS over the
|
|
2181
|
+
# now-settled replicas is the correct, already-decided
|
|
2182
|
+
# answer -- there is no crossbar replica left to weight
|
|
2183
|
+
# specially any more.
|
|
2161
2184
|
p = [
|
|
2162
2185
|
self.sim[hq[0][0]].prob(hq[0][1]),
|
|
2163
2186
|
self.sim[hq[1][0]].prob(hq[1][1]),
|
|
2164
2187
|
self.sim[hq[2][0]].prob(hq[2][1]),
|
|
2165
2188
|
self.sim[hq[3][0]].prob(hq[3][1]),
|
|
2166
|
-
self.sim[hq[4][0]].prob(hq[4][1]),
|
|
2167
2189
|
]
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
qrms = math.sqrt(
|
|
2171
|
-
(
|
|
2172
|
-
(1 - p[0]) ** 2
|
|
2173
|
-
+ (1 - p[1]) ** 2
|
|
2174
|
-
+ 3 * ((1 - p[2]) ** 2)
|
|
2175
|
-
+ (1 - p[3]) ** 2
|
|
2176
|
-
+ (1 - p[4]) ** 2
|
|
2177
|
-
)
|
|
2178
|
-
/ 7
|
|
2179
|
-
)
|
|
2190
|
+
prms = math.sqrt(sum(x**2 for x in p) / 4)
|
|
2191
|
+
qrms = math.sqrt(sum((1 - x) ** 2 for x in p) / 4)
|
|
2180
2192
|
else:
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
self.sim[hq[0][0]].prob(hq[0][1]),
|
|
2195
|
-
self.sim[hq[1][0]].prob(hq[1][1]),
|
|
2196
|
-
self.sim[hq[2][0]].prob(hq[2][1]),
|
|
2197
|
-
]
|
|
2198
|
-
# The three real replicas are already mutually consistent
|
|
2199
|
-
# here (the _correct() call above already ran the
|
|
2200
|
-
# conditional tie-breaking cascade and forced agreement via
|
|
2201
|
-
# x()). Re-weighting in the LHV here would reintroduce the
|
|
2202
|
-
# same center-dragging distortion the cascade was built to
|
|
2203
|
-
# avoid -- a plain RMS over the now-settled replicas is the
|
|
2204
|
-
# correct, already-decided answer.
|
|
2205
|
-
prms = math.sqrt((p[0] ** 2 + p[1] ** 2 + p[2] ** 2) / 3)
|
|
2206
|
-
qrms = math.sqrt(((1 - p[0]) ** 2 + (1 - p[1]) ** 2 + (1 - p[2]) ** 2) / 3)
|
|
2193
|
+
# The 2 real replicas are already mutually consistent here
|
|
2194
|
+
# (the _correct() call above already ran the conditional
|
|
2195
|
+
# tie-breaking cascade, using the LHV proxy as needed, and
|
|
2196
|
+
# forced agreement via x()). Re-weighting in the LHV here
|
|
2197
|
+
# would reintroduce the same center-dragging distortion the
|
|
2198
|
+
# cascade was built to avoid -- a plain RMS over the
|
|
2199
|
+
# now-settled pair is the correct, already-decided answer.
|
|
2200
|
+
p = [
|
|
2201
|
+
self.sim[hq[0][0]].prob(hq[0][1]),
|
|
2202
|
+
self.sim[hq[1][0]].prob(hq[1][1]),
|
|
2203
|
+
]
|
|
2204
|
+
prms = math.sqrt((p[0] ** 2 + p[1] ** 2) / 2)
|
|
2205
|
+
qrms = math.sqrt(((1 - p[0]) ** 2 + (1 - p[1]) ** 2) / 2)
|
|
2207
2206
|
|
|
2208
2207
|
return (prms + (1 - qrms)) / 2
|
|
2209
2208
|
|
|
@@ -3502,10 +3502,26 @@ class QrackSimulator:
|
|
|
3502
3502
|
return out
|
|
3503
3503
|
|
|
3504
3504
|
def lossy_out_to_file(self, f, p=6, b=4):
|
|
3505
|
+
"""TurboQuant-based state out-to-file (for all simulator types)
|
|
3506
|
+
|
|
3507
|
+
Saves the simulator state to file, with TurboQuant-based lossy compression.
|
|
3508
|
+
|
|
3509
|
+
Args:
|
|
3510
|
+
f: Name of file
|
|
3511
|
+
p: base-2 exponent of block size
|
|
3512
|
+
b: compressed bits per block
|
|
3513
|
+
"""
|
|
3505
3514
|
Qrack.qrack_lib.lossy_out_to_file(self.sid, f.encode("utf-8"), min(p, self.num_qubits()), b)
|
|
3506
3515
|
self._throw_if_error()
|
|
3507
3516
|
|
|
3508
3517
|
def lossy_in_from_file(self, f):
|
|
3518
|
+
"""TurboQuant-based state in-from-file (for all simulator types)
|
|
3519
|
+
|
|
3520
|
+
Loads the simulator state from file, with TurboQuant-based lossy compression.
|
|
3521
|
+
|
|
3522
|
+
Args:
|
|
3523
|
+
f: Name of file
|
|
3524
|
+
"""
|
|
3509
3525
|
Qrack.qrack_lib.lossy_in_from_file(self.sid, f.encode("utf-8"))
|
|
3510
3526
|
self._throw_if_error()
|
|
3511
3527
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/neuron_activation_fn.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/qrack_neuron_torch_layer.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/qrack_system/__init__.py
RENAMED
|
File without changes
|
{pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/qrack_system/qrack_system.py
RENAMED
|
File without changes
|
{pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/quimb_circuit_type.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/stats/load_quantized_data.py
RENAMED
|
File without changes
|
{pyqrack_cpu_complex128-2.25.4 → pyqrack_cpu_complex128-2.26.0}/pyqrack/stats/quantize_by_range.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|