Circuits¶
- class QuantumCircuit(*args, **kwargs)¶
-
- 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)
- 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.
- 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.
- 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>|^2over 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
- 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_qubits(self, qubits: collections.abc.Sequence[int]) None¶
Reset multiple qubits to
|0>.
- 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).