Changelog¶
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog.
[0.1.5] - 2026-09-08¶
Added¶
- Change abstract propagator from boilerplate to a functional interface.
DictTermSum, a reusable dict-backedAbstractTermSumfor a Python-defined basis, with real coeff term I/OAbstractTermgainedn_units,trace_with_fock_state, and concretedagger/words/from_bytesdefaults.AbstractRotationand a minimalAbstractCircuit, inpropaq.circuits.PauliRotation/MajoranaRotationare nowAbstractRotationsubclasses.resolve_truncation/ResolvedTruncationinpropaq.truncation, the Python facing interpreter for truncators.PropagationResult(Rust) can now be constructed directly from Python.
Changed¶
- The qudit Weyl–Heisenberg custom-basis notebook now uses the new abstract interface.
[0.1.4] - 2026-09-01¶
Added¶
- Pre-commit hooks for
ruff,mypyandcargoformatting. - Added
examplesextra for installing required dependencies for running the example notebooks. - Added more documentation for logging semantics.
- Overridden
isinstance()on the public truncation wrapper classes to match Rust instances.
Changed¶
- Moved
ffsimfrom a required runtime dependency to an extra for Windows compatibility. - Updated wheels to use appropriate Rust flags for each platform.
GateNoiseModelcan now be subclassed directly, defining the appropriate methods.- Extrapolators now allow for custom noise models and truncators to be swept instead of the hardcoded ones.
- Added
terms_gainedto logging to track the number of branches created at each gate. - Updated CI to execute notebooks prior to building the documentation.
- Renamed
map_termstotermsinGateEvent. - Renamed
avg_ms_per_gatetoms_per_gateinGateEvent. - Renamed
SurrogateFlushEventtoSurrogateMergeEventand updated the corresponding fields inLogParser. - Changed
truncation_rangetomin_termsinTruncationPolicyandFrequencyTruncationPolicy.
Fixed¶
- A bug in occupancy reporting for the hot loop.
- Stale logging events in all propagators.
- Pin
quimbto<1.15in thehybridextra to avoid breaking QASM parsing. - Surrogate propagator
GateEvent/SurrogateMergeEvent.gate_idxnow starts from 0, matching the numerical propagators and the documented convention.
Removed¶
- Removed references to
_rust_coreoutside the source code. - Removed
TermBudget.max_termsas it was only used in the previous propagation architecture. - Removed
MonomialBudgetas it was only used in the previous propagation architecture. - Removed
GateEvent.outbox_termsas it was always hardcoded to0and not meaningful.
[0.1.3] - 2026-08-12¶
Added¶
- Term-aware truncation and noise plugin compatibility through dependencies.
- A notebook demonstrating the use of
AbstractPropagatorwith a custom basis, namely the Weyl-Heisenberg group for qudit systems. - More example plugins in C, Julia, and Rust with the new plugin ABI
Fixed¶
- Parameter ordering issue in
TermBudgetandMonomialBudget
Changed¶
- Rust backend now uses a sparse list representation with a transpose view for efficient anticommutation checks.
- Progress bar is now routed through the engine rather than a direct call to
tqdm. - Documentation is now generated with mkdocs.
[0.1.2] - 2026-07-31¶
Added¶
- Arbitrary Qiskit gate support in
PauliCircuit.from_qiskit,MajoranaCircuit.from_qiskit,SurrogatePauliCircuit.from_qiskit, andSurrogateMajoranaCircuit.from_qiskit. Gates outside the native rotation basis (xx_plus_yy,p,rz,rx,ry,cp,x,swap) are now decomposed via Qiskit's transpiler into that basis instead of raising, via a new shared dispatch modulepropaq/circuits/_gates.py. Emits aUserWarningnaming the gate and the resulting rotation count, since decomposition cost varies a lot by gate. rx/ryadded to the native rotation basis, closing the basis under Qiskit's standard ZXZ Euler decomposition and letting the transpiler-based fallback reach essentially any 1- or 2-qubit gate, and multi-qubitUnitaryGates, without it.- Random-Qiskit-gate test coverage:
tests/circuits/test_arbitrary_gates.py,tests/propagator/test_loschmidt_random_gates.py, and random-arbitrary-gate coverage added totests/circuits/test_surrogate_from_qiskit.py. - Optional Cirq support, mirroring the Qiskit architecture:
from_cirqonPauliCircuit,MajoranaCircuit,SurrogatePauliCircuit, andSurrogateMajoranaCircuit, gated behind a newcirqextra (pip install propaq[cirq]). - Persistent, open-addressed hash table for merging
- Hybrid Schrodinger-Heisenberg simulation of expectation values via
hybrid_expectation_value. - Custom gate registry for user-defined gates, with internal validation against native decomposition.
Fixed¶
MajoranaTermSum._xx_plus_yy_terms's relative sign between its two Majorana monomials was computed with period 2 in the qubit gap (1 if d % 2 == 1 else -1), but the correct sign (from reordering the JW string into canonical bit order) has period 4. This gave us the wrong sign forXXPlusYYGate(theta, beta)on non-adjacent qubits withbeta != 0at gapsd % 4 in (2, 3).MajoranaTermSum.from_swaphad the analogous bug, but distributed differently across its three monomials.
Changed¶
- Add hydrogen chain benchmarks and remove old stale benchmarks.
.github/workflows/benchmarks.yml: the ASV (Python) benchmark job now runs unconditionally on every PR push, instead of only when the PR is labeledbenchmark. The Criterion (Rust) job now also runs automatically on every push tomain(post-merge tracking), in addition to its existing PR label.
[0.1.1] - 2026-06-29¶
Added¶
- Added timing information to logging output, which prints the average time taken for each gate application and the total time taken for the truncation.
- Updated README.md with
initial_stateparameter in theexpectation_valuemethod ofMajoranaPropagatorandPauliPropagatorclasses, replacing the deprecatedfock_state. qiskit_gate_idxfield in JSONL log output for bothgateandtruncationevents. Each event now reports the index of the originating Qiskit gate so log data can be mapped back to specific positions in the source circuit. Multiple propaq rotations that expand from a single parameterized Qiskit gate share the sameqiskit_gate_idx. Circuits not constructed viafrom_qiskitemitnullfor this field.- Test suite for logger/log-parser integration under
tests/log/, covering Qiskit-sourced circuits, truncation events, and directly constructed circuits. to_sparse_pauli_op()method onMajoranaTermSumandPauliTermSumto convert back to a QiskitSparsePauliOp.
[0.1.0] - 2026-06-27¶
Changed¶
- BMI2 PEXT optimization for
compress_to_qubitsinMajoranaMonomial, we can use_pext_u64via runtime CPU feature detection, extracting qubit bits from mode bitsets in ~2 instructions per 64-qubit word instead of a scalar bit-loop. Falls back to the scalar path on non-BMI2 hardware. - Replaced XOR-fold
partition_keywith FxHash inMajoranaMonomialandPauliString. The XOR-fold produced high collision rates for large workloads, permanently pinning terms to the same partition regardless of thread count. - Parallelized
initialize_frominAbstractPropagator: a sequential pass buckets each term by its owner partition, then each Rayon worker fills its ownFxHashMapin parallel. Each worker first touches its own map, which helps for NUMA locality.
[0.1.0] - 2026-06-26¶
Added¶
WeightCutoffExtrapolatorandCoefficientCutoffExtrapolatorclasses implementing Zero-Cutoff Extrapolation (ZCE) by sweeping weight and coefficient truncation cutoffs respectively, then fitting with a user-supplied function viascipy.optimize.curve_fit.ZCEResultdataclass holding the extrapolated zero-cutoff value, the sweep data, and the fit parameters and covariance matrix.noiseproperty andset_noise()method onAbstractPropagator,MajoranaPropagator, andPauliPropagatorto allow dynamic swapping of the noise model between runs.truncationproperty andset_truncation()method onAbstractPropagator,MajoranaPropagator, andPauliPropagatorto allow dynamic adjustment of truncation policies during propagation.- Test cases for
WeightCutoffExtrapolatorandCoefficientCutoffExtrapolatorclasses to validate their functionality and ensure correct extrapolation behavior. - Example notebook demonstrating the usage of ZCE on a hydrogen chain.
Changed¶
AbstractPropagatorabstractmethods for consistency with concrete implementations.- Register
PauliPropagatorandMajoranaPropagatorclasses as subclasses ofAbstractPropagatorto enforce the implementation of required methods. noiseandtruncationconstructor parameters inMajoranaPropagatorandPauliPropagatorstubs now use concrete types (UniformNoiseModel | GateNoiseModel | NoneandTruncationPolicy | None) instead ofobject | None.GateNoiseModel.apply_noisestub now acceptsMajoranaTermSum | PauliTermSuminstead ofobject.
Fixed¶
- Renamed
fock_stateparameter toinitial_statein theexpectation_valuemethod of bothPauliPropagatorandMajoranaPropagatorclasses for API consistency for use in Zero-Cutoff Extrapolation (ZCE) and Zero-Noise Extrapolation (ZNE) methods. - Fix
ZeroNoiseExtrapolatortyping and docstring to matchZeroCutoffExtrapolatorfor consistency.
[0.1.0] - 2026-06-22¶
Added¶
- Started tracking changes in the project.
- Added initial implementation of the
propaqlibrary, including core functionalities and basic features.