Modules

QuantumDebugger - Interactive Quantum Circuit Debugger and Simulator

A comprehensive Python library for quantum circuit debugging, profiling, and simulation with realistic noise models and error mitigation.

Features: - Step-through circuit debugging - State inspection and visualization - Realistic noise simulation (v0.3.0) - Zero-noise extrapolation (v0.4.0) - Qiskit integration - Hardware profile support

class quantum_debugger.AmplitudeDamping(gamma: float)[source]

Bases: NoiseModel

Amplitude damping: Energy loss (T1 decay)

|1> can decay to |0> with rate gamma. Models spontaneous emission and energy relaxation.

apply(state: QuantumState, qubits: list | None = None)[source]

Apply amplitude damping

class quantum_debugger.BlochSphere[source]

Bases: object

Bloch sphere visualization for single qubits

static plot(state: QuantumState, qubit: int = 0, figsize: tuple = (8, 8))[source]

Plot qubit state on Bloch sphere

Parameters:
  • state – Quantum state

  • qubit – Index of qubit to visualize (for multi-qubit systems)

  • figsize – Figure size

static plot_trajectory(states: list, qubit: int = 0, figsize: tuple = (8, 8))[source]

Plot trajectory of state evolution on Bloch sphere

Parameters:
  • states – List of QuantumState objects

  • qubit – Qubit index to visualize

  • figsize – Figure size

class quantum_debugger.Breakpoint(gate_index: int | None = None, condition: Callable[[QuantumState], bool] | None = None, description: str = '')[source]

Bases: object

Represents a breakpoint in circuit execution

should_break(current_gate: int, state: QuantumState) → bool[source]

Check if breakpoint should trigger

Parameters:
  • current_gate – Current gate index

  • state – Current quantum state

Returns:

True if breakpoint should trigger

class quantum_debugger.BreakpointManager[source]

Bases: object

Manages breakpoints for debugging

add(gate_index: int | None = None, condition: Callable[[QuantumState], bool] | None = None, description: str = '') → Breakpoint[source]

Add a breakpoint

Parameters:
  • gate_index – Gate index to break at

  • condition – Condition function

  • description – Breakpoint description

Returns:

Created breakpoint

check(gate_index: int, state: QuantumState) → Breakpoint | None[source]

Check if any breakpoint should trigger

Parameters:
  • gate_index – Current gate index

  • state – Current quantum state

Returns:

Triggered breakpoint or None

clear()[source]

Remove all breakpoints

disable_all()[source]

Disable all breakpoints

enable_all()[source]

Enable all breakpoints

list_breakpoints() → List[Breakpoint][source]

Get list of all breakpoints

remove(breakpoint: Breakpoint)[source]

Remove a breakpoint

class quantum_debugger.CircuitMetrics(circuit: QuantumCircuit)[source]

Bases: object

Container for circuit analysis metrics

estimate_error_rate(single_error: float = 0.001, cnot_error: float = 0.01) → float[source]

Estimate cumulative error rate

Parameters:
  • single_error – Error rate for single-qubit gates

  • cnot_error – Error rate for CNOT gates

Returns:

Estimated cumulative error rate

estimate_execution_time(gate_time: float = 1.0, cnot_time: float = 10.0) → float[source]

Estimate execution time on quantum hardware

Parameters:
  • gate_time – Time for single-qubit gate (μs)

  • cnot_time – Time for CNOT gate (μs)

Returns:

Estimated time in microseconds

get_summary() → Dict[source]

Get summary dictionary of all metrics

class quantum_debugger.CircuitProfiler(circuit: QuantumCircuit)[source]

Bases: object

Profiler for analyzing quantum circuit performance

analyze() → CircuitMetrics[source]

Analyze the circuit and return metrics

Returns:

CircuitMetrics object with analysis results

compare_with_ideal() → Dict[source]

Compare circuit with theoretical ideal

Returns:

Comparison metrics

get_optimization_suggestions() → List[str][source]

Get suggestions for circuit optimization

Returns:

List of optimization suggestions

print_report()[source]

Print comprehensive profiling report

class quantum_debugger.CompositeNoise(noise_models: List[NoiseModel])[source]

Bases: NoiseModel

Composite noise model that applies multiple noise sources sequentially

Allows realistic simulation by combining different noise types: - Thermal relaxation (T1/T2) - Depolarizing errors - Readout errors - etc.

Example

>>> thermal = ThermalRelaxation(t1=100e-6, t2=80e-6, gate_time=50e-9)
>>> depol = DepolarizingNoise(0.001)
>>> composite = CompositeNoise([thermal, depol])
apply(state, qubits: list | None = None)[source]

Apply all noise models sequentially

Parameters:
  • state – QuantumState to apply noise to

  • qubits – Optional list of qubits (None = all qubits)

class quantum_debugger.DepolarizingNoise(probability: float)[source]

Bases: NoiseModel

Depolarizing channel: random Pauli errors

With probability p, apply random Pauli (X, Y, or Z) error. Simulates random bit/phase flips.

apply(state: QuantumState, qubits: list | None = None)[source]

Apply depolarizing noise to state

get_kraus_operators()[source]

Get Kraus operators for stochastic sampling

These describe the same channel as apply(), which implements the Pauli-error convention this class documents:

rho -> (1 - p) rho + (p/3) (X rho X + Y rho Y + Z rho Z)

so K0 = sqrt(1 - p) I and K1..K3 = sqrt(p/3) {X, Y, Z}.

The previous sqrt(p/4) form implemented a different convention, rho -> (1 - p) rho + p I/2, which coincides with the above only at 4p/3. StochasticNoiseSampler consumes this method, so the mismatch made sampled noise 4/3 stronger than apply() produced for the same p.

Returns:

List of Kraus operators [K0, K1, K2, K3] for depolarizing channel

class quantum_debugger.GateLibrary[source]

Bases: object

Library of standard quantum gates

CNOT = array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],        [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],        [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]])
static CP(theta: float) → ndarray[source]

Controlled-Phase gate (two-qubit)

CZ = array([[ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],        [ 0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j],        [ 0.+0.j,  0.+0.j,  1.+0.j,  0.+0.j],        [ 0.+0.j,  0.+0.j,  0.+0.j, -1.+0.j]])
H = array([[ 0.70710678+0.j,  0.70710678+0.j],        [ 0.70710678+0.j, -0.70710678+0.j]])
static PHASE(theta: float) → ndarray[source]

Phase shift gate (P gate)

static RX(theta: float) → ndarray[source]

Rotation around X-axis

static RY(theta: float) → ndarray[source]

Rotation around Y-axis

static RZ(theta: float) → ndarray[source]

Rotation around Z-axis

S = array([[1.+0.j, 0.+0.j],        [0.+0.j, 0.+1.j]])
SWAP = array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],        [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j]])
T = array([[1.        +0.j        , 0.        +0.j        ],        [0.        +0.j        , 0.70710678+0.70710678j]])
TOFFOLI = array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]])
X = array([[0.+0.j, 1.+0.j],        [1.+0.j, 0.+0.j]])
Y = array([[ 0.+0.j, -0.-1.j],        [ 0.+1.j,  0.+0.j]])
Z = array([[ 1.+0.j,  0.+0.j],        [ 0.+0.j, -1.+0.j]])
class quantum_debugger.MPS(tensors, max_bond=None)[source]

