Esempio n. 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
Esempio n. 2
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
Esempio n. 3
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)
Esempio n. 4
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
Esempio n. 5
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
Esempio n. 6
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
Esempio n. 7
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
Esempio n. 8
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
Esempio n. 9
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
Esempio n. 10
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)
Esempio n. 11
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)
Esempio n. 12
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=[[], [], []])