Skip to main content

Drop-in Lindblad dephasing simulator backed by the Finite Possibility Mechanics affine map

Project description

fpm-qsim

Drop-in Lindblad dephasing simulator backed by the Finite Possibility Mechanics affine map.

fpm-qsim is a small, dependency-light Python package that lets you simulate open-system quantum dephasing dynamics using the FPM affine coherence map. The map

c_{t+1} = kappa * c_t + nu

with kappa ∈ [0, 1] is the engine. Theorem 3 of the FPM paper identifies one particular choice — kappa = 1 - gamma*dt — with the Euler-discretized Lindblad dephasing equation. This package uses the exact continuous form

kappa = exp(-gamma * dt)

which is also a valid FPM affine-map coefficient and which makes the integrator machine-precise for pure dephasing: it reproduces the analytic continuous-dephasing solution

rho(t) = exp(-gamma*t) * (rho_0 - diag(rho_0)) + diag(rho_0)

to machine precision (about 5e-16 in the benchmark), matching Kraus and matrix-exponential references for pure dephasing.

The honest positioning is not "uniquely fastest." fpm-qsim is the reference implementation of the FPM affine-map primitives: it provides competitive pure-dephasing simulation, a NumPy-only pure-dephasing path, the FPM falsifiability ceiling, and the conservation-ledger primitives needed by downstream FPM research.

For speed, the important distinction is structural vs constant-factor: pure dephasing can be implemented in O(N^2) per step by any dephasing-aware method. fpm-qsim is competitive with that specialized baseline and much faster than a general matrix-exponential Liouvillian on the same pure-dephasing problem.


Installation

Install from PyPI:

pip install fpm-qsim

From source:

git clone https://github.com/alxspiker/fpm-qsim.git
cd fpm-qsim
pip install -e .

Requirements: Python ≥ 3.9, NumPy ≥ 1.22. SciPy is optional for tests and for unitary_step.


Quick start

import math
import numpy as np
import fpm_qsim as fpm

# Start in the |+><+| state (maximal coherence).
rho0 = fpm.pure_state([1, 1])

# Apply one dephasing step.  Off-diagonal contracts by exp(-gamma*dt):
rho1 = fpm.lindblad_step(rho0, gamma=0.1, dt=1.0)
assert math.isclose(abs(rho1[0, 1]), math.exp(-0.1) * abs(rho0[0, 1]))

# Roll out a full trajectory.
traj = fpm.simulate(rho0, gamma=0.05, dt=1.0, n_steps=200)
assert traj.shape == (201, 2, 2)

Drop-in replacement

If you have an existing Lindblad dephasing loop, swap one import:

# Before
# from your_qsim_library import dephasing_step
# rho = dephasing_step(rho, c_ops=[sqrt(gamma / 2) * sigma_z], dt=0.1)

# After
from fpm_qsim import lindblad_step
rho = lindblad_step(rho, gamma=gamma, dt=0.1)

Ontological distinction: method="euler" vs method="exact" (v0.1.4)

The FPM affine map c_{t+1} = kappa * c_t + nu_t constrains kappa ∈ [0, 1] but does not mandate a specific form. v0.1.4 exposes two forms with strict ontological boundaries between them:

method="euler" — the FPM-native lattice map

rho_next = fpm.lindblad_step(rho, gamma=0.05, dt=1.0, method="euler")

Uses kappa = 1 - gamma*dt. This is the literal Theorem 3 identification: the FPM affine map with this kappa is algebraically equivalent to the Euler-discretized Lindblad dephasing equation.

Under FPM's discrete action principle, this is the physically realizable lattice operation. Per state variable per step, the simulated route cost is exactly 1 multiplication + 1 addition — both finite-integer operations on the discrete lattice. Billable to the ConservationLedger:

ledger.bill_compute_cost(daemon, n_multiplies=1, n_adds=1, cost_per_op=1e-5)

This preserves closed-universe structural coherence: every operation performed inside the simulated universe is paid for by the daemon that performed it. Use this method when running FPM-aligned simulations where the closed-universe ledger must remain balanced.

Constraint: requires 0 ≤ gamma*dt ≤ 1 for the map to remain contractive. Use method="exact" for unbounded gamma*dt.

method="exact" — the legacy continuous-math oracle