Bases: object

Matrix product state on n qubits with maximum bond dimension max_bond.

add(other: MPS, normalize: bool = True) → MPS[source]

Sum of two MPS by the direct-sum-of-bonds construction: the result represents |self> + |other> (normalized by default). Bond dimensions add.

amplitude(bits) → complex[source]

The amplitude <bits|psi> for a computational-basis string (qubit i = bits[i]), by contracting the fixed-bit tensor slices – O(n·chi^2), no dense state.

apply_mpo(mpo, max_bond: int = None) → MPS[source]

Apply a matrix product operator mpo (list of rank-4 W tensors) to this MPS, returning H|psi> as a new MPS whose bond dimension is multiplied by the MPO bond dimension (optionally recompressed to max_bond).

apply_single(gate, qubit: int) → MPS[source]

Apply a single-qubit gate to qubit (exact, local contraction).

apply_two(gate, qubit: int) → MPS[source]

Apply a two-qubit gate (4x4) to the neighbouring pair (qubit, qubit+1), then re-split by SVD and truncate the bond to max_bond. The gate is indexed as acting on |q, q+1> with qubit the lower (little-endian) index.

apply_two_long_range(gate, qubit_a: int, qubit_b: int) → MPS[source]

Apply a two-qubit gate to any pair (qubit_a, qubit_b), not just neighbours: SWAP the qubits together with a ladder of nearest-neighbour SWAPs, apply the gate, then SWAP back. The gate is indexed on |qubit_a, qubit_b> with qubit_a the lower index (as for apply_two()).

bloch_vector(qubit: int) → ndarray[source]

Bloch vector (<X>, <Y>, <Z>) of one qubit (contraction, no dense state).

bond_dimensions() → list[source]

The bond dimension on each of the n-1 links.

bond_entropies() → list[source]

Entanglement entropy (bits) across each of the n-1 bonds, from the Schmidt spectrum obtained by canonicalizing the MPS (a right-to-left SVD sweep to right-canonical form, then a left-to-right SVD sweep reading off the singular values). Scales to large n – no dense state. The maximum over bonds is the state’s peak bipartite entanglement.

compress(max_bond: int) → MPS[source]

Recompress the MPS to bond dimension max_bond by an SVD roundtrip (canonicalize, truncate). Returns a new MPS; the truncation fidelity to the original is |<compressed|self>|^2.

concurrence(qubit_a: int, qubit_b: int) → float[source]

Wootters concurrence between two qubits (from their reduced density matrix) – the pairwise entanglement, 0 for a product pair and 1 for a Bell pair.

correlation(obs_a, qubit_a: int, obs_b, qubit_b: int) → float[source]

Two-point correlation <psi| O_a O_b |psi> for single-qubit operators on qubit_a and qubit_b (contraction, no dense state).

correlation_profile(obs_a, obs_b, ref: int = 0) → list[source]

<O_a(ref) O_b(j)> versus site j – a spatial correlation function.

energy(terms) → float[source]

Expectation <psi|H|psi> of a Hamiltonian given as (coefficient, pauli_string) terms (the format of pauli_decompose / the VQE solver), summed by contraction. Lets any Hamiltonian – molecular, Fermi-Hubbard, spin – be evaluated on a large MPS.

entanglement_entropy(bond: int) → float[source]

Entanglement entropy (bits) across bond (the cut between sites 0..bond and bond+1..n-1).

entanglement_spectrum(bond: int) → ndarray[source]

The Schmidt coefficients (singular values, descending) across bond – the full entanglement spectrum, of which entanglement_entropy() is a summary.

expectation(observable, qubit: int) → float[source]

Expectation <psi|O|psi> of a single-qubit observable on qubit, via O(n * chi^3) tensor contraction – works for hundreds of qubits without ever building the dense state. Normalized by <psi|psi>.

expectation_mpo(mpo) → float[source]

<psi|H|psi> for an MPO, delegating to quantum_debugger.mpo.mpo_expectation().

expectation_pauli(pauli_string: str) → float[source]

Expectation <psi|P|psi> of a full Pauli string P (pauli_string[q] in I/X/Y/Z acts on qubit q), by O(n * chi^3) contraction – so any multi-qubit observable is measurable on a large MPS with no dense state.

fidelity(other: MPS) → float[source]

State fidelity |<other|self>|^2 / (||self||^2 ||other||^2) to another MPS.

classmethod from_bitstring(bits, max_bond: int = None) → MPS[source]

Computational-basis-state MPS |bits> from a bit sequence (qubit i = bits[i], little-endian). All bond dimensions 1.

classmethod from_circuit(circuit, max_bond: int = None) → MPS[source]

Run a QuantumCircuit on the MPS engine, starting from |0...0>. Single-qubit gates are applied exactly; two-qubit gates use the long-range SWAP path (any connectivity), truncating the bond to max_bond. Three-or-more qubit gates must be decomposed first (e.g. via toffoli_gates / mcx_gates).

For low-entanglement circuits this runs at scales the dense simulator cannot.

classmethod from_product(single_qubit_states, max_bond: int = None) → MPS[source]

Product-state MPS from a list of single-qubit amplitude pairs [a, b] per qubit (each normalized). All bond dimensions are 1.

classmethod from_statevector(state_vector, max_bond: int = None, tol: float = 1e-12) → MPS[source]

Exact MPS for a dense state_vector via sequential SVD (truncated to max_bond if given). Qubit i becomes site i (little-endian).

magnetization_profile(observable) → list[source]

<O_i> on every qubit for a single-qubit observable (e.g. Z).

max_bond_dimension() → int[source]
most_probable(shots: int = 2000, seed: int = 0)[source]

The most probable computational-basis outcome, estimated from shots samples (returns the bitstring and its exact Born probability).

mutual_information(qubit_a: int, qubit_b: int) → float[source]

Quantum mutual information I(a:b) = S(a) + S(b) - S(ab) between two qubits (bits), from their reduced density matrices – total correlation across the pair.

norm() → float[source]

The state norm sqrt(<psi|psi>) via tensor contraction (no dense vector).

normalize() → MPS[source]

Rescale the MPS to unit norm in place (folding the scale into the first tensor). Returns self.

overlap(other: MPS) → complex[source]

Inner product <other|self> of two MPS on the same number of qubits, by sweeping the double-layer contraction in O(n * chi^3) – no dense state.

probability(bits) → float[source]

Born probability |<bits|psi>|^2 of a computational-basis outcome.

purity_profile() → list[source]

Single-qubit purity Tr(rho_i^2) on every site (1 = pure, 0.5 = maximally mixed) – a local measure of how entangled each qubit is with the rest.

classmethod random(n: int, bond: int = 4, seed: int = 0, max_bond: int = None) → MPS[source]

A random MPS on n qubits with bond dimension bond (bonds taper to 1 at the ends). Normalized. Useful for testing and benchmarking.

renyi_entropy(bond: int, alpha: float = 2.0) → float[source]

Renyi-alpha entanglement entropy across bond (bits). alpha -> 1 is the von Neumann entropy (entanglement_entropy()); alpha = 2 is the collision entropy -log2 sum lambda^4.

sample(shots: int, seed: int = 0) → dict[source]

Draw shots computational-basis measurement outcomes from the MPS by exact sequential conditional sampling – O(shots * n * chi^2), with no dense state. Returns a dict mapping bitstring (character i = qubit i) to its count; the distribution is the exact Born rule.

schmidt_gap(bond: int) → float[source]

Gap between the two largest squared Schmidt values across bond – an order parameter that closes at a quantum phase transition. 1 for a product cut.

single_qubit_rdm(qubit: int) → ndarray[source]

Reduced density matrix of one qubit – built from its Pauli expectations rho = (I + <X>X + <Y>Y + <Z>Z)/2 by contraction, so it scales to large systems with no dense state.

structure_factor(observable, momentum: float) → float[source]

Static structure factor S(k) = (1/n) sum_{i,j} e^{i k (i-j)} <O_i O_j> at wavevector momentum – the Fourier transform of the spatial correlations, peaking at the ordering wavevector.

to_statevector() → ndarray[source]

Contract the MPS back into a dense little-endian state vector.

total_magnetization(observable) → float[source]

Sum of <O_i> over all qubits for a single-qubit observable.

truncation_error(max_bond: int) → float[source]

Weight lost when the MPS is compressed to bond dimension max_bond: 1 - |<compressed|self>|^2. Zero when the state already fits (a GHZ at max_bond >= 2); grows as more of the entanglement spectrum is discarded.

two_qubit_rdm(qubit_a: int, qubit_b: int) → ndarray[source]

Reduced density matrix of two qubits, assembled from their 16 two-qubit Pauli expectations (1/4) sum_{P,Q} <P_a Q_b> P (x) Q – scalable, matching the dense partial trace. The pair is returned in sorted (little-endian) order.

two_site_expectation(operator, qubit_a: int, qubit_b: int) → float[source]

Expectation of a two-qubit operator (4x4, indexed on |a, b> little-endian) via the two-qubit reduced density matrix: Tr(O rho_ab) – for bond energies and general two-site observables.

variance(terms) → float[source]

Energy variance <H^2> - <H>^2 of a Pauli-sum Hamiltonian terms – zero iff the MPS is an exact eigenstate (a convergence check for DMRG/imaginary TEBD).

classmethod zero_state(n: int, max_bond: int = None) → MPS[source]

The |0...0> product state (all bond dimensions 1).

class quantum_debugger.PhaseDamping(gamma: float)[source]

Bases: NoiseModel

Phase damping: Phase coherence loss (T2 dephasing)

Random Z rotations causing phase errors. Preserves populations but destroys coherence.

apply(state: QuantumState, qubits: list | None = None)[source]

Apply phase damping

class quantum_debugger.QiskitAdapter[source]

Bases: object

Adapter for converting between Qiskit and QuantumDebugger circuits

GATE_MAP = {'ccx': 'toffoli', 'cp': 'cp', 'cx': 'cnot', 'cz': 'cz', 'h': 'h', 'p': 'phase', 'rx': 'rx', 'ry': 'ry', 'rz': 'rz', 's': 's', 'swap': 'swap', 't': 't', 'x': 'x', 'y': 'y', 'z': 'z'}
static check_qiskit_available()[source]

Check if Qiskit is installed

classmethod compare_circuits(qiskit_circuit: None, qd_circuit: QuantumCircuit) → dict[source]

Compare a Qiskit circuit with a QuantumDebugger circuit

Returns:

Dictionary with comparison results

classmethod from_qiskit(qiskit_circuit: None) → QuantumCircuit[source]

Convert a Qiskit QuantumCircuit to QuantumDebugger circuit

Parameters:

qiskit_circuit – Qiskit QuantumCircuit to convert

Returns:

QuantumDebugger QuantumCircuit

Example

>>> from qiskit import QuantumCircuit
>>> qc_qiskit = QuantumCircuit(2)
>>> qc_qiskit.h(0)
>>> qc_qiskit.cx(0, 1)
>>> qc_qd = QiskitAdapter.from_qiskit(qc_qiskit)
classmethod to_qiskit(qd_circuit: QuantumCircuit) → None[source]

Convert a QuantumDebugger circuit to Qiskit QuantumCircuit

Parameters:

qd_circuit – QuantumDebugger circuit to convert

Returns:

Qiskit QuantumCircuit

Example

>>> from quantum_debugger import QuantumCircuit
>>> qc_qd = QuantumCircuit(2)
>>> qc_qd.h(0)
>>> qc_qd.cnot(0, 1)
>>> qc_qiskit = QiskitAdapter.to_qiskit(qc_qd)
class quantum_debugger.QuantumCircuit(num_qubits: int, num_classical: int = 0, noise_model: Any | None = None, noise_simulation_method: str = 'density_matrix', backend: str = 'auto')[source]

Bases: object

Quantum circuit with gate operations

ccx(control1: int, control2: int, target: int)[source]

Alias for Toffoli

cnot(control: int, target: int)[source]

Apply CNOT (controlled-NOT) gate

count_gates(gate_name: str = None) → int[source]

Count gates of specific type

Parameters:

gate_name – Name of gate to count (None for all gates)

cp(theta: float, control: int, target: int)[source]

Apply controlled-phase gate

cx(control: int, target: int)[source]

Alias for CNOT

cz(control: int, target: int)[source]

Apply CZ (controlled-Z) gate

depth() → int[source]

Calculate circuit depth (number of gate layers)

draw(output: str = 'text') → str[source]

Draw the circuit

Parameters:

output – Output format (‘text’ for ASCII art)

Returns:

String representation of circuit

get_statevector(initial_state: QuantumState | None = None, use_gpu: bool = False, precision: str = 'double') → QuantumState[source]

Get final state vector without measurements.

Parameters:
  • initial_state – Optional initial state

  • use_gpu – Run the whole circuit on the GPU (CuPy). The state lives on the GPU for every gate and is transferred back to the CPU once at the end. Falls back to CPU if CuPy is unavailable.

  • precision – ‘double’ (complex128, default, exact) or ‘single’ (complex64 – much faster on consumer GPUs, at reduced precision).

Returns:

Final quantum state (always CPU/NumPy-backed)

h(qubit: int)[source]

Apply Hadamard gate

measure(qubit: int, classical_bit: int = None)[source]

Measure a qubit

Parameters:
  • qubit – Qubit index to measure

  • classical_bit – Classical bit to store result (defaults to same as qubit)

measure_all()[source]

Measure all qubits

phase(theta: float, qubit: int)[source]

Apply phase shift gate

run(shots: int = 1, initial_state: QuantumState | None = None, use_gpu: bool = False, precision: str = 'double') → dict[source]

