Ejemplo n.º 1
0
def comparing_n_a_gate_v1_and_n_a_gate_with_ancilla(n_qbits):
    n = n_qbits

    controlled_n_a_gate = create_controlled_n_a_gate_v1(n)
    print('\nc_n_a_gate version 1\n', controlled_n_a_gate)
    #     print(np.array(controlled_n_a_gate, dtype = float))

    controlled_n_a_gate_with_ancilla = create_controlled_n_a_gate_with_ancilla(
        n + 1)
    print('\nc_n_a_gate with ancilla\n', controlled_n_a_gate_with_ancilla)
    #     print(np.array(controlled_n_a_gate_with_ancilla, dtype = float))

    psi = apply_tensor(qubit_one, qubit_one)
    psi = apply_tensor(psi, qubit_one)
    print('\npsi inicial')
    print_psi(psi)

    psi_temp = apply_gate_to_psi(controlled_n_a_gate, psi)
    print('\napply controlled_n_a_gate to psi')
    print_psi(psi_temp)

    psi_temp = apply_gate_to_psi(controlled_n_a_gate_with_ancilla,
                                 apply_tensor(psi, qubit_zero))
    print('\napply controlled_n_a_gate_with_ancilla to psi')
    print_psi(psi_temp)
Ejemplo n.º 2
0
def create_controlled_n_a_gate_without_ancilla(n_qbits):
    """
    Description:
        Make a non unitary O gate
    Required Params:
        n_qbits: Number of qbits that algorithm will computer
    Optional Params:
        None
    Return Value:
        A non unitary O gate
    Example:
    
    """

    a_row = a**(1 / 2**(n_qbits - 2))

    c_n_a_row_gate = np.identity(4, dtype=complex)
    c_n_a_row_gate[3][3] = a_row

    identity_tensor = apply_n_tensor_to(n_qbits - 2, i)

    identity_c_n_a_row_gate = apply_tensor(identity_tensor, c_n_a_row_gate)

    controlled_n_not_identity_tensor = apply_tensor(
        create_controlled_n_not(n_qbits - 2), i)

    controlled_n_a_gate_without_ancilla = apply_gate_to_psi(
        identity_c_n_a_row_gate, controlled_n_not_identity_tensor)

    c_n_1_a_row_gate = np.identity(4, dtype=complex)
    c_n_1_a_row_gate[3][3] = 1 / a_row

    identity_c_n_1_a_row_gate = apply_tensor(identity_tensor, c_n_1_a_row_gate)

    controlled_n_a_gate_without_ancilla = apply_gate_to_psi(
        identity_c_n_1_a_row_gate, controlled_n_a_gate_without_ancilla)

    controlled_n_a_gate_without_ancilla = apply_gate_to_psi(
        controlled_n_not_identity_tensor, controlled_n_a_gate_without_ancilla)

    matrix_size = 2**n_qbits
    c_n_a_row_2_gate = np.identity(matrix_size, dtype=complex)
    c_n_a_row_2_gate[matrix_size - 1][matrix_size - 1] = a_row
    c_n_a_row_2_gate[matrix_size - 3][matrix_size - 3] = a_row

    controlled_n_a_gate_without_ancilla = apply_gate_to_psi(
        c_n_a_row_2_gate, controlled_n_a_gate_without_ancilla)

    # Returning controlled_n_a_gate_with_ancilla
    return controlled_n_a_gate_without_ancilla
Ejemplo n.º 3
0
def aplicar_medicao(operador_n, psi):
    # Aplicação do operador de medição
    # M|psi> = (n * |psi>) / sqrt(<psi| * ((n_t * n) * |psi>))

    # (n * |psi>)
    resultado = apply_gate_to_psi(operador_n, psi)

    # (n_t * n)
    projetor_n = np.dot(np.transpose(operador_n), operador_n)

    # ((n_t * n) * |psi>)
    normalizador = np.dot(projetor_n, psi)

    psi_t = np.transpose(psi)

    # <psi| * ((n_t * n) * |psi>)
    normalizador = np.dot(psi_t, normalizador)

    # sqrt(<psi| * ((n_t * n) * |psi>))
    normalizador = sqrt(normalizador)

    # (n * |psi>) / sqrt(<psi| * ((n_t * n) * |psi>))
    resultado = (1 / normalizador[0][0]) * resultado

    return resultado
