HQS Qorrelator App User Guide

The HQS Qorrelator App is designed to provide users with a simple tool to perform the calculation of correlation functions on a quantum computer. Correlation functions are important for many areas of physics and chemistry. One of the most commercially important aspects is that correlation functions can be used to calculate response spectra. Specifically, correlation functions of two spin operators, with respect to the Hamiltonian of the nuclear material, can be used to obtain the NMR spectral function. Due to the enormous practical relevance of NMR spectra, the first version of the HQS Qorrelator App focuses on providing ways to obtain the NMR correlation functions on a quantum computer.

In the near future, all available quantum computers will be NISQ quantum computers, where the qubits of the quantum computer experience environmental noise. In most applications, environmental noise is purely a source of errors. At HQS, we have realised that, for certain applications, environmental noise is not detrimental and can even be used as an computational resource.

The HQS Qorrelator App also incorporates these approaches in an user-friendly manner, by providing an easy way to obtain an estimate of the spectral broadening due to the effective time evolution that occurs on a noisy quantum computer.

Fundamental Physical concepts

Background

In this chapter we provide background knowledge on the basics of nuclear magnetic resonance (NMR) from experimental and theoretical perspectives. We also describe the maths behind the calculation of spectra in the HQS Qorrelator App. Lastly, we explain how quantum computers can be used to calculate NMR spectra.

Noise models

We consider physical noise, meaning noise on the hardware-level, that is caused by qubits coupling to some fluctuating environment, either during control operations, or at all times. This is assumed to cause damping, dephasing, and/or depolarization of their quantum states. Our model of a noisy quantum computer is based on adding corresponding non-unitary (noise) operations after or before (ideal) unitary gate operations. This model is described in detail on page modeling.

Noise mapping

The HQS Qorrelator App allows the user to investigate how noise affects the calculation of correlation functions to obtain NMR spectra. Particularly, it derives the Lindblad open-system model that the noisy quantum simulator is effectively implementing in the time propagation that is part of the calculation of the correlation function. Foundations of this mapping (between physical and simulated noise) are discussed on page mapping or in more detail in this arxiv paper.

Using the program

On the interface page, we go through the Python interface of the HQS Qorrelator App package and discuss how to construct quantum programs that will calculate correlations, how to get an estimated broadening based on the noise in a device and how to extract the noisy algorithm model.

API Documentations

Changelog

For a changelog starting from version 0.2 please see here.

Background

This chapter provides an overview of the fundamentals behind the HQS Qorrelator App.

In the first section, NMR, we describe the basics of nuclear magnetic resonance (NMR) from both experimental and theoretical perspectives. We discuss, for example, the different relevant parameters entering an NMR calculation, such as the chemical shifts and the couplings between nuclear spins, and introduce the relevant Hamiltonian of a molecule for NMR.

In maths, we describe in greater detail the mathematics behind the calculation of spectra in the HQS Qorrelator App.

The last section, Quantum Computing, explains how quantum computers can be used to calculate NMR spectra. We analyze the relevant algorithms and discuss the influence of noise on spectrum calculations on quantum computers.

NMR

Nuclear magnetic resonance (NMR) spectroscopy is one of the most important analytical techniques in chemistry and related fields. It is widely used to identify molecules, as well as to obtain information about their structure, dynamics, and chemical environment. Some fundamental aspects of NMR are summarized below.

NMR spectrometers place the sample into a strong, but constant, magnetic field and use a weak, oscillating magnetic field to perturb the nuclei. At or near resonance, when the oscillation frequency matches the intrinsic frequency of a nucleus, the system responds by producing an electromagnetic signal with a frequency characteristic of the magnetic field at the respective nucleus.

Zeeman interaction

For the simulation of NMR spectra for molecules, a crucial component is the Zeeman effect, which describes the interaction of the nuclear spin with the external magnetic field \(\mathbf{B}\). The corresponding Hamiltonian can be written as

\[ \hat{H}_{\text{Z}} = - \gamma \mathbf{B} \cdot \hat{\mathbf{S}} , \]

where \(\gamma\) is the gyromagnetic ratio, the ratio of a system's magnetic moment to its angular momentum, and \(\hat{\mathbf{S}} = (\hat{S}^x, \hat{S}^y, \hat{S}^z)^{\text{T}}\) is the total spin operator. Assuming that the strong (and constant) magnetic field is in the \(z\)-direction only, meaning \(\mathbf{B} = (0, 0, B^z)\), the Hamiltonian simplifies to

\[ \hat{H}_{\text{Z}} = - \gamma B^z \hat{S}^z = \omega_0 \hat{S}^z , \]

where \(\omega_0 = - \gamma B^z\) is the so-called Larmor frequency, the angular frequency corresponding to the precession of the spin magnetization around the magnetic field at the position of the nucleus.

As an example, consider the simplest nucleus, \(^1\)H, consisting of only one proton, for which the gyromagnetic ratio is \(\gamma/ 2\pi = 42.6\) MHz T\(^{-1}\), meaning that a 500 MHz NMR spectrometer has a static magnetic field of about 11.7 Tesla. The energy of radiation of the Larmor frequency \(\omega_0 = 2 \pi \cdot \nu = 2 \pi \cdot 500\) MHz (\(h\nu \approx 3.3 \cdot 10^{-25}\) J) is several orders of magnitude smaller than the average thermal energy of a molecule at a temperature of \(T = 298\) K (\(k_{\text{B}} T \approx 4.1 \cdot 10^{-21}\) J). Therefore, the occupations of the spin states are almost equal at room temperature, and only a small surplus is responsible for the sample magnetization.

Chemical shift

Perhaps the most important aspect of NMR spectroscopy in chemistry is that the nuclei in molecules are shielded against the external magnetic field by the electrons surrounding them. This can be expressed by adding a correction term to the Hamiltonian as

\[ \hat{H}_{\text{Z}} = - \gamma ({1} - \boldsymbol{\sigma}) \mathbf{B} \cdot \hat{\mathbf{S}} , \]

where \(\boldsymbol{\sigma}\) is referred to as the shielding tensor, quantifying the change in the local magnetic field experienced by the nucleus in the molecule, relative to a bare nucleus in vacuum. However, if the molecules of interest are in solution, or in liquid phase in general, they can rotate freely and only the isotropic chemical shift \(\sigma = \frac13 \text{Tr}(\boldsymbol{\sigma})\) is of interest,

\[ \hat{H}_{\text{Z}} = - \gamma (1 - \sigma) B^z \hat{S}^z . \]

In practice, chemical shifts are normally used instead of chemical shieldings: instead of invoking the Larmor frequency of a nucleus in a vacuum, shifts are defined with respect to the resonance frequency \(\nu_{\text{ref}}\) of a reference compound:

\[ \delta = \frac{\nu - \nu_{\text{ref}}}{\nu_{\text{ref}}} \approx \sigma_\text{ref} - \sigma . \]

