Better-balanced approximate near-Clifford in QStabilizer
We have an exact near-Clifford method (which is too slow for almost anything but one-off checks of single probability amplitudes, or a small number at a time), and we have two approximate near-Clifford methods. QStabilizerHybrid co-opts the "reverse phase-injection gadgets" from the exact method as stochastic injection points, at point of terminal measurement, for either the closest or second-closest Clifford phase gate to a requested RZ operation: any RZ gate implies a "phase quadrant" defined by the closest possible Clifford rotation only in terms of S-gate increments and the complementary second-closest possible S-gate increment on the unit circle. (If the RZ gate is equivalent to a T gate, then the ideal gate sits at the exactly balanced midpoint between these two closest possible S gates.) QStabilizer relies on this same concept of an "S-gate quadrant," though it applies the stochastic RZ gate correction at the point the gate is requested, instead of deferred with an "injection gadget" until terminal measurement, and it tries to "complete the S gate" downstream, propagating and completing complements of phase remainder to at least first order.
In QStabilizer, at the point an RZ gate is requested, there are four "logically equivalent" representations of state that lead to different downstream stochastic side effects, holding the requested RZ gate definition fixed. The "remainder" of the RZ gate that cannot be applied exactly is retained as a buffered scalar and continues to participate statistically downstream. Upon application of the RZ gate, we could apply side-effects to other scalar phase buffers based on either the closest or else second-closest pure-Clifford S-gate quadrant. (We have taken to calling the closest state, "major," and the second-closest state, "minor.") The decision of which of these two to apply initially is based on a biased "coin flip," weighted linearly by the angle imbalance between closest and second-closest states. (So, for a T gate, at the exact midpoint, the probability of either approximate state convention is equal, and for the square root of T, for example, it would be 3/4 probability in favor of the closest state vs. 1/4 in favor of the second closest.) Secondly, downstream, we continue to incorporate the statistical side effects of the "remainder" between pure-Clifford phase application and requested RZ gate, for either "major" or "minor" representation, but we don't apply cumulative "side effects" on other scalar phase remainder buffers, as if this were the initial application of the RZ gate. Hence, we also have "reverse major" and "reverse minor" possible states, where "major" and "minor" representations are reversed without statistical side effects of initial gate application. (Empirically, this is the best policy we have found, for the stochastic approximation.) Hence, we also choose "reverse" or "forward" representation with equal probability, for best possible statistical balance, to approximate the non-Clifford phase in ensemble of multiple independent measurement shots.
This release of Qrack consistently applies the logic described above in QStabilizer. It also exposes new methods for fine-grained user control to toggle between "major," "minor," "forward," and "reverse" representations that are considered the four closest "logically-equivalent" representations to any arbitrary non-Clifford RZ gate application.
In the PyQrack release, we also provide QrackNearCliffordQecBackend. This back end potentially improves overall statistical balance of the stochastic QStabilizer simulation through n-repetition code, with default n=5. "Forward" and "reverse" copies of the state are systematically "rebalanced" throughout the circuit, which gives a more consistent fidelity-degradation profile. Syndrome decoding and repair can be applied, optionally, by setting constructor option layers_per_qec_round to any value greater than 0 (or set it to 0 to turn this option off), but remember that we only keep n count of statistically-balanced stochastically approximate copies of the state, not an actual pure state, so syndrome decoding and repair can introduce more error than it removes, depending.
Full Changelog:
unitaryfoundation/qrack@vm6502q.v10.1.9...vm6502q.v10.2.0
v1.84.14...v1.85.0
sha1sum results:
76fd40a6e348d6fc5d5db0245d63d79af2c8ef80 pyqrack-1.85.0-py3-none-macosx_14_0_arm64.whl
8bdbe520ff0f5b12a51f1d1b749a7e0e496cb136 pyqrack-1.85.0-py3-none-macosx_15_0_arm64.whl
8879a07bb575b08414f3d12f876e37102672faa9 pyqrack-1.85.0-py3-none-macosx_15_0_x86_64.whl
4e7c2ae4b0dce72d8c03b8bf23c4f00b6d10f1bc pyqrack-1.85.0-py3-none-manylinux_2_35_x86_64.whl
a23e9e34d8c92ade1531e88e62e066f35dd6bea9 pyqrack-1.85.0-py3-none-manylinux_2_39_x86_64.whl
5367063a6df7dacf2ba285d660e4d8c0f010697f pyqrack-1.85.0-py3-none-win_amd64.whl
5a5a81b136c05642a60312c6e6005a7fb7f9039f pyqrack-1.85.0.tar.gz
7093b8c26c2ba7d6f561db782e59df3681117fce pyqrack_complex128-1.85.0-py3-none-macosx_14_0_arm64.whl
42b5ea3d320d5d4d56424f06036f2235930efe37 pyqrack_complex128-1.85.0-py3-none-macosx_15_0_arm64.whl
fb06b0ef599fd171f65b6bda0822d1dd9488d7c6 pyqrack_complex128-1.85.0-py3-none-macosx_15_0_x86_64.whl
b223d2af786af5f6fe530b987c20c11087da2580 pyqrack_complex128-1.85.0-py3-none-manylinux_2_35_x86_64.whl
2c9ac5b675236a85a077e9c0bc4937b841a9ccdc pyqrack_complex128-1.85.0-py3-none-manylinux_2_39_x86_64.whl
9cc1800868efbc4f40ac152b802024300cf94faa pyqrack_complex128-1.85.0-py3-none-win_amd64.whl
c85673d55c7063bfe932e7a7778bea2d431b6312 pyqrack_complex128-1.85.0.tar.gz
fd3d1f09a265ec1e5b5847f2c818024b96122c44 pyqrack_cpu-1.85.0-py3-none-macosx_14_0_arm64.whl
24d8e5ad7bff4e97dba0203e6ae573de64e7b7b9 pyqrack_cpu-1.85.0-py3-none-macosx_15_0_arm64.whl
7948b7e90b4651f360bcae92bb043d1e9a8bab9a pyqrack_cpu-1.85.0-py3-none-macosx_15_0_x86_64.whl
477dfb77e21f9731d1131a8cf5845163bfb98092 pyqrack_cpu-1.85.0-py3-none-manylinux_2_35_x86_64.whl
8f7d23b2aa596ab9431f293fbb0e98d9c366cacb pyqrack_cpu-1.85.0-py3-none-manylinux_2_39_x86_64.whl
1914ac088bfa27adef4642fd06a76741bcfc3345 pyqrack_cpu-1.85.0-py3-none-win_amd64.whl
23c4a67b3d7ec242e8b259ea67e3ae38dd306e25 pyqrack_cpu-1.85.0.tar.gz
9f46bb6b2f17c98d3081d50f5852a97fec506970 pyqrack_cpu_complex128-1.85.0-py3-none-macosx_14_0_arm64.whl
e9afe56c57fd9081894f9c3e57f931096a7b3e4b pyqrack_cpu_complex128-1.85.0-py3-none-macosx_15_0_arm64.whl
2a5b5fd508137dd3ad6a9283230341024230d897 pyqrack_cpu_complex128-1.85.0-py3-none-macosx_15_0_x86_64.whl
bdccefecb28d1de7ce6ba1a7243ca9528de7b3e8 pyqrack_cpu_complex128-1.85.0-py3-none-manylinux_2_35_x86_64.whl
4e80085c174bd2396f746677e57a40ecb6884ae1 pyqrack_cpu_complex128-1.85.0-py3-none-manylinux_2_39_x86_64.whl
8b8ecd636435c1c3f13bd6b825ffff61c5b40b38 pyqrack_cpu_complex128-1.85.0-py3-none-win_amd64.whl
8f3ad5fc64e2d814af01ee652c98d09c67e2ffbe pyqrack_cpu_complex128-1.85.0.tar.gz
a4349c65712690c47b40168c660c39f436b1e7cc pyqrack_cuda-1.85.0.tar.gz
cae861d632121ce15da3be7b9a6469a0b741f6dd pyqrack_cuda_complex128-1.85.0.tar.gz