Пример #1
0
def update_qc(
        nb_qubits,
        depth=1):  # compute the circuit, with CNOT and single qubit gates
    global gate_number, gate_apply
    circuit = qtn.Circuit(N=nb_qubits)

    def entangle_layer(circ):
        """
        Creates a linear entangeling layer"""
        for ii in range(0, nb_qubits - 1, 2):
            circ.apply_gate('CNOT', ii, ii + 1)
        for ii in range(1, nb_qubits - 1, 2):
            circ.apply_gate('CNOT', ii, ii + 1)

    def apply_rotation_gates(n, d, qubit):
        gate_number = operations[n * d + qubit]
        e = '{}'.format(gate_number)
        q = 'gate_apply=gate' + e + '.copy()'
        exec(q, globals(), globals())
        b = len(gate_apply)
        for l in range(0, b, 1):
            x = gate_apply[l]
            circuit.apply_gate(x, qubit)

    def last_rotation_layer(n, qubit):

        gate_number = operations[n]

        e = '{}'.format(gate_number)
        q = 'gate_last=gate' + e + '.copy()'
        exec(q, globals(), globals())
        c = len(gate_last)
        for l in range(0, c, 1):
            x = gate_last[l]
            circuit.apply_gate(x, qubit)

    for d in range(depth):
        for ii in range(nb_qubits):
            # gate_number= operations[nb_qubits * d + i]
            # exec(f'gate_to_apply= gate{gate_number}')
            # b=len(gate_to_apply)
            # for l in range(0,b,1):
            #     x=gate_to_apply[l]
            #     circuit.apply_gate(x, i)
            apply_rotation_gates(nb_qubits, d, ii)
            entangle_layer(circuit)
    for j in range(nb_qubits * depth, nb_qubits + nb_qubits * depth):
        for i in range(nb_qubits):
            last_rotation_layer(j, i)
            # gate_number= operations[j]
            # exec(f'gate_to_apply_last= gate{gate_number}')
            # c=len(gate_to_apply_last)
            # for l in range(0,c,1):
            #     x=gate_to_apply_last[j]
            #     circuit.apply_gate(x, iii)
            # x = operations[j]
            # circuit.apply_gate(x, iii)
    return circuit
Пример #2
0
 def test_prepare_GHZ(self):
     qc = qtn.Circuit(3)
     gates = [
         ('H', 0),
         ('H', 1),
         ('CNOT', 1, 2),
         ('CNOT', 0, 2),
         ('H', 0),
         ('H', 1),
         ('H', 2),
     ]
     qc.apply_circuit(gates)
     assert qu.expec(qc.psi.to_dense(), qu.ghz_state(3)) == pytest.approx(1)
Пример #3
0
def random_circuit(nb_qubits, depth=1):
    # global gate_numbers, gates_apply
    circuit = qtn.Circuit(N=nb_qubits)

    def entangle_layer(circ, gate_round=None):
        """
        Creates a linear entangeling layer"""
        for ii in range(0, nb_qubits - 1, 2):
            circ.apply_gate('CNOT', ii, ii + 1, gate_round=gate_round)
        for ii in range(1, nb_qubits - 1, 2):
            circ.apply_gate('CNOT', ii, ii + 1, gate_round=gate_round)

    def apply_rotation_gates(n, d, qubit, gate_round=None):
        gate_numbers = operations_random[n * d + qubit]
        e = '{}'.format(gate_numbers)
        q = 'gates_apply=gate' + e + '.copy()'
        exec(q, globals(), globals())
        b = len(gates_apply)
        for l in range(0, b, 1):
            x = gates_apply[l]
            circuit.apply_gate(x, qubit, gate_round=gate_round)

    def last_rotation_layer(n, qubit, gate_round=None):

        gate_numbers = operations_random[n]

        e = '{}'.format(gate_numbers)
        q = 'gate_last=gate' + e + '.copy()'
        exec(q, globals(), globals())
        c = len(gate_last)
        for l in range(0, c, 1):
            x = gate_last[l]
            circuit.apply_gate(x, qubit, gate_round=gate_round)

    def U3_gates(qubit, gate_round=None):
        circuit.apply_gate('U3', 0, 0, 0, qubit, gate_round=gate_round)

    for d in range(depth):
        for ii in range(nb_qubits):
            apply_rotation_gates(nb_qubits, d, ii, gate_round=d)
            U3_gates(ii, gate_round=d)
        entangle_layer(circuit, gate_round=d)
    for j in range(nb_qubits * depth, nb_qubits + nb_qubits * depth):
        for i in range(nb_qubits):
            last_rotation_layer(j, i, gate_round=depth)
            U3_gates(i, gate_round=depth)

    return circuit
