qiskit-aer
qiskit-aer copied to clipboard
Random Kraus error
What is the expected behavior?
One may think of a random quantum channel without knowlege of some parameters. Because there is no implementation of such an error channel in Qiskit I provide such an error channel, based on the paper Generating random quantum channels by R.Kukulski et al.
The function random_kraus_error(num_kraus, num_qubits, prob, seed)
generates an arbitrary number of Kraus matrices with random normally distributed complex entries, which are then weighted by a probability prob
of the error. If we choose just one Kraus matrix (num_kraus=1
) we get an unital channel. If we additionally choose prob=1
this corresponds to a unitary transformation. For $\mathrm{num}_{kraus} \gg 1$ the channel approximates a depolarizing channel $\mathcal{E}_r (\rho) \rightarrow (1-p) \rho + p/d$
Perhaps you are interested to implement such a channel in Qiskit.
import scipy as sp
import numpy as np
from qiskit.providers.aer.noise import kraus_error
def random_kraus_error(num_kraus=4, prob=0.5, num_qubits=1, seed=None):
'''
Calculates a random error channel of probability prob
consisting of a set of num_kraus random Kraus matrices.
Set seed to a number to get a reproducible set.
'''
sig=1/np.sqrt(2)
krauss = []
dim = 2**num_qubits
h = np.zeros([dim,dim])
if seed != None: np.random.seed(seed)
# generate a set of num_kraus complex valued matrices
# from a Ginibre ensemble
for i in range(num_kraus):
gmat = (np.random.normal(0,sig,(dim,dim)) +
1.j*np.random.normal(0,sig,(dim,dim)))
h = h + gmat.conj().T @ gmat
krauss.append(gmat)
# calculate the scaling matrix to ensure the
# completeness relation and normalize Kraus matrices
h = np.linalg.inv(sp.linalg.sqrtm(h))
prob_sqrt = np.sqrt(prob)
for i in range(num_kraus):
krauss[i] = prob_sqrt * krauss[i] @ h
# append the identity operator with probability 1- prob
krauss.append(np.sqrt(1-prob)*np.eye(dim))
return kraus_error(krauss)