Metadata-Version: 2.4
Name: tencirpauli
Version: 0.2.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Rust
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Dist: numpy>=1.23
Requires-Dist: tensorcircuit-ng>=1.8,<2
Requires-Dist: pytest>=7 ; extra == 'benchmark'
Requires-Dist: pytest-benchmark>=4 ; extra == 'benchmark'
Requires-Dist: scipy>=1.10 ; extra == 'examples'
Requires-Dist: black>=24.10,<26 ; extra == 'quality'
Requires-Dist: mypy>=1.14,<2 ; extra == 'quality'
Requires-Dist: ruff>=0.9,<1 ; extra == 'quality'
Requires-Dist: pytest>=7 ; extra == 'test'
Provides-Extra: benchmark
Provides-Extra: examples
Provides-Extra: quality
Provides-Extra: test
License-File: LICENSE
Summary: Rust-native Pauli algebra and propagation with a first-class Python API
Home-Page: https://github.com/tensorcircuit/TenCirPauli
Author-email: refraction-ray <znfesnpbh@gmail.com>
License: Apache-2.0
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/tensorcircuit/TenCirPauli
Project-URL: Issues, https://github.com/tensorcircuit/TenCirPauli/issues
Project-URL: Repository, https://github.com/tensorcircuit/TenCirPauli

<div align="center">
  <img src="docs/assets/tencirpauli-logo.png" alt="TenCirPauli logo" width="180">
  <h1>TenCirPauli</h1>
  <p><strong>Fast, Rust-native Pauli algebra and quantum-circuit primitives for TensorCircuit.</strong></p>
  <p>
    <a href="https://github.com/tensorcircuit/TenCirPauli/actions/workflows/ci.yml"><img src="https://github.com/tensorcircuit/TenCirPauli/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI status"></a>
    <a href="https://tensorcircuit.github.io/TenCirPauli/"><img src="https://img.shields.io/badge/docs-latest-blue.svg" alt="Documentation"></a>
    <a href="https://pypi.org/project/tencirpauli/"><img src="https://img.shields.io/pypi/v/tencirpauli.svg" alt="PyPI version"></a>
    <a href="https://pypi.org/project/tencirpauli/"><img src="https://img.shields.io/pypi/pyversions/tencirpauli.svg" alt="Python versions"></a>
    <a href="https://pypi.org/project/tencirpauli/"><img src="https://img.shields.io/pypi/dm/tencirpauli.svg" alt="PyPI downloads"></a>
    <a href="https://github.com/tensorcircuit/TenCirPauli/stargazers"><img src="https://img.shields.io/github/stars/tensorcircuit/TenCirPauli.svg?style=flat" alt="GitHub stars"></a>
    <a href="https://github.com/tensorcircuit/TenCirPauli/blob/main/LICENSE"><img src="https://img.shields.io/github/license/tensorcircuit/TenCirPauli.svg" alt="Apache 2.0 license"></a>
  </p>
</div>

TenCirPauli brings a compact Rust core and a Python-first API to the Pauli-heavy parts of quantum workflows. Build Hamiltonians, group measurements, reduce symmetries, work in fixed-particle-number sectors, and propagate observables without leaving the TensorCircuit ecosystem.

## Why TenCirPauli?

| Workflow | What you get |
| --- | --- |
| **Pauli algebra** | Canonical words, products, phases, commutation, support, and deterministic term aggregation. |
| **Hamiltonians** | Dense, COO, CSR, matrix-vector products, and reusable native or TensorCircuit backend plans. |
| **Measurement and symmetry** | QWC/general commuting groups, Z2 tapering, and U(1) sector restriction. |
| **Native circuit execution** | Fixed-particle-number circuits, deterministic Pauli propagation, gradients, and stochastic Pauli-path estimates. |
| **Structured fermion workflows** | Majorana algebra, Jordan–Wigner/parity/Bravyi–Kitaev plans, exact additive charges, and guarded restricted sectors. |

## Install

```bash
python -m pip install tencirpauli
```

Released wheels target CPython 3.9+ on Linux x86_64/aarch64, macOS x86_64/arm64, and Windows x64. A matching wheel does not require a local Rust toolchain.

## Quick start

```python
import tencirpauli as tcp

hamiltonian = tcp.PauliOperator.from_terms(
    2,
    (("XX", 0.5), ("ZI", -1.25j)),
)

matrix = hamiltonian.compile(target="dense")
print(matrix.shape)  # (4, 4)
```

For a complete circuit example, see [`examples/`](examples/) and the TensorCircuit integration guide below.

## Built for the ecosystem

TenCirPauli is designed for TensorCircuit users, while its Rust core remains independent of Python and TensorCircuit. The public package is distributed on PyPI with wheels and an sdist; source builds require Rust 1.85+, Cargo, and maturin.