Execute the circuit.

The statevector is computed once and all shots are sampled from the resulting distribution. This is equivalent, for independent projective Z-measurements, to collapsing the state per shot, but costs O(gates + shots) instead of the previous O(shots x gates) (which re-simulated the whole circuit for every shot).

Parameters:
  • shots – Number of measurement samples

  • initial_state – Optional initial state (defaults to |0...0>)

  • use_gpu – Simulate the circuit on the GPU (see get_statevector)

  • precision – ‘double’ (complex128) or ‘single’ (complex64) for the GPU path

Returns:

Dictionary with measurement results and statistics

rx(theta: float, qubit: int)[source]

Apply RX rotation gate

ry(theta: float, qubit: int)[source]

Apply RY rotation gate

rz(theta: float, qubit: int)[source]

Apply RZ rotation gate

s(qubit: int)[source]

Apply S (phase) gate

set_noise_model(noise_model: Any | None, noise_simulation_method: str = 'density_matrix')[source]

Set or update noise model for the circuit

Parameters:
  • noise_model – NoiseModel instance, HardwareProfile, or None to disable

  • noise_simulation_method – ‘density_matrix’, ‘stochastic’, or ‘approximate’

size() → int[source]

Total number of gates

swap(qubit1: int, qubit2: int)[source]

Apply SWAP gate

t(qubit: int)[source]

Apply T gate

toffoli(control1: int, control2: int, target: int)[source]

Apply Toffoli (CCNOT) gate

x(qubit: int)[source]

Apply Pauli-X (NOT) gate

y(qubit: int)[source]

Apply Pauli-Y gate

z(qubit: int)[source]

Apply Pauli-Z gate

class quantum_debugger.QuantumDebugger(circuit: QuantumCircuit, initial_state: QuantumState | None = None)[source]

Bases: object

Interactive debugger for quantum circuits

add_breakpoint_at_gate(gate_index: int)[source]

Add breakpoint at specific gate index

clear_breakpoints()[source]

Remove all breakpoints

compare_with_expected(expected_state: QuantumState) → Dict[source]

Compare current state with expected state

Parameters:

expected_state – Expected quantum state

Returns:

Comparison metrics

continue_execution()[source]

Continue execution until end (alias for run_to_end)

get_current_state()[source]

Get current quantum state (alias for get_state)

get_execution_trace() → List[Dict][source]

Get full execution trace

Returns:

List of execution states with information

get_state() → QuantumState[source]

Get current quantum state

inspect_state() → Dict[source]

Get detailed information about current state

Returns:

Dictionary with state information

print_status()[source]

Print current debugging status

reset()[source]

Reset debugger to initial state

run_to_end()[source]

Execute all remaining gates

run_until_breakpoint()[source]

Execute until a breakpoint is hit or circuit ends

set_breakpoint(gate: int | None = None, condition=None, description: str = '') → Breakpoint[source]

Set a breakpoint

Parameters:
  • gate – Gate index to break at

  • condition – Conditional function

  • description – Breakpoint description

Returns:

Created breakpoint

step(steps: int = 1) → bool[source]

Execute one or more gates

Parameters:

steps – Number of gates to execute

Returns:

True if stepped successfully, False if at end

step_back(steps: int = 1) → bool[source]

Step backwards in execution history

Parameters:

steps – Number of steps to go back

Returns:

True if stepped back successfully

visualize()[source]

Print visualization of current state

class quantum_debugger.QuantumState(num_qubits: int, state_vector: ndarray | None = None, backend='auto')[source]

Bases: object

Represents a quantum state vector

apply_gate(gate_matrix: ndarray, target_qubits: List[int])[source]

Apply a quantum gate to specific qubits.

Uses tensor contraction, applying the k-qubit gate directly to the relevant axes of the state tensor. This is O(2**n) per gate instead of the O(4**n) cost of materializing the full 2**n x 2**n operator, so it is dramatically faster and more memory efficient for multi-qubit circuits.

Parameters:
  • gate_matrix – Unitary matrix of the gate (2**k x 2**k for k qubits)

  • target_qubits – List of qubit indices to apply gate to. Gate qubit j acts on target_qubits[j] (matches the previous convention).

bloch_vector(qubit: int = 0) → Tuple[float, float, float][source]

Get Bloch sphere coordinates for a single qubit

Parameters:

qubit – Index of qubit (for multi-qubit systems, traces out other qubits)

Returns:

(x, y, z) coordinates on Bloch sphere

copy()[source]

Create a deep copy of this state

entropy() → float[source]

Calculate von Neumann entropy

fidelity(other: QuantumState) → float[source]

Calculate fidelity with another quantum state

Parameters:

other – Another quantum state

Returns:

Fidelity value between 0 and 1

get_measurement_probability(qubit: int, outcome: int) → float[source]

Get probability of measuring a specific outcome for a qubit

get_probabilities() → ndarray[source]

Get probability distribution over all basis states

is_entangled() → bool[source]

Check if state is entangled (simple check for 2-qubit systems)

For 2 qubits: state is entangled if it cannot be written as tensor product

measure(qubit: int) → int[source]

Measure a qubit and collapse the state

Parameters:

qubit – Index of qubit to measure

Returns:

Measurement result (0 or 1)

measure_all() → List[int][source]

Measure all qubits

class quantum_debugger.StateInspector[source]

Bases: object

Utilities for inspecting quantum states during debugging

static check_superposition(state: QuantumState, qubit: int, threshold: float = 0.1) → bool[source]

Check if a qubit is in superposition

Parameters:
  • state – Quantum state

  • qubit – Qubit index

  • threshold – Threshold for considering a state in superposition

Returns:

True if qubit is in superposition

static compare_states(state1: QuantumState, state2: QuantumState) → Dict[source]

Compare two quantum states

Parameters:
  • state1 – First quantum state

  • state2 – Second quantum state

Returns:

Dictionary with comparison metrics

static format_state_string(state: QuantumState, max_terms: int = 10) → str[source]

Format quantum state as readable string

Parameters:
  • state – Quantum state

  • max_terms – Maximum number of terms to show

Returns:

Formatted string representation

static get_amplitude_info(state: QuantumState) → List[Dict][source]

Get detailed amplitude information for all basis states

Parameters:

state – Quantum state

Returns:

List of dictionaries with amplitude information

static get_measurement_stats(state: QuantumState) → Dict[str, float][source]

Get measurement statistics for all computational basis states

Parameters:

state – Quantum state

Returns:

Dictionary mapping basis states to probabilities

static get_qubit_probabilities(state: QuantumState, qubit: int) → Tuple[float, float][source]

Get measurement probabilities for a specific qubit

Parameters:
  • state – Quantum state

  • qubit – Qubit index

Returns:

(probability of 0, probability of 1)

static get_state_summary(state: QuantumState) → Dict[source]

Get a comprehensive summary of a quantum state

Parameters:

state – Quantum state to inspect

Returns:

Dictionary with state information

static print_state_info(state: QuantumState)[source]

