Skip to main contentIBM Quantum Documentation Preview

Tensor-network error mitigation (TEM): A Qiskit Function by Algorithmiq


Overview

The Tensor-network error mitigation (TEM) function computes expectation values of quantum circuits and observables by post-processing noise-induced errors in estimations of physical observables.

The method consists of constructing a tensor network representing the inverse of the global noise channel affecting the state of the quantum processor, and then applying the map to informationally complete measurement outcomes obtained from the noisy state.

As an advantage, TEM leverages informationally complete measurements to give access to a vast set of mitigated expectation values of observables and has optimal sampling overhead on the quantum hardware [1]. TEM can also be advantageous with respect to purely classical tensor network methods, giving accurate results with a smaller computational cost than a classical-only tensor network approach.

See reference [1] for further details.

References

  1. S. Filippov, M. Leahy, M. A. C. Rossi, G. García-Pérez, Scalable tensor-network error mitigation for near-term quantum computing, arXiv:1111.6950 [quant-ph]

Function description

The TEM function takes a noisy circuit with the noisy layers identified. The circuit is measured with an informationally complete positive operator-valued measure (IC-POVM), and the collected measurement outcomes are processed on a classical computer. This measurement is used to perform the tensor network methods and build a noise-inversion map N1\mathcal{N}^{-1}. The function applies a map M\mathcal{M} that fully inverts the whole noisy circuit using matrix product operators to represent the noisy layers.

TEM schematics
Error-mitigated estimation of an observable O via post-processing measurement outcomes of the noisy quantum processor. U and N denote an ideal quantum operation and the associated noise map, which can be generally non-local (and extended to grey boxes). D stands for a tensor of operators that are dual to the effects in the IC measurement. The noise mitigation module M is a tensor network that is efficiently contracted from the middle out. The first iteration of the contraction is represented by the dotted purple line, the second one by the dashed line, and the third one by the solid line.

To mitigate the noise, the algorithm performs a contraction that starts from the middle (where the inverted noisy circuit ends and the ideal circuit starts) and propagates outward by involving two layers on the left side and one layer on the right side at each iteration. Therefore, the noisy circuit output state ρ\rho is reverted back to (00)N(\vert 0 \rangle\langle0\vert)^{\otimes N}, which in turn is mapped to the ideal noiseless state operator ψψ\vert\psi\rangle\langle \psi\vert.

The noise-mitigated estimation of an observable O{O} is then read as

Oˉn.m=1Sktr[M(Dk)O]=1Sktr[DkM(O)],\bar{O}_{\text{n}.\text{m}} = \frac{1}{S} \sum_{\mathbf{k}} \text{tr} [\mathcal{M}(D_{\mathbf{k}})O] = \frac{1}{S} \sum_{\mathbf{k}} \text{tr} [D_{\mathbf{k}}\mathcal{M}^{\dagger}(O)],

where DkD\mathbf{k} is the dual operator of the corresponding POVM associated with a measurement shot k\mathbf{k} in a set of SS shots.

The algorithm is described in further detail in Filippov et al. (2023).

Methods

run

run(pubs,options)

The run() method allows computing the expectation values for a primitive unified bloc (PUB) containing a circuit and a list of observables.

Parameters

NameTypeDescriptionRequiredExample
pubsIterable[EstimatorPubLike]An iterable of PUB-like (primitive unified bloc) objects, such as tuples (circuit, observables) or (circuit, observables, parameter_values). See Overview of PUBs for more information. The circuits don’t need to be ISA circuits.Yes(circuit, observables, parameter_values)
instancestrThe hub/group/project to use in that format.No"hub1/group1/project1"
optionsdictInput options. See Options section for more details.No{"optimization_level": 3}

Options

A dictionary containing the options for the TEM. The dictionary should contain the following keys:

NameTypeDescriptionExample
backend_namestrName of the backend to make the query."ibm_fez"
simulate_with_noise_modelboolA Boolean flag indicating whether to simulate the noisy circuit or not.False
max_bond_dimensionintThe maximum bond dimension to be used for MPOs.True
tem_compression_cutofffloatThe cutoff value to be used for MPOs.1e-16
num_max_shotsintThe maximum number of shots.10_000
num_randomizationsintThe number of randomizations to be used for gate twirling.32
mitigate_readout_errorboolA Boolean flag indicating whether to perform QDT readout error mitigation or not.24
num_readout_calibration_shotsintThe number of shots to be used for QDT readout error mitigation.1000
logging_levelstrThe logging level to be used for the TEM runner."INFO"

Returns

A PubResult containing the TEM mitigated result:

NameTypeDescription
dataDataBinA DataBin containing the TEM mitigated observable and its standard error. The DataBin has the following fields:
  • observable: The TEM mitigated observable value.
  • observable_stderr: The standard error of the TEM mitigated observable.
metadadatadictA dictionary containing additional results. The dictionary contains the following keys:
  • "observable_non_mitigated": The observable value without error mitigation.
  • "observable_non_mitigated_stderr": The standard error of the result without error mitigation.
  • "observable_simulated": If its computation is enabled in the TEM options, contains the result obtained by simulating the circuit with the learned noise.

Get started

Authenticate using your IBM Quantum™ Platform API token, and select the TEM as follows:

[1] :
from qiskit_ibm_catalog import QiskitFunctionsCatalog
 
tem_function_name = "algorithmiq/tem"
catalog = QiskitFunctionsCatalog(token = "<YOUR_IQP_API_TOKEN>")
 
# Load your function
tem = catalog.load(tem_function_name)

Example

The following snippet shows an example where TEM is used to compute the expectation values of an observable given a simple quantum circuit.

[7] :
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit_ibm_runtime import QiskitRuntimeService
 
# Create a quantum circuit
qc = QuantumCircuit(3)
qc.u(0.4, 0.9, -0.3, 0)
qc.u(-0.4, 0.2, 1.3, 1)
qc.u(-1.2, -1.2, 0.3, 2)
for _ in range(2):
    qc.barrier()
    qc.cx(0, 1)
    qc.cx(2, 1)
    qc.barrier()
    qc.u(0.4, 0.9, -0.3, 0)
    qc.u(-0.4, 0.2, 1.3, 1)
    qc.u(-1.2, -1.2, 0.3, 2)
 
# Define the observables
observable = SparsePauliOp("YXZ", 1.0)
 
# Define the execution options
service = QiskitRuntimeService()
backend_name = service.least_busy(operational=True).name
instance = "<IQP_HUB/IQP_GROUP/IQP_PROJECT>"
 
pub = (qc, observable)
options = {
    "backend_name": backend_name,
    "num_max_shots": 100,
}
job = tem.run(instance=instance, pub=pub, options=options)

The following code checks your Qiskit Function workload's status or return results:

[ ] :
print(job.status())
result = job.result()

Advanced options

You can fine-tune your calculations and get more verbose information by passing additional options to TEM.

[7] :
import logging
 
options = {
        "backend_name": backend_name,
        "num_max_shots": 1_000,
        "simulate_with_noise_model": True,
        "mitigate_readout_error": True,
        "num_readout_calibration_shots": 10_000,
        "logging_level": logging.WARNING
    }
 
 
job = tem.run(instance = instance, pub = pub, options = options)

Get support

Reach out to qiskit_ibm@algorithmiq.fi

Be sure to include the following information:

  • Qiskit Function Job ID (qiskit-ibm-catalog), job.job_id
  • A detailed description of the issue
  • Any relevant error messages or codes
  • Steps to reproduce the issue

Next steps