Skip to main content

qnmlab

Black-hole quasinormal modes with quantum algorithms.

qnmlab computes the ringing frequencies of black holes with variational quantum algorithms. You choose a black hole, a size in qubits, a representation, and a simulated or real quantum backend, and compare the result with trusted reference values.

The two ideas behind it:

  • Phase readout. On hyperboloidal slices the modes are eigenvalues of one linear operator, so a mode's frequency is two measured averages, Re ω = −⟨H₂⟩, Im ω = ⟨H₁⟩. That costs about 130 times fewer shots than detecting where a matrix becomes singular.
  • Seedless search. A thresholded scan of the complex frequency plane produces a shortlist of candidates, and the phase readout verifies each one. No starting guess is needed.

Classical methods compute these modes faster; qnmlab is for studying, benchmarking and running the quantum formulation, not for replacing them.

Install

pip install qnmlab                 # core: numpy, scipy, sympy
pip install "qnmlab[hardware]"     # + Qiskit, to export circuits for real devices

Latest development version:

pip install git+https://github.com/abir-tech/qnmlab.git

Quick start

import qnmlab as ql

bh = ql.KazakovSolodukhin(a=0.5)          # or ql.Schwarzschild(), ql.ReissnerNordstrom(Q), ql.Hayward(l)
ql.reference_modes(bh, ell=2, n_modes=2)  # classical ground truth

# read the fundamental on a simulated noisy 3-qubit device
r = ql.measure_mode(bh, qubits=3, noise=ql.NoiseModel.emerald_random(), shots=800)
print(r.omega, r.meta["error_vs_reference"])

# find modes with no starting guess (Schwarzschild, 4 qubits)
res = ql.find_modes(ql.Schwarzschild(), qubits=4)
print(res.modes)          # the fundamental and the first overtone

From the command line:

qnmlab modes   --model kazakov-solodukhin --parameter 0.5
qnmlab readout --model schwarzschild --qubits 3 --noise emerald-random --shots 800
qnmlab search  --model schwarzschild --qubits 4

What you can choose

choice options
black hole Schwarzschild(), KazakovSolodukhin(a) — validated against published frequencies; ReissnerNordstrom(Q), Hayward(l) — experimental (cross-checked against an independent method, not against published values)
size qubits; operator dimension 2**qubits
readout representation "hyperboloidal" (any model), "ultraspherical" (banded generalised pencil, Schwarzschild)
search representation "leaver" (tridiagonal, Schwarzschild), "frobenius" (any model)
search solver "exact" (fast) or "variational" (a variational solver at every grid point)
noise NoiseModel.ideal(), .emerald_random(), .emerald_coherent(), or your own NoiseModel(p2, eps, readout)

Real hardware

op = ql.readout_operator(ql.Schwarzschild(), qubits=3)
state = ql.prepare_state(op, lead=0.48 - 0.097j, layers=2)
job = ql.hardware.build_job(op, state)                 # 11 circuits
ok = ql.hardware.verify(job)                            # Qiskit export matches the simulation
circuits = [ql.hardware.to_qiskit(c, 3) for c in job["circuits"]]
# ... run them with your provider, collect raw counts by circuit name ...
result = ql.hardware.analyse_counts(job, raw_counts)    # measures bit order, mitigates readout

analyse_counts measures the provider's bit order from two calibration circuits and stops if a qubit is stuck — both happened on real devices while this package was developed.

The raw counts of the 2026 IQM Emerald run ship with the package:

ql.benchmarks.reanalyse_emerald_2026()   # (0.43919 - 0.10430i), exact 0.48186 - 0.09674i

Scope and honesty

  • The end-to-end search ran in simulation; on hardware only the readout was run, from a classically prepared state.
  • The search costs about 10^13 measurement shots at 4 qubits.
  • The hardware error (~0.04) is dominated by gate noise; more qubits help only once it falls.

Citing

If you use qnmlab, please cite the accompanying paper (see CITATION.cff): A. Chekroun, H. Al-Yoorby, M. A. Assal, Z. Lourghi, A. Boussahi, Phase Readout and Seedless Search for Black-Hole Quasinormal Modes on Quantum Processors (2026).

Development

pip install -e ".[dev]"
pytest -m "not slow"     # ~5 minutes
pytest                   # includes the ~40-minute end-to-end search

MIT licence.

Metadata

Release files for qnmlab 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 qnmlab 0.1.0
File Size Uploaded Provenance
qnmlab-0.1.0.tar.gz 82.4 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 164.4 kB

Release files / qnmlab-0.1.0.tar.gz

Download URL qnmlab-0.1.0.tar.gz
Size 82.4 kB
Tags Source
SHA-256 checksum
How to use checksums
ffe6149ce2e90cf9780e81b3ddca3d7c4026c4e17cd8ec5dd41115145f9202aa
BLAKE2b-256 checksum
How to use checksums
abe8da7f9f671af6d5966839b49f2adbb629acc60c36849db9444280b89ecd92
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.0

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

Download URL qnmlab-0.1.0-py3-none-any.whl
Size 81.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
12e1f2c237ffa075ed3cfdf60bc1ea99d56e65a8ed5cfc9149a4949f617f5f23
BLAKE2b-256 checksum
How to use checksums
6c0314b07a401e719da6131f307fc5bf2c430a1ed7cdacc44169542792f7f74d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.0

Security for qnmlab 0.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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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