rho_next = fpm.lindblad_step(rho, gamma=0.05, dt=1.0, method="exact")  # default

Uses kappa = exp(-gamma*dt). Machine-precise continuous-dephasing solution: reproduces the analytic result to ~5e-16, matching Kraus / matrix-exponential / QuTiP integrators.

Ontological warning. Under FPM, exp is a continuous-math idealization. The simulated system cannot natively evaluate exp(-gamma*dt); doing so requires a discrete computational construction (Taylor series, CORDIC, Padé approximant) whose finite-integer route cost must be paid by the simulated daemons. When method="exact" is used, the host evaluates np.exp and hands the result to the simulated system as a zero-cost oracle, deliberately breaking the FPM closed-universe ledger.

Use this method only for legacy-continuous-QM comparison, e.g. when you need to benchmark FPM against standard quantum mechanics. To preserve closed-universe accounting with this method, the caller must explicitly bill the simulated construction cost:

# After each method="exact" step, bill the simulated Taylor
# construction of exp(-gamma*dt) via a K-term series.
# cost_per_op is the energy fraction per simulated op; pick a value
# appropriate to your simulation's thermodynamic regime.
fpm.bill_exp_route_cost(ledger, daemon, taylor_order=8, cost_per_op=1e-5)

This bills (2K multiplies + K additions) per exp evaluation, keeping the ledger closed despite the oracle injection. The taylor_order parameter controls the simulated approximation depth (default 8, giving ~1e-15 accuracy for |gamma*dt| < 1).

Default

method="exact" is the default for backward compatibility and for users who want machine-precision results without thinking about FPM ontology. FPM-purist research should explicitly pass method="euler".


What's distinctive about fpm-qsim

Property fpm-qsim QuTiP matrix-exp Kraus
Dephasing accuracy ~5e-16 ~2e-7 in the benchmark ~5e-16 ~5e-16
Pure-dephasing speed Competitive with dephasing-specialized O(N^2) General solver overhead General or specialized Single-qubit baseline
Dependencies NumPy for pure dephasing; SciPy only for unitary_step SciPy + Cython + ... SciPy for general matrix-exp NumPy
Falsifiability ceiling gamma_max = 31.87 --- --- ---
Theorem-verified affine map Theorem 3 --- --- ---
Closed-universe ledger Yes --- --- ---
Combined unitary + dephasing Explicit unitary_step + user-chosen splitting Built in Built in Channel-specific

The only Lindblad integrator in the Python ecosystem with a built-in falsifiability ceiling: observations with gamma > 32.0 raise FalsificationError rather than silently producing unphysical results. This is the FPM finite-lag-ceiling theorem (paper Test 09) made operational.

Equally important: this package is where the FPM theorem is made operational. kappa_exact, kappa_from_gamma, bounded_gamma, ConservationLedger, and DaemonState are not generic convenience functions; they are the public primitives for building FPM-aligned simulators, auditors, and falsification tests.


Benchmarks

The benchmark corrected three earlier overclaims:

  • The large speedup against general matrix-exp is real, but structural: it comes from exploiting pure-dephasing structure, which any dephasing-aware implementation can also exploit.
  • With the gamma convention corrected, fpm-qsim, matrix-exp, and Kraus all match the analytic pure-dephasing solution at machine precision.
  • The old H parameter on lindblad_step was removed because it used a naive Euler unitary kick. Use unitary_step and compose the splitting explicitly.

Speed results for 1,000 pure-dephasing steps:

Qubits Dim fpm-qsim general matrix-exp dephasing-specialized matrix-exp scipy solve_ivp QuTiP Kraus
1 2 3.38 ms 1.88 ms 1.18 ms 13.28 ms 10.44 ms 5.47 ms
2 4 3.31 ms 1.98 ms 1.45 ms 13.76 ms --- ---
3 8 3.39 ms 15.03 ms 1.86 ms 28.58 ms --- ---
4 16 4.03 ms 136.08 ms 3.19 ms 147.54 ms --- ---
5 32 7.28 ms --- 6.19 ms --- --- ---
6 64 17.30 ms --- 18.34 ms --- --- ---

