Circuits

class QuantumCircuit(*args, **kwargs)
ccx(self, arg0: int, arg1: int, arg2: int, /) → None
ch(self, arg0: int, arg1: int, /) → None
coherent_estimate(self, observables: object, noise_model: maestro.NoiseModel, noise_realizations: int = 100, config: maestro.SimulatorConfig = SimulatorConfig(), noise_seed: int | None = None) → dict

Estimate expectation values with coherent noise.

Example

qc.coherent_estimate(['ZZ', 'XX'], nm, noise_realizations=200)
coherent_execute(self, noise_model: maestro.NoiseModel, config: maestro.SimulatorConfig = SimulatorConfig(), shots: int = 1024, noise_realizations: int = 64, noise_seed: int | None = None) → dict

Execute with sampled coherent over/under-rotation errors.

Example

qc.coherent_execute(nm, shots=1000)
cp(self, arg0: int, arg1: int, arg2: float, /) → None
crx(self, arg0: int, arg1: int, arg2: float, /) → None
cry(self, arg0: int, arg1: int, arg2: float, /) → None
crz(self, arg0: int, arg1: int, arg2: float, /) → None
cswap(self, arg0: int, arg1: int, arg2: int, /) → None
csx(self, arg0: int, arg1: int, /) → None
csxdg(self, arg0: int, arg1: int, /) → None
cu(self, arg0: int, arg1: int, arg2: float, arg3: float, arg4: float, arg5: float, /) → None
cx(self, arg0: int, arg1: int, /) → None
cy(self, arg0: int, arg1: int, /) → None
cz(self, arg0: int, arg1: int, /) → None
delay(self, qubit: int, duration: float) → None
delay(self, duration: float, qubit: int) → None

Append a delay idle operation on a qubit for a given duration in seconds.

estimate(self, observables: object, config: maestro.SimulatorConfig = SimulatorConfig()) → dict
execute(self, config: maestro.SimulatorConfig = SimulatorConfig(), shots: int = 1024) → dict
full_noise_estimate(self, observables: object, noise_model: maestro.NoiseModel, noise_realizations: int = 100, config: maestro.SimulatorConfig = SimulatorConfig(), noise_seed: int | None = None) → dict

Estimate with combined noise (coherent + crosstalk + T1 + Pauli).

Example

qc.full_noise_estimate(['ZZ', 'XX'], nm)
full_noise_execute(self, noise_model: maestro.NoiseModel, config: maestro.SimulatorConfig = SimulatorConfig(), shots: int = 1024, noise_realizations: int = 64, noise_seed: int | None = None) → dict

Execute with combined noise: coherent + crosstalk + T1 + Pauli.

DM/MPO methods use exact channels for T1 and Pauli layers; trajectory-only layers remain sampled.

Example

qc.full_noise_execute(nm, shots=1000)
get_statevector(self, config: maestro.SimulatorConfig = SimulatorConfig()) → list[complex]

Get the full statevector (complex amplitudes) after executing the circuit.

h(self, qubit: int, noiseless: bool = False) → None

Apply a Hadamard gate. With noiseless=True, noise models add no gate noise after it (for basis changes of a measurement or reset).

inner_product(self, other: maestro.circuits.QuantumCircuit, config: maestro.SimulatorConfig = SimulatorConfig()) → complex

Compute the inner product <psi_self|psi_other> = <0|U_self^dag U_other|0> between this circuit’s state and another circuit’s state, using ProjectOnZero.

k(self, arg: int, /) → None
measure(self, qubits_and_bits: collections.abc.Sequence[tuple[int, int]], readout_error: float = 0.0) → None

Measure each (qubit, classical bit) pair.

readout_error flips each recorded result with that probability, like Stim’s M(p); a NoiseModel’s readout error is applied on top.

measure_all(self) → None
mirror_fidelity(self, config: maestro.SimulatorConfig = SimulatorConfig(), shots: int = 1024, full_amplitude: bool = False, observables: object | None = None) → object

Compute mirror fidelity: run circuit forward then its adjoint in reverse, returning P(|0...0>). Uses shot-based sampling by default. Set full_amplitude=True for exact statevector computation (small circuits only). Pass observables (a Pauli string, ‘;’-separated string or list) to instead return the expectation of each observable on the mirror circuit: a float for a single string, otherwise a list.

noisy_estimate(self, observables: object, noise_model: maestro.NoiseModel, config: maestro.SimulatorConfig = SimulatorConfig()) → dict

Single-layer analytical noisy estimation (zero simulation overhead). Applies per-qubit Pauli damping to the ideal expectation values.

WARNING – this is a SINGLE-LAYER approximation, not an exact result. The damping factor is exact only for one Pauli layer applied immediately before measurement. A circuit that carries noise after every gate is not modelled: Pauli channels do not commute through non-Clifford gates, and the damping does not compound with the number of noisy layers acting on each qubit. The returned values therefore UNDERESTIMATE the noise, increasingly so with circuit depth.