## Architecture

```text
TensorCircuit / Python facade
        │
        ├── PauliOperator, grouping, symmetry, backend MVP
        ├── U1Circuit
        ├── PropagationCircuit       (deterministic native facade)
        ├── SPPSCircuit              (stochastic native facade)
        └── Majorana/mapping/charge  (structured Phase 7.5 facade)
        │
        ▼
PyO3 batch boundary
        │
        ├── Rust U(1) restricted-state executor
        ├── Rust deterministic Heisenberg propagation executor
        └── Rust stochastic Pauli-path executor
```

The three circuit facades share Python-level construction, parameter and objective conventions. Their native executors remain independent because they implement different numerical contracts.

## Core conventions

External Pauli codes are `0=I`, `1=X`, `2=Y`, `3=Z`. Internal packed words use qubit zero as the least-significant bit. Matrix and TensorCircuit computational-basis interfaces use qubit zero as the most-significant bit. Coefficients are complex128-compatible, duplicate Pauli terms are aggregated deterministically, and public arrays are returned read-only where the API promises immutable results.

## Main objects

| Task | Entry point |
| --- | --- |
| Pauli algebra | `PauliWord`, `PauliOperator` |
| Hamiltonian targets | `.dense()`, `.coo()`, `.csr()`, `.mvp()` |
| Reusable native MVP | `.native_mvp_plan()` |
| TensorCircuit backend MVP | `.backend_mvp_plan()`, `backend_mvp()` |
| QWC/general grouping | `.group_commuting()` |
| Z2 symmetry/tapering | `.find_z2_symmetries()`, `.taper_z2()` |
| Fixed-particle-number operator | `U1Sector`, `.restrict_u1()` |
| Fixed-particle-number circuit | `U1Circuit` |
| Majorana algebra and fermion mappings | `MajoranaOperator`, `FermionQubitMapping` |
| Additive-charge sectors | `AdditiveCharge`, `ChargeSector`, `.restrict_charge()` |
| Deterministic Pauli propagation | `PropagationCircuit` (advanced `GateTape`/`PropagationEngine` remain available) |
| Stochastic Pauli-path estimation | `SPPSCircuit` (low-level `SPPSEngine` remains available) |

## Structured operator algebra

Phase 7 adds `FermionOperator`, `BosonOperator`, `QuditWeylOperator`, and `OperatorSpace` for canonical fermionic CAR, symbolic bosonic CCR, hybrid mixed-radix layouts, and uniform-dimension Weyl words. Fermions map through Jordan–Wigner; boson cutoffs are required only at finite compilation and use the projected open-boundary Fock convention. The batch `OperatorBuilder` is available under [`tencirpauli.advanced`](python/tencirpauli/advanced.py).

Phase 7.5 adds exact `MajoranaWord`/`MajoranaOperator` conversion, reusable Jordan–Wigner, parity, and Bravyi–Kitaev occupation mappings, and integer `AdditiveCharge`/`ChargeSector` workflows. Charge sectors use exact conservation checks, infer simple finite boson bounds, retain uncharged qudit spectators, and expose guarded dense/COO/CSR plus matrix-free restricted plans. See [`examples/majorana_charge.py`](examples/majorana_charge.py) and the frozen [`phase-7.5-spec.md`](docs/vibe/phase-7.5-spec.md).

Finite targets are selected explicitly with `compile("dense" | "coo" | "csr" | "native_mvp" | "backend_mvp")`. Dense/COO/CSR and native MVP are available for guarded finite structured layouts. `backend_mvp` is available for Pauli plans and uniform pure-qudit Weyl plans through direct TensorCircuit NumPy/JAX backend operations; finite boson and mixed-dimension hybrid backend plans raise `NotImplementedError` rather than falling back silently. See [`examples/structured_algebra.py`](examples/structured_algebra.py) for an executable example.

## Common circuit facade

Phase Alpha defines the target Python contract for the three circuit classes. The circuit structure is built once; runtime values are supplied as a parameter vector.

```python
import tencirpauli as tcp

p0 = tcp.Parameter(0)
p1 = tcp.Parameter(1)

circuit = tcp.U1Circuit(nqubits=4, particle_number=2, occupied=[0, 1])
circuit.iswap(0, 1, theta=p0)
circuit.rzz(1, 2, theta=2.0 * p1 + 0.1)

hamiltonian = tcp.PauliOperator.from_terms(
    4,
    (("XXII", 0.5), ("YYII", 0.5), ("ZIZI", -0.2)),
)

result = circuit.value_and_grad(
    hamiltonian,
    parameters=[0.2, -0.3],
)
energy = circuit.expectation(hamiltonian, parameters=[0.2, -0.3])
```

