Example #1
0
def ghz_state(n, noisy=False, kraus=None):
    """
    This creates an n qubit ghz state
    :param n:  The number of qubits in the state
    :param string: The string for the initial state of the density matrix e.g '000' produces a state where all
    the three qubits are in the ground state while '111' produces a state where all the qubits are the excited state
    :param ar: This is a list of numbers that specifies the various control and target position
    e.g ghz_state(4, '0000', [1,2,1,3,1,4]) creates two control operations with first qubit being the
    control and the second qubit being the target and the second operation has first being the control
    with the third qubit being the target third operation has the first qubit being the control and the
    fourth qubit being the target
     :param noisy: If true decoherence is added between gate applications
    :param kraus: This will be a 3 dimensional array of kraus matrices
    :return: returns the state of the qubit after the controlled x operations. This should be a ghz state.
    """
    string = '0'*n
    q = qubit.Qubit(string, n)
    h_gate = op.superkron(g.h(), np.eye(pow(2, n-1)))
    q.state = np.dot(h_gate, np.dot(q.state, h_gate))
    if noisy is False:
        for i in range(1, n+1):
            controlgate = g.c_u(g.x(), n, i, i + 1)
            q.state = np.dot(controlgate, np.dot(q.state, op.ctranspose(controlgate)))
    else:
        for i in range(1, n+1):
            controlgate = g.c_u(g.x(), n, i, i + 1)
            q.q_decohere(kraus, n)
            q.state = np.dot(controlgate, np.dot(q.state, op.ctranspose(controlgate)))

    return q
Example #2
0
def clusterstate(n, noisy=False, kraus=None):
    """
    This creates a cluster state
    :param n: This is the number of qubits in the system
    :param string: This is the string that determines the state of the initial system. e.g
    '0000' produces 4 qubit state being all in the ground state while '01010' produces a five qubits with
    qubits being in ground and excited states alternately
    :param ar: This is a list of numbers that specifies the various control and target position
    e.g clusterstate(4, '0000', [1,3,2,4]) creates two control operations with first qubit being the control and the third qubit
    being the target and the second operation has second being the control with the fourth qubit being the target.
    :param noisy: If true decoherence is added between gate applications
    :param kraus: This will be a 3 dimensional array of kraus matrices
    :return: returns the state of the qubit after the controlled z operations. This should be a cluster state

    """
    string = '0'*n
    q = qubit.Qubit(string, n)
    q.state = np.dot(g.multi_hadamard(n), np.dot(q.state, g.multi_hadamard(n)))
    if noisy is False:
        for i in range(1, n+1):
            controlgate = g.c_u(g.z(), n, i, i+1)
            q.state = np.dot(controlgate, np.dot(q.state, op.ctranspose(controlgate)))
    else:
        for i in range(1, n+1):
            controlgate = g.c_u(g.z(), n, i, i+1)
            q.q_decohere(kraus, n)
            q.state = np.dot(controlgate, np.dot(q.state, op.ctranspose(controlgate)))
    return q