The standard reference for \(^{1}\)H-NMR is the Larmor frequency of the protons in TMS [tetramethylsilane, Si(CH\({_3}\))\({_4}\)]. Chemical shifts are normally reported on a scale of ppm (parts per million): most \(^{1}\)H chemical shifts are observed in the range between 0 and 10 ppm, and most \(^{13}\)C chemical shifts between 0 and 200 ppm. Since the scale of chemical shieldings is so small in absolute terms \(\left( |\sigma| \ll 1 \right)\), for practical intents and purposes the chemical shift can be substituted directly into the Hamiltonian:

\[ \hat{H}_{\text{Z}} = - \gamma (1 + \delta) B^z \hat{S}^z . \]

Spin-spin coupling

Up to this point, the nuclear spins have been regarded to be isolated from each other. However, their magnetic moments have an effect on neighboring spins. The interaction between the nuclear spins can happen through two different mechanisms. The first one is the direct (or through space) spin-spin coupling, where the interaction strength depends on the distance of the two nuclei and the angle of their distance vector relative to the external field. As it comes from the direct interaction of two magnetic dipoles, it is also referred to as the dipolar coupling. However, the effect is generally not observable in liquid phase since the free rotation of the molecules averages over all orientations and thus results in a vanishing average coupling.

An effect observable in the NMR spectrum is indirect spin-spin coupling, which is mediated by the electrons of a chemical bond. Due to the Pauli principle, the electrons of a covalent bond always have an anti-parallel spin orientation, and one electron will be closer to one nucleus than to the other, preferring an anti-parallel orientation with the nearby nucleus. Depending on the number of electrons involved in the transmission of the interaction, either a parallel or an anti-parallel orientation of two nuclei may result in a lower energy. Importantly, this interaction does not average out in solution since it mainly depends on the electron density at the position of the nucleus and not on the orientation of the distance vector relative to the field, which is why it is also referred to as the scalar coupling. Since only s-orbitals have a finite electron density at the nucleus, the coupling depends on the electron density in those orbitals alone.

The interaction Hamiltonian in the case of homonuclear coupling is given by

\[ \hat{H}_J = 2\pi J \hat{\mathbf{I}}_1 \cdot \hat{\mathbf{S}}_2 \]

where \(\hat{\mathbf{I}} = \hbar^{-1} \hat{\mathbf{S}}\). In heteronuclear coupling, where the difference in Larmor frequencies is much larger in magnitude than the corresponding coupling constant (i.e. \(|\omega_1 - \omega_2| \gg | J |\)), the Hamiltonian can be written in terms of the \(z\)-components only,

\[ \hat{H}_J = 2\pi J \hat{I}_1^{z} \hat{S}_2^{z} , \]

It should be noted that the \(\mathbf{J}\)-coupling tensor is a real \(3 \times 3\) matrix that depends on the molecular orientation, but in liquid phase only its isotropic part \(J\) is observed due to motional averaging. Typical \(J\)-coupling strengths between protons in \(^{1}\)H-NMR amount to a few Hz.

NMR spin Hamiltonian for molecules in a liquid phase

The spin Hamiltonian in a static magnetic field in frequency units (rad s\(^{-1}\)) is given by

\[ \hbar^{-1} \hat{H} = - \sum_k \gamma_k (1 + \delta_k) B_0 \hat{\mathbf{I}}^z_k + 2\pi \sum_{k<l} J_{kl} \hat{\mathbf{I}}_k \cdot \hat{\mathbf{I}}_l
\]

where the sum runs over all nuclear spins of interest.

There are several interactions that have not been taken into account here. As already mentioned, the direct dipolar spin-spin interaction vanishes in liquids due to motional averaging. Interactions beyond dipolar coupling, e.g. quadrupolar interactions, are relevant only for nuclei with spin quantum number \(I \ge 1\). Furthermore, interactions with unpaired electrons need special treatment as well. While most organic compounds are diamagnetic (closed-shell), paramagnetic NMR also exists.

Mathematics

The hamiltonian \(\hat{H}\) we use for NMR systems is of the form

\[ \begin{align} \hat{H} &= -\sum_\ell \gamma_\ell B^z \left( 1 + \delta_\ell\right) \hat{I}^z_\ell + 2 \pi\sum_{k < l} J_{kl} \mathbf{\hat I}_k \cdot \mathbf{\hat I}_l \end{align} \]

with gyromagnetic factors \(\gamma_\ell\), chemical shifts \(\delta_\ell\) of nuclear spin \(\ell\), coupling between spins \(k\) and \(l\) denoted as \(J_{kl}\), and \(\hat{I}^\alpha = \hat{S}^\alpha / \hbar\), with \(\hat{S}^\alpha\) being the usual \(su(2)\) spin operators.

Within NMR, we have a strong magnetic field \(B_z\) in the \(z\)-direction, and electromagnetic pulses / oscillating fields are applied to flip the spins into the \(x/y\) plane. Since typically \(B_z\) is of the order of 500Mhz, the pulses of 10kHz bandwidth, and the required resolution is sub 1Hz, we refrain from modeling the explicit time dependence of the pulses. Instead, we model the pulses directly by calculating the spectral function, i.e., time-dependent correlations between the corresponding \(\hat{M}^\pm\) operators.

The spectrum measured in an NMR experiment corresponds to the spectral function, which is the Fourier transform of the correlation function of the operators \(\hat{M}^\pm\), calculated by the quantum program created by the HQS Qorrelator App.

Calculation of the spectral function

The spectral function of the NMR problem is given by the Fourier transform

\[ \begin{align} \\ \cal{G}(\omega) &= \mathcal{FT} G(t) \\ G(t) &= -i \langle \hat{M}^-(t) \hat{M}^+(0) \rangle \\ \hat{I}^\pm &= \hat{I}^x \pm i \hat{I}^y \\ \hat{M}^\alpha &= \sum_\ell \gamma_\ell \hat{I}^\alpha_\ell \end{align} \]

where the \(\hat{M}^\alpha\) operators, \(\alpha \in {x, y, z, +, -}\), contain the gyromagnetic factors for convenience, and \(t\) is the real time dependence.

The contribution of an individual nuclear spin \(\ell\) to the full NMR spectrum is obtained via

\[ \begin{align} G_\ell(t) &= -i \langle \gamma_\ell \hat{I}_\ell^-(t) \hat{M}^+(0) \rangle, \end{align} \]

while the full NMR signal is the sum of individual contributions.

Quantum computing

This section assumes the reader is already familiar with the relation of the NMR response function to the correlator of spin operators. Otherwise, we recommend reading the NMR and Maths chapters first.

The use of quantum computers to measure time-resolved correlation functions is well established, for example to measure the Green's function with respect to a ground state prepared on a quantum computer (see for example Wecker et. al, doi:10.1103/PhysRevA.92.062318). This use case typically assumes an ideal quantum computer. The correlator is measured with respect to a pure state and all noise present in the system is a source of error.

In calculating NMR response functions, we do not aim for a quantum computer operating on pure states. We are in fact aiming for the infinite-temperature limit, where we start from a fully-mixed-state density matrix and run the correlation measurement in the presence of noise.

While the traditional way to measure correlators (Wecker et. al) would still be applicable, the infinite-temperature initial state allows us to further simplify the algorithm and eliminate the need for an additional ancilla qubit.

Quantum algorithm

