ZNEMitigation#

class qiskit_calculquebec.mitigation.zne.ZNEMitigation(backend, scale_factors: list[float] | None = None, factory=None, scale_noise=None, shots: int = 1024)#

Bases: object

Zero-Noise Extrapolation (ZNE) for MonarQ.

Runs the circuit at several noise scale factors, then extrapolates to the zero-noise limit using the chosen inference factory.

Parameters:
  • backend (MonarQBackend) – Calcul Québec backend.

  • scale_factors (list[float] | None) – Noise scale factors. Default: [1.0, 1.5, 2.0, 2.5, 3.0].

  • factory (mitiq.zne.inference.Factory | None) – Extrapolation method. NoneLinearFactory(scale_factors). Richardson is theoretically more accurate but tends to diverge with 4+ scale factors. Examples: LinearFactory([1,2,3]), RichardsonFactory([1,2,3]), ExpFactory([1,2,3], asymptote=0.5).

  • scale_noise (callable | None) – Noise scaling method. Nonefold_gates_at_random (mitiq default). Alternative: fold_global.

  • shots (int) – Shots per circuit. Default: 1024.

Examples

Default observable — P(|0…0⟩):

>>> zne_mit = ZNEMitigation(backend, scale_factors=[1.0, 2.0, 3.0])
>>> result = zne_mit.run(circuit)
>>> print(f"Raw: {zne_mit.run_unmitigated(circuit):.4f}  Mitigated: {result:.4f}")

Arbitrary Pauli observable:

>>> from mitiq import Observable, PauliString
>>> obs = Observable(PauliString("ZZ", support=[0, 1]))  # <Z0 Z1>
>>> result = zne_mit.run(circuit, observable=obs)

Custom factory:

>>> from mitiq.zne.inference import LinearFactory
>>> from mitiq.zne.scaling import fold_global
>>> zne_mit = ZNEMitigation(
...     backend,
...     factory=LinearFactory([1.0, 1.5, 2.0, 2.5, 3.0]),
...     scale_noise=fold_global,
... )
>>> result = zne_mit.run(circuit)

ZNE combined with REM:

>>> rem = ReadoutMitigation(backend, method='m3')
>>> rem.cals_from_system()
>>> pm = generate_preset_pass_manager(optimization_level=0, backend=backend)
>>> t = pm.run(circuit)
>>> physical_qubits = (
...     [t.layout.final_layout[q] for q in t.qubits]
...     if t.layout and t.layout.final_layout
...     else list(range(circuit.num_qubits))
... )
>>> result = zne_mit.run(circuit, rem=rem, qubits=physical_qubits)

run(circuit[, observable, rem, qubits])

Run the circuit with ZNE and return the mitigated value.

run_scaled(circuit[, observable])

Run the circuit at each scale factor and return the noise curve.

run_unmitigated(circuit[, observable, rem, ...])

Run the circuit without mitigation (scale=1) for baseline comparison.

run(circuit, observable=None, rem=None, qubits=None) float#

Run the circuit with ZNE and return the mitigated value.

Measurements are stripped before passing to mitiq in both modes:

  • observable mode: mitiq adds its own measurements via observable.measure_in().

  • float mode: the executor re-adds measurements via measure_all() if absent.

This also lets mitiq correctly assess circuit length for the short-circuit warning.

Parameters:
  • circuit (QuantumCircuit) – Circuit to execute. Measurements are handled internally by mitiq.

  • observable (mitiq.Observable | None) – Pauli observable to measure. None → P(|0…0⟩). Example: Observable(PauliString("ZZ", support=[0, 1]))

  • rem (ReadoutMitigation | None) – Optional REM correction applied inside the executor.

  • qubits (list[int] | None) – Physical qubits; required when rem is provided.

Returns:

Extrapolated ⟨observable⟩, or P(|0…0⟩) if

observable is None.

Return type:

float

run_scaled(circuit, observable=None) dict[float, float]#

Run the circuit at each scale factor and return the noise curve.

Returns a mapping {scale_factor: expectation_value}. Useful for inspecting the noise curve before extrapolation.

Parameters:
  • circuit (QuantumCircuit) – Circuit to execute.

  • observable (mitiq.Observable | None) – Pauli observable to measure. None → P(|0…0⟩).

Returns:

Scale factor → expectation value at that noise

level.

Return type:

dict[float, float]

run_unmitigated(circuit, observable=None, rem=None, qubits=None) float#

Run the circuit without mitigation (scale=1) for baseline comparison.

Parameters:
  • circuit (QuantumCircuit) – Circuit to execute.

  • observable (mitiq.Observable | None) – Pauli observable to measure. None → P(|0…0⟩).

  • rem (ReadoutMitigation | None) – Optional REM correction applied inside the executor.

  • qubits (list[int] | None) – Physical qubits; required when rem is provided.

Returns:

Raw ⟨observable⟩, or P(|0…0⟩) if observable is None.

Return type:

float