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)
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
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
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
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
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)
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)
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)
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)
# 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)
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)