Skip to main content

QuDenoise

A from-scratch, pure-Python Matrix Product State (MPS) quantum circuit simulator with Kraus-channel noise (quantum trajectories) and a quantum-autoencoder (QAE) denoiser. Runs on NumPy everywhere; optionally runs every tensor operation on a GPU through CuPy.

Install

pip install qudenoise            # NumPy/SciPy only (CPU)
pip install "qudenoise[viz]"     # + matplotlib for plotting examples

GPU (optional)

CuPy publishes one wheel per CUDA version, so QuDenoise does not pin a CuPy variant. Install the one matching your toolkit yourself, e.g.

pip install cupy-cuda12x         # CUDA 12.x
pip install cupy-cuda11x         # CUDA 11.x

(pip install "qudenoise[gpu]" pulls the generic cupy source package, which needs a local CUDA toolchain.) CuPy is imported lazily: without it QuDenoise imports and runs with no errors or warnings. With device="auto" (default) the GPU is used when available and this is logged once (QuDenoise: running on GPU (CuPy) / running on CPU (NumPy)); force a backend with Simulator(device="cupy") or device="numpy".

Quick start

from qudenoise import Circuit, Simulator

c = Circuit(20).h(0)
for i in range(19):
    c.cnot(i, i + 1)

sim = Simulator(bond_dim=8)              # chi cap; also truncation_threshold=...
state = sim.run(c)                       # -> MPS
print(state.bond_dimensions(), state.fidelity_estimate)
samples, report = sim.sample(c, shots=1000, seed=1)

Non-adjacent two-qubit gates are routed with SWAP chains automatically; every insertion is logged (logger qudenoise, INFO) and recorded in sim.last_report.routing_log.

Noise

c = Circuit(2).h(0).cnot(0, 1).depolarizing(0, 0.05).amplitude_damping(1, 0.1)
res = Simulator().run_observable(c, lambda m: observables.expectation(m, {0: gates.Z(), 1: gates.Z()}).real,
                                 n_trajectories=2000, seed=0)
print(res.mean, "+/-", res.sem)

Channels: depolarizing (1q/2q), amplitude_damping, phase_damping, bit_flip, phase_flip, or any KrausChannel. Trajectories are seeded per index (spawn_seeds), so results are identical for any worker count. CPU runs with 8+ trajectories use a process pool; GPU runs are sequential in-process.

Quantum autoencoder

from qudenoise import QAE
qae = QAE(n_qubits=4, n_latent_qubits=2, ansatz_depth=2, seed=1)
qae.fit(training_states, epochs=60, lr=0.1)      # MPS / Circuit / dense vectors
clean_estimate = qae.denoise(noisy_state)

Cost = 1 - mean probability of the trash qubits being |0..0>, computed directly from the MPS. Gradients use the parameter-shift rule through qudenoise.qae.compute_gradient; pass gradient_fn= to plug in a JAX ([autodiff]) backend without changing the API.

CLI

qudenoise run circuit.json --qubits 20 --bond-dim 32 --shots 1000 [--device auto|numpy|cupy] [-o out.json]
qudenoise train-qae config.yaml

Circuit JSON: {"n_qubits": N, "ops": [{"gate": "h", "qubits": [0]}, {"gate": "rz", "qubits": [1], "params": [0.3]}, {"noise": "depolarizing", "qubits": [0], "param": 0.01}]}. A .py file defining circuit or build_circuit(n) also works (executed as ordinary Python - only run files you trust). See examples/qae_config.yaml.

Conventions and limits

  • Big-endian qubit order (|q0 q1 ...>); rotations are exp(-i theta P / 2).
  • MPS.to_dense() refuses above 24 qubits unless forced. qudenoise.reference (dense/density-matrix simulators) exists to validate the MPS code in tests; it is not a supported product feature.
  • With truncation, state.truncation_error, state.fidelity_estimate (product of 1 - eps_k) and state.fidelity_lower_bound track accuracy loss.

Development

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

Tests run on NumPy and, when CuPy + a GPU are present, are repeated on CuPy (backend-parity check). See docs/design_notes.md.

MIT licensed.

Release files for qudenoise 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qudenoise 0.1.0
File Size Uploaded
qudenoise-0.1.0.tar.gz 56.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for qudenoise 0.1.0
File Interpreter ABI Platform
qudenoise-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 101.0 kB

Release files / qudenoise-0.1.0.tar.gz

Download URL qudenoise-0.1.0.tar.gz
Size 56.9 kB
Tags Source
SHA-256 checksum
How to use checksums
c00cfa5477372fce3597540f991ef43b82bc5c32a0fd4a5b2a556ff39d3d419f
BLAKE2b-256 checksum
How to use checksums
39a885e1780a83a00e74ab3161e471068a5dec8c9877a565fb6b94dc38a8d84d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Release files / qudenoise-0.1.0-py3-none-any.whl

Download URL qudenoise-0.1.0-py3-none-any.whl
Size 44.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1e9526a49a23161ed4df8091766bf41547211766d873bff003926933d0af5dbd
BLAKE2b-256 checksum
How to use checksums
8d098c8ee117c0adbbdf361236b51d92841400fc6b1ea7778289fabe2f2af216
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page