Ejemplo n.º 4
0
def create_d_gate(n_qbits):

    c_n_a_gate = create_controlled_n_a_gate_v1(n_qbits)
    #     print('\nc_n_a_gate')
    #     print(np.array(c_n_a_gate, dtype = float))

    x_tensor = apply_n_tensor_to(n_qbits, x)
    #     print('\nx_tensor')
    #     print(np.array(x_tensor, dtype = float))

    i_x_tensor = apply_tensor(apply_n_tensor_to(n_qbits - 1, i), x)
    #     print('\ni_x_tensor')
    #     print(np.array(i_x_tensor, dtype = float))

    d_gate = x_tensor

    d_gate = apply_gate_to_psi(c_n_a_gate, d_gate)

    d_gate = apply_gate_to_psi(i_x_tensor, d_gate)

    d_gate = apply_gate_to_psi(c_n_a_gate, d_gate)

    d_gate = apply_gate_to_psi(x_tensor, d_gate)

    d_gate = apply_gate_to_psi(c_n_a_gate, d_gate)

    d_gate = apply_gate_to_psi(i_x_tensor, d_gate)

    d_gate = apply_gate_to_psi(c_n_a_gate, d_gate)

    return d_gate
Ejemplo n.º 5
0
def create_controlled_n_a_gate_with_ancilla(n_qbits):
    """
    Description:
        Make a non unitary O gate
    Required Params:
        n_qbits: Number of qbits that algorithm will computer
    Optional Params:
        None
    Return Value:
        A non unitary O gate
    Example:
    
    """

    matrix_size = 2**n_qbits

    # Creating matrix identity
    c_n_not_gate = np.identity(matrix_size, dtype=complex)

    c_n_not_gate[matrix_size - 1][matrix_size - 1] = 0
    c_n_not_gate[matrix_size - 2][matrix_size - 2] = 0
    c_n_not_gate[matrix_size - 1][matrix_size - 2] = 1
    c_n_not_gate[matrix_size - 2][matrix_size - 1] = 1

    identity_tensor = np.identity(int(matrix_size / 2), dtype=complex)

    n_a_gate = create_n_a_gate()

    identity_n_a_tensor = apply_tensor(identity_tensor, n_a_gate)

    controlled_n_a_gate_with_ancilla = apply_gate_to_psi(
        identity_n_a_tensor, c_n_not_gate)

    controlled_n_a_gate_with_ancilla = apply_gate_to_psi(
        c_n_not_gate, controlled_n_a_gate_with_ancilla)

    # Returning controlled_n_a_gate_with_ancilla
    return controlled_n_a_gate_with_ancilla
Ejemplo n.º 6
0
def testing_d_gate(n_qbits):
    n = n_qbits

    d_gate = create_d_gate(n)
    print('\nd_gate\n', d_gate)
    #     print(np.array(d_gate, dtype = float))

    psi = apply_n_tensor_to(n, qubit_one)
    print('\ninitial psi')
    print_psi(psi)

    psi = apply_gate_to_psi(d_gate, psi)
    print('\napplying d_gate to psi')
    print_psi(psi)
Ejemplo n.º 7
0
def testing_controlled_n_a_gate_v1(n_qbits):
    n = n_qbits

    controlled_n_a_gate = create_controlled_n_a_gate_v1(n)
    print('\nc_n_a_gate version 1\n', controlled_n_a_gate)
    #     print(np.array(controlled_n_a_gate, dtype = float))

    psi = apply_tensor(qubit_one, qubit_one)
    psi = apply_tensor(psi, qubit_one)
    print('\npsi inicial')
    print_psi(psi)

    psi = apply_gate_to_psi(controlled_n_a_gate, psi)
    print('\napplying controlled_n_a_gate to psi')
    print_psi(psi)
Ejemplo n.º 8
0
def testing_controlled_n_a_gate_with_ancilla(n_qbits):
    n = n_qbits

    controlled_n_a_gate_with_ancilla = create_controlled_n_a_gate_with_ancilla(
        n + 1)
    print('\ncontrolled_n_a_gate_with_ancilla\n',
          controlled_n_a_gate_with_ancilla)
    #     print(np.array(controlled_n_a_gate, dtype = float))

    psi = apply_tensor(qubit_one, qubit_one)
    psi = apply_tensor(psi, qubit_one)
    print('\npsi inicial')
    print_psi(psi)

    psi = apply_gate_to_psi(controlled_n_a_gate_with_ancilla,
                            apply_tensor(psi, qubit_zero))
    print('\napplying controlled_n_a_gate_with_ancilla to psi')
    print_psi(psi)