We only describe the simplified algorithm for the infinite-temperature case in detail. For a detailed discussion of the standard correlation measurement we refer the reader to the literature.

Time evolution

To measure a correlation function in the time domain for a time difference \(t\), it is necessary to propagate the density matrix prepared on the quantum computer for a virtual time \(t\) (not to be confused with the time that passes in the laboratory frame of reference \(\tau\)).

The time propagation is handled with a standard Trotterization approach. The Hamiltonian of our NMR system can be written as a sum of partial Hamiltonians \[ \hat H = \sum_k \hat H_k \] and the time propagation under a partial Hamiltonian can be implemented on the quantum computer directly \[ \hat U_k(t) = e^{- \textrm{i} \hat H_k t} \ . \] For an NMR system, \(\hat H_k\) correspond to the onsite energy terms (Zeeman Hamiltonian) or the sum of all interaction terms between a specific pair of spins.

The time evolution under the full Hamiltonian can then be approximated as \[ e^{-\textrm{i} \hat H t} \approx \prod_{\alpha=1}^{M} \prod_{k} \hat U_k\left(\frac{t}{M}\right) \ , \] where the approximation is well controlled if \(M\) is sufficiently large.

The main difference in the methods provided by the HQS Software are

  • How each \(\hat U_k(t) \) is implemented in quantum gates.
  • How the necessary swapping of qubits between \( \hat U_k(t) \) is implemented.

The HQS software provides three optional algorithms:

  • QSWAP - The \(\hat U_k(t) \) involving two spins are implemented as gates that also swap the position of the two qubits
  • ParityBased - The \(\hat U_k(t) \) involving two spins are implemented without swapping two spins with the help of two CNOT operations

QSWAP

The QSWAP algorithm is the algorithm used by default. It implements every two-spin time propagation \(\hat U_k(t)\) with a so-called Qsim gate between neighbouring qubits (e.g. between \(0\) and \(1\) or \(2\) and \(3\) etc.). A Qsim gate applies the time evolution under a two-spin Hamiltonian \[ \hat H = J_x \hat S^x_j \hat S^x_{j+1} + J_y \hat S^y_j \hat S^y_{j+1} + J_z \hat S^z_j \hat S^z_{j+1} \] and also swaps the information content between the two involved qubits. Due to the repeated application of Qsim gates, the spins of NMR are swapped through the qubits in the quantum computer. At different stages of the algorithm, the same qubit can represent different spins. This "swap network" (for a Fermionic variant see Kivlichan et. al) also takes care of qubit routing. In many quantum computing devices, the number of other qubits a qubit can interact with is limited. For example, only next-neighbour interactions in 1D or 2D might be possible. For devices with at least 1D next-neighbour connectivity (meaning qubit \(0\) can interact with qubit \(1\), \(1\) with \(2\) and so on) the QSWAP algorithm already introduces all necessary SWAPS so that all gates in the produced quantum circuit can be applied without inserting additional SWAPS.

The QSWAP algorithm produces a Trotterization circuit with depth \(\mathcal{O}(N)\) and number of qubits \(\mathcal{O}(N^2)\), where N is the number of spins in the system.

Parity-Based

The parity-based algorithm directly implements the interaction between two qubits by applying a basis rotation, constructing the overall parity of the two qubits in one of the two qubits, and applying a single qubit rotation. For example, to implement an XX interaction, we can use the circuit

CNOT implementation of XX interaction

The Hadamard gates H rotate the qubits into the X basis, the CNOT prepares the parity and the \(\textrm{R}_z\) gate propagates under the XX interaction for time \(t\).

The parity-based algorithm does not introduce a reordering of spins on the qubits of the device. In general, on devices with a limited connectivity, additional SWAP gates need to be introduced to be able to run a circuit implementing the parity-based algorithm.

In the general case, the parity-based algorithm will lead to a larger gate count than a QSWAP algorithm. However, for devices with all-to-all connectivity (where each qubit can interact with every other qubit), inserting additional SWAP operations is not necessary. For those devices, the number of gates in the parity-based algorithm scales linearly with the number of XX, YY and ZZ operations in the Hamiltonian of interest.

State initialisation

We want to measure correlators \(\langle A(t)B \rangle\) with respect to the infinite-temperature state, represented by the maximally-mixed density matrix

\[ \hat \rho_0 = \frac{1}{2^N} \hat 1 . \]

There are different ways to achieve this goal.

The default way to achieve this measurement in the HQS Qorrelator App is to use a sum over all initial states (reducing the number of initial states by using a spin symmetry). This measures the infinite temperature operator by running the correlation measurement over all possible initial eigenstates of the \( B \) operator. With this option, the number of circuits and measurements scales exponentially with the number of qubits. It has, however, the least requirements for the quantum computer. Other measurement methods (referred to initialisations of the infinite-temperature state) can require active reset or mid circuit measurement operations.

The other initialisations that are available in the HQS Qorrelator App are:

  • ActiveReset: Uses an initialisation that prepares the infinite-temperature state by dephasing after applying Hadamard gates. Assumes the \( B \) operator only acts on one qubit. Actively resets the qubit the \( B \) operator is acting on and adds two measurement circuits:

    • One where the qubit is set to 0 and the output of a virtual qubit is set to zero
    • One where the qubit is set to 1 and the output of a virtual qubit is set to zero

    This avoids measuring inside the circuit which is more efficient. This can only be applied when the \( B \) operator is a sum of local operators and the number of measurements is comparable to the dimension of the Hilbert space of the system. The sequence is: Hadamard on all qubits -> ActiveReset on qubit -> Two Circuits: One where qubit is 0 one where qubit is 1 -> Rotate back from \( B \) basis.

  • NonCorrelatingMeasurement: Uses an initialisation that prepares the infinite-temperature state by applying Hadamard gates and using the measurement that is normally necessary to extract the correlator with the \( B \) correlation operator. This can only be applied when the \( B \) operator is a sum of local operators and the number of measurements is comparable to the dimension of the Hilbert space of the system. The sequence is: Hadamard on all qubits -> Measure -> Rotate back from \( B \) basis. It is recommended to only use this on an experimental basis.

  • GeneralMeasurement: Uses an initialisation that prepares the infinite-temperature state by measuring after a Hadamard gate. This can only be applied when the number of measurements is comparable to the dimension of the Hilbert space of the system. The sequence is: Hadamard on all qubits -> Measure -> Rotate into \( B \) basis -> Measure -> Rotate back from \( B \) basis. It is recommended to only use this on an experimental basis.

  • GeneralDephasing: Uses an initialisation that prepares the infinite-temperature state by dephasing after applying Hadamard gates. This can only be applied when the number of measurements is comparable to 2^N where N is the number of qubits the \( B \) operator acts on. The sequence is: Hadamard on all qubits -> Let system dephase -> Rotate into \( B \) basis -> Measure -> Rotate back from \( B \) basis. It is recommended to only use this on an experimental basis.

Correlator Measurement

The spin correlator is measured in the time domain

\[ C(t) = \textrm{Tr}\left[ \hat{M}^{+}(t) \hat{M}^{-} \hat \rho_0 \right] \ , \]

where we have the total spin operators