Print comprehensive state information to console

Parameters:

state – Quantum state to inspect

class quantum_debugger.StateVisualizer[source]

Bases: object

Visualize quantum states

static plot_density_matrix(state: QuantumState, figsize: tuple = (10, 8))[source]

Plot density matrix representation

Parameters:
  • state – Quantum state

  • figsize – Figure size

static plot_probabilities(state: QuantumState, figsize: tuple = (10, 6))[source]

Plot measurement probabilities

Parameters:
  • state – Quantum state

  • figsize – Figure size

static plot_qubit_probabilities(state: QuantumState, figsize: tuple = (10, 6))[source]

Plot per-qubit measurement probabilities

Parameters:
  • state – Quantum state

  • figsize – Figure size

static plot_state_comparison(state1: QuantumState, state2: QuantumState, labels: tuple = ('State 1', 'State 2'), figsize: tuple = (12, 6))[source]

Compare two quantum states

Parameters:
  • state1 – First quantum state

  • state2 – Second quantum state

  • labels – Labels for the states

  • figsize – Figure size

static plot_state_vector(state: QuantumState, show_phase: bool = True, figsize: tuple = (12, 5))[source]

Plot state vector amplitudes and phases

Parameters:
  • state – Quantum state to visualize

  • show_phase – Whether to show phase information

  • figsize – Figure size

class quantum_debugger.ThermalRelaxation(t1: float, t2: float, gate_time: float)[source]

Bases: NoiseModel

Thermal relaxation: Combined T1 and T2 effects

Models realistic decoherence with both amplitude and phase damping. Based on T1 (energy relaxation) and T2 (phase coherence) times.

apply(state: QuantumState, qubits: list | None = None)[source]

Apply thermal relaxation

quantum_debugger.adaptive_fold(circuit, scale_factor: float, gate_error_rates: Dict[str, float] | None = None)[source]

Adaptive folding: fold gates proportional to their error rates.

Gates with higher error rates are folded more aggressively.

Parameters:
  • circuit – QuantumCircuit to fold

  • scale_factor – Target noise scaling

  • gate_error_rates – Dict mapping gate names to error rates If None, uses default hardware error rates

Returns:

Adaptively folded circuit

Example

>>> error_rates = {'cnot': 0.01, 'h': 0.0003, 'rx': 0.0005}
>>> folded = adaptive_fold(circuit, 2.0, error_rates)
quantum_debugger.global_fold(circuit, scale_factor: float)[source]

Global circuit folding: C → C + C† + C

Amplifies noise by factor approximately equal to scale_factor.

Parameters:
  • circuit – QuantumCircuit to fold

  • scale_factor – Target noise scaling (>= 1.0) scale=1.0: original circuit scale=3.0: C + C† + C (2 folds) scale=5.0: C + (C† + C) * 2

Returns:

Folded circuit with amplified noise

Example

>>> circuit = QuantumCircuit(2)
>>> circuit.h(0).cnot(0, 1)
>>> folded = global_fold(circuit, scale_factor=3.0)
>>> # folded has 3x the gates and ~3x the noise
quantum_debugger.local_fold(circuit, scale_factor: float, gate_indices: List[int] | None = None)[source]

Local circuit folding: fold only specific gates.

Better for targeted error mitigation of high-error gates (e.g., CNOT).

Parameters:
  • circuit – QuantumCircuit to fold

  • scale_factor – Target noise scaling

  • gate_indices – Indices of gates to fold. If None, fold two-qubit gates

Returns:

Locally folded circuit

Example

>>> circuit = create_vqe_circuit()
>>> # Fold only CNOT gates (highest error rate)
>>> folded = local_fold(circuit, scale_factor=2.0)
quantum_debugger.zero_noise_extrapolation(circuit, scale_factors: List[float] | None = None, extrapolation_method: str = 'richardson', folding_method: str = 'global', shots: int = 1000, **kwargs) → Dict[source]

Zero-Noise Extrapolation: run circuit at multiple noise levels and extrapolate to zero.

Parameters:
  • circuit – QuantumCircuit to mitigate

  • scale_factors – Noise scaling factors (e.g., [1.0, 2.0, 3.0]) Default: [1.0, 1.5, 2.0, 2.5, 3.0]

  • extrapolation_method – ‘richardson’, ‘linear’, ‘exponential’, ‘adaptive’

  • folding_method – ‘global’, ‘local’, or ‘adaptive’

  • shots – Number of measurement shots per noise level

  • **kwargs – Additional arguments for folding/extrapolation

Returns:

  • mitigated_value: Extrapolated zero-noise expectation

  • unmitigated_value: Original noisy result

  • improvement_factor: Ratio of improvement

  • noise_levels: Scale factors used

  • expectation_values: Measured at each scale

  • method: Extrapolation method used

  • fidelity_unmitigated: Original fidelity (if available)

  • fidelity_mitigated: Estimated mitigated fidelity

Return type:

Dictionary with

Example

>>> from quantum_debugger import QuantumCircuit
>>> from quantum_debugger.noise import IBM_PERTH_2025
>>> from quantum_debugger.mitigation import zero_noise_extrapolation
>>>
>>> circuit = QuantumCircuit(2, noise_model=IBM_PERTH_2025.noise_model)
>>> circuit.h(0).cnot(0, 1)
>>>
>>> result = zero_noise_extrapolation(circuit, shots=1000)
>>> print(f"Mitigated fidelity: {result['fidelity_mitigated']:.4f}")
>>> print(f"Improvement: {result['improvement_factor']:.2f}x")

Submodules

Core quantum computing components

class quantum_debugger.core.GateLibrary[source]

Bases: object

Library of standard quantum gates

CNOT = array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],        [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],        [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]])
static CP(theta: float) → ndarray[source]

Controlled-Phase gate (two-qubit)

CZ = array([[ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],        [ 0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j],        [ 0.+0.j,  0.+0.j,  1.+0.j,  0.+0.j],        [ 0.+0.j,  0.+0.j,  0.+0.j, -1.+0.j]])
H = array([[ 0.70710678+0.j,  0.70710678+0.j],        [ 0.70710678+0.j, -0.70710678+0.j]])
static PHASE(theta: float) → ndarray[source]

Phase shift gate (P gate)

static RX(theta: float) → ndarray[source]

Rotation around X-axis

static RY(theta: float) → ndarray[source]

Rotation around Y-axis

static RZ(theta: float) → ndarray[source]

Rotation around Z-axis

S = array([[1.+0.j, 0.+0.j],        [0.+0.j, 0.+1.j]])
SWAP = array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],        [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j]])
T = array([[1.        +0.j        , 0.        +0.j        ],        [0.        +0.j        , 0.70710678+0.70710678j]])
TOFFOLI = array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],        [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]])
X = array([[0.+0.j, 1.+0.j],        [1.+0.j, 0.+0.j]])
Y = array([[ 0.+0.j, -0.-1.j],        [ 0.+1.j,  0.+0.j]])
Z = array([[ 1.+0.j,  0.+0.j],        [ 0.+0.j, -1.+0.j]])
class quantum_debugger.core.QuantumCircuit(num_qubits: int, num_classical: int = 0, noise_model: Any | None = None, noise_simulation_method: str = 'density_matrix', backend: str = 'auto')[source]

