qiskit-aer icon indicating copy to clipboard operation
qiskit-aer copied to clipboard

Random Kraus error

Open smiserman opened this issue 2 years ago • 0 comments

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)  

smiserman avatar Nov 08 '22 16:11 smiserman