The same high-level shape is used by the implemented `PropagationCircuit` and `SPPSCircuit` facades:

```python
circuit = tcp.PropagationCircuit(nqubits=4, initial_state=tcp.ZeroState())
circuit.ry(0, theta=p0)
circuit.cnot(0, 1)
circuit.rz(1, theta=p1)

result = circuit.value_and_grad(hamiltonian, parameters=[0.2, -0.3])
energy = circuit.expectation(hamiltonian, parameters=[0.2, -0.3])
```

`Parameter` reuse means shared differentiation. A static `theta=0.2` is not a differentiable parameter. Concrete NumPy arrays, Python sequences, and concrete JAX arrays are converted to host contiguous float64 vectors for native calls. Native circuit calls are not JAX-traceable; use the backend MVP path when the computation must remain inside a JAX graph.

The current implementation contract and rollout status are recorded in [`docs/vibe/phase-alpha-spec.md`](docs/vibe/phase-alpha-spec.md).

## Backend MVP

Use the TensorCircuit backend path when JAX/JIT/autodiff or a TensorCircuit backend tensor must remain active:

```python
import numpy as np
import tensorcircuit as tc
import tencirpauli as tcp

tc.set_backend("numpy")
tc.set_dtype("complex128")

h = tcp.PauliOperator.from_terms(2, (("XY", 0.5), ("ZI", -1.25j)))
plan = h.backend_mvp_plan()
state = np.arange(4, dtype=np.complex128)
result = tcp.backend_mvp(plan)(state)
```

The plan structure is static; coefficients may be supplied as backend tensors where the plan API permits it. This path is distinct from native deterministic or stochastic circuit gradients.

## Existing low-level propagation API

The low-level API remains available when an Agent needs explicit tape or engine control:

```python
from tencirpauli import advanced

tape = advanced.GateTape(3)
tape.h(0)
tape.cnot(0, 1)
tape.rz(1, parameter=0)

observable = tcp.PauliOperator.from_terms(3, (("ZII", 1.0),))
engine = advanced.PropagationEngine(tape, observable, max_weight=3)
result = engine.value_and_grad([0.125])
```

`PropagationEngine` propagates the observable in reverse Heisenberg order. `max_weight=None` or a cutoff at least as large as `nqubits` is exact; a finite cutoff applies deterministic Pauli-weight projection after same-word contributions have been aggregated. The gradient is for the executed frozen sparse trace, not a dense derivative at support-change points.

The Phase Alpha facade adds the corresponding value-only form `circuit.expectation(observable, parameters=...)`; it must agree with `value_and_grad(...).value` for deterministic execution without computing a gradient.

`SPPSEngine` provides seeded stochastic value-and-gradient estimates with fixed or adaptive per-term sample budgets. Its result includes standard-error and stopping-proxy metadata and must not be interpreted as a deterministic gradient result.

## U(1) semantics

`U1Sector` and `U1Circuit` use TensorCircuit computational-basis integer ordering. `U1Circuit` stores and executes only the fixed-Hamming-weight sector; `state()`/`probability()` are restricted-space terminals and `state_full()`/`probability_full()` are explicit full-space terminals. The native restricted implementation supports arbitrary-width packed occupation limbs, while full-space materialization remains subject to the public `DEFAULT_MAX_BYTES` guard.

## TensorCircuit conversion

TensorCircuit is the required ecosystem dependency. User-facing conversion uses target-type classmethods:

```python
native_u1 = tcp.U1Circuit.from_circuit(tc_u1_circuit)
native_propagation = tcp.PropagationCircuit.from_circuit(tc_circuit)
```

Low-level QIR restoration remains available through `from_qir()`. Numeric QIR produces static gates; direct symbolic references produce parameter slots. TensorCircuit gate objects are normalized at the boundary to a static logical payload, especially for `diagonal` gates.

## Development

The local quality gate is:

```bash
python scripts/check.py --benchmark smoke
```

The full release checks include Rust formatting, Clippy, Rust tests, Black, Ruff, strict mypy, release maturin installation, Python tests, and benchmark harness smoke tests. TensorCircuit differential tests use the supported TensorCircuit installation and compare ordering, gate conventions, state/observable values, backend MVP results, and native conversion behavior.

See [`CONTRIBUTING.md`](CONTRIBUTING.md), [`docs/vibe/phase-alpha-spec.md`](docs/vibe/phase-alpha-spec.md), [`docs/vibe/semantics.md`](docs/vibe/semantics.md), and [`docs/vibe/releasing.md`](docs/vibe/releasing.md).

## License

Apache License 2.0.