Example #3
0
    def __init__(self, string, n, no_measurment_qubits=1, left_justified=False):
        """
        :param string: This should be a string of 1's and 0's where 1 is the |1> and
        0 is |0>
        :param n: The number of qubits in the system
        :param no_measurment_qubits:  The number of qubits that will be measured
        :return: Returns the

        Description of class variables
        state: This is the density matrix of the system
        classical_states: This is a dictionary of computational basis states that should have
        has its keys labels of computational basis states and values the corresponding
        probabilities
        no_measurement_qubits: The number of qubits you intend to measure
        classical_states_history: Has a key values all possible measurement syndromes and keeps a record of their
        probabilities
        single_kraus: These are the kraus operators used for a single qubit. They are used to create kraus operators
        for the n qubit system
        partial_bath: This is aa boolean variable. If true some qubits the last m qubits on the left will not decohere
        no_non_ideal_qubits: These are the number of qubits, k that will decohere.  m+k must equal to n the number of
        qubits in the system
        hamiltonian: The hamiltonian of the system
        T: The total evolution time of the system
        state: The state of the quantum system for n qubits
        """
        self.oper_dict = {'0': g.b1(), '1': g.b4(), '2': g.id()}

        self.state = op.superkron(self.oper_dict, val=1, string=string)
        self.n = n
        self.no_measurement_qubits = no_measurment_qubits
        self.measurement_string = op.createlabel(self.no_measurement_qubits, 2)
        for i in range(len(self.measurement_string)):
            if left_justified:
                self.measurement_string[i] = self.measurement_string[i].ljust(self.n, '2')
            else:
                self.measurement_string[i] = self.measurement_string[i].rjust(self.n, '2')
        # self.projectors = {i.replace('2', ''): op.superkron(self.oper_dict, val=1, string=i) for i in
        #                    self.measurement_string}
        self.classical_states = {i.replace('2', ''): 0 for i in self.measurement_string}
        self.classical_states_history = {i.replace('2', ''): [] for i in self.measurement_string}
        self.hamiltonian = None
        self.dt = None
        self.U = None
        self.xlabel = ''
        self.ylabel = ''
        self.T = None
        self.kraus_operators = []
        self.expect_values = {}
        self.yield_kraus = None
        self.single_kraus = None
        self.partial_bath= False
        self.no_non_ideal_qubits = 0
Example #4
0
def pta_ad(n, t, t1):
    """
    Produces the kraus matrices for the pta channel
    :param n: number of qubit
    :param t: time step for evolution
    :param t1: relaxation time
    :return: returns a 3 dimensinal array of pta kraus matrices
    """
    gamma = 1 - np.exp(-t / t1)
    px = py = gamma / 4.0
    pz = 1.0 / 2.0 - py - np.sqrt(1 - gamma) / 2
    pi = 1 - (px + py + pz)
    A = np.zeros((pow(4, n), pow(2, n), pow(2, n)), dtype=complex)  # 3 dimensional array to store kraus matrices
    ptaOperators = {
        '0': np.sqrt(pi) * g.id(),
        '1': np.sqrt(px) * g.x(),
        '2': np.sqrt(py) * g.y(),
        '3': np.sqrt(pz) * g.z()
    }

    # get labels
    labels = op.createlabel(n, 4)

    for i in range(len(labels)):
        temp = 1
        for digit in labels[i]:
            temp = np.kron(temp, ptaOperators[digit])
        A[i] = temp
    return A
Example #5
0
def kraus_pta(n, t, t1, t2):
    """
    Produces the kraus matrices for the pta channel
    :param n: number of qubit
    :param t: time step for evolution
    :param t1: relaxation time
    :param t2: dephasing time
    :return: returns a 3 dimensinal array of pta kraus matrices
    """
    gamma = 1 - np.exp(-t / t1)
    t_phi = Decimal(1 / t2) - Decimal(1 / (2 * t1))
    # lambda1 = np.exp(-t/t1)*(1-np.exp(-2*(t/t_phi)))
    px = py = gamma / 4.0
    pz = 1.0 / 2.0 - py - np.exp(-t / (2 * t1)) * np.exp(-(t / t_phi)) / 2
    pi = 1 - (px + py + pz)
    print('px: ', py, 'pz: ', pz, 'pi: ', pi)
    A = np.zeros((pow(4, n), pow(2, n), pow(2, n)), dtype=complex)  # 3 dimensional array to store kraus matrices
    ptaOperators = {
        '0': np.sqrt(pi) * g.id(),
        '1': np.sqrt(px) * g.x(),
        '2': np.sqrt(py) * g.y(),
        '3': np.sqrt(pz) * g.z()
    }

    # get labels
    labels = op.createlabel(n, 4)

    for i in range(len(labels)):
        temp = 1
        for digit in labels[i]:
            temp = np.kron(temp, ptaOperators[digit])
        A[i] = temp
    return A
Example #6
0
 def get_projectors(self, measure_strings):
     """
     :return:
     """
     if isinstance(measure_strings, list):
         for i in measure_strings:
             yield op.superkron(self.oper_dict, val=1, string=i)
