qat.qpus.MPO

class qat.qpus.MPO(hardware_model=None, compression_method: str = 'SVD', truncation_threshold: float = None, bond_dimension: int = None, fidelity: float = None, adaptative_strategy: str = 'naive', maximum_adaptative_bond_dimension: int = 1024, compute_fidelity: bool = False, merge_gate: bool = False, progress_bar: bool = False, qubit_grouping: list = None, disable_resource_management: bool = False, verbose: bool = False, heisenberg_picture: bool = False, nnizer_kwargs: dict | None = None, seed: int | None = None, **kwargs)

Matrix Product Operator simulator QPU for noisy quantum circuits.

Three computation modes exist:

  • Fixed bond dimension mode: Setting a bond_dimension will compute the MPO and truncate any bond dimension above given bond_dimension value.

  • Truncation threshold mode: The bond dimension is set by discarding the singular values smaller than the truncation threshold.

  • Adaptative bond dimension mode: Setting a fidelity will ensure the final quantum state reaches a minima this fidelity value. The algorithm will adapt dynamically the bond dimension used throughout the calculation to ensure optimal bond dimension sizes and minimal error. The fidelity set at the start is guaranteed. (Priority is given to this mode over the trunctation threshold mode if both are set).

Notes

  • MPO are well adapted to circuits with a 1D topology, but any circuit is supported. The NNizer plugin will be called automatically to transform any circuit into 1D topology.

  • If bond_dimension and fidelity are set to None, the algorithm will not truncate any bond dimension, and the simulation will be exact.

Parameters:
  • hardware_model (HardwareModel, optional) – A hardware model. If unset, uses the noiseless :class:’~qat.hardware.DefaultHardwareModel’.

  • compression_method (str, optional) – The method of truncation to use. For now only one is available: - “SVD”: Truncation method based on SVD truncations.

  • bond_dimension (int, optional) – The maximum bond dimension size allowed throughout the tensor network simulation.

  • truncation_threshold (float, optional) – The truncation threshold when discarding singular values. In the Heisenberg picture, the default value is 1e-14, and None otherwise.

  • fidelity (float, optional) – Required precision for the truncation of the density matrix. If set to None, no precision goal will be set for each truncation. If set to a value, the set bond dimension will be allowed to increase to reach this specific truncation fidelity.

  • adaptative_strategy (str, optional) –

    Strategy to adopt when selecting the target truncation fidelity of each quantum gate. The list of strategy includes:

    • ”naive”: The fidelity goal is defined at the start of the simulation and is not dynamically updated.

    • ”nearest”: The fidelity goal is updated from neighbour to neighbour. The first truncation fidelity computed updates the next nearest target truncation fidelity, while enforcing a total simulation fidelity higher than set input fidelity goal.

    • ”global”: The fidelity is updated globally. Every computed truncation fidelity updates every remaining target truncation fidelity.

  • maximum_adaptative_bond_dimension (int, optional) – Maximum bond dimension the adaptative truncation scheme is allowed to reach. Falls back to maximum bond dimension truncation scheme if exceeded. In that case, the input fidelity is not guaranteed.

  • compute_fidelity (bool, optional) – If True, each truncation fidelity will be stored for each truncation and each qubit, and added to the Result metadata.

  • merge_gate (bool, optional) – In some cases, the noise is added to noiseless gates by adding a noise gate just after it in the circuit. This is seen within the truncation algorithm as another gate, leading to truncation. To avoid truncating such gates, the merge_gate flag can be set to True. This prevents the truncation of every second gates being applied. Note that if a limit bond_dimension is set, the maximum bond dimension reached will be bond_dimension * 4.

  • progress_bar (bool, optional) – If a progress bar should be displayed during the circuit simulation.

  • qubit_grouping (List[int], optional) – grouping of the qubits. E.g (4, 5, 2) for 3 groups with a total of 4+5+2=11 qubits. Defaults to None: no grouping, i.e (1, 1, …) (nqbits 1’s)

  • disable_resource_management (bool, optional) – If True, disable the resource management and set no limit on how much memory the QPU can use.

  • heisenberg_picture (bool, optional) – If True, computing the expectation value of an observable is done is the Heisenberg picture, meaning that the circuit is contracted from the observable instead of the initial state. Only if the job contains an :class:’~qat.core.Observable’

  • nnizer_kwargs (dict, optional) – Dictionary of arguments to pass to the Nnizer plugin. Defaults to None. Refer to the Nnizer plugin documentation for more information.

  • seed (int, optional) – random number generator seed. Used in sampling mode with finite number of shots.

Mathematical description

Any mixed state can be described by a density matrix \(\hat{\rho}\):

\[\hat{\rho} = \sum_{\substack{\sigma, \sigma'}}C_{\sigma_{1}\sigma'_{1},...,\sigma_{N}\sigma'_{N}}|{\sigma_1}\rangle\langle{\sigma'_1}|\otimes...\otimes|{\sigma_N}\rangle\langle{\sigma'_N}|\]

with \(C_{\sigma_{1}\sigma'_{1},...,\sigma_{N}\sigma'_{N}}\) a 2D tensor containing \(2^N \times 2^N\) complex values and \(\{|\sigma_i\rangle\}\) forming an orthonormal basis.

\(\hat{\rho}\) can be cast into an matrix product operator [Schollwoeck2010], via successive SVD decompositions:

\[\hat{\rho} = \sum_{\chi_1...\chi_N} A^{[1]\sigma_1, \sigma'_1}_{1, \chi_1} A^{[2] \sigma_2, \sigma'_2}_{\chi_1, \chi_{2}} ...A^{[N] \sigma_N, \sigma'_N}_{\chi_{N-1}, 1}|{\sigma_1}\rangle\langle{\sigma'_1}|\otimes...\otimes|{\sigma_N}\rangle\langle{\sigma'_N}|\]

We obtain a product of \(N\) complex-valued tensors \(\{A^{[i]\sigma_i}\}\), separated by bond dimensions \(\{\chi_1, \chi_2, ..., \chi_{N-1}\}\). Assuming the \(\chi\) are bounded by a maximum bond dimension \(\chi_{max}\), the number of values contained in the MPO scales in \(\mathcal{O}(N^2\chi_{max}^3)\) with \(N\) the number of qubits of the system.

Essentially, applying operators (the quantum gates) increases bond dimensions throughout the simulation, and truncating these bond dimensions allows us to approximate the state. For more informations on the two truncation modes we provide, please refer to our user guide on MPO.

In sample mode with a finite number of shots, samples are obtained efficiently using the OPES algorithm [Ballarin2024].

The MPO simulator can also be used to the compute expectation value of an observable \(O\) in the Heisenberg picture. Unlike the conventional Schrödinger picture, where the initial state is evolved forward in time by applying gates directly to the state, here the process is reversed: the observable is evolved backward in time through a circuit \(U\) (with or without noise) by computing \(U^\dagger O U\) and then projected onto the initial state. This contraction approach can be beneficial for simulating quantum circuits with a larger number of qubits, especially when the qubit topology is not restricted to one dimension, when circuits are close to Clifford circuits, or when circuit depths permit light-cone structures.

Accepts circuits of any connectivity. The plugin qat.plugins.Nnizer is used to map the circuit onto a linear nearest neighbour (LNN) topology automatically, while respecting the correct noise model.