Ejemplo n.º 9
0
def create_n_a_gate_v2():

    matrix_size = 4

    c_n_u_gate = np.identity(matrix_size, dtype=complex)

    c_n_u_gate[matrix_size - 1][matrix_size - 1] = -1 * a
    c_n_u_gate[matrix_size - 2][matrix_size - 2] = a
    c_n_u_gate[matrix_size - 1][matrix_size - 2] = sqrt(1 - (a**2))
    c_n_u_gate[matrix_size - 2][matrix_size - 1] = sqrt(1 - (a**2))

    n_zero = np.zeros((2, 2), dtype=complex)
    n_zero[0][0] = 1

    i_n_zero_tensor = apply_tensor(np.identity(2, dtype=complex), n_zero)

    n_a_gate_v2 = apply_gate_to_psi(c_n_u_gate, i_n_zero_tensor)

    return n_a_gate_v2
tensor_i_h = apply_tensor(tensor_i, h)

# Creating projection_operator
projection_operator = apply_tensor(
    tensor_i, np.dot(qubit_zero, np.transpose(qubit_zero)))

############################################################
####### Circuit Execution ##################################
############################################################
# psi_0 - Creating tensor product between inputs: |000000>
psi = apply_n_tensor_to(n + 1, qubit_zero)
print("\npsi_0 - Creating tensor product between inputs: |000000>\n")
print_psi(psi)

# psi_1 - Applying tensor_h (divider) to psi_0
psi = apply_gate_to_psi(tensor_h, psi)
print("\npsi_1 - Applying tensor_h (divider) to psi\n")
print_psi(psi)

# psi_2 - Applying oracle to psi_1
psi = apply_gate_to_psi(oracle, psi)
print("\npsi_2 - Applying oracle to psi\n")
print_psi(psi)

# psi_3 - Applying controlled_u_1 to psi_2
psi = apply_gate_to_psi(controlled_u_1, psi)
print("\npsi_3 - Applying controlled_u_1 to psi\n")
print_psi(psi)

# psi_4 - Applying tensor_i_h (combiner) to psi_3
psi = apply_gate_to_psi(tensor_i_h, psi)
# Creating projection_operator
zero_projection_operator = np.dot(qubit_zero, np.transpose(qubit_zero))
projection_operator = apply_tensor( tensor_i, zero_projection_operator )
print("\nprojection_operator")
print(projection_operator.real)

   
 