Example #7
0
def pauli_group(n, full=False, normalize=True):
    """
    :param n: number of qubits
    :param full: If true returns the full pauli group for n qubits including group elements that differ by center
    of the group
    :param normalize: If true returns pauli group elements so that group are normalized
    :return: Returns a dictionary of unitary representation of the single qubit pauli group
    """
    if normalize:
        pauli_matrix = {
            'I': id() / sqrt(2),
            'X': x() / sqrt(2),
            'Y': y() / sqrt(2),
            'Z': z() / sqrt(2)
        }
    else:
        pauli_matrix = {'I': id(), 'X': x(), 'Y': y(), 'Z': z()}
    center = {'i': 1j, '-i': -1j, '1': 1, '-1': -1}
    pauli_labels = [''.join(i) for i in product('IXYZ', repeat=n)]
    qubit_group = {}
    pauli_dict = {}
    if full is False:
        for pl in pauli_labels:
            pauli_dict[pl] = op.superkron(pauli_matrix, val=1, string=pl)
    else:
        for i in center:
            for p in pauli_dict:
                qubit_group[str(i) + str(p)] = dot(center[i], pauli_dict[p])

    return pauli_dict
Example #8
0
 def circuit_unitary(self):
     """
     :return: Returns the unitary for the circuit
     """
     out = np.eye(2**self.n, dtype='complex128')
     for i in self.bucket:
         out = np.dot(out, self.step_operator(i))
     out = op.ctranspose(out)
     return out
Example #9
0
def apply_kraus(K, rho_s, n, non_ideal_qubits=0, partial_bath=False):
    """
    :param K: List of kraus operators
    :param rho: density matrix of system
    :param n: Number of qubits
    :return: Return evolved density matrix
    """
    out = np.zeros((pow(2, n), pow(2, n)), dtype=complex)
    if partial_bath:
        ideal_qubits_oper = {'0': g.id()}
        id_oper = op.superkron(ideal_qubits_oper, val=1, string='0' * (n - non_ideal_qubits))
        for kraus in K:
            new_kraus = op.superkron(kraus, id_oper)
            out += np.dot(new_kraus, np.dot(rho_s, op.ctranspose(new_kraus)))
        return out
    else:
        for kraus in K:
            out += np.dot(kraus, np.dot(rho_s, op.ctranspose(kraus)))
        return out
Example #10
0
def bakersmap(n):
    """
    :param n: The number of qubits
    :return:
    """
    q = qft(n)
    q_1 = qft(n / 2)
    out = op.ctranspose(q) * kron(id(), q_1)

    return out
Example #11
0
def c_u(u, n, i, j):
    """
    This creates a controlled unitary operation on n qubits
    :param u: Unitary matrix
    :param n: The number of qubits to be used
    :param i: the position of control qubit for the controlled operation
    :param j: the position of target qubit for the controlled operation
    :return:  the controlled operation
    """
    term_1 = {"0": id(), "1": e_ij((2, 2), 1, 1)}
    term_2 = {"0": id(), "2": u, "1": e_ij((2, 2), 2, 2)}

    # What happens when the control qubit is in the zero state
    label_1 = op.generatetensorstring(n, i)
    cu_1 = op.superkron(term_1, val=1, string=label_1)

    # What happens when the control bit is in the one state
    label_2 = op.controlgatestring(n, ('1', i), ('2', j))
    cu_2 = op.superkron(term_2, val=1, string=label_2)

    return cu_1 + cu_2
Example #12
0
 def measure_basis(self, pauli_string='', undo_basis=False):
     """
     :param pauli_string: Basis in which to make the measurement
     :param undo_basis: Boolean variable
     :return:
     """
     measurement_operator = 1
     if pauli_string != '' and undo_basis is False:
         for char in pauli_string:
             if char == 'X':
                 measurement_operator = op.superkron(measurement_operator, g.r_y(-np.pi / 2))
             elif char == 'Y':
                 measurement_operator = op.superkron(measurement_operator, g.r_x(np.pi / 2))
             else:
                 measurement_operator = op.superkron(measurement_operator, g.id())
         self.operator(measurement_operator)
     elif pauli_string != '' and undo_basis is True:
         for char in pauli_string:
             if char == 'X':
                 measurement_operator = op.superkron(measurement_operator, g.r_y(np.pi / 2))
             elif char == 'Y':
                 measurement_operator = op.superkron(measurement_operator, g.r_x(-np.pi / 2))
             else:
                 measurement_operator = op.superkron(measurement_operator, g.id())
         self.operator(measurement_operator)
     else:
         pass
