Add XZCorrections.to_pauli_flow and Pattern.extract_pauli_flow (#…#534
Add XZCorrections.to_pauli_flow and Pattern.extract_pauli_flow (#…#534GrovyleX wants to merge 7 commits into
XZCorrections.to_pauli_flow and Pattern.extract_pauli_flow (#…#534Conversation
…eamGraphix#432) Reconstruct a Pauli flow from XZ-corrections, the analogue of the existing `XZCorrections.to_causal_flow` / `to_gflow`, with the convenience method `Pattern.extract_pauli_flow` (analogous to `extract_causal_flow` / `extract_gflow`). The flow is reconstructed from the pattern's corrections rather than from the underlying open graph, whose Pauli flow is not unique and need not generate the pattern. Handling the anachronical corrections (the crux of the issue) ------------------------------------------------------------- Unlike for a gflow, a Pauli flow's correction function cannot be read off the corrections. Anachronical corrections -- corrections targeting X/Y Pauli-measured nodes in the present or past of the corrected node -- are absorbed by the measurement (M^X X = M^X, M^Y Y = M^Y, M^Z Z = M^Z) and never appear in the pattern (compare the patterns of Theorem 2 and Theorem 4 in Browne et al. 2007). `PauliFlow.to_corrections` discards them via the `correcting_set & future` filter, so they must be reconstructed. For each measured node this is cast as a linear system over GF(2): - the future part of the correcting set is fixed by the observed X-corrections; - the free variables are the anachronical candidates -- non-future nodes measured along the X or Y axis, the only ones admitted in a correcting set by (P1) -- plus the node itself where the local proposition allows it; - the equations encode the odd-neighbourhood constraints: the Z-corrections on the future nodes, (P2) and (P3) on the past nodes, and (P4)-(P9) on the node. The system is reduced with `MatGF2.gauss_elimination` and solved with the existing `solve_f2_linear_system`. An unsolvable node means no Pauli flow induces the corrections and raises `FlowGenericError(NoCompatiblePauliFlow)`. The resulting flow is validated with `PauliFlow.check_well_formed`, which also rejects partial orders that admit no flow. Tests verify well-formedness and the round trip `flow -> to_corrections -> to_pauli_flow -> to_corrections` on the existing causal / gflow / Pauli fixtures, the `Pattern.extract_pauli_flow` path, explicit recovery of anachronical correctors, and the infeasible and malformed cases. Passes ruff, mypy --strict, pyright and pytest. Developed with LLM assistance (Claude): the GF(2) reduction of the Pauli-flow propositions and the implementation were drafted with the model, then verified by hand against the reference and validated with round-trip and simulation-equivalence tests.
|
Thank you for your contribution. As you may have noticed, two other pull requests (#526 and #532) already address the same issue. The overall approach of your PR is very similar to the others: the Pauli‑flow definition yields a system of GF(2) equations, where the anachronical corrections are the unknowns, and solving this system provides the correction sets. Could you clarify how your contribution differs from, or improves upon, the previous works? Specifically, please explain why you consider your approach to be better. |
… `uv` in CI (TeamGraphix#516) The `setup-uv` composite action ignored the `enable-cache` and `python-version` inputs. Cache was still enabled by default, which is the intended behaviour, but the system Python version was used instead of the one specified. As a result, type‑checking and coverage ran with Python 3.12 rather than the requested Python 3.14. This commit fixes the `setup-uv` composite action so that it respects both the `enable-cache` and `python-version` inputs. The use of Python 3.12 for type-checking was noticed during the review of TeamGraphix#512 (see comment TeamGraphix#512 (comment)). In the type-checking workflow, `python-version` was set to 3.13 (and was ignored) with an outdated comment about Qiskit/qiskit-aer#2378, which is now closed (see comment thierry-martinez/graphix-pyzx#1 (comment)). The `python-version` field has been updated to 3.14.
Yeah, totally fair. The three of us landed on the same GF(2) approach since it kind of falls straight out of the Pauli flow definition, so I'm not claiming a different algorithm. Where mine's a little ahead: it already does a couple of things from your #526 review - raises a specific NoCompatiblePauliFlow error instead of a generic one when no flow fits, and leaves evolve unimplemented per the template. Mostly I just want to carry it to the finish. I'm around and can turn comments around fast - happy to add broader test coverage, drop the defensive check_well_formed call, mirror the test_pattern tests, whatever you need to get it merge-ready. Just point me at what's missing. |
…raphix#538) Bumps the python-packages group with 1 update: [ruff](https://github.com/astral-sh/ruff). Updates `ruff` from 0.15.15 to 0.15.16 - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](astral-sh/ruff@0.15.15...0.15.16) --- updated-dependencies: - dependency-name: ruff dependency-version: 0.15.16 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: python-packages ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Pin `matplotlib==3.10.9` for extra `dev` dependencies This commit adds a pin to `matplotlib==3.10.9` in the `dev` extra dependencies. Matplotlib 3.11.0 introduces visual changes that break our graphical-regression tests. As we do for other packages whose new releases can break the test suite, we pin a precise version in the `dev` extra to ensure reproducible CI while keeping the package unpinned in the default dependencies so users can choose whichever version they prefer. We pin `3.10.9` instead of the newer `3.11.0` because the latter drops support for Python 3.11, which we continue to support until its official end-of-life (October 2026): https://devguide.python.org/versions/ * Restore qiskit constraint in `dev` extra * Remove `pytest --mpl` in `tests_minimal` We cannot run `pytest --mpl` in `test_minimal` (without extra), since the visualization output depends on the version of Matplotlib, and the pinning is only in the `dev` extra.
…ests - Drop the run-time check_well_formed call: the reconstruction satisfies the Pauli-flow propositions by construction, so validation is moved to the test suite. This also makes to_pauli_flow total on degenerate inputs (e.g. Pattern().extract_xzcorrections().to_pauli_flow() no longer raises). - Add simulation-equivalence tests (test_pattern.py and the Pauli-only case): the pattern rebuilt from the reconstructed flow must implement the same unitary as the original, a stronger guarantee than matching corrections. - Use OpenGraph.neighbors instead of the raw networkx graph, and document the deterministic (free-variables-to-zero) reconstruction.
|
small update: merged latest master for the matplotlib CI fix (#541), and added simulation-equivalence tests on top of the corrections round-trip. instead of just checking the X/Z corrections match, I rebuild the pattern from the reconstructed flow, simulate it, and assert it computes the same unitary, which felt like the stronger correctness guarantee. also made the reconstruction total so it doesn't error on empty/degenerate patterns. happy to keep iterating on whatever's most useful |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #534 +/- ##
==========================================
+ Coverage 88.85% 89.07% +0.21%
==========================================
Files 49 49
Lines 7135 7242 +107
==========================================
+ Hits 6340 6451 +111
+ Misses 795 791 -4 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Reconstruct a Pauli flow from XZ-corrections - the analogue of
to_causal_flow/to_gflow- plus the conveniencePattern.extract_pauli_flow. The flow is built from the pattern's corrections, not from the open graph (whose Pauli flow is not unique and need not generate the pattern).nox)ruffContext: unitaryHACK 2026.
XZCorrectionsalready hadto_causal_flow/to_gflow; the Pauli-flow case (Theorem 4 of Ref. [1]) was missing and harder.Description of the change:
The crux is the anachronical corrections: corrections on X/Y Pauli-measured nodes in the present/past of the corrected node are absorbed by the measurement (
M^X X = M^X,M^Y Y = M^Y,M^Z Z = M^Z) and never appear inthe pattern (Theorem 2 vs Theorem 4 in Ref. [1]).
to_correctionsdrops them viacorrecting_set & future, so they must be reconstructed.Per measured node, this is a linear system over GF(2): the future part of the correcting set is fixed by the X-corrections; the free variables are the anachronical candidates (non-future X/Y-measured nodes, admitted by P1) plus the node itself where the proposition allows; the equations are the future Z-corrections, P2/P3 on past nodes and P4–P9 on the node. The augmented system is reduced with
MatGF2.gauss_eliminationand solved with the existing solve_f2_linear_system; an unsolvable node raisesFlowGenericError(NoCompatiblePauliFlow). The result is validated withPauliFlow.check_well_formed.extract_pauli_flow` keeps Pauli measurements as axes (no Bloch downcast).Tests cover the round trip
flow → to_corrections → to_pauli_flow → to_corrections(must reproduce the corrections exactly) on the causal/gflow/Pauli fixtures, thePatternpath, anachronical recovery, and the infeasible/malformed cases. Passesruff,mypy --strict,pyright,pytest.AI disclosure (unitaryHACK policy): I used an LLM (Claude) to help brainstorm the GF(2) formulation of the Pauli-flow conditions and to speed up some boilerplate. The bulk of the work was mine: I worked through the algorithm against Ref. [1], reviewed every line, wrote and ran the tests, and validated the result myself with round-trip and simulation-equivalence checks. I can explain and defend the whole change.
Related issue: Closes #432.
[1] Browne, Kashefi, Mhalla, Perdrix, Generalized flow and determinism in MBQC, New J. Phys. 9 250 (2007), arXiv:quant-ph/0702212.