Bases: object

Quantum circuit with gate operations

ccx(control1: int, control2: int, target: int)[source]

Alias for Toffoli

cnot(control: int, target: int)[source]

Apply CNOT (controlled-NOT) gate

count_gates(gate_name: str = None) → int[source]

Count gates of specific type

Parameters:

gate_name – Name of gate to count (None for all gates)

cp(theta: float, control: int, target: int)[source]

Apply controlled-phase gate

cx(control: int, target: int)[source]

Alias for CNOT

cz(control: int, target: int)[source]

Apply CZ (controlled-Z) gate

depth() → int[source]

Calculate circuit depth (number of gate layers)

draw(output: str = 'text') → str[source]

Draw the circuit

Parameters:

output – Output format (‘text’ for ASCII art)

Returns:

String representation of circuit

get_statevector(initial_state: QuantumState | None = None, use_gpu: bool = False, precision: str = 'double') → QuantumState[source]

Get final state vector without measurements.

Parameters:
  • initial_state – Optional initial state

  • use_gpu – Run the whole circuit on the GPU (CuPy). The state lives on the GPU for every gate and is transferred back to the CPU once at the end. Falls back to CPU if CuPy is unavailable.

  • precision – ‘double’ (complex128, default, exact) or ‘single’ (complex64 – much faster on consumer GPUs, at reduced precision).

Returns:

Final quantum state (always CPU/NumPy-backed)

h(qubit: int)[source]

Apply Hadamard gate

measure(qubit: int, classical_bit: int = None)[source]

Measure a qubit

Parameters:
  • qubit – Qubit index to measure

  • classical_bit – Classical bit to store result (defaults to same as qubit)

measure_all()[source]

Measure all qubits

phase(theta: float, qubit: int)[source]

Apply phase shift gate

run(shots: int = 1, initial_state: QuantumState | None = None, use_gpu: bool = False, precision: str = 'double') → dict[source]

Execute the circuit.

The statevector is computed once and all shots are sampled from the resulting distribution. This is equivalent, for independent projective Z-measurements, to collapsing the state per shot, but costs O(gates + shots) instead of the previous O(shots x gates) (which re-simulated the whole circuit for every shot).

Parameters:
  • shots – Number of measurement samples

  • initial_state – Optional initial state (defaults to |0...0>)

  • use_gpu – Simulate the circuit on the GPU (see get_statevector)

  • precision – ‘double’ (complex128) or ‘single’ (complex64) for the GPU path

Returns:

Dictionary with measurement results and statistics

rx(theta: float, qubit: int)[source]

Apply RX rotation gate

ry(theta: float, qubit: int)[source]

Apply RY rotation gate

rz(theta: float, qubit: int)[source]

Apply RZ rotation gate

s(qubit: int)[source]

Apply S (phase) gate

set_noise_model(noise_model: Any | None, noise_simulation_method: str = 'density_matrix')[source]

Set or update noise model for the circuit

Parameters:
  • noise_model – NoiseModel instance, HardwareProfile, or None to disable

  • noise_simulation_method – ‘density_matrix’, ‘stochastic’, or ‘approximate’

size() → int[source]

Total number of gates

swap(qubit1: int, qubit2: int)[source]

Apply SWAP gate

t(qubit: int)[source]

Apply T gate

toffoli(control1: int, control2: int, target: int)[source]

Apply Toffoli (CCNOT) gate

x(qubit: int)[source]

Apply Pauli-X (NOT) gate

y(qubit: int)[source]

Apply Pauli-Y gate

z(qubit: int)[source]

Apply Pauli-Z gate

class quantum_debugger.core.QuantumState(num_qubits: int, state_vector: ndarray | None = None, backend='auto')[source]

Bases: object

Represents a quantum state vector

apply_gate(gate_matrix: ndarray, target_qubits: List[int])[source]

Apply a quantum gate to specific qubits.

Uses tensor contraction, applying the k-qubit gate directly to the relevant axes of the state tensor. This is O(2**n) per gate instead of the O(4**n) cost of materializing the full 2**n x 2**n operator, so it is dramatically faster and more memory efficient for multi-qubit circuits.

Parameters:
  • gate_matrix – Unitary matrix of the gate (2**k x 2**k for k qubits)

  • target_qubits – List of qubit indices to apply gate to. Gate qubit j acts on target_qubits[j] (matches the previous convention).

bloch_vector(qubit: int = 0) → Tuple[float, float, float][source]

Get Bloch sphere coordinates for a single qubit

Parameters:

qubit – Index of qubit (for multi-qubit systems, traces out other qubits)

Returns:

(x, y, z) coordinates on Bloch sphere

copy()[source]

Create a deep copy of this state

entropy() → float[source]

Calculate von Neumann entropy

fidelity(other: QuantumState) → float[source]

Calculate fidelity with another quantum state

Parameters:

other – Another quantum state

Returns:

Fidelity value between 0 and 1

get_measurement_probability(qubit: int, outcome: int) → float[source]

Get probability of measuring a specific outcome for a qubit

get_probabilities() → ndarray[source]

Get probability distribution over all basis states

is_entangled() → bool[source]

Check if state is entangled (simple check for 2-qubit systems)

For 2 qubits: state is entangled if it cannot be written as tensor product

measure(qubit: int) → int[source]

Measure a qubit and collapse the state

Parameters:

qubit – Index of qubit to measure

Returns:

Measurement result (0 or 1)

measure_all() → List[int][source]

Measure all qubits

Debugger module for step-through quantum circuit execution

class quantum_debugger.debugger.BreakpointManager[source]

Bases: object

Manages breakpoints for debugging

add(gate_index: int | None = None, condition: Callable[[QuantumState], bool] | None = None, description: str = '') → Breakpoint[source]

Add a breakpoint

Parameters:
  • gate_index – Gate index to break at

  • condition – Condition function

  • description – Breakpoint description

Returns:

Created breakpoint

check(gate_index: int, state: QuantumState) → Breakpoint | None[source]

Check if any breakpoint should trigger

Parameters:
  • gate_index – Current gate index

  • state – Current quantum state

Returns:

Triggered breakpoint or None

clear()[source]

Remove all breakpoints

disable_all()[source]

Disable all breakpoints

enable_all()[source]

Enable all breakpoints

list_breakpoints() → List[Breakpoint][source]

Get list of all breakpoints

remove(breakpoint: Breakpoint)[source]

Remove a breakpoint

class quantum_debugger.debugger.QuantumDebugger(circuit: QuantumCircuit, initial_state: QuantumState | None = None)[source]

Bases: object

Interactive debugger for quantum circuits

add_breakpoint_at_gate(gate_index: int)[source]

Add breakpoint at specific gate index

clear_breakpoints()[source]

Remove all breakpoints

compare_with_expected(expected_state: QuantumState) → Dict[source]