Example #13
0
def stabilizer(stabilizer, n, ancilla_label):
    """
    Stabilizer must contain only X and Z operators

    :param stabilizer: The stabilizer you want to measure
    :param ancilla_label: The ancilla_label qubit used to measure the stabilizer
    :param n: The number of data qubits in the circuit
    :return: A unitary that represents a quantum circuit that is used to measure a specific stabilizer,
    using CNOT and Hadamard gates
    """

    # The numbering of qubits starts from 1 rather than 0
    stabilizer_dict = {}
    oper_dict = {'0': id(), '1': h()}
    unitary = identity(pow(2, n))
    for counter, s in enumerate(stabilizer, 1):
        if s == 'I' or s == 'i':
            continue
        else:
            stabilizer_dict[counter] = s

    for s in stabilizer_dict:
        if stabilizer_dict[s] == 'Z' or stabilizer_dict[s] == 'z':
            unitary = dot(unitary, c_u(x(), n, s, ancilla_label))
        elif stabilizer_dict[s] == 'X' or stabilizer_dict[s] == 'x':
            string = op.generatehamiltoniantring(n,
                                                 '1',
                                                 onestring=True,
                                                 pos=s - 1,
                                                 pad='0')
            unitary = dot(unitary, op.superkron(oper_dict,
                                                val=1,
                                                string=string))
            unitary = dot(unitary, c_u(x(), n, s, ancilla_label))
            unitary = dot(unitary, op.superkron(oper_dict,
                                                val=1,
                                                string=string))
    return unitary
Example #14
0
 def time_step_evolve(self, basis=''):
     """
     :param h: Hamiltonian by which to evolve the system
     :param dt: time step to evolve by could be small or large
     :param basis: Basis of measurement
     :return: returns the state of qubit after evolution
     """
     self.U = expm(-1j * self.hamiltonian * self.dt)
     self.state = np.dot(self.U, np.dot(self.state, op.ctranspose(self.U)))
     for state, projector in zip(self.classical_states, self.get_projectors(self.measurement_string)):
         # Possibly change basis of measurement before calculating probability history.
         self.measure_basis(pauli_string=basis)
         self.classical_states_history[state].append(np.trace(np.dot(self.state, projector)).real)
         self.measure_basis(pauli_string=basis, undo_basis=True)
Example #15
0
def kraus_generator(n, non_ideal_qubits=0, classical_error=False, partialbath=False, opers=[]):
    """
    :param n:
    :param classical_error:
    :param opers:
    :param prob_error:
    :return:
    """
    num_operators = len(opers)
    kraus_operators = {str(i): opers[i] for i in range(len(opers))}
    if classical_error is False and partialbath is False:
        labels = op.createlabel(n, num_operators)
        for i in range(len(labels)):
            kraus = 1
            for digit in labels[i]:
                kraus = np.kron(kraus, kraus_operators[digit])
            yield kraus
    elif classical_error is False and partialbath:
        labels = op.createlabel(non_ideal_qubits, num_operators)
        for i in range(len(labels)):
            kraus = 1
            for digit in labels[i]:
                kraus = np.kron(kraus, kraus_operators[digit])
            yield kraus
Example #16
0
def serial_decohere(K, rho_s, n_s):
    """
    :param K: List of kraus operators
    :param rho: density matrix of system
    :param n: Number of qubits
    :return: Return evolved density matrix
    """
    K = list(K)
    out = np.zeros((pow(2, n_s), pow(2, n_s)), dtype=complex)
    try:
        assert type(K) == list
        for i in range(len(K)):
            out += np.dot(K[i], np.dot(rho_s, op.ctranspose(K[i])))
    except:
        raise TypeError('The input K must be a list of numpy arrays')
    return out