Only the all-gates Pauli layer is modelled; a NoiseModel with any other layer (T1, thermal, coherent, correlated, gate-type or two-qubit noise) raises ValueError, see compute_damping_covers_model(). Use noisy_estimate_montecarlo(), full_noise_estimate(), or noisy_execute() with a density-matrix or MPO method, when the magnitude of the noise matters.

Example

qc.noisy_estimate(['ZZ', 'XX'], nm)
noisy_estimate_montecarlo(self, observables: object, noise_model: maestro.NoiseModel, noise_realizations: int = 100, config: maestro.SimulatorConfig = SimulatorConfig(), noise_seed: int | None = None) → dict

Gate-by-gate Monte Carlo noisy estimation.

Example

qc.noisy_estimate_montecarlo(['ZZ'], nm, noise_realizations=200)
noisy_execute(self, noise_model: maestro.NoiseModel, config: maestro.SimulatorConfig = SimulatorConfig(), shots: int = 1024, noise_realizations: int = 64, noise_seed: int | None = None) → dict

Execute with exact Pauli/T1 channels for density-matrix/MPO methods, or sampled trajectories for pure-state methods.

Example

qc.noisy_execute(nm, shots=1000)
noisy_fidelity(self, noise_model: maestro.NoiseModel, noise_realizations: int = 100, config: maestro.SimulatorConfig = SimulatorConfig(), noise_seed: int | None = None) → dict

Compute fidelity to the ideal unitary circuit state under noise.

Injects all configured noise types (correlated, coherent, crosstalk, T1, Pauli) and averages |<psi_ideal|psi_noisy>|^2 over noise realizations.

Returns dict with ‘fidelity’, ‘infidelity’, ‘std_error’, ‘time_taken’, ‘noise_realizations’.

Example

qc.noisy_fidelity(nm, noise_realizations=200)
noisy_prob(self, target_state: str, noise_model: maestro.NoiseModel) → dict

Compute readout-corrected probability using path integral.

When the noise model has readout error, uses first-order expansion: P_noisy(b) ≈ Π_j(1-a_j)·P(b) + Σ_i c_i·Π_{j≠i}(1-a_j)·P(b⊕eᵢ) where a_i = P(read ¬b_i | prepared b_i) and c_i = P(read b_i | prepared ¬b_i).

This requires n+1 path integral evaluations (target + n flipped variants).

Parameters:
  • target_state – Bitstring like ‘10001001’.

  • noise_model – NoiseModel with readout error set. Any other (gate) noise raises ValueError, since the path integral is noiseless.

Returns:

dict with ‘probability’, ‘target_state’, ‘time_taken’, ‘has_readout_error’.

property num_qubits

(self) -> int

p(self, arg0: int, arg1: float, /) → None
pauli_channel(self, qubits: collections.abc.Sequence[int], probabilities: collections.abc.Sequence[float]) → None

Apply a Pauli channel to one or two qubits, e.g. a Stim DEPOLARIZE1.

probabilities has 4**len(qubits) entries summing to one. Base-4 digit k of an index selects I, X, Y or Z on qubits[k], so one qubit is [pI, pX, pY, pZ] and two are II, XI, YI, ZI, IX, XX, … ZZ.

Density-matrix and MPO backends apply the channel exactly. Pure-state and MPS backends sample one Pauli per noise realization, so run the circuit through noisy_execute or full_noise_execute with noise_realizations=shots; plain execute rejects it there.

prob(self, target_state: str) → dict

Compute the probability of a specific output state using the Pauli path integral simulator.

Example: qc.prob(‘111’) returns the probability of |111>.

Parameters:

target_state – Bitstring like ‘10001001’ (qubit 0 leftmost).

Returns:

dict with ‘probability’, ‘amplitude’, ‘target_state’, ‘time_taken’.

remove_end_measurements(self) → maestro.circuits.QuantumCircuit

Create a new circuit holding shared pointers to the original operations, with terminal measurements removed.

reset(self, qubit: int) → None

Reset a qubit to |0>.

reset_qubits(self, qubits: collections.abc.Sequence[int]) → None

Reset multiple qubits to |0>.

rx(self, arg0: int, arg1: float, /) → None
ry(self, arg0: int, arg1: float, /) → None
rz(self, arg0: int, arg1: float, /) → None
s(self, qubit: int, noiseless: bool = False) → None

Apply an S gate. With noiseless=True, noise models add no gate noise after it (for basis changes of a measurement or reset).

sdg(self, qubit: int, noiseless: bool = False) → None

Apply an S-dagger gate. With noiseless=True, noise models add no gate noise after it (for basis changes of a measurement or reset).

swap(self, arg0: int, arg1: int, /) → None
sx(self, arg: int, /) → None
sxdg(self, arg: int, /) → None
t(self, arg: int, /) → None
tdg(self, arg: int, /) → None
u(self, arg0: int, arg1: float, arg2: float, arg3: float, /) → None
x(self, arg: int, /) → None
y(self, arg: int, /) → None
z(self, arg: int, /) → None