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.
Files changed (31) hide show
  1. {pyqrack_complex128-2.29.0/pyqrack_complex128.egg-info → pyqrack_complex128-2.29.2}/PKG-INFO +1 -1
  2. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_ace_backend.py +66 -118
  3. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2/pyqrack_complex128.egg-info}/PKG-INFO +1 -1
  4. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/setup.py +1 -1
  5. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/LICENSE +0 -0
  6. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/MANIFEST.in +0 -0
  7. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/Makefile +0 -0
  8. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/README.md +0 -0
  9. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyproject.toml +0 -0
  10. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/__init__.py +0 -0
  11. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/neuron_activation_fn.py +0 -0
  12. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/pauli.py +0 -0
  13. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_ace_mps_backend.py +0 -0
  14. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_circuit.py +0 -0
  15. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_near_clifford_qec_backend.py +0 -0
  16. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_neuron.py +0 -0
  17. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_neuron_torch_layer.py +0 -0
  18. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_simulator.py +0 -0
  19. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_stabilizer.py +0 -0
  20. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_system/__init__.py +0 -0
  21. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/qrack_system/qrack_system.py +0 -0
  22. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/quimb_circuit_type.py +0 -0
  23. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/stats/__init__.py +0 -0
  24. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/stats/load_quantized_data.py +0 -0
  25. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack/stats/quantize_by_range.py +0 -0
  26. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/SOURCES.txt +0 -0
  27. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/dependency_links.txt +0 -0
  28. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/not-zip-safe +0 -0
  29. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/requires.txt +0 -0
  30. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/pyqrack_complex128.egg-info/top_level.txt +0 -0
  31. {pyqrack_complex128-2.29.0 → pyqrack_complex128-2.29.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqrack-complex128
3
- Version: 2.29.0
3
+ Version: 2.29.2
4
4
  Summary: pyqrack - Pure Python vm6502q/qrack Wrapper
5
5
  Home-page: https://github.com/vm6502q/pyqrack
6
6
  Author: Daniel Strano
@@ -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 _correct). Default is the point where a single
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/_correct, which assume
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 _correct() falls
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 _correct()/
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 _correct() can
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 _correct(self, lq, phase=False, skip_rotation=False):
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 _correct)
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 _correct)
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 _correct)
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._correct(lq1)
1651
- self._correct(lq2)
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 _correct/m's classical
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._correct(lq2, False, pauli != Pauli.PauliX)
1707
+ self.correct(lq2, False, pauli != Pauli.PauliX)
1708
1708
  if pauli != Pauli.PauliX:
1709
- self._correct(lq2, True)
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 _correct() before
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 -- _correct() is a no-op for
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._correct(lq1)
2096
- self._correct(lq2)
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 _correct's own len(hq)==1 guard.
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._correct(lq2)
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._correct(lq1)
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 _correct() via _cpauli, so no
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
- self._correct(t)
2213
+ return
2299
2214
 
2300
- self._in_gadget_capture = True
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._correct(lq)
2281
+ self.correct(lq)
2334
2282
  # The real replicas are already mutually consistent here (the
2335
- # _correct() call above already ran the appropriate tie-breaking
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
- # _correct() was built to avoid.
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._correct(lq)
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 (_correct() is already a no-op there, nothing for the
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
- # _correct()-skip-during-capture fix, and the post-selection
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 _correct() internally and reconciles across every
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqrack-complex128
3
- Version: 2.29.0
3
+ Version: 2.29.2
4
4
  Summary: pyqrack - Pure Python vm6502q/qrack Wrapper
5
5
  Home-page: https://github.com/vm6502q/pyqrack
6
6
  Author: Daniel Strano
@@ -7,7 +7,7 @@ from setuptools import setup
7
7
  from setuptools.command.build_py import build_py
8
8
 
9
9
 
10
- VERSION = "2.29.0"
10
+ VERSION = "2.29.2"
11
11
 
12
12
  # Read long description from README.
13
13
  README_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'README.md')