Пример #4
0
def qcnewcircuit(nb_qubits, depth):
    """
    Creates a new random 'cliffod' circuit"""
    Warning("Currently only makes a reduced Clifford circuit")
    global op_list
    op_list = []
    # Construct circuit
    circuit = qtn.Circuit(N=nb_qubits)

    # Need to increase the gate set here... maybe this isn't the best way
    # Might need to use u3 params instead, but this will do for now
    # gate_list = ['H', 'X', 'Y',
    #              'Z', 'IDEN', 'S']

    def entangle_layer(circ):
        """
        Creates a linear entangeling layer"""
        for ii in range(0, nb_qubits - 1, 2):
            circ.apply_gate('CNOT', ii, ii + 1)
        for ii in range(1, nb_qubits - 1, 2):
            circ.apply_gate('CNOT', ii, ii + 1)

    def rotaiton_layer(circ):
        """
        Creates a layer of single qubit rotations based on the list 'single_rotatoins'"""

        # random_points = np.random.randint(
        #     0, len(gate_list), circ.num_qubits)
        for ii in range(nb_qubits):
            # for random_number in cliff_gates:
            random_number = random.choice(cliff_gates)
            exec(f'random_gate= gate{random_number}', globals(), globals())
            op_list.append(random_number)
            x = len(random_gate)
            for j in range(x):
                gate = random_gate[j]
                circ.apply_gate(gate, ii)

    # Apply first rotation layer (else CX layer does nothing)
    rotaiton_layer(circuit)

    # Loop though and alternate rotation and entangelment layers
    for ii in range(depth):
        entangle_layer(circuit)
        rotaiton_layer(circuit)
    return circuit
Пример #5
0
def Target_circuit():
    """
    Generate the circuit of the target state
    """
    qc = qtn.Circuit(N=n, tags='PSI0')
    #qc = qtn.Tensor(data=qcc)
    for i in range(d):
        for j in range(n):
            gates(qubit_structure[n * i + j], target_gates[n * i + j], qc)
        for j in range(0, n - 1, 2):
            qc.apply_gate('CNOT', j, j + 1, gate_round=1)
        for j in range(1, n - 1, 2):
            qc.apply_gate('CNOT', j, j + 1, gate_round=1)
        #qc.barrier()
    for i in range(n * d, n * d + n):
        gates(qubit_structure[i], target_gates[i], qc)

    return qc
Пример #6
0
 def test_prepare_GHZ(self):
     qc = qtn.Circuit(3)
     gates = [
         ('H', 0),
         ('H', 1),
         ('CNOT', 1, 2),
         ('CNOT', 0, 2),
         ('H', 0),
         ('H', 1),
         ('H', 2),
     ]
     qc.apply_circuit(gates)
     assert qu.expec(qc.psi.to_dense(), qu.ghz_state(3)) == pytest.approx(1)
     counts = qc.simulate_counts(1024)
     assert len(counts) == 2
     assert '000' in counts
     assert '111' in counts
     assert counts['000'] + counts['111'] == 1024
Пример #7
0
def Output_circuit():
    """
    Generate the circuit of the output state
    """
    global energy, t_star
    P = 0
    qc = qtn.Circuit(N=n, tags='PSI0')
    new_gates = []
    Ord_Ga = random.randint(0, g - 1)  #Nth gates
    Ind_Ga = NN(output_gates[Ord_Ga])
    for i in range(g):
        new_gates.append(output_gates[i])
    new_gates[Ord_Ga] = Ind_Ga
    for i in range(d):
        for j in range(n):
            gates(qubit_structure[n * i + j], target_gates[n * i + j], qc)
        for j in range(0, n - 1, 2):
            qc.apply_gate('CNOT', j, j + 1, gate_round=1)
        for j in range(1, n - 1, 2):
            qc.apply_gate('CNOT', j, j + 1, gate_round=1)
    for i in range(n * d, n * d + n):
        gates(qubit_structure[i], target_gates[i], qc)

    psi = qc.to_dense()
    E = np.real(1 - (psi.H @ target) * (target.H @ psi))
    if E < 0.01 and t_star == 0:
        t_star = counts
    if E < np.real(energy):
        P = 1
    else:
        P = math.exp(-Beta * (np.real(E) - np.real(energy)))
    if random.random() < P:
        energy = E
        Energy_matrix.append(np.real(energy))
        output_gates[Ord_Ga] = Ind_Ga
    else:
        Energy_matrix.append(energy)
    return qc
Пример #8
0
import random
import quimb.tensor as qtn
import quimb as qu
%config InlineBackend.figure_formats = ['svg']

# 10 qubits and tag the initial wavefunction tensors
circ = qtn.Circuit(N=10, tags='PSI0')

# initial layer of hadamards
for i in range(10):
    circ.apply_gate('H', i, gate_round=0)

# # 8 rounds of entangling gates
for r in range(1, 9):
    #
    #     # even pairs
    #     for i in range(0, 10, 2):
    #         circ.apply_gate('CNOT', i, i + 1, gate_round=r)
    #
    # Y-rotations
    for i in range(10):
        circ.apply_gate('RY', 1.234, i, gate_round=r)
#
#     # odd pairs
#     for i in range(1, 9, 2):
#         circ.apply_gate('CZ', i, i + 1, gate_round=r)

# final layer of hadamards
for i in range(10):
    circ.apply_gate('H', i, gate_round=r + 1)