At 4 qubits, fpm-qsim is about 34x faster than the general matrix-exp baseline, but about 25% slower than a matrix-exp baseline that is specialized for pure dephasing. The fair claim is that fpm-qsim is competitive with the best dephasing-specialized approach while also carrying the FPM research API and falsifiability checks.

Accuracy results, measured as max absolute error vs the analytic solution after 1,000 steps:

Qubits Dim fpm-qsim general matrix-exp dephasing-specialized matrix-exp scipy solve_ivp QuTiP Kraus
1 2 4.6e-16 4.6e-16 4.6e-16 4.00e-12 2.04e-07 4.6e-16
2 4 3.5e-16 3.5e-16 3.5e-16 1.57e-12 --- ---
3 8 3.4e-16 3.4e-16 3.4e-16 1.33e-12 --- ---
4 16 1.9e-16 1.9e-16 1.9e-16 1.16e-12 --- ---
5 32 9.7e-17 --- 9.7e-17 --- --- ---
6 64 7.4e-17 --- 7.4e-17 --- --- ---

Benchmark configuration: gamma = 0.02, dt = 1.0, Haar-random pure initial state, wall time reported as the minimum of three repeats.


API reference

Core FPM primitives (fpm_qsim.core)

Symbol Description
GAMMA_MAX = 31.8738... Falsifiable Lorentz-factor ceiling derived from the finite-lag theorem.
FALSIFICATION_THRESHOLD = 32.0 Observations above this falsify FPM.
ENERGY_FLOOR_FRACTION = 0.03138... v5.0 zero-energy floor (Test 07).
ISOTROPIC_WEIGHT_LIMIT = 1/3 Spectral-gap isotropic limit weight (Test 04).
kappa_from_gamma(gamma, dt=1.0) Euler-form contraction coefficient 1 - gamma*dt (Theorem 3 form).
kappa_exact(gamma, dt=1.0) Exact continuous-form contraction coefficient exp(-gamma*dt). This is what lindblad_step uses.
gamma_from_kappa(kappa, dt=1.0) Inverse of kappa_from_gamma.
fpm_affine_step(c, kappa, nu=0.0) One tick of the affine map c_{t+1} = kappa*c_t + nu.
fpm_affine_trajectory(c0, kappa, nu=0.0, n_steps=1) Closed-form rollout of the affine map.
bounded_gamma(gamma_raw, gamma_max=GAMMA_MAX) Clip a rate to the ceiling; raise if it would falsify.
FalsificationError Raised when an observation would falsify FPM.

Lindblad-equivalent API (fpm_qsim.lindblad)

Symbol Description
lindblad_step(rho, gamma, dt=1.0, *, method="exact", bounded=False) v0.1.4: Advance a density matrix by one FPM-affine dephasing step. method="euler" is the FPM-native lattice map (Theorem 3, billable). method="exact" is the legacy continuous-math oracle (machine-precise, breaks closed-universe ledger unless explicitly billed).
unitary_step(rho, H, dt=1.0) Apply one exact Hamiltonian step, rho -> U rho U^dagger, using a matrix exponential.
simulate(rho0, gamma, dt=1.0, n_steps=1, *, method="exact", bounded=False, record=True) v0.1.4: Roll out a pure-dephasing trajectory. method is forwarded to lindblad_step.

State utilities (fpm_qsim.states)

Symbol Description
basis_state(index, dim) Computational basis column vector.
pure_state(amplitudes) Build `
maximally_mixed(dim) I_dim / dim.
partial_trace(rho, keep, dims) Partial trace over a tensor-product Hilbert space.
is_density_matrix(rho, tol=1e-9) Validate Hermiticity, trace, positivity.
trace_distance(rho, sigma) `0.5 *
fidelity(rho, sigma) Uhlmann fidelity.

Closed-universe conservation (fpm_qsim.conservation)

Symbol Description
DaemonState Per-daemon bookkeeping (energy, coherence, cumulative flows).
ConservationLedger Closed-universe ledger; tracks replenish == spend + landauer.
ConservationLedger.bill_compute_cost(daemon, n_multiplies, n_adds) v0.1.4. Bill a daemon for simulated discrete computational work. Use after method="euler" steps (1 mul + 1 add per state var) or any other simulated compute.
exp_route_cost(taylor_order=8) v0.1.4. Return (n_multiplies, n_adds) cost of constructing exp(-gamma*dt) via a K-term Taylor series under FPM's discrete action principle.
bill_exp_route_cost(ledger, daemon, taylor_order=8) v0.1.4. Convenience wrapper: bill the simulated Taylor construction of one exp evaluation. Use after each method="exact" step to keep the closed-universe ledger balanced despite the oracle.