# psi_0 - Creating tensor product between inputs: |000000>
psi = apply_n_tensor_to(n + 1, qubit_zero)
print("\npsi_0 - Creating tensor product between inputs: |000000>\n")
print_psi(psi)
      
  
# psi_1 - Applying tensor_h to psi_0 on work qubits
psi = apply_gate_to_psi( apply_tensor(tensor_h, i), psi )
print("\npsi_1 - Applying tensor_h to psi_0 on work qubits\n")
print_psi(psi)
     
  
# # psi_2 - Applying oracle to psi_1
# psi = apply_gate_to_psi( apply_tensor(oracle, i), psi )
# print("\npsi_2 - Applying oracle to psi\n")
# print_psi(psi)
     
     
# psi_3 - Applying v (qwd) to psi_2
psi = apply_gate_to_psi( apply_tensor(tensor_i, v), psi )
print("\npsi_3 - Applying v (qwd) to psi_2\n")
print_psi(psi)
 
    print(u_tau.real)

    # Creating v gate (qwd)
    # On the article it is defined in equation 11
    v = create_n_4_qwd_gate(n, m)
    print("\nv operator")
    print(v)

    # Creating controlled_0_Us (controlled_0_u_0)
    # On the article, in equation 15, the u_s is defined as:
    # u_s = 2 * |psi_0><psi_0| - identity
    # On the article, in equation 8, the |psi_0> is defined as:
    psi_0 = apply_n_tensor_to(n, qubit_zero)
    print("psi_0")
    print_psi(psi_0)
    psi_0 = apply_gate_to_psi(tensor_h, psi_0)
    print("psi_0")
    print_psi(psi_0)

    # |psi_0><psi_0|
    psi_0_transposed_psi_0 = np.dot(psi_0, np.transpose(psi_0))
    print("psi_0_transposed_psi_0")
    print(psi_0_transposed_psi_0)

    # 2 * |psi_0><psi_0| - identity
    u_s = 2 * psi_0_transposed_psi_0 - tensor_i
    print("u_s")
    print(u_s)

    # u_s = 2 * items_to_search_projector - tensor_i
    controlled_0_Us = create_controlled_u_gate(u_s, 0)
    tensor_h = apply_n_tensor_to(n, h)

    # Creating Fredkin's tensors
    tensor_f = apply_n_tensor_to(int(n / 3), f)

    # Creating Indentity's tensors
    tensor_i = apply_n_tensor_to(n - 1, i)

    # Creating O operator
    tensor_o_i = apply_tensor(create_o_gate(n), tensor_i)

    # psi_0 - Creating tensor product between inputs: |000000>
    psi = apply_n_tensor_to(n, qubit_zero)
    print('\npsi_0 - Creating tensor product between inputs: |000000>')
    print_psi(psi)

    # psi_1 - Applying tensor_h to psi_0
    psi = apply_gate_to_psi(tensor_h, psi)
    print('\npsi_1 - Applying tensor_h to psi_0')
    print_psi(psi)

    # psi_2 - Applying tensor_f to psi_1
    psi = apply_gate_to_psi(tensor_f, psi)
    print('\npsi_2 - Applying tensor_f to psi_2')
    print_psi(psi)

    # psi_3 - Applying tensor_o_i to psi_2
    psi = apply_gate_to_psi(tensor_o_i, psi)
    print('\npsi_3 - Applying tensor_o_i to psi_3')
    print_psi(psi)
Ejemplo n.º 14
0
    # Creating Hadamard's tensors
    tensor_h = apply_n_tensor_to(n, h)

    # Creating phase inversion gate (Oracle, Uf)
    phase_inversion = create_phase_inversion_gate(n, index)

    # Creating inversion about mean gate
    inversion_about_mean = create_inversion_about_mean_gate(n)

    # psi_0 - applying tensor to zeros qbits
    psi = apply_n_tensor_to(n, qubit_zero)
    print('\npsi_0 - applying tensor to zeros qbits')
    print(psi)

    # psi_1 - applying Hadamard's tensors to psi_0
    psi = apply_gate_to_psi(tensor_h, psi)
    print('\npsi_1 - applying Hadamards tensors to psi_0')
    print(psi)

    # Applying phase inversion gate and inversion about mean gate ( sqrt(2**n) times )
    for i in range(int(np.sqrt(2**n))):

        # psi_2 - applying phase inversion gate to psi_1
        psi = apply_gate_to_psi(phase_inversion, psi)
        print('\npsi_2.%d applying phase inversion gate' % (i + 1))
        print(psi)

        # psi_3 - applying inversion about mean gate to psi_2
        psi = apply_gate_to_psi(inversion_about_mean, psi)
        print('\npsi_3.%d applying inversion about mean gate' % (i + 1))
        print(psi)
Ejemplo n.º 15
0
    n = 2

    # Creating Hadamard's tensors
    tensor_h = apply_n_tensor_to(n, h)

    # Creating Identity's tensors
    tensor_i = apply_n_tensor_to(n, i)

    # Creating tensor product between:
    # Hadamard's tensors and Identity's tensors
    tensor_h_i = apply_tensor(tensor_h, tensor_i)

    # Creating Uf gate matrix
    uf = create_uf_gate(n)

    # psi_0 - Creating tensor product between inputs: X1 = |0> and X2 = |0>
    psi = apply_n_tensor_to(2 * n, qubit_zero)

    # psi_1 - Applying tensor_h_i to psi_0
    psi = apply_gate_to_psi(tensor_h_i, psi)

    # psi_2 - Applying Uf to psi_1
    psi = apply_gate_to_psi(uf, psi)

    # psi_3 - Applying tensor_h_i to psi_2
    psi = apply_gate_to_psi(tensor_h_i, psi)

    # Showing psi_3 state
    #     psi = np.array(psi, dtype=float)
    print(psi)