No project description provided
Project description
Qubit Kirkwood-Dirac Simulator
A Python package for simulating quantum circuits with qubits using the Kirkwood-Dirac (KD) quasiprobability distribution. This simulator implements a hidden variable model that efficiently simulates stabilizer circuits and reveals when quantum computation requires genuine quantum resources.
Overview
This package implements a classical simulation framework for qubit quantum circuits based on the Kirkwood-Dirac quasiprobability representation. The KD distribution provides a phase-space-like representation of quantum states that becomes a true probability distribution for certain quantum states, enabling efficient classical simulation.
The simulator supports:
- Preparation of arbitrary single-qubit states
- Efficient sampling from KD distributions
- Clifford gates (Hadamard, Pauli X, Pauli Z, CNOT)
- Computational basis measurements
- Fast vectorized operations for statistical simulations
- Multiple visualization tools for measurement outcomes
- Detection of quantum advantage through KD nonpositivity
Installation
pip install kd_simulator
Requirements
- Python 3.8+
- NumPy
- Matplotlib
Quick Start
import numpy as np
from KD_Simulator import (
make_qubit_rhos,
compute_per_qubit_kd,
sample_from_per_qubit_kd,
Hadamard_vectorized,
CNOT_vectorized,
Zmeasurement_vectorized,
plot_top_k
)
# Initialize random number generator
rng = np.random.default_rng()
# Prepare initial states: two qubits in |0+⟩ state
state_labels = ["0", "+"]
rho_list = make_qubit_rhos(state_labels)
# Compute KD distributions
kd_matrices = compute_per_qubit_kd(rho_list)
# Sample hidden variables
num_samples = 10000
g_all, chi_all = sample_from_per_qubit_kd(kd_matrices, num_samples, rng)
# Apply gates to create Bell state
g_all, chi_all = Hadamard_vectorized(g_all, chi_all)
g_all, chi_all = CNOT_vectorized(g_all, chi_all, 0, 1, num_qubits=2)
# Measure both qubits
outcomes_0, g_all, chi_all = Zmeasurement_vectorized(g_all, chi_all, 0, rng)
outcomes_1, g_all, chi_all = Zmeasurement_vectorized(g_all, chi_all, 1, rng)
# Combine outcomes and count
output_all = np.column_stack([outcomes_0, outcomes_1])
counts = np.bincount([int(''.join(map(str, row)), 2) for row in output_all],
minlength=4)
# Visualize results
plot_top_k(counts, num_qubits=2, k=4)
Theoretical Background
Kirkwood-Dirac Quasiprobability Distribution
The Kirkwood-Dirac distribution is a quasiprobability representation of quantum states defined with respect to two incompatible observables. For qubits, we consider computational basis states {|g⟩} and Hadamard-basis states {|χ⟩}, where g, χ ∈ {0, 1}.
For a single-qubit density matrix ρ, the KD distribution is:
Q(g, χ) = [(ρH†) ∘ Hᵀ]_{g,χ}
where:
- H is the Hadamard matrix: H = (1/√2)[[1, 1], [1, -1]]
- ∘ denotes element-wise (Hadamard) product
- The result is a real-valued 2×2 matrix representing K(g, χ)
Key Properties
- Normalization: ΣK(g, χ) = 1 (marginals sum to 1)
- Quasiprobability: K(g, χ) can be negative for quantum states
- KD-positive states: When K(g, χ) ≥ 0 for all (g, χ), the state is "classical" and admits efficient simulation
- Resource for quantum advantage: KD nonpositivity (negative values) is a necessary resource for quantum computational advantage
Classical Simulation via Hidden Variables
When all KD values are non-negative, K(g, χ) can be interpreted as a classical joint probability distribution over the binary variables (g, χ). The simulation workflow:
- Initialization: Compute K(g, χ) for each qubit's initial state
- Sampling: Draw (g, χ) pairs according to K as a probability distribution
- Gate evolution: Update (g, χ) deterministically via linear transformations (mod 2)
- Measurement: Extract outcome from g with stochastic update to χ
This approach efficiently simulates circuits where KD distributions remain non-negative throughout, revealing when quantum resources are genuinely required.
Core Functions
State Preparation
make_qubit_rhos(state_labels)
Creates density matrices for common single-qubit states.
- Parameters:
state_labels: List of state labels, one per qubit"0": |0⟩ state"1": |1⟩ state"+": |+⟩ state (equal superposition)"-": |−⟩ state (X-basis)"r": |R⟩ state (right circular)"l": |L⟩ state (left circular)
- Returns: List of density matrices (2×2 complex arrays)
compute_per_qubit_kd(rho_list)
Computes the Kirkwood-Dirac distribution for each qubit independently.
- Parameters:
rho_list: List of single-qubit density matrices
- Returns: List of 2×2 KD matrices (real-valued)
- Raises:
ValueErrorif the state has negative KD values (non-simulatable)
This function verifies that:
- The KD matrix is real (checks imaginary components)
- All KD values are non-negative (required for classical simulation)
Hidden Variable Sampling
sample_from_per_qubit_kd(kd_matrices, num_samples, rng)
Samples hidden variables (g, χ) for all qubits across many runs.
- Parameters:
kd_matrices: List of KD matrices fromcompute_per_qubit_kd()num_samples: Number of sampling runsrng: NumPy random number generator (np.random.default_rng())
- Returns: Tuple (g_all, chi_all), each of shape (num_samples, num_qubits)
Each qubit's (g, χ) is sampled independently from its marginal KD distribution.
Quantum Gates
All gates operate on batched hidden variables and return updated copies. Gates transform (g, χ) via deterministic linear operations over ℤ₂.
Single-Qubit Gates:
Hadamard_vectorized(g_all, chi_all): Hadamard on all qubits (swaps g and χ)PauliX_vectorized(g_all, chi_all, qubit): Pauli X gate (bit flip on g)PauliZ_vectorized(g_all, chi_all, qubit): Pauli Z gate (bit flip on χ)
Two-Qubit Gates:
CNOT_vectorized(g_all, chi_all, control_qubit, target_qubit, num_qubits): Controlled-NOT gate
Parameters:
g_all, chi_all: Hidden variable arrays (num_samples, num_qubits)qubit: Target qubit indexcontrol_qubit, target_qubit: Control and target indices for CNOTnum_qubits: Total number of qubits in the circuit
Returns: Updated (g_all, chi_all) arrays
Measurement
Zmeasurement_vectorized(g_all, chi_all, qubit, rng)
Performs computational basis (Z-basis) measurement on a specified qubit.
- Parameters:
g_all, chi_all: Hidden variable arrays (num_samples, num_qubits)qubit: Index of qubit to measurerng: NumPy random number generator
- Returns: Tuple (outcomes, g_all, chi_all)
outcomes: Measurement results (num_samples,) - values are 0 or 1g_all: Unchanged g valueschi_all: Updated χ values (stochastically flipped with probability 0.5)
The measurement outcome is deterministically given by g[qubit], with a random post-measurement update to χ[qubit].
Visualization Functions
plot_top_k(counts, num_qubits, k=20)
Displays the k most probable measurement outcomes as a bar chart.
plot_hamming_weight(counts, num_qubits)
Shows the distribution of measurement outcomes grouped by Hamming weight (number of 1s).
plot_single_qubit_marginals(counts, num_qubits)
Visualizes the marginal probability distribution for each individual qubit as a heatmap.
plot_sample_heatmap(output_all)
Creates a heatmap showing sampled bitstrings across shots and qubits.
plot_qubit_correlation(output_all)
Displays the correlation matrix between all pairs of qubits.
Common Parameters:
counts: Array of length 2^num_qubits with outcome countsoutput_all: Array of shape (num_samples, num_qubits) with measurement outcomesnum_qubits: Number of qubits in the circuitk: Number of top outcomes to display
Performance Considerations
- Vectorized operations: All gate operations are fully vectorized over samples for maximum efficiency
- Memory scaling: O(num_samples × num_qubits) for hidden variable storage
- Time complexity: O(num_gates × num_samples × num_qubits) for circuit simulation
- Optimal sample sizes: 10,000-100,000 samples provide good statistical accuracy
- Qubit scaling: Efficient for 10-20 qubits with reasonable sample counts
Limitations
- KD-positive states only: Cannot simulate states with negative KD values (magic states, T-gate outputs)
- Clifford gates only: Supports H, X, Z, CNOT; does not support T gate or arbitrary rotations
- Computational basis measurements: Only Z-basis measurements are directly supported
- Product state initialization: Initial states must be tensor products of single-qubit states
- Positivity requirement: The simulator will raise an error if it encounters negative KD values
Mathematical Details
KD Distribution Formula
For a single-qubit density matrix ρ, the Kirkwood-Dirac distribution is:
K(g, χ) = ⟨g|ρ|χ⟩⟨χ|g⟩
In the computational basis {|0⟩, |1⟩} and Hadamard basis {|+⟩, |−⟩}, this becomes:
K = (ρH†) ∘ Hᵀ
where ∘ is element-wise multiplication. The result is a 2×2 real matrix satisfying ΣK(g,χ) = 1.
Gate Update Rules (mod 2 arithmetic)
Hadamard: (g, χ) → (χ, g)
Pauli X on qubit q: gq → gq ⊕ 1 (flip g bit)
Pauli Z on qubit q: χq → χq ⊕ 1 (flip χ bit)
CNOT from control c to target t:
- g' = g · Act where Act = I + |t⟩⟨c|
- χ' = χ · Bct where Bct = I + |c⟩⟨t|
All operations are linear transformations over ℤ₂ (binary field).
Measurement Protocol
Measuring qubit q in the computational basis:
- Outcome: mq = gq (deterministic)
- Post-measurement update: With probability 1/2, flip χq
This reflects the contextual nature of quantum measurements in the KD framework.
Quantum Advantage and KD Nonpositivity
This simulator implements results from recent research showing that KD nonpositivity is a necessary resource for quantum computational advantage:
- Stabilizer circuits preserve KD-positivity and can be efficiently simulated classically
- Magic states (e.g., T-gate outputs) introduce negative KD values
- Quantum speedup requires operations that produce negative KD values
When the simulator encounters negative KD values, it signals that the quantum circuit requires genuine quantum resources beyond classical hidden variable models.
Relation to Other Frameworks
- Wigner functions: The KD distribution is analogous to Wigner functions but defined over discrete phase space for qubits
- Stabilizer formalism: Stabilizer states are precisely the KD-positive states
Contributing
Contributions are welcome! Please open an issue to discuss changes or submit a Pull Request.
Citation
If you use this simulator in your research, please cite:
@software{qubit_kd_simulator,
title={Qubit Kirkwood-Dirac Simulator},
author={Rishi Goel},
year={2025},
url={https://github.com/rishigoel2003/KD_Simulator}
}
And please cite the foundational paper on KD distributions as a computational resource:
@article{thio2025kirkwood,
title={Kirkwood-Dirac Nonpositivity is a Necessary Resource for Quantum Computing},
author={Thio, Jonathan J and Yang, Songqinghao and De Bi{\`e}vre, Stephan and Barnes, Crispin HW and Arvidsson-Shukur, David RM},
journal={arXiv preprint arXiv:2506.08092},
year={2025}
}
Contact
For questions and support, please open an issue on GitHub or contact [rishigoel25@gmail.com].
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kd_simulator-0.2.1.tar.gz.
File metadata
- Download URL: kd_simulator-0.2.1.tar.gz
- Upload date:
- Size: 9.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64ce5c1b13432961b8b08b0db4f3c396d2181bc416f33d2e8b86132462b15345
|
|
| MD5 |
5d096013a732818596006df6712a619d
|
|
| BLAKE2b-256 |
0411ed9e13ebce30688010b01c6c07482aeb7be60ea0039417c7bf284f9ff453
|
File details
Details for the file kd_simulator-0.2.1-py3-none-any.whl.
File metadata
- Download URL: kd_simulator-0.2.1-py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0dbfa61f9ac5c8036737b0a7cc9928d092a7f36af9216ab59cab9b0e8c510ca8
|
|
| MD5 |
39460ad4627bccc9394009fb270560a1
|
|
| BLAKE2b-256 |
5ec4153ed4aa0531684f23c6fe9d4b40a5b9af7af6d287094ad66d9eb18ca5c8
|