Example #17
0
def q_Hamiltonian(ham, n, s):
    """
    :param ham: hamiltonian by which the qubits will evolve by
    :param s : must be a string of ones e.g 010 represents id (tensor)ham(tensor)id while 10 represents ham(tensor) id
    :param n : The length of the string. This determines how many zeros there will be
    :return:
    """

    label = op.generatehamiltoniantring(n, s)
    a = zeros((pow(2, n), pow(2, n)), dtype=complex)
    terms = {"0": id(), "1": ham}
    for qubit in range(len(label)):
        tmp = 1
        for digit in label[qubit]:
            tmp = kron(tmp, terms[digit])
        a += tmp
    return a
Example #18
0
 def step_operator(self, step):
     """
     :param step: The step in the circuit
     :return: Returns a the operator for the particular step in the circuit
     """
     op_list = []
     if isinstance(step, str):
         for s in self.bucket[step]:
             op_list.append(self.gate_list[s])
         operators = list(map(eval, op_list))
         for i in range(len(operators)):
             if self.check_signature(operators[i]) is not []:
                 arg = self.arg_bucket[step][operators[i].__name__]
                 operators[i] = operators[i](*arg)
             else:
                 operators[i] = operators[i]()
     o = op.superkron(*operators)
     return o
Example #19
0
def generic_kraus(n, classical_error=False, opers=[], prob_error=[], generator=False):
    """
    This functions takes as an input generic operators and outputs a corresponding list of kraus operators for those
    n qubits. It also can do a classical simulation of noise by throwing down errors classically
    :param n:  The number of qubits experiencing the noise
    :param classical_error: If True the user must supply list of probabilities for list in oper
    :param opers: The list of kraus operators that appear in the sum
    :param prob_error: The list of probabilities for each operator in oper. Entries must add to 1. First operator is
    returned with probability in first position of prob_error.
    :param generator: Function becomes a generator in order to save memeory when a large number of qubits is being used
    :return:
    """

    num_operators = len(opers)

    if classical_error is False:
        A = np.zeros((pow(num_operators, n), pow(2, n), pow(2, n)),
                     dtype=complex) # 3 dimensional array to store kraus matrices
        kraus_operators = {str(i): opers[i] for i in range(len(opers))}
        labels = op.createlabel(n, num_operators)

        for i in range(len(labels)):
            temp=1
            for digit in labels[i]:
                temp = np.kron(temp, kraus_operators[digit])
            A[i] = temp
        return A

    if classical_error:
        # Returns a 3 dimensional array which stores only one kraus matrix
        A = np.zeros((pow(num_operators, 0), pow(2, n), pow(2, n)),
                     dtype=complex)  # 3 dimensional array to store kraus matrices
        if len(prob_error) != 0 or len(prob_error) != len(opers):
            if math.isclose(sum(prob_error), 1, rel_tol=1e-4):
                operators = {i: prob_error[i]*100 for i in range(len(prob_error))}
                lea_object = pmf(operators)
                picked_operator = lea_object.random()
                A[0] = opers[picked_operator]
                return A
            else:
                raise Exception('Probabilities must add to 1')
        else:
            raise Exception('prob_error list is empty or does not equal oper list')
Example #20
0
 def noise_op(self, same_bath=True, relax=True, dephase=False, create=False):
     noise_op_string_list = op.generatehamiltoniantring(self.n, '1')
     for qubit, string in enumerate(noise_op_string_list):
         for char in string:
             self.c_op[str(qubit)].append(self.annihilate[char])
             self.dephase_op[str(qubit)].append(self.dephase[char])
             self.create_op[str(qubit)].append(self.create[char])
     for q, q1, q2 in zip(self.c_op, self.dephase_op, self.create_op):
         if relax:
             self.c_op[q] = tensor(*self.c_op[q])
         if dephase:
             self.dephase_op[q1] = tensor(*self.dephase_op[q1])
         if create:
             self.create_op[q2] = tensor(*self.create_op[q2])
             self.collap.append(self.create_op[q2])
     if same_bath:
         if relax:
             for qs in self.c_op:
                 self.c_op[qs] = np.sqrt(1 / self.t1[0]) * self.c_op[qs]
                 self.collap.append(self.c_op[qs])
         if dephase:
             for qs in self.dephase_op:
                 self.dephase_op[qs] = np.sqrt(1 / (2 * self.t2[0])) * self.dephase_op[qs]
                 self.collap.append(self.dephase_op[qs])
         if create:
             for qs in self.dephase_op:
                 self.create_op[qs] = np.sqrt(1 / (self.t3[0])) * self.create_op[qs]
                 self.collap.append(self.create_op[qs])
     if same_bath is False:
         if relax:
             for t1_list, qs in enumerate(self.c_op):
                 self.c_op[qs] = np.sqrt(1 / self.t1[t1_list]) * self.c_op[qs]
                 self.collap.append(self.c_op[qs])
         if dephase:
             for t2_list, qs in enumerate(self.dephase_op):
                 self.dephase_op[qs] = np.sqrt(1 / (2 * self.t2[t2_list])) * self.dephase_op[qs]
                 self.collap.append(self.dephase_op[qs])
         if create:
             for t3_list, qs in enumerate(self.create_op):
                 self.create_op[qs] = np.sqrt(1 / self.t3[t3_list]) * self.create_op[qs]
                 self.collap.append(self.create_op[qs])
Example #21
0
def kraus_exact(n, t, t1, t2, markovian=False, alpha=None):
    """
    Produces the kraus matrices for the exact evolution of amplitude damping with dephasing channel
        :param n: number of qubit
        :param t: time step for evolution
        :param t1: relaxation time
        :param t2: dephasing time must be smaller than t1
        :param markovian: If true the kraus matrices are for non markovian evolution and
        t2 takes the role of  t_phi
        :param alpha: The power of 1/f^{alpha} flux noise
        :return:  a 3 dimensinal array of kraus matrices with amplitude damping and dephasing

    """
    A = np.zeros((pow(3, n), pow(2, n), pow(2, n)), dtype=complex)  # 3 dimensional array to store kraus matrices
    gamma = 1 - np.exp(-t / t1)
    if markovian:
        t_phi = 1 / t2 - 1 / (2 * t1)
        lambda1 = np.exp(-t / t1) * (1 - np.exp(-2 * (t / t_phi)))
        print('We are markovian')
    else:
        print('We are non markovian')
        t_phi = t2
        lambda1 = np.exp(-t / t1) * (1 - np.exp(-2 * (t / t_phi) ** (1 + alpha)))

    krausOperators = {
        "0": np.array([[1, 0], [0, np.sqrt(1 - gamma - lambda1)]]),
        "1": np.array([[0, np.sqrt(gamma)], [0, 0]]),
        "2": np.array([[0, 0], [0, np.sqrt(lambda1)]]),
    }

    labels = op.createlabel(n, 3)

    for i in range(len(labels)):
        temp = 1
        for digit in labels[i]:
            temp = np.kron(temp, krausOperators[digit])
        A[i] = temp

    return A
Example #22
0
def kraus_ad(n, t, t1):
    """
      Produces the kraus matrices for the amplitude damping channel
        :param n: number of qubit
        :param t: time step for evolution
        :param t1: relaxation time
        :return: returns a 3 dimensinal array of amplitude damping kraus matrices
      """

    A = np.zeros((pow(2, n), pow(2, n), pow(2, n)), dtype=complex)  # 3 dimensional array to store kraus matrices
    gamma = 1 - np.exp(-t / t1)
    adOperators = {
        "0": np.array([[1, 0], [0, np.sqrt(1 - gamma)]]),
        "1": np.array([[0, np.sqrt(gamma)], [0, 0]])
    }

    labels = op.createlabel(n, 2)

    for i in range(len(labels)):
        temp = 1
        for digit in labels[i]:
            temp = np.kron(temp, adOperators[digit])
        A[i] = temp
    return A
