Source code for netQuil.noise

import numpy as np
import uuid

from pyquil.gates import *
from pyquil.quil import DefGate
from pyquil.noise import pauli_kraus_map

__all__ = ["bit_flip", "phase_flip", "depolarizing_noise", "measure","normal_unitary_rotation"]

ro = None

def kraus_op_bit_flip(prob: float):
    noisy_I = np.sqrt(1-prob) * np.asarray([[1, 0], [0, 1]])
    noisy_X = np.sqrt(prob) * np.asarray([[0, 1], [1, 0]])
    return [noisy_I, noisy_X]


def kraus_op_phase_flip(prob: float):
    noisy_I = np.sqrt(1-prob) * np.asarray([[1, 0], [0, 1]])
    noisy_Z = np.sqrt(prob) * np.asarray([[1, 0], [0, -1]])
    return [noisy_I, noisy_Z]


def kraus_op_depolarizing_channel(prob: float):
    noisy_I = np.sqrt(1-prob) * np.asarray([[1, 0], [0, 1]])
    noisy_X = np.sqrt(prob/3) * np.asarray([[0, 1], [1, 0]])
    noisy_Z = np.sqrt(prob/3) * np.asarray([[1, 0], [0, -1]])
    noisy_Y = np.sqrt(prob/3) * np.asarray([[0, 0-1.0j], [0+1.0j, 0]])
    return [noisy_I, noisy_X, noisy_Y, noisy_Z]

def random_unitary(n):
    # draw complex matrix from Ginibre ensemble
    z = np.random.randn(n, n) + 1j * np.random.randn(n, n)
    # QR decompose this complex matrix
    q, r = np.linalg.qr(z)
    # make this decomposition unique
    d = np.diagonal(r)
    l = np.diag(d) / np.abs(d)
    return np.matmul(q, l)



[docs]def bit_flip(program, qubit, prob: float): ''' Apply a bit flip with probability :param Program program: program to apply noise to :param Integer qubit: qubit to apply noise to :param Float prob: probability of apply noise ''' unique_id = uuid.uuid1().int flip_noisy_I_definition = DefGate("flipNOISE" + str(unique_id), random_unitary(2)) program += flip_noisy_I_definition program.define_noisy_gate("flipNOISE" + str(unique_id), [qubit], kraus_op_bit_flip(prob)) program += ("flipNOISE" + str(unique_id), qubit)
[docs]def phase_flip(program, qubit, prob: float): ''' Apply a phase flip with probability :param Program program: program to apply noise to :param Integer qubit: qubit to apply noise to :param Float prob: probability of apply noise ''' unique_id = uuid.uuid1().int phase_noisy_I_definition = DefGate("phaseNOISE" + str(unique_id), random_unitary(2)) program += phase_noisy_I_definition program.define_noisy_gate("phaseNOISE" + str(unique_id), [qubit], kraus_op_phase_flip(prob)) program += ("phaseNOISE" + str(unique_id), qubit)
[docs]def depolarizing_noise(program, qubit, prob: float): ''' Apply depolarizing noise with probability :param Program program: program to apply noise to :param Integer qubit: qubit to apply noise to :param Float prob: probability of apply noise ''' unique_id = uuid.uuid1().int dp_noisy_I_definition = DefGate("dpNOISE" + str(unique_id), random_unitary(2)) program += dp_noisy_I_definition program.define_noisy_gate("dpNOISE" + str(unique_id), [qubit], kraus_op_depolarizing_channel(prob)) program += ("dpNOISE" + str(unique_id), qubit)
[docs]def measure(program, qubit, prob: float, name): ''' Measure the qubit with probability :param Program program: program to apply noise to :param Integer qubit: qubit to apply noise to :param Float prob: probability of apply noise :param String name: name of quil classical register to measure to. :returns: None if qubit is not measured and qubit if qubit is measured ''' if np.random.rand()> prob: global ro devices_ro_exists = False ro_exists = False for inst in program.instructions: try: if inst.name == name: devices_ro_exists = True elif inst.name == "ro": ro_exists = True except: pass if not ro_exists: ro = program.declare("ro", 'BIT', 1) elif ro_exists and not devices_ro_exists: ro = program.declare(name, 'BIT', 1) program += MEASURE(qubit, ro) return qubit return None
[docs]def normal_unitary_rotation(program, qubit, prob:float, variance): ''' Apply X and Z rotation with probability :param Program program: program to apply noise to :param Integer qubit: qubit to apply noise to :param Float prob: probability of apply noise :param Float variance: variance of rotation angle ''' if np.random.rand() > prob: x_angle, z_angle = np.random.normal(0, variance, 2) program += RX(x_angle, qubit) program += RZ(z_angle, qubit)