Compare current state with expected state

Parameters:

expected_state – Expected quantum state

Returns:

Comparison metrics

continue_execution()[source]

Continue execution until end (alias for run_to_end)

get_current_state()[source]

Get current quantum state (alias for get_state)

get_execution_trace() → List[Dict][source]

Get full execution trace

Returns:

List of execution states with information

get_state() → QuantumState[source]

Get current quantum state

inspect_state() → Dict[source]

Get detailed information about current state

Returns:

Dictionary with state information

print_status()[source]

Print current debugging status

reset()[source]

Reset debugger to initial state

run_to_end()[source]

Execute all remaining gates

run_until_breakpoint()[source]

Execute until a breakpoint is hit or circuit ends

set_breakpoint(gate: int | None = None, condition=None, description: str = '') → Breakpoint[source]

Set a breakpoint

Parameters:
  • gate – Gate index to break at

  • condition – Conditional function

  • description – Breakpoint description

Returns:

Created breakpoint

step(steps: int = 1) → bool[source]

Execute one or more gates

Parameters:

steps – Number of gates to execute

Returns:

True if stepped successfully, False if at end

step_back(steps: int = 1) → bool[source]

Step backwards in execution history

Parameters:

steps – Number of steps to go back

Returns:

True if stepped back successfully

visualize()[source]

Print visualization of current state

class quantum_debugger.debugger.StateInspector[source]

Bases: object

Utilities for inspecting quantum states during debugging

static check_superposition(state: QuantumState, qubit: int, threshold: float = 0.1) → bool[source]

Check if a qubit is in superposition

Parameters:
  • state – Quantum state

  • qubit – Qubit index

  • threshold – Threshold for considering a state in superposition

Returns:

True if qubit is in superposition

static compare_states(state1: QuantumState, state2: QuantumState) → Dict[source]

Compare two quantum states

Parameters:
  • state1 – First quantum state

  • state2 – Second quantum state

Returns:

Dictionary with comparison metrics

static format_state_string(state: QuantumState, max_terms: int = 10) → str[source]

Format quantum state as readable string

Parameters:
  • state – Quantum state

  • max_terms – Maximum number of terms to show

Returns:

Formatted string representation

static get_amplitude_info(state: QuantumState) → List[Dict][source]

Get detailed amplitude information for all basis states

Parameters:

state – Quantum state

Returns:

List of dictionaries with amplitude information

static get_measurement_stats(state: QuantumState) → Dict[str, float][source]

Get measurement statistics for all computational basis states

Parameters:

state – Quantum state

Returns:

Dictionary mapping basis states to probabilities

static get_qubit_probabilities(state: QuantumState, qubit: int) → Tuple[float, float][source]

Get measurement probabilities for a specific qubit

Parameters:
  • state – Quantum state

  • qubit – Qubit index

Returns:

(probability of 0, probability of 1)

static get_state_summary(state: QuantumState) → Dict[source]

Get a comprehensive summary of a quantum state

Parameters:

state – Quantum state to inspect

Returns:

Dictionary with state information

static print_state_info(state: QuantumState)[source]

Print comprehensive state information to console

Parameters:

state – Quantum state to inspect

Profiler module for quantum circuit analysis

class quantum_debugger.profiler.CircuitMetrics(circuit: QuantumCircuit)[source]

Bases: object

Container for circuit analysis metrics

estimate_error_rate(single_error: float = 0.001, cnot_error: float = 0.01) → float[source]

Estimate cumulative error rate

Parameters:
  • single_error – Error rate for single-qubit gates

  • cnot_error – Error rate for CNOT gates

Returns:

Estimated cumulative error rate

estimate_execution_time(gate_time: float = 1.0, cnot_time: float = 10.0) → float[source]

Estimate execution time on quantum hardware

Parameters:
  • gate_time – Time for single-qubit gate (μs)

  • cnot_time – Time for CNOT gate (μs)

Returns:

Estimated time in microseconds

get_summary() → Dict[source]

Get summary dictionary of all metrics

class quantum_debugger.profiler.CircuitProfiler(circuit: QuantumCircuit)[source]

Bases: object

Profiler for analyzing quantum circuit performance

analyze() → CircuitMetrics[source]

Analyze the circuit and return metrics

Returns:

CircuitMetrics object with analysis results

compare_with_ideal() → Dict[source]

Compare circuit with theoretical ideal

Returns:

Comparison metrics

get_optimization_suggestions() → List[str][source]

Get suggestions for circuit optimization

Returns:

List of optimization suggestions

print_report()[source]

Print comprehensive profiling report

Visualization module for quantum states and circuits

class quantum_debugger.visualization.BlochSphere[source]

Bases: object

Bloch sphere visualization for single qubits

static plot(state: QuantumState, qubit: int = 0, figsize: tuple = (8, 8))[source]

Plot qubit state on Bloch sphere

Parameters:
  • state – Quantum state

  • qubit – Index of qubit to visualize (for multi-qubit systems)

  • figsize – Figure size

static plot_trajectory(states: list, qubit: int = 0, figsize: tuple = (8, 8))[source]

Plot trajectory of state evolution on Bloch sphere

Parameters:
  • states – List of QuantumState objects

  • qubit – Qubit index to visualize

  • figsize – Figure size

class quantum_debugger.visualization.StateVisualizer[source]

Bases: object

Visualize quantum states

static plot_density_matrix(state: QuantumState, figsize: tuple = (10, 8))[source]

Plot density matrix representation

Parameters:
  • state – Quantum state

  • figsize – Figure size

static plot_probabilities(state: QuantumState, figsize: tuple = (10, 6))[source]

Plot measurement probabilities

Parameters:
  • state – Quantum state

  • figsize – Figure size

static plot_qubit_probabilities(state: QuantumState, figsize: tuple = (10, 6))[source]

Plot per-qubit measurement probabilities

Parameters:
  • state – Quantum state

  • figsize – Figure size

static plot_state_comparison(state1: QuantumState, state2: QuantumState, labels: tuple = ('State 1', 'State 2'), figsize: tuple = (12, 6))[source]

Compare two quantum states

Parameters:
  • state1 – First quantum state

  • state2 – Second quantum state

  • labels – Labels for the states

  • figsize – Figure size

static plot_state_vector(state: QuantumState, show_phase: bool = True, figsize: tuple = (12, 5))[source]

Plot state vector amplitudes and phases

Parameters:
  • state – Quantum state to visualize

  • show_phase – Whether to show phase information

  • figsize – Figure size

Framework Integrations

Universal compatibility layer for quantum frameworks: - Qiskit (IBM) - PennyLane (Xanadu) - Cirq (Google)

All integrations are optional - quantum-debugger works standalone.

class quantum_debugger.integrations.CirqAdapter[source]

Bases: object

Adapter for converting between Cirq and QuantumDebugger circuits

