Skip to content

feat(gates): add RotXY in-plane single-qubit rotation (R gate)#170

Merged
david-pl merged 1 commit into
mainfrom
feat/single-qubit-rotations
Jul 8, 2026
Merged

feat(gates): add RotXY in-plane single-qubit rotation (R gate)#170
david-pl merged 1 commit into
mainfrom
feat/single-qubit-rotations

Conversation

@david-pl

@david-pl david-pl commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Merge order

Part of splitting #168 into small, focused PRs. Full stack (independent items may merge in any relative order; dependents wait for their base):

  1. single-qubit rotations (this PR)main
  2. core tableau expectation/reset (feat/tableau-expectation-reset) → main
  3. native .pyi type stubs (feat/native-pyi-stubs) → this PR (declares the native r added here)
  4. vihaco-circuit-isa (feat(vihaco-circuit-isa): add standalone circuit ISA crate #169) → main
  5. circuit component (david/42.2-circuit-component) → feat(vihaco-circuit-isa): add standalone circuit ISA crate #169
  6. composite (david/42.3-composite) → PauliSum printing should properly display small floating points #5
  7. CLI + TUI (Add a composable ratatui TUI to ppvm-cli #166) → Trotter circuit simulation #6

Items 1, 2, and 4 are mutually independent off main.

Summary

Adds the RotXY trait to ppvm-traits and implements it for both backends (ppvm-tableau, ppvm-pauli-sum), plus the r(...) Python binding on the native PauliSum / tableau classes and the RotationsMixin / TruncatingRotationsMixin wrappers.

RotXY is a single-qubit rotation about an arbitrary axis in the X/Y plane:

R(axis_angle, θ) = exp(-i θ/2 · (cos(axis_angle)·X + sin(axis_angle)·Y))
                 = RZ(axis_angle)·RX(θ)·RZ(−axis_angle)

Pure addition alongside the existing RotationOne (RX/RY/RZ) rotations; no new module wiring. Like u3, r is single-qubit (scalar addr0), not batched over targets.

Provenance

Snapshotted from the tip of #168 (not cherry-picked); the R gate is a prerequisite for the circuit-component backends there.

Testing

cargo test -p ppvm-traits -p ppvm-tableau -p ppvm-pauli-sum green (incl. test_rx/ry/rz/r). Python: maturin develop + pytest test/test_basics.py test/generalized_tableau/test_basics.py → 37 passed. prek hooks (fmt, check, clippy, machete, ruff, ty, license) all pass.

Add the `RotXY` trait to `ppvm-traits` and implement it for both
backends (`ppvm-tableau`, `ppvm-pauli-sum`), plus the `r(...)` Python
binding on the native PauliSum / tableau classes and the
`RotationsMixin` / `TruncatingRotationsMixin` wrappers.

`RotXY` is a single-qubit rotation about an arbitrary axis in the X/Y
plane:

    R(axis_angle, θ) = exp(-i θ/2 · (cos(axis_angle)·X + sin(axis_angle)·Y))
                     = RZ(axis_angle)·RX(θ)·RZ(−axis_angle)

Pure addition alongside the existing `RotationOne` (RX/RY/RZ) rotations;
no new module wiring. Native type stubs (`.pyi`) for the whole module
are split into a separate follow-up PR. Snapshotted from #168, where the
R gate is a prerequisite for the circuit-component backends.

Merge order for the #168 split: single-qubit rotations (this) and core
tableau expectation/reset target `main` independently; native .pyi stubs
stack on this; then vihaco-circuit-isa (#169) -> circuit component ->
composite -> CLI/TUI (#166).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-07-08 09:06 UTC

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for an in-plane single-qubit rotation gate R(axis_angle, θ) across the Rust trait layer, both simulation backends (tableau + PauliSum), and the Python API surface, including targeted regression tests to ensure the intended Heisenberg/Schrödinger ordering semantics.

Changes:

  • Introduces the RotXY trait in ppvm-traits and re-exports it for downstream consumers.
  • Implements RotXY::r for GeneralizedTableau (Schrödinger picture via RZ(-φ) → RX(θ) → RZ(φ)) and for PauliSum (Heisenberg picture ordering).
  • Exposes r(...) in the native Python bindings and Python mixins, and adds Rust + Python tests validating key identities (e.g., axis_angle=0 => RX, axis_angle=π/2 => RY).

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
ppvm-python/test/test_basics.py Adds PauliSum-level Python tests for r(...) matching rx/ry special cases.
ppvm-python/test/generalized_tableau/test_basics.py Adds GeneralizedTableau Python tests confirming r(...) reduces to rx/ry at key axis angles.
ppvm-python/src/ppvm/mixins.py Adds r(...) to RotationsMixin and TruncatingRotationsMixin with docstring math and truncation support.
crates/ppvm-traits/src/traits/mod.rs Re-exports RotXY from the traits prelude.
crates/ppvm-traits/src/traits/branch/rot1.rs Defines the new RotXY trait and documents the RZ(φ) RX(θ) RZ(-φ) decomposition.
crates/ppvm-traits/src/traits/branch/mod.rs Re-exports RotXY from the branch module.
crates/ppvm-tableau/src/gates/rot1.rs Implements RotXY for GeneralizedTableau and adds backend-level tests for identity/special cases/statistics equivalence.
crates/ppvm-python-native/src/interface.rs Adds native PauliSum binding r(addr0, axis_angle, theta, truncate=True).
crates/ppvm-python-native/src/interface_tableau.rs Adds native tableau binding r(addr0, axis_angle, theta).
crates/ppvm-pauli-sum/src/sum/rot1.rs Implements RotXY for PauliSum and adds a test guarding the Heisenberg-order sign convention.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@david-pl david-pl merged commit 6dacadf into main Jul 8, 2026
15 checks passed
@david-pl david-pl deleted the feat/single-qubit-rotations branch July 8, 2026 09:06
david-pl added a commit that referenced this pull request Jul 8, 2026
## Merge order

Part of splitting #168 into small, focused PRs. Full stack (independent
items may merge in any relative order; dependents wait for their base):

1. single-qubit rotations (#170) → `main`
2. **core tableau expectation/reset (this PR)** → `main`
3. native `.pyi` type stubs (`feat/native-pyi-stubs`) → #170
4. vihaco-circuit-isa (#169) → `main`
5. circuit component (`david/42.2-circuit-component`) → #169
6. composite (`david/42.3-composite`) → #5
7. CLI + TUI (#166) → #6

Items 1, 2, and 4 are mutually independent off `main`.

## Summary

Adds `expectation.rs` for `GeneralizedTableau`:
- `expectation` — single-Pauli ⟨ψ|P|ψ⟩ for a `PauliWord`, conjugating P
through the tableau and overlapping with the sparse coefficient vector.
- `trace` — Σ over Paulis matching a `PauliPattern`.

Supporting changes in `data.rs`:
- `compute_decomposition_word` — multi-qubit conjugation used by
`expectation`.
- `reset_all` on both `Tableau` and `GeneralizedTableau` — reinitialise
to |0…0⟩, clearing coefficients and loss state (refactors `new` via a
shared `new_data` helper).
- the rayon-nesting guard on the coefficient path (avoids nesting rayon
inside shot-level parallelism; a no-op on the single-shot path).

`lib.rs` gains `pub mod expectation`; `Cargo.toml` gains a
`ppvm-pauli-word` dependency. Pure core addition, snapshotted from #168.

## Testing

`cargo test -p ppvm-tableau` green (12 expectation tests + reset/noise).
prek hooks all pass.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
david-pl added a commit that referenced this pull request Jul 8, 2026
## Merge order

Part of the #168 split. **Stacked on #170** (base branch
`feat/single-qubit-rotations`) because this stub file declares the
native `r` binding that #170 adds. Merge #170 first, then this.

Full stack: single-qubit rotations (#170) → **this** ; core tableau
expectation/reset (`feat/tableau-expectation-reset`) → `main` ;
vihaco-circuit-isa (#169) → `main` ; then circuit component → composite
→ CLI/TUI (#166).

## Summary

Adds `ppvm_python_native.pyi` — the first type-stub file for the
compiled `ppvm._core` module (none exists on `main`). It declares the
macro-generated concrete classes (`PauliSumIndexMapFxHash{0..15}`,
`PauliSumLossIndexMapFxHash{0..15}`, the `GeneralizedTableau{N}` family,
`StimProgram`) via synthetic `_PauliSumBase` / `_PauliSumLossBase` /
`_GeneralizedTableauBase` bases that hold the shared method signatures
once.

Pure additive typing surface; no runtime effect. Split out of #170
because the block covers the whole module — only `r` is new API; the
rest describe pre-existing bindings.

## Provenance

Snapshotted from the tip of #168.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants