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:
| Simulator | State Representation | Noise Support | Best For |
|---|---|---|---|
| CPUQVM | State vector | Yes | General-purpose simulation |
| DensityMatrixSimulator | Density matrix | Yes | Mixed states, partial trace, noise analysis |
| PartialAmplitudeQVM | State vector (partial) | No | Large circuits where only select amplitudes are needed |
| SingleAmplitudeQVM | Tensor network | No | Querying individual amplitudes in large circuits |
| Stabilizer | Stabilizer (Clifford) | Yes | Large Clifford circuits, efficient sampling |
| MPSQVM | Matrix product state | Yes | Large weakly-entangled circuits |
| SparseHeisenbergSimulator | Heisenberg picture (sparse) | No | Fast Pauli-Hamiltonian expectation values (non-sampling, no state vector) |
| GPUQVM | State vector (GPU) | Yes | High-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
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 # deprecatedCPUQVM.init
CPUQVM(precision: str = "float64") -> NoneConstructs a new CPUQVM instance.
Parameters
| Parameter | Type | Description |
|---|---|---|
| precision | str | Arithmetic 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
CPUQVM.run(prog: QProg, shots: int, model: NoiseModel = NoiseModel()) -> NoneExecutes 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
| Parameter | Type | Description |
|---|---|---|
| prog | QProg | The quantum program to execute. |
| shots | int | The number of times to repeat the execution. Measurement outcomes are aggregated across all shots. |
| model | NoiseModel | Optional 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
CPUQVM.result() -> QResultRetrieves 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:
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:
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:
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
CPUQVM.init_state(state: numpy.ndarray[complex128]) -> NoneSets 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
| Parameter | Type | Description |
|---|---|---|
| state | numpy.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
RuntimeErrorif the state size is not a power of 2, the state is not normalized, or it contains NaN or Inf.ValueErrorif the input is not a 1-D array (e.g. a 2-D array).RuntimeErrorif the state has a single amplitude (size 1).
Example
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
CPUQVM.current_state() -> numpy.ndarrayReturns 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().
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:
before init_state: 0
after init_state: complex64 (4,)
via result(): 4Parameters
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.
expval_hamiltonian(prog: QProg, hamiltonian: Hamiltonian, shots: int = 1000, noise_model: NoiseModel = NoiseModel()) -> floatexpval_pauli_operator
Calculate the expectation value of a Pauli operator.
Deprecated: Use the module-level
expval_pauli_operator()function instead.
expval_pauli_operator(prog: QProg, pauli_operator: PauliOperator, shots: int = 1000, noise_model: NoiseModel = NoiseModel()) -> floatSee Also
- QResult -- Result object with counts, state vector, and probabilities
- NoiseModel -- Noise model configuration
- QProg -- Quantum program construction
- expval_hamiltonian -- Global function for Hamiltonian expectation values
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
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
DensityMatrixSimulator(precision: str = "float64") -> NoneConstructs a new DensityMatrixSimulator instance.
Parameters
| Parameter | Type | Description |
|---|---|---|
| precision | str | Arithmetic precision: "float32" or "float64" (default). Immutable after construction. |
Returns
A new DensityMatrixSimulator instance.
DensityMatrixSimulator.run
DensityMatrixSimulator.run(prog: QProg, model: NoiseModel = NoiseModel()) -> NoneExecutes a quantum program with an optional noise model, evolving the density matrix accordingly.
Parameters
| Parameter | Type | Description |
|---|---|---|
| prog | QProg | The quantum program to execute. |
| model | NoiseModel | Optional 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)
DensityMatrixSimulator.state_prob(index: int) -> floatReturns the probability of the computational basis state at the given integer index.
Parameters
| Parameter | Type | Description |
|---|---|---|
| index | int | The integer index of the computational basis state. |
Returns
The probability (float) of the specified state.
DensityMatrixSimulator.state_prob (by binary string)
DensityMatrixSimulator.state_prob(index: str) -> floatReturns the probability of the computational basis state identified by the given binary string.
Parameters
| Parameter | Type | Description |
|---|---|---|
| index | str | The binary string representation of the basis state (e.g., "01"). |
Returns
The probability (float) of the specified state.
DensityMatrixSimulator.state_probs (all states)
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)
DensityMatrixSimulator.state_probs(qubits: list[int]) -> list[float]Returns the marginal probability distribution for the specified subset of qubits.
Parameters
| Parameter | Type | Description |
|---|---|---|
| qubits | list[int] | Indices of the qubits to compute probabilities for. |
Returns
A list of probabilities for the specified qubits.
DensityMatrixSimulator.state_probs (by binary strings)
DensityMatrixSimulator.state_probs(bin_indices: list[str]) -> list[float]Returns the probabilities for the states specified by a list of binary strings.
Parameters
| Parameter | Type | Description |
|---|---|---|
| bin_indices | list[str] | A list of binary string representations of basis states. |
Returns
A list of probabilities corresponding to the given states.
DensityMatrixSimulator.density_matrix
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
DensityMatrixSimulator.density_matrix_native() -> numpy.ndarrayReturns 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
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
| Parameter | Type | Description |
|---|---|---|
| qubits | list[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:
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:
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
class PartialAmplitudeQVM:
def __init__(precision: str = "float64") -> None
def run(prog: QProg) -> None
def get_state_vector(amplitudes: list[str]) -> numpy.ndarrayPartialAmplitudeQVM.init
PartialAmplitudeQVM(precision: str = "float64") -> NoneConstructs a new PartialAmplitudeQVM instance.
Parameters
| Parameter | Type | Description |
|---|---|---|
| precision | str | Arithmetic precision: "float32" or "float64" (default). Immutable after construction. |
Returns
A new PartialAmplitudeQVM instance.
PartialAmplitudeQVM.run
PartialAmplitudeQVM.run(prog: QProg) -> NoneExecutes 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
| Parameter | Type | Description |
|---|---|---|
| prog | QProg | The quantum program to execute. |
Returns
None.
PartialAmplitudeQVM.get_state_vector
PartialAmplitudeQVM.get_state_vector(amplitudes: list[str]) -> list[complex]Retrieves the complex amplitudes for the specified computational basis states.
Parameters
| Parameter | Type | Description |
|---|---|---|
| amplitudes | list[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:
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
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
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
SingleAmplitudeQVM(precision: str = "float64") -> NoneConstruct a new SingleAmplitudeQVM instance.
Parameters
| Parameter | Type | Description |
|---|---|---|
| precision | str | Arithmetic precision: "float32" or "float64" (default). Immutable after construction. |
Returns
A new SingleAmplitudeQVM instance.
SingleAmplitudeQVM.run
SingleAmplitudeQVM.run(prog: QProg, max_rank: int = 30) -> NoneRun 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
| Parameter | Type | Description |
|---|---|---|
| prog | QProg | The quantum program to execute. |
| max_rank | int | Maximum 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
SingleAmplitudeQVM.pmeasure_bin_index(index: str) -> complexReturn a single amplitude by binary basis-state index.
Parameters
| Parameter | Type | Description |
|---|---|---|
| index | str | Binary 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
RuntimeErrorifindexcontains invalid characters (not 0/1).RuntimeErrorifindexlength does not match the program's qubit count.
SingleAmplitudeQVM.pmeasure_dec_index
SingleAmplitudeQVM.pmeasure_dec_index(index: str) -> complexReturn a single amplitude by decimal basis-state index.
Parameters
| Parameter | Type | Description |
|---|---|---|
| index | str | Decimal basis-state index string (e.g. "0", "3"). |
Returns
The complex amplitude of the selected computational basis state.
Raises
RuntimeErrorifindexexceeds the state space dimension.
SingleAmplitudeQVM.PMeasure_bin_index / PMeasure_dec_index
These are CamelCase aliases for pmeasure_bin_index and pmeasure_dec_index, functionally identical.
SingleAmplitudeQVM.stats
SingleAmplitudeQVM.stats() -> SingleAmplitudeStatsReturns 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:
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> = 0jQuery using decimal index on a larger circuit:
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_stateis not exposed in the Python bindings (0.4.1); useCPUQVM.init_stateon the Python side.
Signature
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.ndarrayMPSQVM.init
MPSQVM(precision: str = "float64", truncation_atol: float | None = None, max_bond_dimension: int | None = None) -> NoneConstruct a new MPSQVM instance. New in 0.5.0: the precision keyword, truncation controls, stats(), and current_state().
| Parameter | Type | Description |
|---|---|---|
precision | str | "float32" or "float64" (default). |
truncation_atol | float or None | Singular values below this weight are discarded after each SVD. Defaults are precision-dependent: 1e-6 for float32, 1e-12 for float64. |
max_bond_dimension | int or None | Hard cap on the bond dimension kept after truncation. None means truncation is tolerance-driven only. |
MPSQVM.stats
MPSQVM.stats() -> MPSRunStatsReturns 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
MPSQVM.current_state() -> numpy.ndarrayReturns 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
MPSQVM.run(prog: QProg, shots: int, model: NoiseModel = NoiseModel()) -> NoneRun a quantum program on the MPS backend.
| Parameter | Type | Description |
|---|---|---|
prog | QProg | The quantum program to run. |
shots | int | The number of shots. |
model | NoiseModel | Optional noise model; defaults to noise-free. |
MPSQVM.result
MPSQVM.result() -> QResultReturns the measurement result of the last run(). The returned QResult exposes the same methods as CPUQVM.
Example
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
TrueSee Also
- CPUQVM -- General-purpose state vector simulator;
QResultmethods 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
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() -> SparseHeisenbergStatsSparseHeisenbergSimulator.init
SparseHeisenbergSimulator(
num_qubits: int,
max_terms: object = None,
truncation_norm: str = "none",
atol: float = 1e-14,
precision: str = "float64",
) -> None| Parameter | Type | Description |
|---|---|---|
num_qubits | int | The number of qubits. |
max_terms | int or None | Upper bound on the number of operator terms; None means unlimited. |
truncation_norm | str | Truncation norm: "none" for no truncation, "l1" for L1-norm truncation. |
atol | float | Absolute tolerance used to decide whether a coefficient is zero during truncation. |
precision | str | Arithmetic precision: "float32" or "float64" (default). New in 0.5.0. |
atol | float | Also readable as a read-only property after construction (new in 0.5.0). |
set_initial_product_state
SparseHeisenbergSimulator.set_initial_product_state(state: list[tuple[complex, complex]]) -> NoneSet 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).
| Parameter | Type | Description |
|---|---|---|
state | list[tuple[complex, complex]] | Per-qubit single-qubit state vectors; length equals the qubit count. |
add_observable / set_hamiltonian / set_pauli_operator / clear_observable
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() -> Noneadd_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
SparseHeisenbergSimulator.evolve_backward(prog: QProg) -> None # overload 1
SparseHeisenbergSimulator.evolve_backward(circuit: QCircuit) -> None # overload 2
SparseHeisenbergSimulator.apply_gate(gate: QGate) -> NoneEvolve 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
SparseHeisenbergSimulator.expectation() -> float
SparseHeisenbergSimulator.stats() -> SparseHeisenbergStatsexpectation() returns the expectation value <H> of the current observable on the (evolved) initial state. stats() returns the truncation statistics as a SparseHeisenbergStats:
| Field | Type | Description |
|---|---|---|
active_terms | int | Number of operator terms retained after truncation. |
truncated_terms | int | Number of operator terms truncated away. |
truncated_l1 | float | Sum of the L1 norms of the truncated terms' coefficients. |
coefficient_l1 | float | Sum of the L1 norms of all (pre-truncation) operator-term coefficients. |
Free function sparse_heisenberg_expectation
sparse_heisenberg_expectation(
prog: QProg,
hamiltonian: Hamiltonian,
initial_product_state: list[tuple[complex, complex]] = [],
max_terms: object = None,
truncation_norm: str = "none",
) -> floatPerforms 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
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.0The
<ZZ>expectation on|00>is1.0(both qubits are definite+1eigenstates), matching the analytic value.
See Also
- Hamiltonian -- Hamiltonian construction
- QProg -- Quantum program construction
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
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() -> StabilizerResultStabilizer.init
Stabilizer() -> NoneConstructs 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
Stabilizer.run(prog: QProg, shots: int, model: NoiseModel = NoiseModel()) -> NoneExecutes 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
| Parameter | Type | Description |
|---|---|---|
| prog | QProg | The quantum program to execute. Must contain only Clifford gates and measurements. |
| shots | int | The number of measurement repetitions. |
| model | NoiseModel | Optional noise model (Clifford-compatible only). Defaults to an ideal model. |
Returns
None. Results are stored internally and retrieved via result().
Stabilizer.result
Stabilizer.result() -> StabilizerResultRetrieves 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:
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
- CPUQVM -- General-purpose state vector simulator
- QResult -- Base result class
- StabilizerResult -- Stabilizer-specific result class
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
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() -> QResultGPUQVM.init
GPUQVM(precision: str = "float64") -> NoneConstructs 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
GPUQVM.init_state(state: list[complex]) -> NoneSets the initial state used by subsequent run() calls. init_state([]) restores the default |0...0>; GPUQVM has no no-argument overload.
- The length must be a power of two; outside the empty list, sizes below 2, NaN/Inf amplitudes, or a non-normalized state raise
RuntimeError(the same validation as CPUQVM). - To check availability on a build without CUDA, use
simulator_capabilities("GPUQVM").available.
Example (requires a CUDA build; not executed locally):
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
GPUQVM.run(prog: QProg, shots: int, model: NoiseModel = NoiseModel()) -> NoneExecutes a quantum program on the GPU for a specified number of shots.
Parameters
| Parameter | Type | Description |
|---|---|---|
| prog | QProg | The quantum program to execute. |
| shots | int | The number of times to repeat the execution. |
| model | NoiseModel | Optional noise model to apply during execution. Defaults to an ideal model. |
Returns
None. Results are stored internally and retrieved via result().
GPUQVM.result
GPUQVM.result() -> QResultRetrieves 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:
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
- CPUQVM -- CPU-based state vector simulator
- QResult -- Result object
- NoiseModel -- Noise model configuration
QResult
Result object returned by CPUQVM.result() and GPUQVM.result(). Contains measurement outcomes, state vector data, and probability distributions.
Signature
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() -> NoneQResult.get_state_vector
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
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
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
| Parameter | Type | Description |
|---|---|---|
| qubits | list[int] | Optional list of qubit indices. If empty, returns probabilities for all qubits. |
Returns
A list of probabilities.
QResult.get_prob_dict
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
| Parameter | Type | Description |
|---|---|---|
| qubits | list[int] | Optional list of qubit indices. If empty, returns probabilities for all qubits. |
Returns
A dictionary mapping bitstrings to their probabilities.
QResult.shots
QResult.shots() -> intReturns the total number of measurement shots performed.
Returns
The number of shots as an integer.
QResult.print_results
QResult.print_results() -> NonePrints the measurement results to standard output in the format bitstring: count, one per line.
See Also
- CPUQVM -- Returns QResult from
result() - GPUQVM -- Returns QResult from
result() - StabilizerResult -- Subclass for Stabilizer results
StabilizerResult
Result object returned by Stabilizer.result(). Extends QResult with additional stabilizer-specific data.
Signature
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() -> NoneSee QResult for full method documentation.
See Also
- Stabilizer -- The simulator that produces this result
- QResult -- Base class