Propagated Noise Absorption (qiskit_addon_pna)¶
Primary propagated noise absortption (PNA) functionality.
- generate_noise_mitigating_observable(noisy_circuit, observable, refs_to_noise_model_map=None, *, max_err_terms, max_obs_terms, search_step=4, num_processes=1, print_progress=False, atol=1e-08, batch_size=1, inject_noise_before=True, mp_start_method='spawn')[source]¶
Generate a noise-mitigating observable by propagating it through the inverse of a learned noise channel.
Note
This function uses the Python
multiprocessingmodule for parallel execution. This function should be called from within anif __name__ == "__main__"guard to prevent unintended process spawning.Starting from the beginning of the circuit, the noise affecting each entangling layer is inverted and each Pauli anti-noise generator is then propagated forward through the remainder of the circuit and applied to the observable. The propagation routines used to implement this method are available in the pauli-prop package.
As each anti-noise generator is propagated forward through the circuit under the action of \(N\) Pauli rotation gates of an $M$-qubit circuit, the number of terms will grow as \(O(2^N)\) towards a maximum of \(4^M\) unique Pauli components. To control the computational cost, terms with small coefficients must be truncated, which will result in some error in the evolved anti-noise channel.
In addition to the truncation of the evolved anti-noise channel, \(\Lambda^{-1}\), \(\tilde{O}\) is also truncated as it is propagated through \(\Lambda^{-1}\). This is also a source of bias in the final mitigated expectation value.
While letting \(\tilde{O}\) grow larger during propagation will increase its accuracy, measuring it requires taking many more shots on the QPU. Typically this increases the coefficients of the original Pauli terms in \(O\), along with creating many new Pauli terms with smaller coefficients. Both the rescaling of the original coefficients and the creation of new terms can increase sampling overhead. In practice, we truncate once more by measuring only the largest terms in \(\tilde{O}\).
- Parameters:
noisy_circuit (QuantumCircuit) –
A circuit with associated Pauli-Lindblad gate noise.
If this circuit is boxed, there are expected to be
InjectNoiseannotations associated with each box for which gate noise should be mitigated. Additionally, therefs_to_noise_model_mapshould provide a mapping from the reference ID of eachInjectNoiseannotation to the associated noise model for that layer, specified as aPauliLindbladMap.If this circuit is not boxed, the noise model is expected to be embedded as
PauliLindbladErrorinstructions adjacent to each circuit layer for which gate noise should be mitigated. In this case,refs_to_noise_model_mapmay be None.observable (SparsePauliOp | Pauli) – The observable which will absorb the anti-noise.
refs_to_noise_model_map (dict[str, PauliLindbladMap] | None) – A dictionary mapping noise injection referencs IDs to their corresponding noise models as
PauliLindbladMap. Ifnoisy_circuitis not boxed and containsPauliLindbladErrorinstructions from qiskit-aer, this mapping is not needed.max_err_terms (int) – The maximum number of terms each anti-noise generator may contain as it evolves through the circuit
max_obs_terms (int) – The maximum number of terms the noise-mitigating observable may contain
search_step (int) – A parameter that can speed up the approximate application of each error to the observable. The relevant subroutine searches a very large 3D space to identify the
max_obs_termslargest terms in a product. Setting this step size >1 accelerates that search by a factor ofsearch_step**3, at a potential cost in accuracy. This inaccuracy is expected to be small forsearch_step**3 << max_obs_terms.num_processes (int) – The number of processes for parallelization. These may be used for forward evolution of generators, and for applying evolved generators to the observable. If
batch_sizeis1(default), all are used for evolving generators. Otherwise,max(min(batch_size, num_processes // 2), 1)of these will be allocated for applying evolved generators to the observable.print_progress (bool) – Whether to print progress to stdout
atol (float) – Terms below this threshold will not be added to operators as they evolve
batch_size (int) – Setting this to a value > 1 allows batches of noise generators to be applied to the observable in parallel. This coarse-grain application of anti-noise to the observable comes at a loss of accuracy related to the probability that more than one error in the batch occurs when the circuit is run. This should usually not be set higher than
max(1, num_processes // 2).inject_noise_before (bool) – If
True, the Pauli Lindblad noise instruction will be inserted before its corresponding 2q-gate layer. Otherwise, it will be inserted after it, defaults toTrue.mp_start_method (str | None) – The method to use when starting new parallel processes. Valid values are
fork,spawn,forkserver, andNone. IfNone, the default method will be used.
- Returns:
The noise-mitigating observable
- Raises:
ValueError – The circuit and observable have mismatching sizes
ValueError – num_processes and batch_size must be >= 1
ValueError –
max_obs_termsshould be larger than the length ofobservableValueError – Incompatible noisy circuit and refs_to_noise_model_map
ValueError – The observable must only contain real-valued coefficients
- Return type: