pyqrack-cpu 2.18.1__tar.gz → 2.18.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 (30) hide show
  1. {pyqrack_cpu-2.18.1/pyqrack_cpu.egg-info → pyqrack_cpu-2.18.2}/PKG-INFO +1 -1
  2. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/qrack_ace_backend.py +66 -42
  3. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2/pyqrack_cpu.egg-info}/PKG-INFO +1 -1
  4. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/setup.py +1 -1
  5. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/LICENSE +0 -0
  6. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/MANIFEST.in +0 -0
  7. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/Makefile +0 -0
  8. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/README.md +0 -0
  9. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyproject.toml +0 -0
  10. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/__init__.py +0 -0
  11. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/neuron_activation_fn.py +0 -0
  12. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/pauli.py +0 -0
  13. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/qrack_circuit.py +0 -0
  14. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/qrack_near_clifford_qec_backend.py +0 -0
  15. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/qrack_neuron.py +0 -0
  16. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/qrack_neuron_torch_layer.py +0 -0
  17. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/qrack_simulator.py +0 -0
  18. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/qrack_stabilizer.py +0 -0
  19. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/qrack_system/__init__.py +0 -0
  20. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/qrack_system/qrack_system.py +0 -0
  21. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/quimb_circuit_type.py +0 -0
  22. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/stats/__init__.py +0 -0
  23. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/stats/load_quantized_data.py +0 -0
  24. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack/stats/quantize_by_range.py +0 -0
  25. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack_cpu.egg-info/SOURCES.txt +0 -0
  26. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack_cpu.egg-info/dependency_links.txt +0 -0
  27. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack_cpu.egg-info/not-zip-safe +0 -0
  28. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack_cpu.egg-info/requires.txt +0 -0
  29. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/pyqrack_cpu.egg-info/top_level.txt +0 -0
  30. {pyqrack_cpu-2.18.1 → pyqrack_cpu-2.18.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqrack-cpu
3
- Version: 2.18.1
3
+ Version: 2.18.2
4
4
  Summary: pyqrack - Pure Python vm6502q/qrack Wrapper
5
5
  Home-page: https://github.com/vm6502q/pyqrack
6
6
  Author: Daniel Strano
@@ -1456,42 +1456,25 @@ class QrackAceBackend:
1456
1456
  b2 = hq2[q2]
1457
1457
  if b1[0] == b2[0]:
1458
1458
  if self.is_error_detection:
1459
- # Error-DETECTION gadget (not correction), directly
1460
- # post-selected via force_m rather than requiring
1461
- # real repeated shots: b1 is always the CONTROL of
1462
- # this gate (by construction -- gate_fn is always
1463
- # called as gate_fn([b1[1]], b2[1])), and a
1464
- # control's Z value is exactly invariant under a
1465
- # controlled-Pauli gate in the noiseless case,
1466
- # regardless of anti/regular control convention or
1467
- # which Pauli. So: XOR b1's value into the patch's
1468
- # shared ancilla immediately before the gate, XOR
1469
- # it in again immediately after -- if nothing
1470
- # disturbed b1 (no injected noise on the gate
1471
- # itself or on either sandwiching CNOT), those two
1472
- # XORs exactly cancel and the ancilla is back to
1473
- # |0>. force_m(ancilla, False) then directly
1474
- # projects the whole simulated state onto that
1475
- # "no disturbance detected" branch and renormalizes
1476
- # -- this is the exact numerical equivalent of what
1477
- # a real experiment gets from measure + discard +
1478
- # repeat, done in one step because the simulator
1479
- # has the full state to project, not just samples
1480
- # from it. The same ancilla is reused for every
1481
- # gate touching this simulator: each round-trip is
1482
- # self-contained and leaves the ancilla at |0>
1483
- # again whenever nothing was detected, so there's
1484
- # no cross-gate bookkeeping needed.
1485
- #
1486
- # Deliberately single-patch, not multi-patch: this
1487
- # protects b1 exactly where the real gate touches
1488
- # it. A multi-patch version (sandwiching every
1489
- # replica of lq1 across every patch it lives in)
1490
- # was tried and measured worse -- RCS XEB against
1491
- # this architecture's own intrinsic approximation
1492
- # error confirmed the single-patch version here is
1493
- # the one that actually works well; the multi-patch
1494
- # generalization added cost without benefit.
1459
+ # Single-patch, not multi-patch: force_m's
1460
+ # post-selection isn't local to the one
1461
+ # simulator it's physically called on -- the
1462
+ # projection it performs reflects the "lab
1463
+ # frame" ground truth for whatever it's checking,
1464
+ # not an independent per-patch fact. Since every
1465
+ # replica of a boundary qubit is meant to
1466
+ # represent the SAME logical value, checking that
1467
+ # invariant via any one patch that has a real
1468
+ # gate touching it already captures the full
1469
+ # syndrome -- separately re-checking lq1's other
1470
+ # replicas in their own patches doesn't add new
1471
+ # independent information, it just adds their
1472
+ # own extra gate exposure for no additional
1473
+ # benefit. So: XOR b1's value into ITS OWN
1474
+ # patch's ancilla immediately before the gate,
1475
+ # XOR it in again immediately after, force_m that
1476
+ # one ancilla -- b1 only, not every replica of
1477
+ # lq1.
1495
1478
  #
1496
1479
  # Also worth being explicit about: what this
1497
1480
  # catches is NOT the same thing as the `noise=`
@@ -1505,17 +1488,46 @@ class QrackAceBackend:
1505
1488
  # sandwiching CNOTs are then subject to that same
1506
1489
  # injected noise too) -- see conversation record.
1507
1490
  #
1508
- # Scope: this only covers the mcx/mcy/mcz path
1509
- # (_cpauli / _apply_coupling). swap/iswap/pswap/etc.
1510
- # exchange both qubits' values rather than leaving
1511
- # either invariant, so this specific gadget doesn't
1512
- # apply to them directly -- left as a documented
1513
- # gap for a later pass, not silently unhandled.
1491
+ # Scope: still only the mcx/mcy/mcz path
1492
+ # (_cpauli / _apply_coupling); swap/iswap/etc.
1493
+ # get their own dedicated gadget (_detect_swap),
1494
+ # and the anti-controlled shadow variants get
1495
+ # theirs (_anti_shadow_wrap) -- see those.
1496
+ #
1497
+ # CZ specifically also checks b2, not just b1:
1498
+ # unlike CX/CY, where the target's Z-population
1499
+ # legitimately, intentionally changes (that IS
1500
+ # the entangling operation -- not an error), CZ
1501
+ # is diagonal in the computational basis and
1502
+ # NEVER changes either qubit's Z-population, only
1503
+ # a relative phase. So b2 is an equally valid
1504
+ # invariance check here, for this gate family
1505
+ # only. Combined as one XOR parity (b1^b2), same
1506
+ # pattern as the SWAP gadget: catches either
1507
+ # participant's first-order (O(p)) disturbance,
1508
+ # only misses the second-order (O(p^2)) case
1509
+ # where both are disturbed simultaneously in a
1510
+ # way that cancels in the combined parity.
1511
+ # (Considered and rejected checking b1 in BOTH
1512
+ # Z and X bases instead, to catch phase-type
1513
+ # errors on the control too -- doesn't work: CX/CY
1514
+ # genuinely, intentionally entangle control with
1515
+ # target, which legitimately degrades the
1516
+ # control's own X/Y-basis coherence as correct
1517
+ # gate behavior, not error. A detector for that
1518
+ # would flag every successful entangling gate and
1519
+ # destroy the entanglement the gate was supposed
1520
+ # to create.)
1521
+ check_b2_too = pauli == Pauli.PauliZ
1514
1522
  anc = self._detect_ancilla[b1[0]]
1515
1523
  sim = self.sim[b1[0]]
1516
1524
  sim.mcx([b1[1]], anc)
1525
+ if check_b2_too:
1526
+ sim.mcx([b2[1]], anc)
1517
1527
  gate_fn([b1[1]], b2[1])
1518
1528
  sim.mcx([b1[1]], anc)
1529
+ if check_b2_too:
1530
+ sim.mcx([b2[1]], anc)
1519
1531
  sim.force_m(anc, False)
1520
1532
  else:
1521
1533
  gate_fn([b1[1]], b2[1])
@@ -2431,11 +2443,23 @@ class QrackAceBackend:
2431
2443
  # passing a smaller x: x scales every pair uniformly, and this
2432
2444
  # doesn't apply uniformly, either across qubits (only ones with a
2433
2445
  # real-gate opportunity qualify) or across gate types (see below).
2446
+ #
2447
+ # Both sides of a real (u=0) pair get added, not just the control:
2448
+ # CZ's own gadget check now covers its target too (CZ is diagonal
2449
+ # -- unlike CX/CY, it never changes either qubit's Z-population,
2450
+ # so the target is an equally valid invariance check there, see
2451
+ # _apply_coupling). The coupling map doesn't distinguish which
2452
+ # gate type a future circuit will actually use for a given pair,
2453
+ # so this necessarily overstates the CX/CY case slightly (where
2454
+ # only the control gets swept) -- an approximation on top of an
2455
+ # already-approximate placeholder, not a new source of precision
2456
+ # lost.
2434
2457
  has_real_partner = set()
2435
2458
  if self.is_error_detection:
2436
2459
  for lq1, lq2 in coupling_map:
2437
2460
  if _uncommon_sim_fraction(lq1, lq2) == 0:
2438
2461
  has_real_partner.add(lq1)
2462
+ has_real_partner.add(lq2)
2439
2463
 
2440
2464
  # This factor is a theory-derived placeholder, not an empirical
2441
2465
  # fit -- deliberately, per instruction not to chase a regression
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqrack-cpu
3
- Version: 2.18.1
3
+ Version: 2.18.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.18.1"
10
+ VERSION = "2.18.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')
File without changes
File without changes
File without changes
File without changes
File without changes