\[ \hat{M}^{\pm} = \sum_j \gamma_j \hat S^{\pm}_j \ , \]

which are the sum of the single-spin operators scaled by the gyromagnetic factors. In an infinite-temperature environment, the initial density matrix is \( \hat \rho_0 = \frac{1}{2^N} \). The correlator \( \langle M^+(t)M^-(0) \rangle \) can be reconstructed by measuring the correlators \( \langle X(t) X(0) \rangle \), \( \langle Y(t) Y(0) \rangle \), \( \langle X(t) Y(0) \rangle \), \( \langle Y(t) X(0) \rangle \). Each of these is obtained as follows:

  • The right operator in the correlator is measured, collapsing the initial state to one of its eigenstates, \( m_n(0) \), and the corresponding eigenvalue \( m_n \) is stored.

  • This eigenstate \( m_n(0) \) is time-evolved with the Trotterization algorithm, obtaining \( m_n(t) \).

  • The expectation value of the left operator in the correlator is measured in this evolved state, obtaining for instance \( \langle m_n(t) | X | m_n(t) \rangle \), given the left operator \(X\).

  • When this procedure is repeated for enough measurements, the full set of eigenstates of the left operator is eventually sampled and the trace is constructed as

    \[ \textrm{Tr}\left[ \hat{X}(t) \hat{Y} \hat \rho_0 \right] = \frac{1}{2^N} \sum_{m_n} m_n \langle X(t) \rangle_{m_n} . \]

Sketch of the correlation measurement

With a growing number of spins, the number of basis states grows exponentially. This would require exponentially many measurements to reconstruct the trace and negate a possible advantage.

One solution, using the active reset initialisation, is to split the correlator measurement into N correlator measurements

\[ C_k(t) = \textrm{Tr}\left[ \hat{M}^{+}(t) \gamma_k \hat S^-_{k} \hat \rho_0 \right] \ . \]

We only measure the qubit \(k\) to prepare for the measurement of \(C_k(t)\) and leave all other qubits in the fully mixed state. In this approach, the number of circuits only scales as \(\mathcal{O}(N)\) with the number of spins \(N\).

As a final optimization, we use the conservation of the total spin so that the correlator between two \(S^+\) operators is always zero, meaning we can replace the first operator with a \(\hat S^x\) operator which is more efficient on a quantum computer \[ C_k(t) = \textrm{Tr}\left[ \hat{M}^{+}(t) \gamma_k \hat S^x_{k} \hat \rho_0 \right] \ . \]

Basis choice in algorithms

It is convention to define the strong magnetic field in NMR along the Z-axis. However, the choice of the axis is arbitrary, as the fundamental problem is symmetric. When choosing to define the NMR system along the X-axis for example, the correlation functions that need to be calculated are \( \langle Y(t) Z(0) \rangle \) and \( \langle Z(t) Z(0) \rangle \), but with respect to a transformed Hamiltonian, the single spin terms are \(X\) terms. This transformation simplifies the construction of initial states in the quantum-computation.

To simplify this process, the HQS Qorrelator App allows the user to create quantum programs that use the X-axis basis and automatically transforms Hamiltonians that are provided into the usual Z-axis basis. The setting can be changed with the b_field_direction property of the NMRCorrelator class, which is the main utility class of the HQS Qorrelator App.

Modeling physical noise

Background

We consider incoherent errors as the predominant noise mechanism in quantum simulation. These errors can originate in interactions between qubits and a fluctuating environment. This mechanism influences the time evolution of the qubits in a way that the errors do not add up coherently. Simple examples of this are superconducting qubits coupled to lossy two-level systems, ion-trap devices with heated vibrational modes or unwanted control-pulse scattering, and spin-qubits in the presence of fluctuating background magnetic-field. During the last few decades, such noise mechanisms have been described successfully using the Lindblad master equation. The HQS Qorrelator App applies this method to model the effect of noise in a digital quantum simulation.

Master equation

Lindbladian

The noise mapping performed by the HQS Qorrelator App can be done for Markovian master equations. This means for noise mechanisms with short memory times. In particular, we apply master equations in the Lindbladian form:

\[ \dot{\rho} = \sum_{ij} M_{ij} \left( A_i \rho A^\dagger_j - \frac{1}{2} A^\dagger_j A_i \rho -\frac{1}{2} \rho A^\dagger_j A_i \right) \equiv L[\rho] \]

where \(\rho\) is the density matrix of the qubits (spins). Operators \(A_i\) offer a basis for representing the noise operators, while matrix \(M\) gives (generalized) noise rates. There is a freedom for definition of operators \(A_i\). So, only in combination with matrix \(M\) (and particularly its non-diagonal entries) can we make judgements of the dominant noise processes and rates.

Noise operators \(A\)

In our software, operators \(A_i\) are chosen to be Pauli-matrices, \(\sigma^x_n, \textrm{i}\sigma^y_n, \sigma^z_n\) (single-qubit noise on qubit \(n\)), and more generally Pauli products, \(\sigma^x_n\sigma^x_m,\sigma^x_n\textrm{i}\sigma^y_m,\sigma^x_n\sigma^z_m,\ldots\) (multi-qubit noise). An imaginary factor is added to Y-operators ( \(\sigma^y_n\rightarrow \textrm{i}\sigma^y_n\) ) so that we avoid having imaginary numbers in matrix \(M\) of the physical noise. (The effective rate matrix can however end up having imaginary entries.)

Rate matrix \(M\)

For clarity in the following, we provide our definition of the spin-lowering and spin-raising operators:

\[ \sigma^-=\frac{1}{2}\left( \sigma^x + \textrm{i}\sigma^y \right) = \begin{pmatrix} 0 & 1 \\ 0 & 0 \end{pmatrix}, \\ \sigma^+=\frac{1}{2}\left( \sigma^x - \textrm{i}\sigma^y \right) = \begin{pmatrix} 0 & 0 \\ 1 & 0 \end{pmatrix} \]

The Lindblad equation for damping of qubit \(1\) has the form:

\[ \dot{\rho} = \gamma_{\textrm{damping}} \left( \sigma^-_1 \rho \sigma^+_1 - \frac{1}{2} \sigma^+_1 \sigma^-_1 \rho - \frac{1}{2} \rho \sigma^+_1 \sigma^-_1 \right) \]

\[ \dot{\rho} = \gamma_{\textrm{damping}} \left[ \frac{1}{4} \left( \sigma^x_1 + \textrm{i} \sigma^y_1 \right) \rho \left( \sigma^x_1 - \textrm{i} \sigma^y_1 \right) -\frac{1}{8} \left( \sigma^x_1 - \textrm{i} \sigma^y_1 \right) \left( \sigma^x_1 + \textrm{i} \sigma^y_1 \right) \rho -\frac{1}{8} \rho \left( \sigma^x_1 - \textrm{i} \sigma^y_1 \right) \left( \sigma^x_1 + \textrm{i} \sigma^y_1 \right) \right] . \]

Our noise matrix then has four non-zero values:

\[ M_{1X, 1X} = \frac{\gamma_\textrm{damping}}{4}, \\ M_{1X, 1 \textrm{i} Y} = \frac{\gamma_\textrm{damping}}{4}, \\ M_{1 \textrm{i} Y, 1X} = \frac{\gamma_\textrm{damping}}{4}, \\ M_{1 \textrm{i} Y, 1 \textrm{i} Y} = \frac{\gamma_\textrm{damping}}{4}. \]

Similarly, dephasing of qubit 1 corresponds to noise matrix with non-zero entry:

\[ M_{1Z, 1Z} = \gamma_\textrm{dephasing}. \]

Depolarization corresponds to identical noise in all directions with rates:

\[ M_{1X, 1X} = \frac{\gamma_\textrm{depolarising}}{4}, \\ M_{1Y, 1Y} = \frac{\gamma_\textrm{depolarising}}{4}, \\ M_{1Z, 1Z} = \frac{\gamma_\textrm{depolarising}}{4}. \]

This definition is based on the density matrix (here) approaching a diagonal matrix with rate \(\gamma_\textrm{depolarising}\).

Form of noise matrix \(M\) for the physical model

Since our physical noise acts individually on each qubit \(n\), our physical noise matrix is a sum over individual contributions \(m^n_{ij}\), where \(i,j\) can be \(nX,n\textrm{i}Y\) or \(nZ\). The matrix is real-valued. In the case where noise acts on all qubits at all times, the total noise matrix has the form:

\[ M = m^0 \oplus m^1 \oplus m^2 \oplus \ldots , \]

whereas, if noise affects only qubits that are being operated on, we have:

\[ M = \bigoplus_{n\in \textrm{acted qubits}} m^n . \] It is important to note that this is the model for physical gates: the form of the effective noise can also include multi-qubit operators and imaginary (non-diagonal) rates, see sections mapping and examples.

Noisy gates

Let us now introduce our model of gate-based quantum simulation with incoherent errors.

Super-operator matrix notation

For simplicity, we now use a notation where each noiseless gate operation (with a given unitary transformation \(U\)) is represented as matrix-multiplication:

\[ U \rho U^{\dagger} \rightarrow G \rho \\ U_2 U_1 \rho U_1^{\dagger} U_{2}^{\dagger} \rightarrow G_2 G_1 \rho . \]

On the right-hand side, the density "matrix" \(\rho\) has become a vector, and the unitary transformations \(G_i\) are matrices acting on it.

Model

In our modeling, we split each gate operation into the ideal unitary gate \(G\) and non-unitary noise \(N\). We then replace each gate in some gate decomposition with:

\[ G \rightarrow N G , \\ G_2 G_1 \rightarrow N_2 G_2 N_1 G_1 , \]

where the noise transformation is given by the Lindblad time-evolution over some physical gate time \(\tau_i\),

\[ N_i \equiv e^{L\tau_i} , \]

where \(L\) is the Lindblad operator. Such a description can always be established if physical gate-times \(\tau_i\) are much shorter than the decoherence rates related to this gate (\(\tau_i \gamma_i \ll 1\)). The question of how correct this description is of some specific hardware realization is then redirected to the question of the correct choice of noise matrix \(M\).

Foundations of noise mapping

On this page, we go through the mathematical foundations of the noise mapping performed by the HQS Qorrelator App. Physical noise on qubits transforms into effective noise on spins in the quantum simulation. For a detailed discussion, see the full paper on noise mapping.

Trotterization of time evolution operator

Decomposition blocks

Digital quantum simulation is based on Trotterization of the time-evolution operator, such that:

\[ e^{-\textrm{i} H t} = \left[ e^{-\textrm{i} H t/m} \right]^m \equiv \left[ e^{-\textrm{i} H \bar t} \right]^m \approx \left[ \Pi_{j} e^{-\textrm{i} H_j \bar t} \right]^m . \]

We consider a time-independent Hamiltonian \(H\) and time-steps \(\bar t = t/m\). The total Hamiltonian \(H\) is divided into elements \(H_j\),

\[ H=\sum_j H_j , \]

which correspond to "small-angle" unitary transformations in the time evolution, \(\exp\left(-\textrm{i} H_j\bar t \right)\).

The goal of the division is to have a sequence of unitary transformations which can be implemented efficiently on hardware. An approximation (error) occurs when individual unitaries do not commute. In the HQS Qorrelator App, such divisions are marked as circuit Decomposition_Blocks.

Small- and large-angle decompositions

Ideally, these unitaries can be implemented directly on hardware by the onset of single-qubit transitions or multi-qubit interactions, e.g., by control-field pulses. These operations then have one-to-one correspondence with equivalent small-angle gates,

\[ e^{-\textrm{i} H_j \bar t} \rightarrow G_j . \]

As described in section modeling, in the presence of noise, each gate \(G_j\) is assigned a noise operator \(N_j\).

However, some unitaries may need to be decomposed into a series of elementary gates,

\[ e^{-\textrm{i} H_j \bar t} \rightarrow \Pi_l G^l_j . \]

Here, each gate \(G^l_j\) comes with noise \(N^l_j\). In practice, such decompositions often include "large-angle" gates, such as CNOT gates or \(\pi\) rotations.

Trotter error

The error in the simplest, first order, Trotter expansion is of size:

\[ \epsilon_\textrm{error} \propto \bar g^2 , \] where \(\bar g= g \bar t\), and \(g\) is some typical energy of non-commuting terms in the Hamiltonian. Note that the error goes to zero in the limit \(\bar t\rightarrow 0\).

Effective noise in the simulated system

Here, we detail how we map the physical noise of a quantum computer to effective noise in the simulated system. For this, it is enough to analyze unitary gates and non-unitary noise operations within one Trotter step. It also turns out that analysis of noise rotations can be done on each decomposition block separately.

Noise transformations

Let us first consider a decomposition of some unitary operation \(\exp\left(-\textrm{i} H_j\bar t \right)\) by two large-angle gates. The generalization to an arbitrary number of gates is straightforward.

By using the fact that gates \(G_i\) are unitary, and thereby invertible, we can write:

