sympauli
Symbolic Pauli Heisenberg Evolution Engine
Evolves quantum observables through parameterized circuits in the Heisenberg picture, keeping all coefficients as exact SymPy expressions. Vibe coded using Claude AI in one afternoon.
Install dependencies
pip install sympy numpy
Usage
from sympauli import PauliSum, evolve, gradient, expectation_value
from sympauli.gates import gate_Ry, gate_CNOT
import sympy as sp
import numpy as np
theta = sp.Symbol('theta', real=True)
n = 2
# Define observable
H = PauliSum.from_dict({'ZZ': 1, 'XI': 1, 'IX': 1}, n=n)
# Define circuit
circuit = [gate_Ry(theta, target=0), gate_Ry(theta, target=1), gate_CNOT(0, 1)]
# Symbolically evolve in the Heisenberg picture: U†·H·U
H_evolved = evolve(H, circuit, n_qubits=n)
# Symbolic gradient w.r.t. theta
dH = gradient(H, circuit, n_qubits=n, param_symbol=theta)
# Expectation value on a state
state = np.array([1, 0, 0, 0], dtype=complex)
ev = expectation_value(H_evolved, state, {theta: 0.5})
Approximate simulation
Exact evolution grows the number of Pauli terms with circuit depth, in the worst case
until it saturates the 4ⁿ available strings. evolve_truncated bounds the working set
instead, discarding terms above a chosen Pauli weight after every gate — truncating
once at the end would save nothing, since the intermediate blow-up has already been paid
for. This is approximate Pauli-path simulation, and it is lossy by construction: the
result equals evolve's only when the cutoff cannot bite.
from sympauli import evolve_truncated
H_approx = evolve_truncated(H, circuit, n_qubits=n, max_weight=2)
A coefficient cutoff is available alongside the weight cutoff via min_magnitude, which
needs a subs dict since coefficients are symbolic; a term whose value is still unknown
after substitution is kept rather than guessed at.
Truncated evolution routes each conjugation through conjugate_by_gate_fast, which
recognizes a single-generator rotation exp(-iθ/2·Q) and applies the closed form
G†PG = P when [P,Q] = 0 and cos(θ)·P − i·sin(θ)·PQ when {P,Q} = 0, instead of
building the triple product and simplifying away the terms that cancel. Anything else
falls back to the exact path, so it is a drop-in replacement for conjugate_by_gate.
Package structure
| Module | Contents |
|---|---|
pauli_string.py |
PauliString — symplectic bitmask representation, multiplication, embedding |
pauli_sum.py |
PauliSum — symbolic linear combination, arithmetic, adjoint, simplification |
gates.py |
40+ standard gates as PauliSums: Rx/Ry/Rz, CNOT, CRy, RXX/RYY/RZZ, CCX, … |
heisenberg.py |
evolve, gradient, expectation_value, validate |
simplify.py |
conjugate_by_gate_fast, as_rotation, simplify_coeffs, is_clifford_gate |
truncation.py |
evolve_truncated, truncate, truncate_weight, truncate_coeff |
example.py |
Runnable demo: python -m sympauli.example |
Qubit convention
PauliString.from_string('AB'):Aacts on qubit 1 (MSB),Bacts on qubit 0 (LSB).gate_CNOT(control=0, target=1): control is qubit 0, target is qubit 1.to_matrix()uses big-endian ordering: qubitn-1is the most significant bit.
Citation
If you found this useful, please consider citing us.
@misc{shirgure2026challengesbarrenplateaumitigation,
title={Challenges in Barren Plateau Mitigation with Dynamic Parameterized Quantum Circuits},
author={Sumeet Shirgure and Efekan Kökcü and Siyuan Niu},
year={2026},
eprint={2606.23751},
archivePrefix={arXiv},
primaryClass={quant-ph},
url={https://arxiv.org/abs/2606.23751},
}
Metadata
Release files for sympauli 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| sympauli-1.1.0.tar.gz | 48.7 kB | Without provenance | Details for sympauli-1.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| sympauli-1.1.0-py3-none-any.whl | Python 3 | none | any | Details for sympauli-1.1.0-py3-none-any.whl |
Total release size: 85.2 kB
Release files / sympauli-1.1.0.tar.gz
| Download URL | sympauli-1.1.0.tar.gz |
|---|---|
| Size | 48.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9aa40d54cdb9aef73eebcd1ead93ba94c443619ee6a04084fa9e8db8f7100def
|
|
BLAKE2b-256 checksum How to use checksums |
442f8efda03485b4db117eaa84da1f13c4cfc0815f8382edc1e14963aaaa7d72
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.19
|
Release files / sympauli-1.1.0-py3-none-any.whl
| Download URL | sympauli-1.1.0-py3-none-any.whl |
|---|---|
| Size | 36.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
77b7e186c133b0d2b6231dc607e4cfbf8db4c4daeb4d686dd96c0a94b16335cf
|
|
BLAKE2b-256 checksum How to use checksums |
65febf239b08fea81763577f14dc72b01bbf45f56d08a192e4c7492befc7851f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.19
|
Security for sympauli 1.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.