The math, in one page

The FPM coherence variable c_t evolves under the affine map

c_{t+1} = kappa * c_t + nu

where kappa ∈ [0, 1] is the contraction coefficient and nu is a bounded innovation noise. The FPM framework constrains kappa to [0, 1] but does not mandate a specific form; different kappa choices correspond to different numerical integrators of the same physics:

kappa choice What it computes Accuracy
1 - gamma*dt Euler-discretized Lindblad dephasing O(dt) per step
exp(-gamma*dt) (this package) Exact continuous Lindblad dephasing machine precision

Theorem 3 (Lindblad Correspondence). The Euler form (kappa = 1 - gamma*dt) is algebraically identical to the Euler discretization of the Lindblad master equation for a dephasing channel with H = 0:

rho_{t+1} = (1 - gamma*dt) * rho_t + gamma*dt * diag(rho_t)

under the identification gamma_t = (1 - kappa_t) / dt. Verified numerically to RMSE 3.6 × 10⁻¹⁷ on off-diagonal density-matrix elements over 600 ticks and 10 random paths (paper Test 02; reproduced in tests/test_lindblad_correspondence.py::test_theorem3_lindblad_correspondence).

The exact form (kappa = exp(-gamma*dt)) is also a valid FPM affine-map coefficient (in [0, 1] for all gamma, dt >= 0) and is what the public lindblad_step uses. It reproduces the analytic continuous-dephasing solution to machine precision, matching Kraus and matrix-exp references. The Euler form remains available in fpm_qsim._reference.euler_lindblad_step for Theorem 3 research.

Hamiltonian evolution

lindblad_step is deliberately scoped to pure dephasing. Earlier versions accepted an H parameter and applied a naive Euler unitary kick before dephasing. That silently reintroduced splitting error for H != 0 and broke the machine-precision guarantee.

For combined unitary + dephasing dynamics, compose the exact Hamiltonian step explicitly. The recommended Strang splitting is:

rho = fpm.unitary_step(rho, H, dt / 2)
rho = fpm.lindblad_step(rho, gamma=gamma, dt=dt)
rho = fpm.unitary_step(rho, H, dt / 2)

This has O(dt^3) per-step splitting error. unitary_step requires SciPy for the matrix exponential; the pure-dephasing path remains NumPy-only.

The falsifiable ceiling

The finite-lag ceiling theorem (paper Test 09) caps the physically admissible gamma at

gamma_max = 31.8738...

The CERN muon (gamma = 29.3) sits below this ceiling. Any observation of gamma > 32.0 falsifies the FPM framework. The package refuses to silently clip such observations; pass bounded=True to lindblad_step and a FalsificationError will be raised — log the observation instead.


Reproducing the paper's tests

The tests/ directory reproduces four of the paper's numerical experiments and adds a machine-precision regression test:

Test file Paper test Reference
tests/test_lindblad_correspondence.py::test_theorem3_lindblad_correspondence Test 02 RMSE 3.6e-17
tests/test_lindblad_correspondence.py::test_public_lindblad_step_machine_precision new in v0.1.1 max err 1.1e-16
tests/test_dispersion_contraction.py Test 01 D* = 1.8e-4
tests/test_conservation.py Test 03 Drift < 5%
tests/test_bounded_gamma.py Test 07 + Test 09 gamma_max = 31.87

Run them with:

pip install -e ".[test]"
pytest -v

Scope and honest limitations

This package implements pure dephasing channels with H = 0, the regime where the FPM theorem provides an algebraic correspondence.

  • lindblad_step does not accept H. For H != 0, compose unitary_step and lindblad_step explicitly, preferably with Strang splitting. Accuracy then depends on the caller's chosen splitting strategy.
  • General Lindblad channels (amplitude damping, depolarizing, etc.) are not directly equivalent to the FPM affine map. Future versions may extend the correspondence.
  • The ConservationLedger is a faithful bookkeeping layer but does not, by itself, enforce the semantic-entropy conservation gate (paper Section 6.6). Callers must implement that gate in their application logic.