Example #23
0
    init = '111'
    oper_dict = {'0': g.z()}
    E = [np.array([[1, 0], [0, np.cos(np.pi/10)]]), np.array([[0, np.sin(np.pi/10)], [0, 0]])]
    # k = ne.generic_kraus(1, classical_error=False, opers=E)
    # generator_kraus = ne.kraus_generator(1, classical_error=False, opers=E)
    # m = [op.superkron(k[i]) for i in range(len(k))]
    q2 = Qubit(init, 3, no_measurment_qubits=3)
    q2.single_kraus = E
    q2.dt = 0.01
    q2.T = 1
    q2.partial_bath = True
    q2.no_non_ideal_qubits = 2
    # k = ne.kraus_ad(q2.n, 0.001, 10 ** (-2))
    # k = ne.kraus_exact(q2.n, q2.dt, 10**(-6), 10**(-6), markovian=True)
    # q2.kraus_operators = m
    # q2.yield_kraus = generator_kraus
    q2.xlabel = 'time'
    q2.ylabel = 'Probability'
    q2.hamiltonian = 0.5*op.superkron(oper_dict, val=1, string='000')
    q2.evolve(basis='ZZZ')
    # print('Returned state : ', q2.measure(return_state=True))
    # print('Probability distribution :', q2.classical_states)
    # q2.expectation_values({'X':op.superkron(g.z(), g.z(), g.z(), g.z(), g.z()), 'Y':op.superkron(g.y(), g.y(), g.y(), g.y(), g.y())})
    q2.graph('111')
    q2.graph('011')
    q2.graph('001')
    q2.graph('000')

    # print(q2.expect_values)
Example #24
0
    out = np.zeros((pow(2, n), pow(2, n)), dtype=complex)
    if partial_bath:
        ideal_qubits_oper = {'0': g.id()}
        id_oper = op.superkron(ideal_qubits_oper, val=1, string='0' * (n - non_ideal_qubits))
        for kraus in K:
            new_kraus = op.superkron(kraus, id_oper)
            out += np.dot(new_kraus, np.dot(rho_s, op.ctranspose(new_kraus)))
        return out
    else:
        for kraus in K:
            out += np.dot(kraus, np.dot(rho_s, op.ctranspose(kraus)))
        return out


if __name__ == '__main__':
    state = op.superkron(g.b4(), g.b4())
    state_1 = op.superkron(g.b4(), g.b4())
    E = [np.array([[1, 0], [0, np.cos(np.pi / 5)]]), np.array([[0, np.sin(np.pi / 5)], [0, 0]])]

    kraus = generic_kraus(2, classical_error=False, opers=E)
    m = [op.superkron(kraus[i]) for i in range(len(kraus))]

    for i in range(4):
        print(i)
        generator_kraus = kraus_generator(2, non_ideal_qubits=1, partialbath=True, classical_error=False, opers=E)
        state = apply_kraus(generator_kraus, state, 2, non_ideal_qubits=1, partial_bath=True)
        print('New Method:', state)

    for i in range(4):
        state_1 = serial_decohere(m, state_1, 2)
        print('Old Method: ', state_1)
Example #25
0
 def apply_op(self, op):
     self.psi = op * self.psi
     self.rho = op * self.rho * op.dag()
Example #26
0
 def operator(self, o):
     """
     :param o: The operator you want applied to the qubit
     :return:  Returns the transformed density matrix after the operation
     """
     self.state = np.dot(o, np.dot(self.state, op.ctranspose(o)))
Example #27
0
            out = np.dot(out, self.step_operator(i))
        out = op.ctranspose(out)
        return out

    def apply_unitary(self):
        """
        Applies unitary to the quantum state

        """
        U = self.circuit_unitary()
        self.qubits.operator(U)


if __name__ == '__main__':
    # This should create a 3 qubit GHZ circuit
    xxx = op.superkron(g.x(), g.x(), g.x())
    c = Circuit('000', measurement_qubits=3)
    c.add_step('h,id,id', arg_list=[[], [], []])
    c.add_step('c_u', arg_list=[[g.x(), 3, 1, 2]])
    c.add_step('c_u', arg_list=[[g.x(), 3, 2, 3]])
    ghz = c.qubits.state
    # print('GHZ state : ', ghz)

    # This should be a Toffoli gate circuit

    d = Circuit('110', measurement_qubits=3)
    d.add_step('x,id,id', arg_list=[[], [], []])
    d.add_step('id,id,r_y', arg_list=[[], [], [g.pi / 4]])
    d.add_step('c_u', arg_list=[[g.x(), 3, 2, 3]])
    d.add_step('id,id,r_y', arg_list=[[], [], [g.pi / 4]])
    d.add_step('id,id,x', arg_list=[[], [], []])