\[ N_2 G_2 N_1 G_1 \rho = N_2 G_2 N_1 G_2^{-1} G_2 G_1 \rho \equiv N_2 N_1' G_2 G_1 \rho \equiv N G \rho , \]

where \(G\) corresponds to a small-angle unitary,

\[ G = G_2 G_1 , \]

and the effective noise operator is:

\[ N = N_2 N_1' , \\ N'_1 = G_2 N_1 G_2^{-1} . \] We see that the first noise operator got transformed by the (large-angle) unitary gate \(G_2\). Importantly, since both operators, \(G\) and \(N\), describe small-angle (or probability) processes, these operators will later define the effective Lindbladian of the simulated system.

More generally, for an arbitrary decomposition we can write:

\[ e^{-\textrm{i} H_j \bar t} \rightarrow \Pi_{l=\textrm{last}}^\textrm{first} N^l_j G^l_j = N_j G_j , \]

with:

\[ G_j \equiv \Pi_{l=\textrm{last}}^\textrm{first} G^l_j, \\ N_j \equiv \prod P_j \\ P_0 = N_j^\textrm{last} \\ P_1 = G_j^\textrm{last} N_j^\textrm{last-1} \left( G_j^\textrm{last}\right)^{-1} \\ P_2 = G_j^\textrm{last} G_j^\textrm{last-1} N_j^\textrm{last-2} \left( G_j^\textrm{last-1}\right)^{-1} \left( G_j^\textrm{last}\right)^{-1} \\ \ldots \]

It follows that the full time-evolution operator can be written as:

\[ \Pi_j \exp\left( -\textrm{i} H_j\bar t \right) = \Pi_{j} N_j G_j . \]

Here, each operator \(G_j\) as well as \(N_j\) is a "small-angle" (or probability) transformation. Finally, within the assumption that rotations over small-angle transformations can be neglected, we get the expression for the full Trotter step:

\[ \Pi_{j} N_j G_j \approx \left(\Pi_j N_j \right) \left(\Pi_j G_j \right) = \left( \Pi_j N_j\right) G. \]

(It should be noted that the QSWAP algorithm of quantum simulation includes large-angle gates between decomposition blocks. The effect on the noise mapping, described above, is however analogous to state swaps and can be accounted for by simple "reordering dictionaries" in decomposition-block definitions.)

Lindbladian in the simulated system

Noise mapping is most intuitively formulated in terms of unitary transformations of Lindbladian operators. When constructing the effective model Lindbladian, we include all consecutive noise operations \(N_j\), each of them being some multiplication of transformed Lindbladians \(N_j=\Pi_k\exp\left(L_j^k\tau_j^k\right)\) (see below), under one (exponentiated) Lindbladian,

\[ \Pi_j N_j = \Pi_{j} \Pi_{k} \exp\left(L_j^k\tau_j^k\right) \approx \exp\left(\sum_{jk} L_j^k\tau_j^k\right) \equiv \exp\left(L_\textrm{effective}\bar t\right). \]

Here, each summed Lindbladian \(L_j^k\) has noise operators \(A_i\) that are conjugated by the unitary gate defined by its corresponding decomposition, \(O_j^k\equiv U_j^\textrm{last}U_j^\textrm{last-1}\ldots U_j^\textrm{k+1}\),

\[ A_{i} \rightarrow A_i^{jk} \equiv O_j^k A_i \left(O_j^k\right)^\dagger. \]

(For native gates there will be no transformation, so that for these \(A_i^{jk} = A_{i}\).) The final effective Lindbladian then takes the form:

\[ L_\textrm{effective}[\rho] \equiv \sum_{ii'jk} \frac{\tau_j^k}{\bar t} M^{jk}_{ii'}\left( S_1- \frac{1}{2}S_2\right). \]

with

\[ S_1 = A_i^{jk} \rho (A^{jk}_{i'})^\dagger \]

and the anti-commutator

\[ S_2 = \lbrace(A^{jk}_{i'})^\dagger A_i^{jk} , \rho \rbrace \]

Here, an important noise scaling factor \(\tau / \bar t\) appears. We notice that the effective noise decreases with increasing Trotter time-step \(\bar t\). An example of this is given on page examples.

Error in the noise mapping

The above approximations are analogous to neglecting the Trotter error. First, we made the approximation that noise transformations can be restricted to individual decomposition blocks. The error of this approximation is of size:

\[ \epsilon_\textrm{error} \propto \bar g \gamma\tau , \]

where \(\bar g= g \bar t\) and \(\gamma \tau\) are some typical Hamiltonian energy and noise probability of non-commuting elements between the two. Importantly, the error goes to zero in the limit \(\bar t\rightarrow 0\).

Second, in the derivation of the Lindbladian, an error occurs when we combine consecutive noise terms (Lindbladians) under one exponent. This step has an error of size:

\[ \epsilon_\textrm{error} \propto (\gamma\tau)^2 \]

The validity of the noise mapping can be investigated numerically by comparing the solution for the original noisy circuit and for the effective Lindbladian, as shown on page examples.

Using the HQS Qorrelator App

In this section, we outline how to employ the HQS Qorrelator App to compute time-resolved correlators for NMR spectroscopy simulations on quantum computers. The HQS Qorrelator App works together with the HQS struqture and qoqo libraries. In this regard, we first briefly show how to create Hamiltonians and open quantum systems using struqture. Then, we discuss the available qoqo noise models that can be used in the simulation, and we show how to set up device information. Finally, we illustrate how to use the HQS Qorrelator App to create a qoqo QuantumProgram for simulating the dynamics of the correlators.

struqture

struqture is a library enabling compact representation of quantum mechanical operators, Hamiltonians, and open quantum systems. The library supports building spin, fermionic and bosonic objects, as well as combinations thereof (mixed systems). Here, we demonstrate its usage with simple spin systems. For more complicated examples, please check the user documentation of struqture.

Creating Spin Hamiltonians

Let us now create a spin Hamiltonian using the struqture library. Here, arbitrary spin operators are built from PauliProduct operators. As the name implies, these are products of single-spin Pauli operators. Each Pauli operator in the PauliProduct operates on a different qubit. Not all qubits need to be represented in a PauliProduct (such qubits contribute via identity operators).

For instance, let us create a simple spin-Hamiltonian in the rotating-wave approximation with respect to a strong external magnetic field in the Z-direction. Such a Hamiltonian is also required as the input for constructing the QuantumProgram used to calculate the NMR correlation function. All single-spin terms need to be Z-terms. All spin-interaction terms need to be at least spin-Z preserving (only XX, YY or ZZ terms, with the same coefficient for XX and YY) or completely symmetric in X, Y and Z (same coefficient for XX, YY and ZZ). The second kind of symmetry is required when setting the b_field_direction option to a different direction from the input Hamiltonian.

For instance, we can create the following Hamiltonian

\[ H= \sum_{i=0}^9 3\sigma_{i}^z + \sum_{i=0}^8 2\sigma_{i}^x\sigma_{i+1}^x \]

using:


from struqture_py import spins
from struqture_py.spins import (SpinHamiltonianSystem, PauliProduct)

number_spins = 10
chemical_shift = 3.0
spin_coupling = 2.0

hamiltonian = SpinHamiltonianSystem()
for site in range(number_spins):
    hamiltonian.add_operator_product(PauliProduct().z(site), chemical_shift)
for site in range(number_spins-1):
    hamiltonian.add_operator_product(PauliProduct().x(site).x(site+1), spin_coupling)
    hamiltonian.add_operator_product(PauliProduct().y(site).y(site+1), spin_coupling)
    hamiltonian.add_operator_product(PauliProduct().z(site).z(site+1), spin_coupling)


Information can be accessed using the following functions:


hamiltonian.keys()             # operator keys (Pauli products / strings)
hamiltonian.get("0X1X")        # front factor of Pauli product "0X1X"
hamiltonian.number_spins()     # number of spins in the system

Creating Spin Lindblad Noise Operators

Let us now create the Lindblad noise operators for a system of spins using struqture. Such noise operators are used to describe the noise part of the the Lindblad master equation

\[ \sum_{i,j}M_{i,j} \left( A_{i}\rho A_{j}^{\dagger} - \frac{1}{2} \lbrace A_j^{\dagger} A_i, \rho \rbrace \right). \]

For more detailed information, please refer to the modeling section. We use struqture DecoherenceProducts as the operator basis. The object SpinLindbladNoiseOperator is given by a HashMap or Dictionary with the tuple (DecoherenceProduct, DecoherenceProduct) as keys and the entries in the rate matrix \(M_{j,k} \) as values. Similarly to SpinOperators, SpinLindbladNoiseOperators have a system equivalent: SpinLindbladNoiseSystem, with a number of involved spins defined by the user. For more information on these, see the user documentation of struqture.

For instance, take \( A_0 = A_1 = \sigma_0^{x} \sigma_2^{z} \) with coefficient 1.0: \( 1.0 \left( A_0 \rho A_1^{\dagger} - \frac{1}{2} \lbrace A_1^{\dagger} A_0, \rho \rbrace \right) \). This is implemented in the following code snippet.


from struqture_py import spins
from struqture_py.spins import SpinLindbladNoiseSystem, DecoherenceProduct
import scipy.sparse as sp

system = spins.SpinLindbladNoiseSystem(3)

dp = spins.DecoherenceProduct().x(0).z(2)

system.add_operator_product((dp, dp), 1.0)

# Accessing information:
system.current_number_spins()     # Result: 2
system.get((dp, dp))              # Result: CalculatorFloat(2)
system.keys()                     # Result: [("0Z1X", "0Z1X")]
dimension = 4**system.number_spins()
matrix = sp.coo_matrix(system.sparse_matrix_superoperator_coo(), shape=(dimension, dimension))

Creating noise models

The current version of the HQS Qorrelator App supports single-qubit physical noise in the form of damping, dephasing, and depolarization, with user-given decoherence rates. We assume that the noise is the same for all gate-types.

We can define a ContinuousDecoherenceModel noise model with the following types of noise:

  • dephasing: using the add_dephasing_rate function
  • depolarisation: using the add_depolarising_rate function
  • damping: using the add_damping_rate function
  • excitations: using the add_excitation_rate function

Each of these functions takes a list of qubits to apply the noise to, as well as a noise rate (float), and returns the modified ContinuousDecoherenceModel. An example code snippet, which creates a noise model with damping and dephasing, reads as follows.

from qoqo import noise_models

# Setting up the noise model.
damping = 1e-3
dephasing = 5e-4
noise_model = noise_models.ContinuousDecoherenceModel().add_damping_rate([0, 1, 2], damping).add_dephasing_rate([3, 4], dephasing)

Creating a device

We can define an AllToAllDevice device with the following settings:

  • number_of_qubits : The number of qubits for the device.
  • single_qubit_gates : The list of single-qubit gates available on the quantum computer.
  • two_qubit_gates : The list of two-qubit gates available on the quantum computer.
  • default_gate_time : The default starting gate time.

The option single_qubit_gates can be any list of single-qubit gates available in qoqo as long as it contains one of the following combinations:

  • RotateX and RotateZ
  • RotateY and RotateZ
  • RotateX and RotateY
  • RotateZ and SqrtPauliX and InvSqrtPauliX

The supported choices for two_qubit_gates are:

  • CNOT
  • ControlledPauliZ
  • ControlledPhaseShift
  • MolmerSorensenXX
  • VariableMSXX

An example code snippet of setting device information reads as follows.

from qoqo import devices

# Setting up the device.
number_of_qubits=5
single_qubit_gates = ["RotateX", "RotateZ", "RotateY"]
two_qubit_gates = ["CNOT"]
default_gate_time = 1.0
device = devices.AllToAllDevice(
    number_of_qubits, single_qubit_gates, two_qubit_gates, default_gate_time
)

Using the HQS Qorrelator App

The HQS Qorrelator App can be initialized without any arguments:

from hqs_qorrelator_app import NMRCorrelator

correlator = NMRCorrelator()

Additionally, there are settings that have default values and can be set with setter functions with the same name as the setting.

  • algorithm : options are ParityBased, QSWAP, QSWAPMolmerSorensen, VariableMolmerSorensen (defaults to QSWAP).
  • b_field_direction: Z (default) and X are possible options. Determines in which direction of the B-field is used for the calculation of the correlator. Automatically transforms compatible input Hamiltonians (e.g. a input Hamiltonian defined for a Z b-field if the X direction is used).
  • noise_mode : options are active_qubits_only (noise added only for qubits involved in operations), all_qubits (noise added for all qubits at each step, default value) and parallelization_blocks (noise added after each parallelization block).
  • noise_placement : before, after or symmetric- The noise is applied before the gate, after the gate based on gate duration or symmetrically (defaults to after)
  • number_measurements : the number of projective measurements used when measuring observables (defaults to 100000)
  • optimization_level : the level of optimization when performing the algorithm: either 0 where no optimizations are applied, or 1 where SingleQubitGates are combined (defaults to 1)
  • initialisation: options are SumOverAllStates (default), ActiveReset, NonCorrelatingMeasurement, GeneralMeasurement, GeneralDephasing. See also the chapter on algorithms. We recommend using the default value.
  • decoherence_loops : This only affects optional initialisation methods and has no effect on the n optional number of loops run after the Hadamards on every qubit and before the main circuit, which are there to let off-diagonal entries of the density matrix decay through decoherence.

The HQS Qorrelator App can create QuantumPrograms to time-propagate a spin state. The QuantumProgram will initialize a spin state on a quantum computer, time-propagate the spin state with a quantum algorithm, measure the values of spin observables and compute the NMR correlator as described in the Quantum Algorithm section. The following example shows how to obtain the QuantumProgram for a previously defined hamiltonian (hamiltonian) and device (device).

from hqs_qorrelator_app import NMRCorrelator

number_qubits = hamiltonian.number_qubits()
trotter_timestep = 0.005
gyromagnetic_factors = [1.0]*number_qubits

correlator = NMRCorrelator()
program = correlator.spectrum_program_fixed_step(
    hamiltonian,
    trotter_timestep,
    gyromagnetic_factors,
    device
)

The QuantumProgram can then be simulated using the backend of the user's choosing. For Linux users, the qoqo-quest Backend is recommended for simulations. The following example shows how to run the obtained QuantumProgram on the backend and get the real and imaginary parts of the NMR correlator from the resulting dictionary.

import numpy as np
from qoqo_quest import Backend

number_trottersteps = 100
backend = Backend(number_qubits)

correlator_re = np.zeros(number_trottersteps, dtype=float)
correlator_im = np.zeros(number_trottersteps, dtype=float)

for i in range(0, number_trottersteps):
    result = backend.run_program(program, [i])
    correlator_re[i] = result["correlator_total_re"]
    correlator_im[i] = result["correlator_total_im"]
    
correlator = correlator_re + 1.0j * correlator_im

Considering the effects of noise

Estimating the overall decoherence rate

Physical noise on the quantum computer used to run the QuantumProgram will lead to a decay in the calculated correlation functions. This decay will lead to a broadening in the NMR spectrum (the Fourier transform of the correlation function).

Based on the choice of algorithm, device specification, and noise models, the mean decoherence rate that affects the spin system during the time evolution can be estimated. This estimated decoherence rate gives an expected broadening of the peaks in the NMR spectrum.

Please note that this is just an estimate, and therefore does not require a computationally costly full simulation of the time evolution.

from hqs_qorrelator_app import NMRCorrelator
from struqture_py import spins
from qoqo import devices, noise_models

# define hamiltonian
gyromagnetic = 1.0
number_spins = 2
time = np.pi/4
coupling = 1.0
shift = 1.0
gyromagnetic_factors = [gyromagnetic for _ in range(number_qubits)]
hamiltonian = spins.SpinHamiltonianSystem(number_spins)
for site in range(number_spins):
    hamiltonian.set("{}Z".format(site), -shift * site)

# Setting up the device.
single_qubit_gates = ["RotateX", "RotateZ", "RotateY"]
two_qubit_gates = ["CNOT"]
gate_times = 1.0
damping = 1e-3
device = devices.AllToAllDevice(
    number_spins, single_qubit_gates, two_qubit_gates, gate_times
)
# While the noise model is not needed to generate the QuantumProgram, it will be required
# when simulating the QuantumProgram.
noise_model = noise_models.ContinuousDecoherenceModel().add_damping_rate([0, 1, 2], damping)

trotter_timestep = 0.01

# Create circuit.
qorrelator_app_sc = NMRCorrelator()
qorrelator_app_sc.algorithm = "QSWAP"
estimated_decoherence_rate = qorrelator_app_sc.estimate_decoherence_rate(hamiltonian, trotter_timestep, device, [noise_model])

print("estimated decoherence rate:", estimated_decoherence_rate) 

Extracting the Noisy algorithm model

The noisy algorithm model represents the effective Lindbladian that is being simulated in the presence of noise. Please refer to this paper and to the mapping section for details.

With the HQS Qorrelator App, the noisy algorithm model of a Hamiltonian can be obtained using the function NMRCorrelator.noisy_algorithm_model, with input arguments:

  • hamiltonian: The Hamiltonian for which the noise algorithm model is created.
  • trotter_timestep: The simulation time the circuit propagates the simulated system.
  • device: The device determining the topology.
  • noise_models: Noise models determining noise properties.

An example is:


from hqs_qorrelator_app import NMRCorrelator
from struqture_py import spins
from struqture_py.spins import (SpinHamiltonianSystem, PauliProduct)
from qoqo import devices, noise_models

# define hamiltonian 
number_spins = 4
hamiltonian = spins.SpinHamiltonianSystem(number_spins)
hamiltonian.add_operator_product(PauliProduct().z(0).z(2).z(3), 4.0)

# Setting up the device
single_qubit_gates = ["RotateX", "RotateZ"]
two_qubit_gates = ["CNOT"]
gate_times = 1.0
damping = 1e-3
device = devices.AllToAllDevice(
    number_spins, single_qubit_gates, two_qubit_gates, gate_times
)

# While the noise model is not needed to generate the QuantumProgram, it will be required
# when simulating the QuantumProgram.
noise_model = noise_models.ContinuousDecoherenceModel().add_damping_rate([0, 1, 2, 3], damping)

# create inputs
trotter_timestep=0.01
qorrelator_app = NMRCorrelator()

# obtain noisy algorithm model
noisy_model = qorrelator_app.noisy_algorithm_model(hamiltonian, trotter_timestep, device, [noise_model])
print(noisy_model)

noisy_model is an object of class struqture.spins.SpinLindbladNoiseSystem.

Backends

The HQS Qorrelator App does not provide an internal simulator, but there are multiple interfaces (such as qoqo-quest, qoqo-for-braket and qoqo-qiskit) which can be used to either simulate the QuantumProgram or run it on quantum hardware.

Should the user wish to run a simulation emulating the device noise, the insert_noise function in the HQS Qorrelator App can be used to add in the chosen noise to the QuantumProgram.


import numpy as np
from struqture_py import spins
from struqture_py.spins import (SpinHamiltonianSystem, PauliProduct)
from hqs_qorrelator_app import NMRCorrelator
from qoqo import devices, noise_models
from qoqo_quest import Backend

number_spins = 2
time = np.pi/4
coupling = 1.0
shift = 1.0
gyromagnetic = 1.0
gyromagnetic_factors = [gyromagnetic for _ in range(number_qubits)]
number_trotter_steps = 20
trotter_timestep = 0.005

hamiltonian = spins.SpinHamiltonianSystem(number_spins)
for site in range(number_spins):
    hamiltonian.set("{}Z".format(site), -shift * site)

# Setting up the device.
single_qubit_gates = ["RotateX", "RotateZ"]
two_qubit_gates = ["CNOT"]
gate_times = 1.0
device = devices.AllToAllDevice(
    number_spins, single_qubit_gates, two_qubit_gates, gate_times
)

# While the noise model is not needed to generate the QuantumProgram, it will be requried
# when simulating the QuantumProgram.
damping = 0.0001
noise_model = noise_models.ContinuousDecoherenceModel().add_damping_rate([0, 1, 2, 3, 4], damping)

qorrelator_app = NMRCorrelator()

quantum_program = qorrelator_app.spectrum_program_fixed_step(hamiltonian, trotter_timestep, gyromagnetic_factors, device)
quantum_program_with_noise = qorrelator_app.insert_noise(quantum_program, device, [noise_model])

backend = Backend(number_spins)

# This is an alternative way of running the QuantumProgram, which allows to substitute one's
# backend of choice in the arguments. It is equivalent to backend.run_program(program, [number_trottersteps])
result = quantum_program_with_noise.run(backend, [number_trottersteps])

Changelog

This changelog track changes to the HQS HQS Qorrelator App starting at version 0.2.0

0.8.0

  • Added support for inputs from struqture 2.0, and moved internal logic from struqture 1.x to 2.x
  • Updated licensing package dependency that adds support for unknown entitlements

0.7.7

  • Dependency updates to add support for new entitlements and to enable working with license file obtained by hqstage copy-license

0.7.6

  • Improved license error messages.
  • Improved documentation.

0.7.5

  • Updated text of LICENSE_FOR_BINARY_DISTRIBUTION

0.7.4

  • Dependency updates for fixing windows license checks

0.7.3

  • Dependencies update to fix license checks on windows.

0.7.2

  • Changed order of optimizations to enable fusion of Qsim operations when decomposition blocks are enabled

0.7.1

  • Updated dependencies and removed prallel feature from default

0.7.0

  • Add option to use decomposition blocks
  • Add MultipleRotationGateSimplifier optimization from qonvert

0.6.1

  • Update to dependency libraries with fix for license checks

0.6.0

  • Refactoring functions not using fixed trotter timestep

0.5.0

  • Added offline licensing checks
  • Fix bug in the preprocessing of the Hamiltonian with field along X

0.4.1

  • Add getters and setters for NMRCorrelator
  • Refactored repository to include options for the direction of the magnetic field and processing of the Hamiltonian
  • New user documentation

0.4.0

  • Renamed the spin correlator app to the HQS Qorrelator App

0.3.0

  • Update to dependency libraries
  • Refactoring of code between App and dependency libraries

0.2.1

  • Update to dependency libraries

0.2.0

  • Fixed default number of measurements to be consistently 100_000