pyqrack-complex128 2.29.0__tar.gz → 2.29.2__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_complex128-2.29.0/pyqrack_complex128.egg-info → pyqrack_complex128-2.29.2}/PKG-INFO +1 -1
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_ace_backend.py +66 -118
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2/pyqrack_complex128.egg-info}/PKG-INFO +1 -1
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/setup.py +1 -1
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/LICENSE +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/MANIFEST.in +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/Makefile +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/README.md +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyproject.toml +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/__init__.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/neuron_activation_fn.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/pauli.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_ace_mps_backend.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_circuit.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_near_clifford_qec_backend.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_neuron.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_neuron_torch_layer.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_simulator.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_stabilizer.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_system/qrack_system.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/stats/load_quantized_data.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/stats/quantize_by_range.py +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/SOURCES.txt +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/dependency_links.txt +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/not-zip-safe +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/requires.txt +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/top_level.txt +0 -0
- {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/setup.cfg +0 -0
|
@@ -317,7 +317,7 @@ class QrackAceBackend:
|
|
|
317
317
|
# between "more separable" (rotation toward consensus is real,
|
|
318
318
|
# useful reconciliation) and "more entangled" (rotation only
|
|
319
319
|
# scrambles a real correlation with another logical qubit's
|
|
320
|
-
# replica -- see
|
|
320
|
+
# replica -- see correct). Default is the point where a single
|
|
321
321
|
# qubit's linear entropy is half its maximum.
|
|
322
322
|
self._rot_epsilon = (1.0 - 1.0 / math.sqrt(2)) / 2
|
|
323
323
|
|
|
@@ -340,7 +340,7 @@ class QrackAceBackend:
|
|
|
340
340
|
# rather than surgically suppressing the wrap step further
|
|
341
341
|
# down (which was tried and reverted -- it produced replica
|
|
342
342
|
# counts, e.g. 2, that the rest of the class was never built
|
|
343
|
-
# to handle, via _get_qb_lhv_indices/
|
|
343
|
+
# to handle, via _get_qb_lhv_indices/correct, which assume
|
|
344
344
|
# counts of 1, 3, or 5 only), means every code path that fires
|
|
345
345
|
# for is_torus=False is one that already exists and is already
|
|
346
346
|
# tested for is_torus=True; only WHICH positions take which
|
|
@@ -373,7 +373,7 @@ class QrackAceBackend:
|
|
|
373
373
|
# for a handful of patches. Every boundary qubit ALSO still gets
|
|
374
374
|
# its classical LHVQubit proxy (self.lhv, below) regardless, same
|
|
375
375
|
# as when this option is off: with the crossbar on, the proxy
|
|
376
|
-
# drops to being only the last-resort tie-breaker
|
|
376
|
+
# drops to being only the last-resort tie-breaker correct() falls
|
|
377
377
|
# back to when even the crossbar replica is itself ambiguous; with
|
|
378
378
|
# it off, the proxy is promoted to cover the crossbar's old
|
|
379
379
|
# tie-breaking role directly.
|
|
@@ -459,11 +459,11 @@ class QrackAceBackend:
|
|
|
459
459
|
# ancilla already allocated there. See _apply_coupling for why
|
|
460
460
|
# this needs to be a genuine logical qubit and not just a raw
|
|
461
461
|
# physical capture: capturing lq1's LOGICAL value via a real,
|
|
462
|
-
# nested cx(lq1, anc) call goes through the full
|
|
462
|
+
# nested cx(lq1, anc) call goes through the full correct()/
|
|
463
463
|
# shadow-coupling machinery robustly, the same way any other
|
|
464
464
|
# logical qubit's value would be determined -- watching one
|
|
465
465
|
# specific physical replica directly (an earlier version of
|
|
466
|
-
# this) isn't a valid invariant, since
|
|
466
|
+
# this) isn't a valid invariant, since correct() can
|
|
467
467
|
# legitimately need to change any single replica's own value.
|
|
468
468
|
self.detect_ancilla_lq = []
|
|
469
469
|
if self.is_error_detection:
|
|
@@ -877,7 +877,7 @@ class QrackAceBackend:
|
|
|
877
877
|
|
|
878
878
|
sim.mtrx([m00, m01, m10, m11])
|
|
879
879
|
|
|
880
|
-
def
|
|
880
|
+
def correct(self, lq, phase=False, skip_rotation=False):
|
|
881
881
|
hq = self._unpack(lq)
|
|
882
882
|
|
|
883
883
|
if len(hq) == 1:
|
|
@@ -1337,7 +1337,7 @@ class QrackAceBackend:
|
|
|
1337
1337
|
if lhv is not None:
|
|
1338
1338
|
lhv.u(th, ph, lm)
|
|
1339
1339
|
|
|
1340
|
-
# Correction deferred to next 2-qubit gate (_cpauli calls
|
|
1340
|
+
# Correction deferred to next 2-qubit gate (_cpauli calls correct)
|
|
1341
1341
|
|
|
1342
1342
|
def r(self, p, th, lq):
|
|
1343
1343
|
hq = self._unpack(lq)
|
|
@@ -1361,7 +1361,7 @@ class QrackAceBackend:
|
|
|
1361
1361
|
elif p == Pauli.PauliZ:
|
|
1362
1362
|
lhv.rz(th)
|
|
1363
1363
|
|
|
1364
|
-
# Correction deferred to next 2-qubit gate (_cpauli calls
|
|
1364
|
+
# Correction deferred to next 2-qubit gate (_cpauli calls correct)
|
|
1365
1365
|
|
|
1366
1366
|
def h(self, lq):
|
|
1367
1367
|
hq = self._unpack(lq)
|
|
@@ -1380,7 +1380,7 @@ class QrackAceBackend:
|
|
|
1380
1380
|
if lhv is not None:
|
|
1381
1381
|
lhv.h()
|
|
1382
1382
|
|
|
1383
|
-
# Correction deferred to next 2-qubit gate (_cpauli calls
|
|
1383
|
+
# Correction deferred to next 2-qubit gate (_cpauli calls correct)
|
|
1384
1384
|
|
|
1385
1385
|
def s(self, lq):
|
|
1386
1386
|
hq = self._unpack(lq)
|
|
@@ -1647,8 +1647,8 @@ class QrackAceBackend:
|
|
|
1647
1647
|
self._in_gadget_capture = False
|
|
1648
1648
|
|
|
1649
1649
|
if not self._in_gadget_capture:
|
|
1650
|
-
self.
|
|
1651
|
-
self.
|
|
1650
|
+
self.correct(lq1)
|
|
1651
|
+
self.correct(lq2)
|
|
1652
1652
|
|
|
1653
1653
|
# A target replica (q2) that shares a simulator with ANY control
|
|
1654
1654
|
# replica in qb1 is going to receive a REAL, exact gate from that
|
|
@@ -1662,7 +1662,7 @@ class QrackAceBackend:
|
|
|
1662
1662
|
# invert the correlation sign the real CNOT is about to
|
|
1663
1663
|
# establish. Confirmed directly: for a boundary-to-boundary
|
|
1664
1664
|
# coupling, measuring the raw physical replica pairs that DO
|
|
1665
|
-
# share a simulator (bypassing all of
|
|
1665
|
+
# share a simulator (bypassing all of correct/m's classical
|
|
1666
1666
|
# reconciliation, and with is_error_detection off) showed near-
|
|
1667
1667
|
# perfect agreement for the one pair untouched by any earlier
|
|
1668
1668
|
# shadow write, but only ~50-60% agreement (chance level) for
|
|
@@ -1704,9 +1704,9 @@ class QrackAceBackend:
|
|
|
1704
1704
|
|
|
1705
1705
|
if not self._in_gadget_capture:
|
|
1706
1706
|
if pauli != Pauli.PauliZ:
|
|
1707
|
-
self.
|
|
1707
|
+
self.correct(lq2, False, pauli != Pauli.PauliX)
|
|
1708
1708
|
if pauli != Pauli.PauliX:
|
|
1709
|
-
self.
|
|
1709
|
+
self.correct(lq2, True)
|
|
1710
1710
|
|
|
1711
1711
|
if anc is not None:
|
|
1712
1712
|
self._in_gadget_capture = True
|
|
@@ -2022,10 +2022,10 @@ class QrackAceBackend:
|
|
|
2022
2022
|
# decomposition for SDRP to truncate. This is the case the noise
|
|
2023
2023
|
# model's common-fraction term assumes is error-free.
|
|
2024
2024
|
|
|
2025
|
-
# _cpauli normally wraps every coupling gate with
|
|
2025
|
+
# _cpauli normally wraps every coupling gate with correct() before
|
|
2026
2026
|
# and after, to reconcile multi-replica consensus. This method
|
|
2027
2027
|
# calls the underlying simulators (and _cx_shadow) directly,
|
|
2028
|
-
# bypassing that wrapper entirely --
|
|
2028
|
+
# bypassing that wrapper entirely -- correct() is a no-op for
|
|
2029
2029
|
# single-replica (bulk) qubits, so this is always safe to call, and
|
|
2030
2030
|
# only actually matters (and was being silently skipped) whenever
|
|
2031
2031
|
# either side is a multi-replica boundary qubit.
|
|
@@ -2092,8 +2092,8 @@ class QrackAceBackend:
|
|
|
2092
2092
|
self.cx(lq2, lq1)
|
|
2093
2093
|
return
|
|
2094
2094
|
|
|
2095
|
-
self.
|
|
2096
|
-
self.
|
|
2095
|
+
self.correct(lq1)
|
|
2096
|
+
self.correct(lq2)
|
|
2097
2097
|
|
|
2098
2098
|
# Partial-match cases: one side is a simple (single-replica) qubit,
|
|
2099
2099
|
# the other has multiple replicas. For the multi-replica side's
|
|
@@ -2120,12 +2120,12 @@ class QrackAceBackend:
|
|
|
2120
2120
|
for _hq2 in non_matching:
|
|
2121
2121
|
self._cx_shadow(_hq1, _hq2)
|
|
2122
2122
|
# No correction on lq1 (bulk, single-replica): already a
|
|
2123
|
-
# structural no-op via
|
|
2123
|
+
# structural no-op via correct's own len(hq)==1 guard.
|
|
2124
2124
|
# lq2 (boundary) DOES take real error here (X-type, verified),
|
|
2125
2125
|
# so it keeps a correction -- phase=False, not True, since the
|
|
2126
2126
|
# error is already Z-basis-population-visible and doesn't need
|
|
2127
2127
|
# an H-rotation first to become detectable.
|
|
2128
|
-
self.
|
|
2128
|
+
self.correct(lq2)
|
|
2129
2129
|
elif len(hq2) == 1 and any(h[0] == hq2[0][0] for h in hq1):
|
|
2130
2130
|
_hq2 = hq2[0]
|
|
2131
2131
|
non_matching = [h for h in hq1 if h[0] != _hq2[0]]
|
|
@@ -2136,14 +2136,14 @@ class QrackAceBackend:
|
|
|
2136
2136
|
self.sim[_hq2[0]].swap(_hq2[1], _hq1[1])
|
|
2137
2137
|
for _hq1 in non_matching:
|
|
2138
2138
|
self._cx_shadow(_hq2, _hq1)
|
|
2139
|
-
self.
|
|
2139
|
+
self.correct(lq1)
|
|
2140
2140
|
else:
|
|
2141
2141
|
# General case: no shared simulator at all (e.g. two simple
|
|
2142
2142
|
# qubits on entirely different sims -- nothing to anchor an exact
|
|
2143
2143
|
# swap on, verified the sandwich branches above give WRONG,
|
|
2144
2144
|
# deterministic results here: 100/100 failures vs 0/15 for this
|
|
2145
2145
|
# fallback), or both sides multi-replica and not fully matched:
|
|
2146
|
-
# cx() already wraps itself with
|
|
2146
|
+
# cx() already wraps itself with correct() via _cpauli, so no
|
|
2147
2147
|
# extra wrapping needed here.
|
|
2148
2148
|
self.cx(lq1, lq2)
|
|
2149
2149
|
self.cx(lq2, lq1)
|
|
@@ -2170,65 +2170,6 @@ class QrackAceBackend:
|
|
|
2170
2170
|
self.mcx([c1, c2], t)
|
|
2171
2171
|
return
|
|
2172
2172
|
|
|
2173
|
-
# AND-invariant, generalized from _apply_coupling's CX/CZ XOR
|
|
2174
|
-
# check to the Toffoli's actual relationship: t should end up as
|
|
2175
|
-
# t_before XOR (c1 AND c2), not just t_before XOR c1 or XOR c2
|
|
2176
|
-
# individually. mcx is the native AND-conditioned flip, so it
|
|
2177
|
-
# plays the same role here that a plain cx(control, anc) played
|
|
2178
|
-
# in the 2-qubit case: capture t's pre-gate value, then fold in
|
|
2179
|
-
# c1 AND c2 via a genuine nested mcx() (which goes through the
|
|
2180
|
-
# same shadow/_correct machinery as any other logical gate, so
|
|
2181
|
-
# this is exposed to the same class of intrinsic approximation
|
|
2182
|
-
# error the CX/CZ check catches, not a raw single-replica read).
|
|
2183
|
-
# Uses t's own patch ancilla2 array, since t itself is guaranteed
|
|
2184
|
-
# bulk on this path (the len(hqt) > 1 case returns earlier,
|
|
2185
|
-
# above) and nothing else in this method uses that array anymore.
|
|
2186
|
-
anc_and = None
|
|
2187
|
-
if self.is_error_detection and not self._in_gadget_capture and ((len(hqt) > 1) or (len(hq1) > 1) or (len(hq2) > 1)):
|
|
2188
|
-
found = False
|
|
2189
|
-
anc_sim = hq1[0][0]
|
|
2190
|
-
t_sims = {y[0] for y in hqt if y[0] >= 0}
|
|
2191
|
-
for x in hq1:
|
|
2192
|
-
if (x[0] < 0) or (x[0] not in t_sims):
|
|
2193
|
-
continue
|
|
2194
|
-
anc_sim = x[0]
|
|
2195
|
-
for y in hq2:
|
|
2196
|
-
if (y[0] < 0) or (y[0] not in t_sims):
|
|
2197
|
-
continue
|
|
2198
|
-
if anc_sim == y[0]:
|
|
2199
|
-
found = True
|
|
2200
|
-
break
|
|
2201
|
-
if found:
|
|
2202
|
-
break
|
|
2203
|
-
self._in_gadget_capture = True
|
|
2204
|
-
anc_and = self.detect_ancilla_lq[anc_sim]
|
|
2205
|
-
self.cx(t, anc_and)
|
|
2206
|
-
# self.mcx() only supports a single control at the logical
|
|
2207
|
-
# level (a syntax-convenience wrapper, confirmed directly --
|
|
2208
|
-
# it raises for 2 controls), so it can't do the AND capture
|
|
2209
|
-
# itself. When c1 and c2 both happen to have a physical
|
|
2210
|
-
# replica in t's own home-patch simulator (the same one
|
|
2211
|
-
# anc_and lives in), use a genuine native mcx there directly
|
|
2212
|
-
# -- exact, and a clean, independent reference to compare the
|
|
2213
|
-
# real Toffoli against. Otherwise, fall back to a recursive
|
|
2214
|
-
# ccx(c1, c2, anc_and): safe from infinite recursion here
|
|
2215
|
-
# specifically because _in_gadget_capture is already True, so
|
|
2216
|
-
# the recursive call's own "not self._in_gadget_capture" gate
|
|
2217
|
-
# skips setting up a second anc_and, and just performs the
|
|
2218
|
-
# ordinary native-witness-or-shadow Toffoli computation on
|
|
2219
|
-
# anc_and instead.
|
|
2220
|
-
c1_idx = next((r[1] for r in hq1 if r[0] == anc_sim), None)
|
|
2221
|
-
c2_idx = next((r[1] for r in hq2 if r[0] == anc_sim), None)
|
|
2222
|
-
if (c1_idx is not None) and (c2_idx is not None):
|
|
2223
|
-
_, anc_and_idx = self.qubits[anc_and][0]
|
|
2224
|
-
self.sim[anc_sim].mcx([c1_idx, c2_idx], anc_and_idx)
|
|
2225
|
-
else:
|
|
2226
|
-
self.ccx(c1, c2, anc_and)
|
|
2227
|
-
self._in_gadget_capture = False
|
|
2228
|
-
|
|
2229
|
-
self._correct(c1)
|
|
2230
|
-
self._correct(c2)
|
|
2231
|
-
|
|
2232
2173
|
qb1, _ = QrackAceBackend._get_qb_lhv_indices(hq1)
|
|
2233
2174
|
qb2, _ = QrackAceBackend._get_qb_lhv_indices(hq2)
|
|
2234
2175
|
qbt, _ = QrackAceBackend._get_qb_lhv_indices(hqt)
|
|
@@ -2253,28 +2194,6 @@ class QrackAceBackend:
|
|
|
2253
2194
|
witnesses.append(witness)
|
|
2254
2195
|
|
|
2255
2196
|
if needs_shadow:
|
|
2256
|
-
# Confirmed directly: whenever even one replica of t lacks a
|
|
2257
|
-
# native witness shared with c1 and c2, the per-replica
|
|
2258
|
-
# fallback to _ccx_shadow craters fidelity specifically when
|
|
2259
|
-
# either control is in genuine superposition -- 0.64-0.68
|
|
2260
|
-
# vs. 0.999+ for every other input tested, stable from 100 to
|
|
2261
|
-
# 2500 shots, so not shot noise. Diverting the WHOLE
|
|
2262
|
-
# operation (not just the unwitnessed replica) to the general
|
|
2263
|
-
# 6-CX decomposition instead: every step here is a genuine
|
|
2264
|
-
# logical cx()/h()/t()/adjt() call, which updates every
|
|
2265
|
-
# replica of t through the same _apply_coupling boundary-
|
|
2266
|
-
# crossing machinery already validated elsewhere in this
|
|
2267
|
-
# file, rather than the lower-level per-replica _cx_shadow
|
|
2268
|
-
# calls _ccx_shadow uses for just the unwitnessed ones.
|
|
2269
|
-
#
|
|
2270
|
-
# Wrapped in _in_gadget_capture, same as established earlier:
|
|
2271
|
-
# without it, each individual cx() here would independently
|
|
2272
|
-
# trigger its own XOR-invariant gadget setup, which corrupts
|
|
2273
|
-
# the precise T/Tdg phase relationships this decomposition
|
|
2274
|
-
# depends on (confirmed directly, the first time this
|
|
2275
|
-
# decomposition was used unconditionally -- corrupted even
|
|
2276
|
-
# c1/c2, which the per-replica path never touched at all).
|
|
2277
|
-
self._in_gadget_capture = True
|
|
2278
2197
|
self.h(t)
|
|
2279
2198
|
self.cx(c2, t)
|
|
2280
2199
|
self.adjt(t)
|
|
@@ -2290,14 +2209,45 @@ class QrackAceBackend:
|
|
|
2290
2209
|
self.t(c1)
|
|
2291
2210
|
self.adjt(c2)
|
|
2292
2211
|
self.cx(c1, c2)
|
|
2293
|
-
self._in_gadget_capture = False
|
|
2294
|
-
else:
|
|
2295
|
-
for (b1, b2, bt) in witnesses:
|
|
2296
|
-
self.sim[b1[0]].mcx([b1[1], b2[1]], bt[1])
|
|
2297
2212
|
|
|
2298
|
-
|
|
2213
|
+
return
|
|
2299
2214
|
|
|
2300
|
-
|
|
2215
|
+
anc_and = None
|
|
2216
|
+
if self.is_error_detection and not self._in_gadget_capture and ((len(hqt) > 1) or (len(hq1) > 1) or (len(hq2) > 1)):
|
|
2217
|
+
found = False
|
|
2218
|
+
anc_sim = hq1[0][0]
|
|
2219
|
+
t_sims = {y[0] for y in hqt if y[0] >= 0}
|
|
2220
|
+
for x in hq1:
|
|
2221
|
+
if (x[0] < 0) or (x[0] not in t_sims):
|
|
2222
|
+
continue
|
|
2223
|
+
anc_sim = x[0]
|
|
2224
|
+
for y in hq2:
|
|
2225
|
+
if (y[0] < 0) or (y[0] not in t_sims):
|
|
2226
|
+
continue
|
|
2227
|
+
if anc_sim == y[0]:
|
|
2228
|
+
found = True
|
|
2229
|
+
break
|
|
2230
|
+
if found:
|
|
2231
|
+
break
|
|
2232
|
+
anc_and = self.detect_ancilla_lq[anc_sim]
|
|
2233
|
+
self.cx(t, anc_and)
|
|
2234
|
+
c1_idx = next((r[1] for r in hq1 if r[0] == anc_sim), None)
|
|
2235
|
+
c2_idx = next((r[1] for r in hq2 if r[0] == anc_sim), None)
|
|
2236
|
+
if (c1_idx is not None) and (c2_idx is not None):
|
|
2237
|
+
_, anc_and_idx = self.qubits[anc_and][0]
|
|
2238
|
+
self.sim[anc_sim].mcx([c1_idx, c2_idx], anc_and_idx)
|
|
2239
|
+
else:
|
|
2240
|
+
self._in_gadget_capture = True
|
|
2241
|
+
self.ccx(c1, c2, anc_and)
|
|
2242
|
+
self._in_gadget_capture = False
|
|
2243
|
+
|
|
2244
|
+
self.correct(c1)
|
|
2245
|
+
self.correct(c2)
|
|
2246
|
+
|
|
2247
|
+
for (b1, b2, bt) in witnesses:
|
|
2248
|
+
self.sim[b1[0]].mcx([b1[1], b2[1]], bt[1])
|
|
2249
|
+
|
|
2250
|
+
self.correct(t)
|
|
2301
2251
|
|
|
2302
2252
|
if anc_and is not None:
|
|
2303
2253
|
self.cx(t, anc_and)
|
|
@@ -2312,8 +2262,6 @@ class QrackAceBackend:
|
|
|
2312
2262
|
self.x(anc_and)
|
|
2313
2263
|
self.x(t)
|
|
2314
2264
|
|
|
2315
|
-
self._in_gadget_capture = False
|
|
2316
|
-
|
|
2317
2265
|
def ccz(self, c1, c2, t):
|
|
2318
2266
|
self.h(t)
|
|
2319
2267
|
self.ccx(c1, c2, t)
|
|
@@ -2330,9 +2278,9 @@ class QrackAceBackend:
|
|
|
2330
2278
|
b = hq[0]
|
|
2331
2279
|
return self.sim[b[0]].prob(b[1])
|
|
2332
2280
|
|
|
2333
|
-
self.
|
|
2281
|
+
self.correct(lq)
|
|
2334
2282
|
# The real replicas are already mutually consistent here (the
|
|
2335
|
-
#
|
|
2283
|
+
# correct() call above already ran the appropriate tie-breaking
|
|
2336
2284
|
# cascade for however many replicas hq has -- 2, 3, 4, or 5,
|
|
2337
2285
|
# depending on self.use_crossbars and whether this is an edge or
|
|
2338
2286
|
# corner boundary qubit -- using the LHV proxy and/or the
|
|
@@ -2341,7 +2289,7 @@ class QrackAceBackend:
|
|
|
2341
2289
|
# correct, already-decided answer, regardless of replica count:
|
|
2342
2290
|
# re-weighting any particular replica specially here would
|
|
2343
2291
|
# reintroduce the same center-dragging distortion the cascade in
|
|
2344
|
-
#
|
|
2292
|
+
# correct() was built to avoid.
|
|
2345
2293
|
p = [self.sim[b[0]].prob(b[1]) for b in hq]
|
|
2346
2294
|
n = len(p)
|
|
2347
2295
|
prms = math.sqrt(sum(x**2 for x in p) / n)
|
|
@@ -2383,7 +2331,7 @@ class QrackAceBackend:
|
|
|
2383
2331
|
b = hq[0]
|
|
2384
2332
|
return self.sim[b[0]].force_m(b[1], result)
|
|
2385
2333
|
|
|
2386
|
-
self.
|
|
2334
|
+
self.correct(lq)
|
|
2387
2335
|
|
|
2388
2336
|
qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
2389
2337
|
|
|
@@ -3033,7 +2981,7 @@ class QrackAceBackend:
|
|
|
3033
2981
|
# _cpauli's own convention) to be a multi-replica (boundary)
|
|
3034
2982
|
# qubit -- see _cpauli: anc1 (the control-invariance capture) is
|
|
3035
2983
|
# unconditional but structurally trivial for a single-replica
|
|
3036
|
-
# control (
|
|
2984
|
+
# control (correct() is already a no-op there, nothing for the
|
|
3037
2985
|
# gadget to protect against), and anc2 (the target-value
|
|
3038
2986
|
# verification against the CX/ACX-predicted output) is
|
|
3039
2987
|
# explicitly gated on len(hq1) > 1. Both halves are gated the
|
|
@@ -3130,13 +3078,13 @@ class QrackAceBackend:
|
|
|
3130
3078
|
# Error type re-verified directly against THIS file (the
|
|
3131
3079
|
# gadget mechanics changed substantially since the type was
|
|
3132
3080
|
# first derived -- swap()'s own cross-check gadget, the
|
|
3133
|
-
#
|
|
3081
|
+
# correct()-skip-during-capture fix, and the post-selection
|
|
3134
3082
|
# floor threshold are all new), to make sure none of that
|
|
3135
3083
|
# changed the underlying picture. It hasn't: _cx_shadow
|
|
3136
3084
|
# itself is untouched by any of it. Reading the LOGICAL
|
|
3137
3085
|
# prob(lq) still tells you nothing (0.00000 deviation in
|
|
3138
3086
|
# both bases on a single isolated swap, gadget on or off --
|
|
3139
|
-
# it calls
|
|
3087
|
+
# it calls correct() internally and reconciles across every
|
|
3140
3088
|
# replica, the same masking this file has run into more than
|
|
3141
3089
|
# once). Reading the RAW, non-matching replica directly
|
|
3142
3090
|
# (bypassing that reconciliation) gives a clean, deterministic
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_near_clifford_qec_backend.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_system/qrack_system.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/stats/load_quantized_data.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/requires.txt
RENAMED
|
File without changes
|
{pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|