Skip to content

Simulator -- CPUQVM, GPUQVM, DensityMatrixSimulator, Stabilizer, PartialAmplitudeQVM, SingleAmplitudeQVM, MPSQVM, SparseHeisenbergSimulator ​

API reference for quantum circuit simulators in pyqpanda3.

Overview ​

pyqpanda3 provides multiple simulator backends for executing quantum programs:

SimulatorState RepresentationNoise SupportBest For
CPUQVMState vectorYesGeneral-purpose simulation
DensityMatrixSimulatorDensity matrixYesMixed states, partial trace, noise analysis
PartialAmplitudeQVMState vector (partial)NoLarge circuits where only select amplitudes are needed
SingleAmplitudeQVMTensor networkNoQuerying individual amplitudes in large circuits
StabilizerStabilizer (Clifford)YesLarge Clifford circuits, efficient sampling
MPSQVMMatrix product stateYesLarge weakly-entangled circuits
SparseHeisenbergSimulatorHeisenberg picture (sparse)NoFast Pauli-Hamiltonian expectation values (non-sampling, no state vector)
GPUQVMState vector (GPU)YesHigh-performance simulation with CUDA

CPUQVM ​

State-vector-based quantum simulator running on the CPU. This is the primary simulator for general-purpose quantum circuit simulation. It stores the full state vector of the quantum system and supports noisy simulation via NoiseModel.

Signature ​

python
class CPUQVM:
    def __init__(precision: str = "float64") -> None
    def run(prog: QProg, shots: int, model: NoiseModel = NoiseModel()) -> None
    def result() -> QResult
    def init_state(state: numpy.ndarray[complex128]) -> None    # no-arg call restores |0...0>
    def current_state() -> numpy.ndarray                        # native-precision state (0.5.0)
    def expval_hamiltonian(prog: QProg, hamiltonian: Hamiltonian, shots: int = 1000, noise_model: NoiseModel = NoiseModel()) -> float  # deprecated
    def expval_pauli_operator(prog: QProg, pauli_operator: PauliOperator, shots: int = 1000, noise_model: NoiseModel = NoiseModel()) -> float  # deprecated

CPUQVM.init ​

python
CPUQVM(precision: str = "float64") -> None

Constructs a new CPUQVM instance.

Parameters ​

ParameterTypeDescription
precisionstrArithmetic precision: "float32" or "float64" (default). Immutable after construction; read back via the precision property. Raises InvalidPrecisionError/UnsupportedPrecisionError (subclasses of ValueError) for invalid values.

Returns ​

A new CPUQVM instance. See Precision & Capabilities for the full precision family, the capability registry, and SIMD diagnostics.

CPUQVM.run ​

python
CPUQVM.run(prog: QProg, shots: int, model: NoiseModel = NoiseModel()) -> None

Executes a quantum program a specified number of times (shots) and stores the results internally. Each shot re-initializes the state and runs the full circuit. If measurement operations are present in the program, the results are aggregated across all shots.

Parameters ​

ParameterTypeDescription
progQProgThe quantum program to execute.
shotsintThe number of times to repeat the execution. Measurement outcomes are aggregated across all shots.
modelNoiseModelOptional noise model to apply during execution. Defaults to an ideal (noise-free) model.

Returns ​

None. Results are stored internally and retrieved via result().

CPUQVM.result ​

python
CPUQVM.result() -> QResult

Retrieves the result of the most recent run() call.

Parameters ​

None.

Returns ​

A QResult object containing measurement counts, state vector, and probability data.

Examples ​

Run a Bell state circuit and retrieve measurement counts:

python
from pyqpanda3.core import CPUQVM, QProg, H, CNOT, measure

# Build a Bell state program
prog = QProg()
prog << H(0) << CNOT(0, 1)
prog << measure(0, 0) << measure(1, 1)

# Run on the CPU simulator
qvm = CPUQVM()
qvm.run(prog, shots=1000)
res = qvm.result()

# Print measurement counts
counts = res.get_counts()
print(counts)
# Example output: {'00': 503, '11': 497}

Output:

{'00': 504, '11': 496}

Get the state vector after running a circuit:

python
from pyqpanda3.core import CPUQVM, QProg, H, CNOT

prog = QProg()
prog << H(0) << CNOT(0, 1)

qvm = CPUQVM()
qvm.run(prog, shots=1)
res = qvm.result()

state = res.get_state_vector()
print(state)
# [0.707+0j, 0+0j, 0+0j, 0.707+0j]

Output:

[(0.7071067811865476+0j), 0j, 0j, (0.7071067811865476+0j)]

Run with a depolarizing noise model:

python
from pyqpanda3.core import (
    CPUQVM, QProg, H, CNOT, measure,
    NoiseModel, depolarizing_error, GateType
)

prog = QProg()
prog << H(0) << CNOT(0, 1)
prog << measure(0, 0) << measure(1, 1)

noise = NoiseModel()
noise.add_all_qubit_quantum_error(depolarizing_error(0.01), [GateType.CNOT])

qvm = CPUQVM()
qvm.run(prog, shots=1000, model=noise)
res = qvm.result()
print(res.get_counts())

Output:

{'11': 487, '10': 11, '00': 497, '01': 5}

CPUQVM.init_state ​

python
CPUQVM.init_state(state: numpy.ndarray[complex128]) -> None

Sets the initial quantum state of the simulator. The simulator resets to this state before each run() (and each evolve()) call. Calling without arguments restores the default |0...0> state.

Parameters ​

ParameterTypeDescription
statenumpy.ndarray[complex128]Initial state vector with 2^n complex amplitudes. Python lists and NumPy arrays (complex128/complex64/float64) are also accepted. When omitted, restores the default `

Raises ​

  • RuntimeError if the state size is not a power of 2, the state is not normalized, or it contains NaN or Inf.
  • ValueError if the input is not a 1-D array (e.g. a 2-D array).
  • RuntimeError if the state has a single amplitude (size 1).

Example ​

python
import numpy as np
from pyqpanda3.core import CPUQVM, QProg, measure

qvm = CPUQVM()
qvm.init_state([1 / np.sqrt(2), 0, 0, 1 / np.sqrt(2)])

prog = QProg() << measure([0, 1], [0, 1])
qvm.run(prog, 1000)
print(qvm.result().get_counts())

qvm.init_state()  # restore default |0...0>
qvm.run(prog, 1000)
print(qvm.result().get_counts())

Output:

{'00': 524, '11': 476}
{'00': 1000}

CPUQVM.current_state ​

python
CPUQVM.current_state() -> numpy.ndarray

Returns the state installed by the most recent init_state(...) call, as a NumPy array in the simulator's native precision: complex64 when constructed with precision="float32", complex128 for "float64". Unlike result().get_state_vector(), no dtype conversion takes place. New in 0.5.0.

run() does not populate this buffer: before any init_state(...) call the returned array is empty (length 0, correct dtype). To read the state a run() produced, use result().get_state_vector().

python
import numpy as np
from pyqpanda3.core import CPUQVM, H, CNOT, QProg

qvm = CPUQVM(precision="float32")
qvm.run(QProg() << H(0) << CNOT(0, 1), 100)
print("before init_state:", len(qvm.current_state()))

qvm.init_state(np.array([0.5, 0.5, 0.5, 0.5], dtype=np.complex64))
print("after init_state:", qvm.current_state().dtype, qvm.current_state().shape)
print("via result():", len(qvm.result().get_state_vector()))

Output:

text
before init_state: 0
after init_state: complex64 (4,)
via result(): 4

Parameters ​

None.

Returns ​

numpy.ndarray of shape (2^n,).

expval_hamiltonian ​

Calculate the expectation value of a Hamiltonian.

Deprecated: Use the module-level expval_hamiltonian() function instead.

python
expval_hamiltonian(prog: QProg, hamiltonian: Hamiltonian, shots: int = 1000, noise_model: NoiseModel = NoiseModel()) -> float

expval_pauli_operator ​

Calculate the expectation value of a Pauli operator.

Deprecated: Use the module-level expval_pauli_operator() function instead.

python
expval_pauli_operator(prog: QProg, pauli_operator: PauliOperator, shots: int = 1000, noise_model: NoiseModel = NoiseModel()) -> float

See Also ​


DensityMatrixSimulator ​

Density-matrix-based quantum simulator. Unlike the state vector simulator, this backend represents the quantum state as a density matrix, enabling simulation of mixed states, noisy evolution, and computation of partial traces. It supports all noise model operations natively.

Signature ​

python
class DensityMatrixSimulator:
    def __init__(precision: str = "float64") -> None
    def run(prog: QProg, model: NoiseModel = NoiseModel()) -> None
    def state_prob(index: int) -> float
    def state_prob(index: str) -> float
    def state_probs() -> list[float]
    def state_probs(qubits: list[int]) -> list[float]
    def state_probs(bin_indices: list[str]) -> list[float]
    def density_matrix() -> numpy.ndarray[complex128]
    def density_matrix_native() -> numpy.ndarray    # native dtype (0.5.0)
    def reduced_density_matrix(qubits: list[int]) -> numpy.ndarray[complex128]

DensityMatrixSimulator.init ​

python
DensityMatrixSimulator(precision: str = "float64") -> None

Constructs a new DensityMatrixSimulator instance.

Parameters ​

ParameterTypeDescription
precisionstrArithmetic precision: "float32" or "float64" (default). Immutable after construction.

Returns ​

A new DensityMatrixSimulator instance.

DensityMatrixSimulator.run ​

python
DensityMatrixSimulator.run(prog: QProg, model: NoiseModel = NoiseModel()) -> None

Executes a quantum program with an optional noise model, evolving the density matrix accordingly.

Parameters ​

ParameterTypeDescription
progQProgThe quantum program to execute.
modelNoiseModelOptional noise model to apply during execution. Defaults to an ideal (noise-free) model.

Returns ​

None. The density matrix is updated internally.

DensityMatrixSimulator.state_prob (by index) ​

python
DensityMatrixSimulator.state_prob(index: int) -> float

Returns the probability of the computational basis state at the given integer index.

Parameters ​

ParameterTypeDescription
indexintThe integer index of the computational basis state.

Returns ​

The probability (float) of the specified state.

DensityMatrixSimulator.state_prob (by binary string) ​

python
DensityMatrixSimulator.state_prob(index: str) -> float

Returns the probability of the computational basis state identified by the given binary string.

Parameters ​

ParameterTypeDescription
indexstrThe binary string representation of the basis state (e.g., "01").

Returns ​

The probability (float) of the specified state.

DensityMatrixSimulator.state_probs (all states) ​

python
DensityMatrixSimulator.state_probs() -> list[float]

Returns the probabilities of all possible computational basis states.

Parameters ​

None.

Returns ​

A list of probabilities for every computational basis state.

DensityMatrixSimulator.state_probs (specific qubits) ​

python
DensityMatrixSimulator.state_probs(qubits: list[int]) -> list[float]

Returns the marginal probability distribution for the specified subset of qubits.

Parameters ​

ParameterTypeDescription
qubitslist[int]Indices of the qubits to compute probabilities for.

Returns ​

A list of probabilities for the specified qubits.

DensityMatrixSimulator.state_probs (by binary strings) ​

python
DensityMatrixSimulator.state_probs(bin_indices: list[str]) -> list[float]

Returns the probabilities for the states specified by a list of binary strings.

Parameters ​

ParameterTypeDescription
bin_indiceslist[str]A list of binary string representations of basis states.

Returns ​

A list of probabilities corresponding to the given states.

DensityMatrixSimulator.density_matrix ​

python
DensityMatrixSimulator.density_matrix() -> numpy.ndarray[complex128]

Returns the full density matrix of the current quantum state.

Parameters ​

None.

Returns ​

A complex-valued NumPy array (numpy.ndarray with complex128 dtype) representing the density matrix.

DensityMatrixSimulator.density_matrix_native ​

python
DensityMatrixSimulator.density_matrix_native() -> numpy.ndarray

Returns the density matrix as a NumPy array in the simulator's native dtype (complex64 for float32, complex128 for float64); density_matrix() always returns complex128. New in 0.5.0.

Returns ​

numpy.ndarray of shape (2^n, 2^n).

DensityMatrixSimulator.reduced_density_matrix ​

python
DensityMatrixSimulator.reduced_density_matrix(qubits: list[int]) -> numpy.ndarray[complex128]

Returns the reduced density matrix obtained by tracing out all qubits not in the specified list.

Parameters ​

ParameterTypeDescription
qubitslist[int]Indices of the qubits to keep. All other qubits are traced out.

Returns ​

A complex-valued NumPy array (numpy.ndarray with complex128 dtype) representing the reduced density matrix for the specified qubits.

Examples ​

Compute the density matrix of a Bell state and trace out one qubit:

python
from pyqpanda3.core import DensityMatrixSimulator, QProg, H, CNOT

prog = QProg()
prog << H(0) << CNOT(0, 1)

sim = DensityMatrixSimulator()
sim.run(prog)

# Full density matrix
rho = sim.density_matrix()
print(rho)

# Reduced density matrix for qubit 0 (trace out qubit 1)
rho_0 = sim.reduced_density_matrix([0])
print(rho_0)
# Expected: maximally mixed state [[0.5, 0], [0, 0.5]]

# Probability of state |00>
p_00 = sim.state_prob(0)
print(f"P(|00>) = {p_00}")

# Probability via binary string
p_11 = sim.state_prob("11")
print(f"P(|11>) = {p_11}")

# All state probabilities
probs = sim.state_probs()
print(probs)
# [0.5, 0.0, 0.0, 0.5]

Output:

[[0.5+0.j 0. +0.j 0. +0.j 0.5+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.5+0.j 0. +0.j 0. +0.j 0.5+0.j]]
[[0.5+0.j 0. +0.j]
 [0. +0.j 0.5+0.j]]
P(|00>) = 0.5000000000000001
P(|11>) = 0.5000000000000001
[0.5000000000000001, 0.0, 0.0, 0.5000000000000001]

Simulate with amplitude damping noise:

python
from pyqpanda3.core import (
    DensityMatrixSimulator, QProg, H, GateType,
    NoiseModel, amplitude_damping_error
)

prog = QProg()
prog << H(0)

noise = NoiseModel()
noise.add_all_qubit_quantum_error(amplitude_damping_error(0.1), GateType.H)

sim = DensityMatrixSimulator()
sim.run(prog, model=noise)

rho = sim.density_matrix()
print(rho)

Output:

[[0.55      +0.j 0.47434165+0.j]
 [0.47434165+0.j 0.45      +0.j]]

See Also ​

  • CPUQVM -- State vector simulator
  • NoiseModel -- Noise model configuration
  • QProg -- Quantum program construction

PartialAmplitudeQVM ​

Partial amplitude simulator. This backend is designed for large quantum circuits where computing the full state vector is infeasible due to memory constraints. Instead of returning the complete state vector, it computes amplitudes for specific computational basis states specified by binary strings.

Signature ​

python
class PartialAmplitudeQVM:
    def __init__(precision: str = "float64") -> None
    def run(prog: QProg) -> None
    def get_state_vector(amplitudes: list[str]) -> numpy.ndarray

PartialAmplitudeQVM.init ​

python
PartialAmplitudeQVM(precision: str = "float64") -> None

Constructs a new PartialAmplitudeQVM instance.

Parameters ​

ParameterTypeDescription
precisionstrArithmetic precision: "float32" or "float64" (default). Immutable after construction.

Returns ​

A new PartialAmplitudeQVM instance.

PartialAmplitudeQVM.run ​

python
PartialAmplitudeQVM.run(prog: QProg) -> None

Executes the quantum program and prepares the simulator for partial amplitude queries. Note: this simulator does not take a shots parameter -- it performs a single state-vector evolution.

Parameters ​

ParameterTypeDescription
progQProgThe quantum program to execute.

Returns ​

None.

PartialAmplitudeQVM.get_state_vector ​

python
PartialAmplitudeQVM.get_state_vector(amplitudes: list[str]) -> list[complex]

Retrieves the complex amplitudes for the specified computational basis states.

Parameters ​

ParameterTypeDescription
amplitudeslist[str]A list of binary strings, each specifying a computational basis state (e.g., ["00", "11"]).

Returns ​

A NumPy array of complex amplitudes in the simulator's native dtype (complex64 for float32, complex128 for float64); since 0.5.0 the return value is a NumPy array rather than a Python list.

Examples ​

Get specific amplitudes from a single-qubit superposition:

python
from pyqpanda3.core import PartialAmplitudeQVM, QProg, H

prog = QProg()
prog << H(0)

qvm = PartialAmplitudeQVM()
qvm.run(prog)

# Get amplitudes for specific basis states
amp_00 = qvm.get_state_vector(["00"])
amp_01 = qvm.get_state_vector(["01"])
print(f"|00>: {amp_00}")
print(f"|01>: {amp_01}")

Output:

|00>: [(0.7071067811865476+0j)]
|01>: [(0.7071067811865476+0j)]

See Also ​

  • CPUQVM -- Full state vector simulator
  • QProg -- Quantum program construction

SingleAmplitudeQVM ​

Single-amplitude simulator. This backend uses tensor networks to efficiently compute amplitudes for selected computational basis states without materializing the full state vector. It is ideal for large quantum circuits where only a few amplitudes need to be queried.

Signature ​

python
class SingleAmplitudeQVM:
    def __init__(precision: str = "float64") -> None
    def run(prog: QProg, max_rank: int = 30) -> None
    def pmeasure_bin_index(index: str) -> complex
    def pmeasure_dec_index(index: str) -> complex
    def PMeasure_bin_index(index: str) -> complex
    def PMeasure_dec_index(index: str) -> complex
    def stats() -> SingleAmplitudeStats                  # (0.5.0)

SingleAmplitudeQVM.init ​

python
SingleAmplitudeQVM(precision: str = "float64") -> None

Construct a new SingleAmplitudeQVM instance.

Parameters ​

ParameterTypeDescription
precisionstrArithmetic precision: "float32" or "float64" (default). Immutable after construction.

Returns ​

A new SingleAmplitudeQVM instance.

SingleAmplitudeQVM.run ​

python
SingleAmplitudeQVM.run(prog: QProg, max_rank: int = 30) -> None

Run a quantum program using the tensor network method. This simulator does not store the full state vector; instead it builds an internal tensor network representation for subsequent amplitude queries.

Parameters ​

ParameterTypeDescription
progQProgThe quantum program to execute.
max_rankintMaximum tensor rank allowed during local tensor contraction. Default of 30 works for most circuits; larger circuits may need a higher value.

Returns ​

None. Simulator state is updated in place.

SingleAmplitudeQVM.pmeasure_bin_index ​

python
SingleAmplitudeQVM.pmeasure_bin_index(index: str) -> complex

Return a single amplitude by binary basis-state index.

Parameters ​

ParameterTypeDescription
indexstrBinary basis-state index string whose length must match the number of qubits (e.g. "0101").

Returns ​

The complex amplitude of the selected computational basis state.

Raises ​

  • RuntimeError if index contains invalid characters (not 0/1).
  • RuntimeError if index length does not match the program's qubit count.

SingleAmplitudeQVM.pmeasure_dec_index ​

python
SingleAmplitudeQVM.pmeasure_dec_index(index: str) -> complex

Return a single amplitude by decimal basis-state index.

Parameters ​

ParameterTypeDescription
indexstrDecimal basis-state index string (e.g. "0", "3").

Returns ​

The complex amplitude of the selected computational basis state.

Raises ​

SingleAmplitudeQVM.PMeasure_bin_index / PMeasure_dec_index ​

These are CamelCase aliases for pmeasure_bin_index and pmeasure_dec_index, functionally identical.

SingleAmplitudeQVM.stats ​

python
SingleAmplitudeQVM.stats() -> SingleAmplitudeStats

Returns a read-only record describing the amplitude-evaluation workspace behavior of the most recent run: cache_hit_count, cache_miss_count, and peak_workspace_bytes. New in 0.5.0.

Examples ​

Query specific amplitudes from a Bell state:

python
from pyqpanda3.core import SingleAmplitudeQVM, QProg, H, CNOT

prog = QProg()
prog << H(0) << CNOT(0, 1)

qvm = SingleAmplitudeQVM()
qvm.run(prog)

# Query |00> and |11> amplitudes
amp_00 = qvm.pmeasure_bin_index("00")
amp_11 = qvm.pmeasure_bin_index("11")
amp_01 = qvm.pmeasure_bin_index("01")

print(f"|00> = {amp_00}")
print(f"|11> = {amp_11}")
print(f"|01> = {amp_01}")

Output:

|00> = (0.7071067811865476+0j)
|11> = (0.7071067811865476+0j)
|01> = 0j

Query using decimal index on a larger circuit:

python
from pyqpanda3.core import SingleAmplitudeQVM, QProg, H, X

prog = QProg()
prog << H(0) << X(1) << H(2)

qvm = SingleAmplitudeQVM()
qvm.run(prog)

# |010> has decimal index 2
amp = qvm.pmeasure_dec_index("2")
print(f"|010> = {amp}")

Output:

|010> = (0.5+0j)

See Also ​

  • PartialAmplitudeQVM -- Batch amplitude query simulator with similar use case
  • CPUQVM -- Full state vector simulator
  • QProg -- Quantum program construction

MPSQVM ​

Matrix-product-state quantum simulator. MPSQVM runs quantum programs on an MPS backend, keeping memory usage low for weakly-entangled circuits even at large qubit counts. After running, retrieve measurement results via result().

Note: MPSQVM's C++ init_state is not exposed in the Python bindings (0.4.1); use CPUQVM.init_state on the Python side.

Signature ​

python
class MPSQVM:
    def __init__(precision: str = "float64", truncation_atol: float | None = None, max_bond_dimension: int | None = None) -> None
    def run(prog: QProg, shots: int, model: NoiseModel = NoiseModel()) -> None
    def result() -> QResult
    def stats() -> MPSRunStats
    def current_state() -> numpy.ndarray

MPSQVM.init ​

python
MPSQVM(precision: str = "float64", truncation_atol: float | None = None, max_bond_dimension: int | None = None) -> None

Construct a new MPSQVM instance. New in 0.5.0: the precision keyword, truncation controls, stats(), and current_state().

ParameterTypeDescription
precisionstr"float32" or "float64" (default).
truncation_atolfloat or NoneSingular values below this weight are discarded after each SVD. Defaults are precision-dependent: 1e-6 for float32, 1e-12 for float64.
max_bond_dimensionint or NoneHard cap on the bond dimension kept after truncation. None means truncation is tolerance-driven only.

MPSQVM.stats ​

python
MPSQVM.stats() -> MPSRunStats

Returns a read-only record of what the SVD truncation did: discarded_weight (total probability weight dropped so far) and max_bond_dimension_seen (largest bond dimension materialized so far).

MPSQVM.current_state ​

python
MPSQVM.current_state() -> numpy.ndarray

Returns the post-run() state as a dense vector in the simulator's native precision (complex64 for "float32", complex128 for "float64"). Unlike CPUQVM.current_state(), which mirrors init_state(...), this one is populated by run(). For very large qubit counts, prefer measurement via result().

MPSQVM.run ​

python
MPSQVM.run(prog: QProg, shots: int, model: NoiseModel = NoiseModel()) -> None

Run a quantum program on the MPS backend.

ParameterTypeDescription
progQProgThe quantum program to run.
shotsintThe number of shots.
modelNoiseModelOptional noise model; defaults to noise-free.

MPSQVM.result ​

python
MPSQVM.result() -> QResult

Returns the measurement result of the last run(). The returned QResult exposes the same methods as CPUQVM.

Example ​

python
from pyqpanda3.core import H, MPSQVM, QProg, measure

prog = QProg() << H(0) << measure(0, 0) << measure(1, 1)

qvm = MPSQVM()
qvm.run(prog, 1000)
result = qvm.result()

print(type(result).__name__)
print(sum(result.get_counts().values()) == 1000)

Output:

QResult
True

See Also ​

  • CPUQVM -- General-purpose state vector simulator; QResult methods apply here
  • QProg -- Quantum program construction

SparseHeisenbergSimulator ​

Sparse Heisenberg-picture expectation simulator. SparseHeisenbergSimulator computes the expectation value of a Pauli Hamiltonian using a sparse Heisenberg-picture algorithm. It is not a shot-based QVM and does not return a state vector; it is well suited to quickly estimating <H> when the gate set is supported and the initial state is a product state.

Workflow: construct the simulator -> set a product initial state -> add observables (or a Hamiltonian) -> evolve_backward(prog) to evolve the circuit backward -> read the expectation with expectation().

Signature ​

python
class SparseHeisenbergSimulator:
    def __init__(num_qubits: int, max_terms: object = None, truncation_norm: str = "none", atol: float = 1e-14, precision: str = "float64")
    def set_initial_product_state(state: list[tuple[complex, complex]]) -> None
    def clear_observable() -> None
    def add_observable(pauli: str, coeff: complex = 1+0j) -> None
    def set_hamiltonian(hamiltonian: Hamiltonian) -> None
    def set_pauli_operator(pauli_operator: PauliOperator) -> None
    def evolve_backward(prog: QProg) -> None          # or evolve_backward(circuit: QCircuit)
    def apply_gate(gate: QGate) -> None
    def expectation() -> float
    def stats() -> SparseHeisenbergStats

SparseHeisenbergSimulator.init ​

python
SparseHeisenbergSimulator(
    num_qubits: int,
    max_terms: object = None,
    truncation_norm: str = "none",
    atol: float = 1e-14,
    precision: str = "float64",
) -> None
ParameterTypeDescription
num_qubitsintThe number of qubits.
max_termsint or NoneUpper bound on the number of operator terms; None means unlimited.
truncation_normstrTruncation norm: "none" for no truncation, "l1" for L1-norm truncation.
atolfloatAbsolute tolerance used to decide whether a coefficient is zero during truncation.
precisionstrArithmetic precision: "float32" or "float64" (default). New in 0.5.0.
atolfloatAlso readable as a read-only property after construction (new in 0.5.0).

set_initial_product_state ​

python
SparseHeisenbergSimulator.set_initial_product_state(state: list[tuple[complex, complex]]) -> None

Set a product initial state, where each qubit is described by a single-qubit state vector (alpha, beta) (alpha is the |0> amplitude, beta is the |1> amplitude).

ParameterTypeDescription
statelist[tuple[complex, complex]]Per-qubit single-qubit state vectors; length equals the qubit count.

add_observable / set_hamiltonian / set_pauli_operator / clear_observable ​

python
SparseHeisenbergSimulator.add_observable(pauli: str, coeff: complex = 1+0j) -> None
SparseHeisenbergSimulator.set_hamiltonian(hamiltonian: Hamiltonian) -> None
SparseHeisenbergSimulator.set_pauli_operator(pauli_operator: PauliOperator) -> None
SparseHeisenbergSimulator.clear_observable() -> None
  • add_observable(pauli, coeff): append a Pauli-string observable (e.g. "ZZ", "X0 Z1") with a coefficient.
  • set_hamiltonian(hamiltonian) / set_pauli_operator(pauli_operator): replace the observable's Hamiltonian representation wholesale.
  • clear_observable(): remove all terms of the current observable.

evolve_backward / apply_gate ​

python
SparseHeisenbergSimulator.evolve_backward(prog: QProg) -> None        # overload 1
SparseHeisenbergSimulator.evolve_backward(circuit: QCircuit) -> None  # overload 2
SparseHeisenbergSimulator.apply_gate(gate: QGate) -> None

Evolve the circuit backward, transforming the observable to the same picture as the initial state. evolve_backward accepts a full program or a quantum circuit; apply_gate applies evolution one gate at a time.

expectation / stats ​

python
SparseHeisenbergSimulator.expectation() -> float
SparseHeisenbergSimulator.stats() -> SparseHeisenbergStats

expectation() returns the expectation value <H> of the current observable on the (evolved) initial state. stats() returns the truncation statistics as a SparseHeisenbergStats:

FieldTypeDescription
active_termsintNumber of operator terms retained after truncation.
truncated_termsintNumber of operator terms truncated away.
truncated_l1floatSum of the L1 norms of the truncated terms' coefficients.
coefficient_l1floatSum of the L1 norms of all (pre-truncation) operator-term coefficients.

Free function sparse_heisenberg_expectation ​

python
sparse_heisenberg_expectation(
    prog: QProg,
    hamiltonian: Hamiltonian,
    initial_product_state: list[tuple[complex, complex]] = [],
    max_terms: object = None,
    truncation_norm: str = "none",
) -> float

Performs the whole flow in one step: construct the simulator, set the initial state, set the Hamiltonian, evolve backward, and return the expectation value. It is shorthand for calling the methods explicitly.

Example ​

python
from pyqpanda3.core import QProg, CZ, SparseHeisenbergSimulator, sparse_heisenberg_expectation
from pyqpanda3.hamiltonian import Hamiltonian

zero = (1 + 0j, 0 + 0j)  # (|0> amplitude, |1> amplitude) for each qubit

prog = QProg() << CZ(0, 1)  # |00> unchanged

sim = SparseHeisenbergSimulator(num_qubits=2)
sim.set_initial_product_state([zero, zero])
sim.add_observable("ZZ", 1.0)
sim.evolve_backward(prog)
print(round(sim.expectation(), 6))

# Equivalent free-function form
ham = Hamiltonian({"Z0 Z1": 1.0})
print(round(sparse_heisenberg_expectation(prog, ham, initial_product_state=[zero, zero]), 6))

Output:

1.0
1.0

The <ZZ> expectation on |00> is 1.0 (both qubits are definite +1 eigenstates), matching the analytic value.

See Also ​


Stabilizer ​

Stabilizer simulator based on the Clifford group representation. This simulator efficiently simulates circuits composed solely of Clifford gates (H, S, CNOT, and measurements). Instead of storing the full state vector, it maintains a stabilizer tableau, allowing simulation of very large numbers of qubits with polynomial memory.

Signature ​

python
class Stabilizer:
    # precision -> "exact" and supported_precisions -> ("exact",), read-only (0.5.0)
    def run(prog: QProg, shots: int, model: NoiseModel = NoiseModel()) -> None
    def result() -> StabilizerResult

Stabilizer.init ​

python
Stabilizer() -> None

Constructs a new Stabilizer simulator instance. The stabilizer formalism is exact: precision always reads "exact" and supported_precisions is ("exact",); requesting an arithmetic precision raises UnsupportedPrecisionError (new in 0.5.0).

Parameters ​

None.

Returns ​

A new Stabilizer instance.

Stabilizer.run ​

python
Stabilizer.run(prog: QProg, shots: int, model: NoiseModel = NoiseModel()) -> None

Executes the quantum program using the stabilizer formalism for a specified number of measurement shots. The circuit must be composed of Clifford gates (H, S, CNOT, X, Y, Z, SWAP, and measurements). Non-Clifford gates (such as T gates) are not supported.

Noise model support is limited to Clifford-compatible noise channels (bit-flip, phase-flip, bit-phase-flip, phase-damping, depolarizing).

Parameters ​

ParameterTypeDescription
progQProgThe quantum program to execute. Must contain only Clifford gates and measurements.
shotsintThe number of measurement repetitions.
modelNoiseModelOptional noise model (Clifford-compatible only). Defaults to an ideal model.

Returns ​

None. Results are stored internally and retrieved via result().

Stabilizer.result ​

python
Stabilizer.result() -> StabilizerResult

Retrieves the result of the most recent run() call. The StabilizerResult object provides access to measurement counts and state information.

Parameters ​

None.

Returns ​

A StabilizerResult object (subclass of QResult) containing measurement outcomes.

Examples ​

Run a Clifford circuit with the stabilizer simulator:

python
from pyqpanda3.core import Stabilizer, QProg, H, CNOT, measure

prog = QProg()
prog << H(0) << CNOT(0, 1)
prog << measure(0, 0) << measure(1, 1)

sim = Stabilizer()
sim.run(prog, shots=1000)
res = sim.result()

counts = res.get_counts()
print(counts)
# Example output: {'00': 501, '11': 499}

Output:

{'00': 504, '11': 496}

See Also ​


GPUQVM ​

GPU-accelerated state vector simulator. This backend uses CUDA to accelerate quantum circuit simulation on NVIDIA GPUs. It provides the same interface as CPUQVM but leverages GPU parallelism for significantly faster execution on circuits with many qubits.

Availability: This simulator requires pyqpanda3 to be compiled with CUDA support (USE_CUDA flag). It is not available in the standard CPU-only build.

Signature ​

python
class GPUQVM:
    def __init__(precision: str = "float64") -> None
    def init_state(state: list[complex]) -> None
    def run(prog: QProg, shots: int, model: NoiseModel = NoiseModel()) -> None
    def result() -> QResult

GPUQVM.init ​

python
GPUQVM(precision: str = "float64") -> None

Constructs a GPU simulator with the given arithmetic precision: "float32" and "float64" are supported (default "float64"). GPUQVM is bound only in USE_CUDA builds; on a build without CUDA, pyqpanda3.core.GPUQVM is None (an ImportWarning is emitted at import time) and cannot be constructed. Use simulator_capabilities("GPUQVM").available to check.

Constructs a new GPUQVM instance. Requires CUDA support at compile time.

Parameters ​

None.

Returns ​

A new GPUQVM instance.

GPUQVM.init_state ​

python
GPUQVM.init_state(state: list[complex]) -> None

Sets the initial state used by subsequent run() calls. init_state([]) restores the default |0...0>; GPUQVM has no no-argument overload.

Example (requires a CUDA build; not executed locally):

python
from pyqpanda3.core import GPUQVM, QProg, measure

qvm = GPUQVM()
qvm.init_state([0, 1])          # |1>
prog = QProg(1)
prog << measure(0, 0)
qvm.run(prog, 16)
print(qvm.result().get_counts())  # {'1': 16}

GPUQVM.run ​

python
GPUQVM.run(prog: QProg, shots: int, model: NoiseModel = NoiseModel()) -> None

Executes a quantum program on the GPU for a specified number of shots.

Parameters ​

ParameterTypeDescription
progQProgThe quantum program to execute.
shotsintThe number of times to repeat the execution.
modelNoiseModelOptional noise model to apply during execution. Defaults to an ideal model.

Returns ​

None. Results are stored internally and retrieved via result().

GPUQVM.result ​

python
GPUQVM.result() -> QResult

Retrieves the result of the most recent run() call.

Parameters ​

None.

Returns ​

A QResult object containing measurement counts, state vector, and probability data.

Examples ​

Run a circuit on the GPU simulator:

python
from pyqpanda3.core import CPUQVM, QProg, H, CNOT, measure

prog = QProg()
prog << H(0) << CNOT(0, 1)
prog << measure(0, 0) << measure(1, 1)

# Use CPUQVM (GPUQVM requires CUDA compilation)
qvm = CPUQVM()
qvm.run(prog, shots=1000)
res = qvm.result()

counts = res.get_counts()
print(counts)

Output:

{'00': 504, '11': 496}

See Also ​


QResult ​

Result object returned by CPUQVM.result() and GPUQVM.result(). Contains measurement outcomes, state vector data, and probability distributions.

Signature ​

python
class QResult:
    def get_state_vector() -> list[complex]
    def get_counts() -> dict[str, int]
    def get_prob_list(qubits: list[int] = []) -> list[float]
    def get_prob_dict(qubits: list[int] = []) -> dict[str, float]
    def shots() -> int
    def print_results() -> None

QResult.get_state_vector ​

python
QResult.get_state_vector() -> list[complex]

Returns the state vector of the quantum system after the final shot of execution.

Returns ​

A list of complex numbers representing the quantum state vector.

QResult.get_counts ​

python
QResult.get_counts() -> dict[str, int]

Returns the aggregated measurement results as a dictionary mapping bitstring outcomes to their frequency counts.

Returns ​

A dictionary where keys are bitstrings (e.g., "00", "11") and values are the number of times that outcome was observed.

QResult.get_prob_list ​

python
QResult.get_prob_list(qubits: list[int] = []) -> list[float]

Returns the probability distribution for the specified qubits (or all qubits if none are specified) as a list.

Parameters ​

ParameterTypeDescription
qubitslist[int]Optional list of qubit indices. If empty, returns probabilities for all qubits.

Returns ​

A list of probabilities.

QResult.get_prob_dict ​

python
QResult.get_prob_dict(qubits: list[int] = []) -> dict[str, float]

Returns the probability distribution for the specified qubits as a dictionary mapping bitstrings to probabilities.

Parameters ​

ParameterTypeDescription
qubitslist[int]Optional list of qubit indices. If empty, returns probabilities for all qubits.

Returns ​

A dictionary mapping bitstrings to their probabilities.

QResult.shots ​

python
QResult.shots() -> int

Returns the total number of measurement shots performed.

Returns ​

The number of shots as an integer.

QResult.print_results ​

python
QResult.print_results() -> None

Prints the measurement results to standard output in the format bitstring: count, one per line.

See Also ​


StabilizerResult ​

Result object returned by Stabilizer.result(). Extends QResult with additional stabilizer-specific data.

Signature ​

python
class StabilizerResult(QResult):
    def get_state_vector() -> list[complex]
    def get_counts() -> dict[str, int]
    def get_prob_list(qubits: list[int] = []) -> list[float]
    def get_prob_dict(qubits: list[int] = []) -> dict[str, float]
    def shots() -> int
    def print_results() -> None

See QResult for full method documentation.

See Also ​

Released under the MIT License.