GATE_MAP = {'CCX': 'toffoli', 'CNOT': 'cnot', 'CX': 'cnot', 'CZ': 'cz', 'H': 'h', 'Rx': 'rx', 'Ry': 'ry', 'Rz': 'rz', 'S': 's', 'SWAP': 'swap', 'T': 't', 'TOFFOLI': 'toffoli', 'X': 'x', 'Y': 'y', 'Z': 'z'}
static check_cirq_available()[source]

Check if Cirq is installed

classmethod compare_circuits(cirq_circuit: cirq.Circuit, qd_circuit: QuantumCircuit) → dict[source]

Compare a Cirq circuit with a QuantumDebugger circuit

Returns:

Dictionary with comparison results

classmethod from_cirq(cirq_circuit: cirq.Circuit) → QuantumCircuit[source]

Convert a Cirq Circuit to QuantumDebugger circuit

Parameters:

cirq_circuit – Cirq Circuit to convert

Returns:

QuantumDebugger QuantumCircuit

Example

>>> import cirq
>>> q0, q1 = cirq.LineQubit.range(2)
>>> cirq_circuit = cirq.Circuit()
>>> cirq_circuit.append([cirq.H(q0), cirq.CNOT(q0, q1)])
>>> qd_circuit = CirqAdapter.from_cirq(cirq_circuit)
classmethod simulate_cirq(qd_circuit: QuantumCircuit) → dict[source]

Simulate a QuantumDebugger circuit using Cirq’s simulator

Parameters:

qd_circuit – QuantumDebugger circuit to simulate

Returns:

Dictionary with simulation results

classmethod to_cirq(qd_circuit: QuantumCircuit, qubits: List[cirq.Qubit] | None = None) → cirq.Circuit[source]

Convert a QuantumDebugger circuit to Cirq Circuit

Parameters:
  • qd_circuit – QuantumDebugger circuit to convert

  • qubits – Optional list of Cirq qubits to use. If None, LineQubits are created.

Returns:

Cirq Circuit

Example

>>> from quantum_debugger import QuantumCircuit
>>> qd_circuit = QuantumCircuit(2)
>>> qd_circuit.h(0)
>>> qd_circuit.cnot(0, 1)
>>> cirq_circuit = CirqAdapter.to_cirq(qd_circuit)
class quantum_debugger.integrations.QiskitAdapter[source]

Bases: object

Adapter for converting between Qiskit and QuantumDebugger circuits

GATE_MAP = {'ccx': 'toffoli', 'cp': 'cp', 'cx': 'cnot', 'cz': 'cz', 'h': 'h', 'p': 'phase', 'rx': 'rx', 'ry': 'ry', 'rz': 'rz', 's': 's', 'swap': 'swap', 't': 't', 'x': 'x', 'y': 'y', 'z': 'z'}
static check_qiskit_available()[source]

Check if Qiskit is installed

classmethod compare_circuits(qiskit_circuit: None, qd_circuit: QuantumCircuit) → dict[source]

Compare a Qiskit circuit with a QuantumDebugger circuit

Returns:

Dictionary with comparison results

classmethod from_qiskit(qiskit_circuit: None) → QuantumCircuit[source]

Convert a Qiskit QuantumCircuit to QuantumDebugger circuit

Parameters:

qiskit_circuit – Qiskit QuantumCircuit to convert

Returns:

QuantumDebugger QuantumCircuit

Example

>>> from qiskit import QuantumCircuit
>>> qc_qiskit = QuantumCircuit(2)
>>> qc_qiskit.h(0)
>>> qc_qiskit.cx(0, 1)
>>> qc_qd = QiskitAdapter.from_qiskit(qc_qiskit)
classmethod to_qiskit(qd_circuit: QuantumCircuit) → None[source]

Convert a QuantumDebugger circuit to Qiskit QuantumCircuit

Parameters:

qd_circuit – QuantumDebugger circuit to convert

Returns:

Qiskit QuantumCircuit

Example

>>> from quantum_debugger import QuantumCircuit
>>> qc_qd = QuantumCircuit(2)
>>> qc_qd.h(0)
>>> qc_qd.cnot(0, 1)
>>> qc_qiskit = QiskitAdapter.to_qiskit(qc_qd)
quantum_debugger.integrations.from_cirq(cirq_circuit) → List[Tuple][source]

Convert Cirq circuit to quantum-debugger format.

Parameters:

cirq_circuit – Cirq Circuit

Returns:

List of gate tuples

Examples

>>> import cirq
>>> qubits = cirq.LineQubit.range(2)
>>> circuit = cirq.Circuit()
>>> circuit.append(cirq.H(qubits[0]))
>>> circuit.append(cirq.CNOT(qubits[0], qubits[1]))
>>> gates = from_cirq(circuit)
quantum_debugger.integrations.from_pennylane(pennylane_tape) → List[Tuple][source]

Convert PennyLane tape/circuit to quantum-debugger format.

Parameters:

pennylane_tape – PennyLane QuantumTape or operations list

Returns:

List of gate tuples

Examples

>>> import pennylane as qml
>>> dev = qml.device('default.qubit', wires=2)
>>> @qml.qnode(dev)
>>> def circuit():
...     qml.Hadamard(wires=0)
...     qml.CNOT(wires=[0, 1])
...     return qml.expval(qml.PauliZ(0))
>>> gates = from_pennylane(circuit.tape)
quantum_debugger.integrations.from_qiskit(qiskit_circuit) → List[Tuple][source]

Convert Qiskit circuit to quantum-debugger format.

Parameters:

qiskit_circuit – Qiskit QuantumCircuit

Returns:

List of gate tuples in quantum-debugger format

Examples

>>> from qiskit import QuantumCircuit
>>> qc = QuantumCircuit(2)
>>> qc.h(0)
>>> qc.cx(0, 1)
>>> gates = from_qiskit(qc)
>>> print(gates)  # [('h', 0), ('cnot', (0, 1))]
quantum_debugger.integrations.to_cirq(gates: List[Tuple]) → cirq.Circuit[source]

Convert quantum-debugger format to Cirq circuit.

Parameters:

gates – List of gate tuples

Returns:

Cirq Circuit

Examples

>>> gates = [('h', 0), ('cnot', (0, 1))]
>>> circuit = to_cirq(gates)
>>> print(circuit)
quantum_debugger.integrations.to_pennylane(gates: List[Tuple], device_name: str = 'default.qubit') → qml.QNode[source]

Convert quantum-debugger format to PennyLane QNode.

Parameters:
  • gates – List of gate tuples

  • device_name – PennyLane device name

Returns:

PennyLane QNode function

Examples

>>> gates = [('h', 0), ('cnot', (0, 1))]
>>> qnode = to_pennylane(gates)
>>> result = qnode()
quantum_debugger.integrations.to_qiskit(gates: List[Tuple], n_qubits: int | None = None) → QuantumCircuit[source]

Convert quantum-debugger format to Qiskit circuit.

Parameters:
  • gates – List of gate tuples

  • n_qubits – Number of qubits (auto-detected if None)

Returns:

Qiskit QuantumCircuit

Examples

>>> gates = [('h', 0), ('cnot', (0, 1))]
>>> qc = to_qiskit(gates)
>>> print(qc)