pyqrack-complex128 2.26.0__tar.gz → 2.26.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.26.0/pyqrack_complex128.egg-info → pyqrack_complex128-2.26.2}/PKG-INFO +1 -1
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/qrack_ace_backend.py +52 -47
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2/pyqrack_complex128.egg-info}/PKG-INFO +1 -1
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/setup.py +1 -1
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/LICENSE +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/MANIFEST.in +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/Makefile +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/README.md +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyproject.toml +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/__init__.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/neuron_activation_fn.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/pauli.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/qrack_circuit.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/qrack_near_clifford_qec_backend.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/qrack_neuron.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/qrack_neuron_torch_layer.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/qrack_simulator.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/qrack_stabilizer.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/qrack_system/qrack_system.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/stats/load_quantized_data.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/stats/quantize_by_range.py +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack_complex128.egg-info/SOURCES.txt +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack_complex128.egg-info/dependency_links.txt +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack_complex128.egg-info/not-zip-safe +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack_complex128.egg-info/requires.txt +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack_complex128.egg-info/top_level.txt +0 -0
- {pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/setup.cfg +0 -0
|
@@ -1384,6 +1384,15 @@ class QrackAceBackend:
|
|
|
1384
1384
|
def _apply_coupling(self, pauli, anti, qb1, hq1, qb2, hq2, lq1_lr, lq1=None, lq2=None):
|
|
1385
1385
|
shadow_targets = []
|
|
1386
1386
|
|
|
1387
|
+
if len(hq1) == len(hq2) and all(hq1[i][0] == hq2[i][0] for i in range(len(hq1))):
|
|
1388
|
+
for i in range(len(hq1)):
|
|
1389
|
+
sim_id, idx1 = hq1[i]
|
|
1390
|
+
gate_fn, shadow_fn = self._get_gate(pauli, anti, sim_id)
|
|
1391
|
+
_, idx2 = hq2[i]
|
|
1392
|
+
self.sim[sim_id].swap(idx1, idx2)
|
|
1393
|
+
gate_fn([idx1], idx2)
|
|
1394
|
+
return
|
|
1395
|
+
|
|
1387
1396
|
# Logical-level error-detection gadget: an earlier version of this
|
|
1388
1397
|
# also captured lq1's own logical value into a dedicated ancilla
|
|
1389
1398
|
# (via a nested cx()), on the theory that the shadow-coupling
|
|
@@ -1410,7 +1419,7 @@ class QrackAceBackend:
|
|
|
1410
1419
|
# a lq2-invariant check for that gate family, same reasoning as
|
|
1411
1420
|
# the single-replica CZ dual-check elsewhere.
|
|
1412
1421
|
anc2 = None
|
|
1413
|
-
if self.is_error_detection and not self._in_gadget_capture and (len(
|
|
1422
|
+
if self.is_error_detection and (not self._in_gadget_capture) and (len(hq2) > 1):
|
|
1414
1423
|
anc_sim = hq1[0][0]
|
|
1415
1424
|
t_sims = {y[0] for y in hq2 if y[0] >= 0}
|
|
1416
1425
|
for x in hq1:
|
|
@@ -1810,42 +1819,6 @@ class QrackAceBackend:
|
|
|
1810
1819
|
hq1 = self._unpack(lq1)
|
|
1811
1820
|
hq2 = self._unpack(lq2)
|
|
1812
1821
|
|
|
1813
|
-
sims1 = {r[0] for r in hq1}
|
|
1814
|
-
sims2 = {r[0] for r in hq2}
|
|
1815
|
-
|
|
1816
|
-
if sims1.isdisjoint(sims2):
|
|
1817
|
-
self._correct(lq1)
|
|
1818
|
-
self._correct(lq2)
|
|
1819
|
-
|
|
1820
|
-
# Once fully resolved, the swap itself is nothing but a
|
|
1821
|
-
# reference exchange: self._qubits[lq] is a reference to the
|
|
1822
|
-
# replica-list object, so swapping which index points to
|
|
1823
|
-
# which object IS the swap -- no separate content to copy.
|
|
1824
|
-
self._qubits[lq1], self._qubits[lq2] = self._qubits[lq2], self._qubits[lq1]
|
|
1825
|
-
|
|
1826
|
-
lhv1 = self._lhv.pop(lq1, None)
|
|
1827
|
-
lhv2 = self._lhv.pop(lq2, None)
|
|
1828
|
-
if lhv2 is not None:
|
|
1829
|
-
self._lhv[lq1] = lhv2
|
|
1830
|
-
if lhv1 is not None:
|
|
1831
|
-
self._lhv[lq2] = lhv1
|
|
1832
|
-
|
|
1833
|
-
# Boundary repetition code needs no bookkeeping here, unlike
|
|
1834
|
-
# self._qubits/self._lhv just above: it's on-demand now, not
|
|
1835
|
-
# a permanent, per-logical-index dict of pre-allocated
|
|
1836
|
-
# partners -- eligibility is just len(self._qubits[lq]) > 1,
|
|
1837
|
-
# computed fresh on every coupling event, so the reference
|
|
1838
|
-
# swap of self._qubits above already, automatically carries
|
|
1839
|
-
# the right eligibility with it. Nothing else to move.
|
|
1840
|
-
return
|
|
1841
|
-
|
|
1842
|
-
# Boundary-to-boundary handling
|
|
1843
|
-
if (len(hq1) > 1) and (len(hq2) > 1):
|
|
1844
|
-
self.cx(lq1, lq2)
|
|
1845
|
-
self.cx(lq2, lq1)
|
|
1846
|
-
self.cx(lq1, lq2)
|
|
1847
|
-
return
|
|
1848
|
-
|
|
1849
1822
|
# Fast/exact path: every replica of lq1 lines up, position-for-
|
|
1850
1823
|
# position, with the corresponding replica of lq2 on the SAME
|
|
1851
1824
|
# underlying simulator. A native swap() there is pure index
|
|
@@ -1872,8 +1845,6 @@ class QrackAceBackend:
|
|
|
1872
1845
|
# two sides can land on different simulators (the partial-match
|
|
1873
1846
|
# branches below) needs separate, careful treatment -- not
|
|
1874
1847
|
# reused as-is from _cpauli's helper.
|
|
1875
|
-
self._correct(lq1)
|
|
1876
|
-
self._correct(lq2)
|
|
1877
1848
|
|
|
1878
1849
|
if len(hq1) == len(hq2) and all(hq1[i][0] == hq2[i][0] for i in range(len(hq1))):
|
|
1879
1850
|
for i in range(len(hq1)):
|
|
@@ -1887,6 +1858,39 @@ class QrackAceBackend:
|
|
|
1887
1858
|
# with or without this call).
|
|
1888
1859
|
return
|
|
1889
1860
|
|
|
1861
|
+
sims1 = {r[0] for r in hq1}
|
|
1862
|
+
sims2 = {r[0] for r in hq2}
|
|
1863
|
+
|
|
1864
|
+
if sims1.isdisjoint(sims2):
|
|
1865
|
+
# Once fully resolved, the swap itself is nothing but a
|
|
1866
|
+
# reference exchange: self._qubits[lq] is a reference to the
|
|
1867
|
+
# replica-list object, so swapping which index points to
|
|
1868
|
+
# which object IS the swap -- no separate content to copy.
|
|
1869
|
+
self._qubits[lq1], self._qubits[lq2] = self._qubits[lq2], self._qubits[lq1]
|
|
1870
|
+
|
|
1871
|
+
lhv1 = self._lhv.pop(lq1, None)
|
|
1872
|
+
lhv2 = self._lhv.pop(lq2, None)
|
|
1873
|
+
if lhv2 is not None:
|
|
1874
|
+
self._lhv[lq1] = lhv2
|
|
1875
|
+
if lhv1 is not None:
|
|
1876
|
+
self._lhv[lq2] = lhv1
|
|
1877
|
+
|
|
1878
|
+
# Boundary repetition code needs no bookkeeping here, unlike
|
|
1879
|
+
# self._qubits/self._lhv just above: it's on-demand now, not
|
|
1880
|
+
# a permanent, per-logical-index dict of pre-allocated
|
|
1881
|
+
# partners -- eligibility is just len(self._qubits[lq]) > 1,
|
|
1882
|
+
# computed fresh on every coupling event, so the reference
|
|
1883
|
+
# swap of self._qubits above already, automatically carries
|
|
1884
|
+
# the right eligibility with it. Nothing else to move.
|
|
1885
|
+
return
|
|
1886
|
+
|
|
1887
|
+
# Boundary-to-boundary handling
|
|
1888
|
+
if (len(hq1) > 1) and (len(hq2) > 1):
|
|
1889
|
+
self.cx(lq1, lq2)
|
|
1890
|
+
self.cx(lq2, lq1)
|
|
1891
|
+
self.cx(lq1, lq2)
|
|
1892
|
+
return
|
|
1893
|
+
|
|
1890
1894
|
anc1, anc2 = None, None
|
|
1891
1895
|
if self.is_error_detection and not self._in_gadget_capture and ((len(hq1) > 1) or (len(hq2) > 1)):
|
|
1892
1896
|
t_sims = {y[0] for y in hq2 if y[0] >= 0}
|
|
@@ -1902,6 +1906,9 @@ class QrackAceBackend:
|
|
|
1902
1906
|
self.cx(lq2, anc2)
|
|
1903
1907
|
self._in_gadget_capture = False
|
|
1904
1908
|
|
|
1909
|
+
self._correct(lq1)
|
|
1910
|
+
self._correct(lq2)
|
|
1911
|
+
|
|
1905
1912
|
# Partial-match cases: one side is a simple (single-replica) qubit,
|
|
1906
1913
|
# the other has multiple replicas. For the multi-replica side's
|
|
1907
1914
|
# non-matching replicas, the correct decomposition (verified
|
|
@@ -2001,10 +2008,6 @@ class QrackAceBackend:
|
|
|
2001
2008
|
self.mcx([c1, c2], t)
|
|
2002
2009
|
return
|
|
2003
2010
|
|
|
2004
|
-
if not self._in_gadget_capture:
|
|
2005
|
-
self._correct(c1)
|
|
2006
|
-
self._correct(c2)
|
|
2007
|
-
|
|
2008
2011
|
# Control-protection ancillas (anc1/anc1b/anc2/anc2b, checking
|
|
2009
2012
|
# whether c1/c2's own values held still) removed entirely, same
|
|
2010
2013
|
# basis as _apply_coupling: instrumented and stress-tested
|
|
@@ -2028,7 +2031,7 @@ class QrackAceBackend:
|
|
|
2028
2031
|
# bulk on this path (the len(hqt) > 1 case returns earlier,
|
|
2029
2032
|
# above) and nothing else in this method uses that array anymore.
|
|
2030
2033
|
anc_and = None
|
|
2031
|
-
if self.is_error_detection and not self._in_gadget_capture and (
|
|
2034
|
+
if self.is_error_detection and not self._in_gadget_capture and (len(hqt) > 1):
|
|
2032
2035
|
found = False
|
|
2033
2036
|
anc_sim = hq1[0][0]
|
|
2034
2037
|
t_sims = {y[0] for y in hqt if y[0] >= 0}
|
|
@@ -2070,6 +2073,9 @@ class QrackAceBackend:
|
|
|
2070
2073
|
self.ccx(c1, c2, anc_and)
|
|
2071
2074
|
self._in_gadget_capture = False
|
|
2072
2075
|
|
|
2076
|
+
self._correct(c1)
|
|
2077
|
+
self._correct(c2)
|
|
2078
|
+
|
|
2073
2079
|
qb1, _ = QrackAceBackend._get_qb_lhv_indices(hq1)
|
|
2074
2080
|
qb2, _ = QrackAceBackend._get_qb_lhv_indices(hq2)
|
|
2075
2081
|
qbt, _ = QrackAceBackend._get_qb_lhv_indices(hqt)
|
|
@@ -2136,6 +2142,8 @@ class QrackAceBackend:
|
|
|
2136
2142
|
for (b1, b2, bt) in witnesses:
|
|
2137
2143
|
self.sim[b1[0]].mcx([b1[1], b2[1]], bt[1])
|
|
2138
2144
|
|
|
2145
|
+
self._correct(t)
|
|
2146
|
+
|
|
2139
2147
|
self._in_gadget_capture = True
|
|
2140
2148
|
|
|
2141
2149
|
if anc_and is not None:
|
|
@@ -2153,9 +2161,6 @@ class QrackAceBackend:
|
|
|
2153
2161
|
|
|
2154
2162
|
self._in_gadget_capture = False
|
|
2155
2163
|
|
|
2156
|
-
if not self._in_gadget_capture:
|
|
2157
|
-
self._correct(t)
|
|
2158
|
-
|
|
2159
2164
|
def ccz(self, c1, c2, t):
|
|
2160
2165
|
self.h(t)
|
|
2161
2166
|
self.ccx(c1, c2, t)
|
|
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.26.0 → pyqrack_complex128-2.26.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.26.0 → pyqrack_complex128-2.26.2}/pyqrack/qrack_system/qrack_system.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack/stats/load_quantized_data.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack_complex128.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack_complex128.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack_complex128.egg-info/requires.txt
RENAMED
|
File without changes
|
{pyqrack_complex128-2.26.0 → pyqrack_complex128-2.26.2}/pyqrack_complex128.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|