Changelog

0.1.4 (2026-06-17)

Ontological boundary between FPM-native and continuous-math maps.

  • Added method parameter to lindblad_step and simulate:
    • method="euler": FPM-native lattice map (kappa = 1 - gamma*dt). The literal Theorem 3 affine map. Per-step simulated route cost is 1 multiply + 1 add — billable to ConservationLedger.
    • method="exact" (default): kappa = exp(-gamma*dt). Machine- precise continuous-dephasing solution. Documented as a non-physical oracle break under FPM. Callers who need closed-universe accounting must explicitly bill the simulated construction cost via bill_exp_route_cost.
  • Added ConservationLedger.bill_compute_cost(daemon, n_multiplies, n_adds) to debit simulated discrete computational work.
  • Added exp_route_cost(taylor_order=8) and bill_exp_route_cost(ledger, daemon, taylor_order=8) to bill the simulated Taylor construction of exp(-gamma*dt) when using method="exact".
  • 57 tests, all passing.

0.1.3 (2026-06-17)

  • Reframed the README around the audit-corrected benchmark: competitive pure-dephasing performance, not unique speed dominance.
  • Added benchmark tables for speed and accuracy.
  • Documented the removal of H from lindblad_step and the explicit unitary_step composition path for H != 0.

0.1.2 (2026-06-17)

  • Clarified the PyPI installation command in the README.

0.1.1 (2026-06-17)

  • Breaking: lindblad_step now uses the exact continuous form kappa = exp(-gamma*dt) instead of the Euler form 1 - gamma*dt. The public API now matches Kraus / matrix-exp / QuTiP to machine precision (max abs error 1.1e-16 vs analytic). The Euler form is preserved in the private fpm_qsim._reference module for Theorem 3 verification.
  • Added kappa_exact(gamma, dt) to the public API.
  • Removed reference_lindblad_step from the public API (moved to fpm_qsim._reference.euler_lindblad_step).
  • Added machine-precision regression test.
  • Added test confirming the exact form handles gamma*dt > 1 without positivity violation (a regime the Euler form cannot reach).
  • Updated README with honest speed and accuracy claims.

0.1.0 (2026-06-17)

Initial release. Euler-form affine map, Lindblad-equivalent API, bounded gamma falsifiability, density-matrix utilities, closed- universe conservation ledger.


Citation

If you use fpm-qsim in published research, please cite:

@misc{spiker2026fpm,
  title  = {Finite Possibility Mechanics: A Unified Information-Theoretic Framework},
  author = {Spiker, Alx},
  year   = {2026},
  note   = {See Theorem 3 (Lindblad Correspondence) and the Finite-Lag-Ceiling Theorem.}
}

@misc{fpm-qsim,
  title  = {fpm-qsim: Drop-in Lindblad dephasing simulator backed by the FPM affine map},
  author = {Spiker, Alx},
  year   = {2026},
  url    = {https://github.com/alxspiker/fpm-qsim},
}

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fpm_qsim-0.1.4.tar.gz (42.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fpm_qsim-0.1.4-py3-none-any.whl (26.6 kB view details)

Uploaded Python 3

File details

Details for the file fpm_qsim-0.1.4.tar.gz.

File metadata

  • Download URL: fpm_qsim-0.1.4.tar.gz
  • Upload date:
  • Size: 42.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for fpm_qsim-0.1.4.tar.gz
Algorithm Hash digest
SHA256 1eed00da3ebc2cab24f3106f58f2b6e52086de8ecde53309cb9c97ffdfa31f65
MD5 a7a17d5ff0abed857a54a22c5d55244b
BLAKE2b-256 2f57ab3b97d1edec24cdd557cfa99a5d065b7e8b698d6dc4418c81c50af8b97f

See more details on using hashes here.

File details

Details for the file fpm_qsim-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: fpm_qsim-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 26.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for fpm_qsim-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 d63bae4fe1077c35baf485bc1ef17311e7630ffc7e5a458e8ab24112d05392a5
MD5 105707bdd3e718b7ea6854a87a9130b0
BLAKE2b-256 4b582545e0333b205e254979509d84b5b1cee9f9c23b71dce34a0bf0e407d439

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page