def find_y(N, a, q, reps=5 ): # Uses the order finding algorithm to give possible values for y simulator = Simulator() # Sets up simulator circuit = cirq.Circuit() number_qubits = q # Sets up all qubits to be used. m_qubits = [cirq.GridQubit(i, 0) for i in range(2 * number_qubits)] x_qubits = [ cirq.GridQubit(i, 0) for i in range(2 * number_qubits, 3 * number_qubits) ] b_qubits = [ cirq.GridQubit(i, 0) for i in range(3 * number_qubits, 4 * number_qubits + 1) ] zero_qubit = cirq.GridQubit(4 * number_qubits + 1, 0) print('Number of qubits: {}'.format(4 * number_qubits + 5)) circuit.append(order_find(a, N, b_qubits, x_qubits, zero_qubit, m_qubits), strategy=InsertStrategy.NEW) # Runs the simulation. return simulator.run(circuit, repetitions=reps).histogram( key='q') # Returns a dictionary of the measurment results.
def calculate_expectation(all_qubits_in_circuit, cirq_circuit, operator_circuits): """ Computes the expectation value according to the formula <psi|O|psi> where O is a Pauli operator represented by the state generated from `operator_circuits` for which the expectation is to be calculated over psi where psi is the state generated from `cirq_circuit` Parameters --------- all_qubits_in_circuit : (list) list of all qubits in `cirq_circuit` cirq_circuit : (Circuit) represents the paramterized circuit for the ansatz operator_circuits : (list of Circuit objects) represents a circuit generated by applying a Pauli operator on a qubit. Returns ------- result_overlaps : (list) represents the expectation values of each Pauli operator in `operator_circuits` given the state represented by `cirq_circuit`. """ simulator = Simulator() result_overlaps = [] simulation_result = simulator.simulate(cirq_circuit) cirq_circuit_amplitudes = simulation_result.final_state for op_circuit in operator_circuits: qubits = all_qubits_in_circuit[:] if(len(op_circuit._moments) == 0): result_overlaps.append( np.conj(cirq_circuit_amplitudes).T.dot(cirq_circuit_amplitudes)) else: if(len(all_qubits_in_circuit) != len(op_circuit.all_qubits())): op_circuit = VQE.modify_operator_circuit( qubits, op_circuit) unitary_matrix_op = unitary(op_circuit) result_overlaps.append(np.conj(cirq_circuit_amplitudes).T.dot( unitary_matrix_op).dot(cirq_circuit_amplitudes)) return result_overlaps
def qubit_wavefunction_from_vacuum(ops: 'QubitOperator', qubits: List['LineQubit']) -> numpy.ndarray: """Generate a cirq wavefunction from the vacuum given qubit operators and a set of qubits that this wavefunction will be represented on Args: ops (QubitOperators) - a sum of qubit operations with coefficients \ scheduling the creation of the qubit wavefunction qubits (Qid) - the qubits of the quantum computer Returns: final_state (numpy.array(dtype=numpy.complex64)) - the fully projected \ wavefunction in the cirq representation """ nqubits = len(qubits) vacuum = init_qubit_vacuum(nqubits) final_state = numpy.zeros(2**nqubits, dtype=numpy.complex128) qpu = Simulator(dtype=numpy.complex128) for term in ops.terms: circuit = qubit_ops_to_circuit(term, qubits) state = vacuum.copy() result = qpu.simulate(circuit, qubit_order=qubits, initial_state=state) final_state += result.final_state_vector * ops.terms[term] return final_state
def test_simulate(self): compressed_status = [True, False] rad = 0.75 pauli_word = PauliWord("XZYX") for initial_state in range(2**len(pauli_word)): results = [] for is_compressed in compressed_status: simulator = Simulator() circuit = Circuit() qubits = [GridQubit(i, j) for i in range(3) for j in range(3)] gate = PauliWordExpGate(rad, pauli_word) operation = gate.on(*qubits[0:len(gate.pauli_word)]) if is_compressed: circuit.append(operation) else: circuit.append(cirq.decompose(operation)) result = simulator.simulate( circuit, initial_state=initial_state ) # type: cirq.SimulationTrialResult # print(circuit) print(result.final_state) # print(cirq.unitary(circuit_compressed)) results.append(result) self.assertTrue( np.allclose(results[0].final_state, results[1].final_state, rtol=1e-4, atol=1e-5))
def qubit_projection(ops: QubitOperator, qubits: List[LineQubit], state: numpy.ndarray, coeff: numpy.ndarray) -> None: """Find the projection of each set of qubit operators on a wavefunction. Args: ops (qubit gates) - A sum of qubit operations which represent the \ full ci wavefunction in the qubit basis. qubits (Qid) - The qubits of a quantum computer. state (numpy.array(dtype=numpy.complex64)) - a cirq wavefunction that \ is being projected coeff (numpy.array(dtype=numpy.complex64)) - a coefficient array that \ will store the result of the projection. """ qpu = Simulator(dtype=numpy.complex128) for indx, cluster in enumerate(ops.terms): circuit = qubit_ops_to_circuit(cluster, qubits) work_state = state.copy() result = qpu.simulate(circuit, qubit_order=qubits, initial_state=work_state) coeff[indx] = result.final_state_vector[0]
def compute_players(self): self.measure_players() simulator = Simulator() for player in self.players: result = '' if player.next_qubit1 != 0 or player.next_qubit2 != 0: result = simulator.run(player.circuit) res = str(result) bits1 = '' bits2 = '' bit = '' for i in range(len(res)): if res[i] == '=': bit = bit + str(res[i + 1]) if player.next_qubit1 > 0: bits1 = bit[:player.next_qubit1] if player.next_qubit2 > 0: bits2 = bit[player.next_qubit1:] if len(player.card1) > 1: player.card1 = [player.card1.pop(int(bits1, 2))] if len(player.card2) > 1: player.card2 = [player.card2.pop(int(bits2, 2))]
def main(): qft_circuit = generate_2x2_grid() print("circuit:") print(qft_circuit) sim = Simulator() res = sim.simulate(qft_circuit) print('\nfinal state:') print(np.around(res.final_state, 3))
def test_QCBM(benchmark, nqubits): benchmark.group = "QCBM" qubits = [cirq.GridQubit(k, 0) for k in range(nqubits)] circuit = generate_qcbm_circuit(nqubits, qubits, 10, [(i, (i+1) % nqubits) for i in range(nqubits)]) simulator = Simulator(dtype=np.complex128) benchmark(simulator.simulate, circuit, qubit_order=qubits)
def run_bench(benchmark, nqubits, gate, locs=(1, )): qubits = [cirq.GridQubit(k, 0) for k in range(nqubits)] circuit = cirq.Circuit() locs = tuple(qubits[k] for k in locs) circuit.append(gate(*locs)) simulator = Simulator(dtype=np.complex128) benchmark(simulator.simulate, circuit, qubit_order=qubits)
def expectation(all_qubits_in_circuit, cirq_circuit, cirq_pauli_sum): """ Computes the expectation value of `cirq_pauli_sum` over the distribution generated from `cirq_circuit`. The expectation value is calculated by calculating <psi|O|psi> Parameters --------- all_qubits_in_circuit : (list) list of all qubits in `cirq_circuit` cirq_circuit : (Circuit) represents the paramterized circuit for the ansatz cirq_pauli_sum : (CirqPauliSum or ndarray) CirqPauliSum representing the Pauli operator for which the expectation value is to be calculated or a numpy matrix representing the Hamiltonian tensored up to the appropriate size. Returns ------- expectation.real : (float) represents the expectation value of cirq_pauli_sum given the distribution generated from `cirq_circuit`. """ if isinstance(cirq_pauli_sum, np.ndarray): simulator = Simulator() simulation_result = simulator.simulate(cirq_circuit) cirq_circuit_amplitudes = simulation_result.final_state cirq_circuit_amplitudes = np.reshape( cirq_circuit_amplitudes, (-1, 1)) average_exp = np.conj(cirq_circuit_amplitudes).T.dot( cirq_pauli_sum.dot(cirq_circuit_amplitudes)).real return average_exp else: operator_circuits = [] operator_coeffs = [] for p_string in cirq_pauli_sum.pauli_strings: op_circuit = Circuit() for qubit, pauli in p_string.items(): gate = pauli op_circuit.append( [gate(qubit)], strategy=InsertStrategy.EARLIEST) operator_circuits.append(op_circuit) operator_coeffs.append(p_string.coefficient) result_overlaps = VQE.calculate_expectation( all_qubits_in_circuit, cirq_circuit, operator_circuits) result_overlaps = list(result_overlaps) expectation = sum( list(map(lambda x: x[0]*x[1], zip(result_overlaps, operator_coeffs)))) return expectation.real
def test_symbolic_gate(self): sym_circuit = Circuit() qubits = [GridQubit(i, j) for i in range(3) for j in range(3)] gate = GlobalPhaseGate(sympy.Symbol("rad")) sym_circuit.append(gate.on(qubits[0])) print(sym_circuit) rad_list = np.random.rand(10) * 5 for rad in rad_list: simulator = Simulator() circuit = cirq.resolve_parameters(sym_circuit, {"rad": rad}) result = simulator.simulate(circuit) self.assertTrue( np.allclose(result.final_state, np.exp(1.0j * rad * np.pi) * np.array([1, 0])))
def solve_maxcut(qubit_pairs, steps=1): """ Solves the maxcut problem on the input graph Parameters ---------- qubit_pairs : (list of GridQubit pairs) represents the graph on which maxcut is to be solved steps : (int) number of mixing and cost function steps to use. Default=1 """ cirqMaxCutSolver = CirqMaxCutSolver(qubit_pairs=qubit_pairs, steps=steps) qaoa_instance = cirqMaxCutSolver.solve_max_cut_qaoa() betas, gammas = qaoa_instance.get_angles() t = np.hstack((betas, gammas)) param_circuit = qaoa_instance.get_parameterized_circuit() circuit = param_circuit(t) sim = Simulator() result = sim.simulate(circuit) display_maxcut_results(qaoa_instance, result)
import cirq from cirq import Simulator q_stay = cirq.NamedQubit('q_stay') q_flip = cirq.NamedQubit('q_flip') c = cirq.Circuit(cirq.X(q_flip)) simulator = Simulator() # first qubit in order flipped result = simulator.simulate(c, qubit_order=[q_flip, q_stay]) print(abs(result.final_state).round(3)) # prints # [0. 0. 1. 0.] # second qubit in order flipped result = simulator.simulate(c, qubit_order=[q_stay, q_flip]) print(abs(result.final_state).round(3)) # prints # [0. 1. 0. 0.]
'n_bReg': n_bReg, 'w_bReg': w_bReg, 'n_phiReg': n_phiReg, 'w_phiReg': w_phiReg } g_1, g_2, g_12 = 2, 1, 0 gp = math.sqrt(abs((g_1 - g_2)**2 + 4 * g_12**2)) if g_1 > g_2: gp = -gp g_a, g_b = (g_1 + g_2 - gp) / 2, (g_1 + g_2 + gp) / 2 u = math.sqrt(abs((gp + g_1 - g_2) / (2 * gp))) eps = .001 circuit = cirq.Circuit() simulator = Simulator() circuit.append([[X((qubit)) for qubit in pReg[i]] for i in range(N + n_i)]) circuit.append([[X((qubit)) for qubit in hReg[i]] for i in range(N)]) w_hReg.extend([GridQubit(N + n_i, j) for j in range(L - 1)]) eReg.extend([GridQubit(N + n_i, L - 1)]) wReg.extend([GridQubit(N + n_i, j) for j in range(L, L + 5)]) n_phiReg.extend([GridQubit(N + n_i + 1, j) for j in range(L)]) w_phiReg.extend([GridQubit(N + n_i + 1, j) for j in range(L, 2 * L - 1)]) n_aReg.extend([GridQubit(N + n_i + 2, j) for j in range(L)]) w_aReg.extend([GridQubit(N + n_i + 2, j) for j in range(L, 2 * L - 1)]) n_bReg.extend([GridQubit(N + n_i + 3, j) for j in range(L)]) w_bReg.extend([GridQubit(N + n_i + 3, j) for j in range(L, 2 * L - 1)]) timeStepList, P_aList, P_bList, P_phiList, Delta_aList, Delta_bList, Delta_phiList = [], [], [], [], [], [], [] cc.populateParameterLists(N, timeStepList, P_aList, P_bList, P_phiList,
def run(formula_original, truth_table): atomics = 0 operations = 0 negations = 0 repetitions = [] formula_original = formula_original.replace(' ', '') formula_original = formula_original.replace('∨', '|') formula_original = formula_original.replace('→', '>') formula_original = formula_original.replace('∧', '&') formula_original = formula_original.replace('¬', '~') formula = list(formula_original) table = list(truth_table) print(formula) #tranforma x > y em ~x | y #ERRO ESTÁ AQUI. A associação é a esquerda, mas o caso (x | y) -> z está vendo traduzido #como x | ~y | z, quando na verdade deve ser ~(x | y) | z # O(n) """ for i in range(len(formula)): if formula[i] == '>': formula[i] = '|' formula.insert(i - 1, '~') """ print(formula) parenteses = 0 # lê a formula, contando cada coisa # O(n) for element in formula: if element == '~': #lidando apenas com a negação de clausulas atomicas. Qualquer negação maior devem ser aplicadas as De Morgan Laws negations = negations + 1 elif element == '|' or element == '&' or element == '>': #aqui deve entrar qualquer uma das operações operations = operations + 1 elif element == '(' or element == ')': parenteses = parenteses + 1 else: atomics = atomics + 1 repetitions.append(element) print("Atomicos: ", end = '') print(atomics) print("operations: ", end = '') print(operations) #print(repetitions) full_size = negations + operations + atomics + parenteses size = operations + atomics + parenteses # cria o numero de qubits adequado qubits = cirq.LineQubit.range(size) circuit = cirq.Circuit() size2 = len(formula) #print(len(formula)) #print(full_size) if full_size != size2: print("Erro nos tamanhos!") exit() # entrelaça os qubits necessários # ignora as negations, que serão lidadas com mais para frente uniques = 0 formula_use = remove_values(formula, '~') #O(n), maximo de ligações é N for i in range(size): if not str(formula_use[i]).isalnum(): #print(formula_use[i]) continue uniques = uniques + 1 circuit.append(cirq.H(qubits[i])) for j in range(i + 1, size): if (formula_use[i] == formula_use[j]): circuit.append([cirq.CNOT(qubits[i], qubits[j])]) formula_use[j] = "_" formula_use[i] = "_" #Cuida das negations #O(n) neg_count = 0 for i in range(full_size): if formula[i] == '~': circuit.append(cirq.X(qubits[i - neg_count])) neg_count = neg_count + 1 indexator = list(range(size)) #faz as operações lógicas #associação a esquerda, não aceita parênteses por enquanto print(formula_use) print(formula) #passada inicial, lidando com os parenteses: print(indexator) print("ENTRANDO -------------") has_parenteses = 1 i = 0 while len(indexator) > 1 and has_parenteses == 1: has_parenteses = 0 for i in range(len(indexator)): if formula_use[indexator[i]] == '(': #achou o abre parenteses print(" ABRIU -------------") has_parenteses = 1 start = i while formula_use[indexator[i]] != ')': #procura o fecha parênteses i = i + 1 if formula_use[indexator[i]] == '(':# achou outro abre parênteses, atualiza o start start = i print("FECHOU ---------") #quando saiu do while, está no primeiro ')' - assumindo que a afirmação está bem formada (numero equilibrado de parenteses) #destruir os parenteses antes internal_count = i - start - 1 print(indexator) del indexator[start] del indexator[i - 1] print(indexator) create_circuit(formula_use, circuit, qubits, indexator, start, start + internal_count) print("CHECK----------") print(i) print(indexator) break #if i >= len(indexator): # i = 0 print("SAINDO ------------------------") print(formula_use) print(indexator) create_circuit(formula_use, circuit, qubits, indexator, 0, len(indexator) - 1) print(indexator) print(circuit) simulator = Simulator() result = simulator.simulate(circuit, initial_state=000000000000000) print(result.dirac_notation()) string_result = str(result.dirac_notation()) original_ones = 0 original_zeros = 0 for i in range(len(table)): if table[i] == 0: original_zeros = original_zeros + 1 else: original_ones = original_ones + 1 ones = 0 zeros = 0 temp_parenteses = 0 for i in range(indexator[0]): if formula_use[i] == ')' or formula_use[i] == '(': temp_parenteses = temp_parenteses + 1 for i in range(len(string_result)): if string_result[i] == "|": if int(string_result[i + indexator[0] + 1 - temp_parenteses]) == 0: zeros = zeros + 1 else: ones = ones + 1 print("Truth Table Ones/Zeros:", end = ' ') print(original_ones, end = '/') print(original_zeros) print("Circuit Result:") print("Ones:", end = '') print(ones) print("Zeros:", end='') print(zeros)
cooling_out_exists = False if os.path.exists(outfile_reheating): print(f'output file {outfile_reheating} exists already.') reheating_out_exists = True else: reheating_out_exists = False if cooling_out_exists and reheating_out_exists: print('exiting.') exit() print('\nBuilding circuit') stopwatch = time.time() system = spinmodels.TFIMChain(L, JvB, 1, sparse=True) system.normalize() circuit = qdccirq.bangbang_protocol(system, COUPLING_PAULIS, nit) simulator = Simulator() print('done in', time.time() - stopwatch, 'seconds.') # cooling if not cooling_out_exists: print('\nRunning cooling simulation') stopwatch = time.time() norm_samples = [] energy_samples = [] gsf_samples = [] for _ in range(n_samples): # initialize random computational-basis system state (this emulates the # maximally-mixed system state) tensored with fridge |0> init_state = np.zeros(2**(L + 1), dtype=np.complex64) init_state[np.random.randint(L)] = 1
def basic_circuit(meas=True): sqrt_x = cirq.X**0.5 yield sqrt_x(q0), sqrt_x(q1) yield cirq.CZ(q0, q1) yield sqrt_x(q0), sqrt_x(q1) if meas: yield cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1') circuit = cirq.Circuit() circuit.append(basic_circuit()) print(circuit) from cirq import Simulator simq = Simulator() result = simq.run(circuit) print(result) #Ciruit Stepping circuit = cirq.Circuit() circuit.append(basic_circuit()) for i, step in enumerate(simq.simulate_moment_steps(circuit)): print('state at step %d: %s' % (i, np.around(step.state_vector(), 3))) #monte carlo noise q = cirq.NamedQubit('a') circuit = cirq.Circuit.from_ops(cirq.bit_flip(p=0.2)(q), cirq.measure(q)) #PauliXGate
if __name__ == '__main__': uniform_vowel = Distribution( { 'a': 1 / 5, 'e': 1 / 5, 'i': 1 / 5, 'o': 1 / 5, 'u': 1 / 5, }, 8) print(uniform_vowel) vowel_aog = AOG(uniform_vowel) vowel_dist = get_dist(Simulator(), vowel_aog.as_circuit(), 8) print(vowel_dist.print_strs()) print(vowel_aog.pprint()) quantum_vowel = vowel_aog.as_circuit() print(quantum_vowel) exit(0) vowel_sim = Simulator() vowel_res = vowel_sim.simulate(quantum_vowel) print(vowel_res) exit(0) dist = {0b0011: 1 / 2, 0b1011: 1 / 4, 0b0101: 1 / 8, 0b1110: 1 / 8} d = Distribution(dist, 4)
# basic circuit constructor def basic_circuit(m=True): sqrt_x = cirq.X**0.5 yield sqrt_x(q0), sqrt_x(q1) yield cirq.CZ(q0, q1) yield sqrt_x(q0), sqrt_x(q1) if (m): yield cirq.measure(q0, key='alpha'), cirq.measure(q1, key='beta') circuit = cirq.Circuit() circuit.append(basic_circuit()) print(circuit) # run the simulator sim = Simulator() res = sim.run(circuit) print(res) def main(): qft_circuit = generate_2x2_grid() print("circuit:") print(qft_circuit) sim = Simulator() res = sim.simulate(qft_circuit) print('\nfinal state:') print(np.around(res.final_state, 3)) def cz_swap(q0, q1, rot):
import cirq import numpy as np from matplotlib import pyplot as plt import torch import math import random from cirq import Simulator simulator = Simulator() def choose_subset(n): a = np.random.randint(0, high=2, size=n) if np.sum(a) % 2 == 0: a[0] = 1 - a[0] subset = [] for i in range(n): if a[i] == 1: subset += [i] return a, subset def subset_parity(subset, input_b, n): s = sum(input_b[subset]) if s % 2 == 0: l_z = 1.0 else: l_z = -1.0 return l_z
import tensorflow as tf import tensorflow_quantum as tfq import cirq from cirq.ops import CCX from cirq import Simulator import sympy import numpy as np # visualization tools import matplotlib.pyplot as plt from cirq.contrib.svg import SVGCircuit simulator = Simulator() q0 = cirq.GridQubit(0, 0) q1 = cirq.GridQubit(1, 0) q2 = cirq.GridQubit(2, 0) q3 = cirq.GridQubit(3, 0) rot_w_gate = cirq.X**sympy.Symbol('x') circuit = cirq.Circuit() circuit.append([rot_w_gate(q0), rot_w_gate(q1)]) for y in range(5): resolver = cirq.ParamResolver({'x': y / 4.0}) result = simulator.simulate(circuit, resolver) print(np.round(result.final_state, 2))
# run methods (run and run_sweep) on the simulator do not give access to the wave function of the quantum computer # simulate methods (simulate, simulate_sweep, simulate_moment_steps) should be used if one wants to debug the circuit and get access to the full wave function import cirq from cirq import Simulator import numpy as np simulator = Simulator() q0 = cirq.GridQubit(0, 0) q1 = cirq.GridQubit(1, 0) def basic_circuit(meas=True): sqrt_x = cirq.X**0.5 yield sqrt_x(q0), sqrt_x(q1) yield cirq.CZ(q0, q1) yield sqrt_x(q0), sqrt_x(q1) if meas: yield cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1') circuit = cirq.Circuit() circuit.append(basic_circuit(False)) print(circuit) result = simulator.simulate(circuit, qubit_order=[q0, q1]) print(np.around(result.final_state, 3))
q1 = cirq.GridQubit(1, 0) def basic_circuit(meas=True): sqrt_x = cirq.X**0.5 yield sqrt_x(q0), sqrt_x(q1) yield cirq.CZ(q0, q1) yield sqrt_x(q0), sqrt_x(q1) if meas: yield cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1') circuit = cirq.Circuit() circuit.append(basic_circuit()) print(circuit) simulator = Simulator() result = simulator.run(circuit) print(result) # Circuit : # (0, 0): ───X^0.5───@───X^0.5───M('q0')─── # │ # (1, 0): ───X^0.5───@───X^0.5───M('q1')─── # Result # q0=0 # q1=1
for _ in range(number_of_iterations): circuit.append(oracle) circuit.append(self.diffusion) return circuit def make_oracle(qubits): circuit = cirq.Circuit() controllee= [] for i in range(length - 1): controllee.append(qubits[i]) circuit.append(cirq.X(qubits[i]) for i in [1,3,4]) circuit.append(cirq.control(cirq.Z, controllee)(qubits[-1])) circuit.append(cirq.X(qubits[i]) for i in [1,3,4]) return circuit grover = Grover(qubits) oracle = make_oracle(qubits) circuit = cirq.Circuit() circuit.append(cirq.H(q) for q in qubits) grover.run(circuit, oracle, number_of_expected_results) circuit.append(cirq.measure(*qubits)) print(circuit) from cirq import Simulator simulator = Simulator() result = simulator.run(circuit, repetitions=int(sys.argv[2])) print(result)
def run(formula_original, truth_table = ""): # Troca simbolos logicos comuns pelos equivalentes esperados formula_original = formula_original.replace(' ', '') formula_original = formula_original.replace('∨', '|') formula_original = formula_original.replace('→', '>') formula_original = formula_original.replace('∧', '&') formula_original = formula_original.replace('¬', '~') formula = list(formula_original) table = list(truth_table) parenteses = 0 atomics = 0 operations = 0 negations = 0 # lê a formula, contando cada elemento # O(n) for element in formula: if element == '~': negations = negations + 1 elif element == '|' or element == '&' or element == '>': #aqui deve entrar qualquer uma das operações operations = operations + 1 elif element == '(' or element == ')': parenteses = parenteses + 1 else: atomics = atomics + 1 full_size = negations + operations + atomics + parenteses size = operations + atomics + parenteses # cria o numero de qubits adequado e o circuito qubits = cirq.LineQubit.range(size) circuit = cirq.Circuit() size2 = len(formula) # checa se há alguma inconsistência na contagem if full_size != size2: print("Erro nos tamanhos") exit() # entrelaça os qubits necessários # ignora as negações, que serão lidadas com mais para frente formula_use = remove_values(formula, '~') #O(n), maximo de ligações é n for i in range(size): if not str(formula_use[i]).isalnum(): # se não for alfanumérico, ignora continue circuit.append(cirq.H(qubits[i])) # aplica o Hadamard no primeiro qubit encontrado para cada clausula atomica for j in range(i + 1, size): # procura no resto da formula outras instâncias da clausula atomica if (formula_use[i] == formula_use[j]): circuit.append([cirq.CNOT(qubits[i], qubits[j])]) # entrelaça as que encontrar com a primeira formula_use[j] = "_" formula_use[i] = "_" # verifica as clausulas que estão negadas, e faz o bit flip #O(n) neg_count = 0 for i in range(full_size): if formula[i] == '~': if formula[i + 1] == '(': #negações aparecem antes de ( ou antes de uma clausula atomica formula_use[i - neg_count] = '[' #troca a representação do parenteses negado neg_count = neg_count + 1 else: circuit.append(cirq.X(qubits[i - neg_count])) neg_count = neg_count + 1 # cria uma lista de inteiros para servir de referência a quais qubits ainda estão com informação importante indexator = list(range(size)) # procura os parenteses mais internos, e chama a função de criar circuito has_parenteses = 1 i = 0 print(formula_use) #O(n^2) while len(indexator) > 1 and has_parenteses == 1: # quando o tamanho de indexador é 1, o algoritmo terminou, e o resultado está no qubit com o indice restante has_parenteses = 0 for i in range(len(indexator)): negated = 0 if formula_use[indexator[i]] == '(' or formula_use[indexator[i]] == '[': #achou o abre parenteses if formula_use[indexator[i]] == '[': negated = 1 has_parenteses = 1 start = i while formula_use[indexator[i]] != ')': #procura o fecha parênteses i = i + 1 if formula_use[indexator[i]] == '(' or formula_use[indexator[i]] == '[':# achou outro abre parênteses, atualiza o start start = i negated = 0 if formula_use[indexator[i]] == '[': negated = 1 #quando saiu do while, está no primeiro ')' - assumindo que a afirmação está bem formada (numero equilibrado de parenteses) internal_count = i - start - 1 #remove os parenteses del indexator[start] del indexator[i - 1] create_circuit(formula_use, circuit, qubits, indexator, start, start + internal_count, negated) break #chama a funçao uma ultima vez, quando nao houver mais nenhum parenteses create_circuit(formula_use, circuit, qubits, indexator, 0, len(indexator) - 1, 0) # a resposta esta no qubit[indexador[0]] print(indexator) print(circuit) simulator = Simulator() result = simulator.simulate(circuit, initial_state=000000000000000) print(result.dirac_notation()) string_result = str(result.dirac_notation()) # conta os 0s e 1s do resultado da simulação e compara com os da truth table original_ones = 0 original_zeros = 0 for i in range(len(table)): if int(table[i]) == 0: original_zeros = original_zeros + 1 elif int(table[i]) == 1: original_ones = original_ones + 1 ones = 0 zeros = 0 temp_parenteses = 0 for i in range(indexator[0]): if formula_use[i] == ')' or formula_use[i] == '(' or formula_use[i] == '[': temp_parenteses = temp_parenteses + 1 for i in range(len(string_result)): if string_result[i] == "|": if int(string_result[i + indexator[0] + 1 - temp_parenteses]) == 0: zeros = zeros + 1 else: ones = ones + 1 print("Truth Table Ones/Zeros:", end = ' ') print(original_ones, end = '/') print(original_zeros) print("Circuit Result:") print("Ones:", end = '') print(ones) print("Zeros:", end='') print(zeros)