def test_simulator_functional_measurement(): sim = StabilizerSimulator(5) eng = MainEngine(sim, []) qubits = eng.allocate_qureg(5) # entangle all qubits: H | qubits[0] for qb in qubits[1:]: CNOT | (qubits[0], qb) All(Measure) | qubits eng.flush() bit_value_sum = sum([int(qubit) for qubit in qubits]) assert bit_value_sum == 0 or bit_value_sum == 5
def run_circuit(eng, n_qubits, circuit_num, gate_after_measure=False): """Run a quantum circuit demonstrating the capabilities of the UnitarySimulator.""" qureg = eng.allocate_qureg(n_qubits) if circuit_num == 1: All(X) | qureg elif circuit_num == 2: X | qureg[0] with Control(eng, qureg[:2]): All(X) | qureg[2:] elif circuit_num == 3: with Control(eng, qureg[:2], ctrl_state=CtrlAll.Zero): All(X) | qureg[2:] elif circuit_num == 4: QFT | qureg eng.flush() All(Measure) | qureg if gate_after_measure: QFT | qureg eng.flush() All(Measure) | qureg
def run_half_adder(eng): """Run the half-adder circuit.""" # allocate the quantum register to entangle circuit = eng.allocate_qureg(4) qubit1, qubit2, qubit3, qubit4 = circuit result_qubits = [qubit3, qubit4] # X gates on the first two qubits All(X) | [qubit1, qubit2] # Barrier Barrier | circuit # Cx gates CNOT | (qubit1, qubit3) CNOT | (qubit2, qubit3) # CCNOT Toffoli | (qubit1, qubit2, qubit4) # Barrier Barrier | circuit # Measure result qubits All(Measure) | result_qubits # Flush the circuit (this submits a job to the IonQ API) eng.flush() # Show the histogram histogram(eng.backend, result_qubits) plt.show() # return a random answer from our results probabilities = eng.backend.get_probabilities(result_qubits) random_answer = random.choice(list(probabilities.keys())) return [int(s) for s in random_answer]
def test_factoring(sim): eng = get_main_engine(sim) ctrl_qubit = eng.allocate_qubit() N = 15 a = 2 x = eng.allocate_qureg(4) X | x[0] H | ctrl_qubit with Control(eng, ctrl_qubit): MultiplyByConstantModN(pow(a, 2**7, N), N) | x H | ctrl_qubit eng.flush() cheat_tpl = sim.cheat() idx = cheat_tpl[0][ctrl_qubit[0].id] vec = cheat_tpl[1] for i in range(len(vec)): if abs(vec[i]) > 1.0e-8: assert ((i >> idx) & 1) == 0 Measure | ctrl_qubit assert int(ctrl_qubit) == 0 del vec, cheat_tpl H | ctrl_qubit with Control(eng, ctrl_qubit): MultiplyByConstantModN(pow(a, 2, N), N) | x H | ctrl_qubit eng.flush() cheat_tpl = sim.cheat() idx = cheat_tpl[0][ctrl_qubit[0].id] vec = cheat_tpl[1] probability = 0.0 for i in range(len(vec)): if abs(vec[i]) > 1.0e-8: if ((i >> idx) & 1) == 0: probability += abs(vec[i])**2 assert probability == pytest.approx(0.5) Measure | ctrl_qubit All(Measure) | x
def _viz_circuit(self): All(Measure) | self.qureg self.eng.flush() # print latex code to draw the circuit: s = self.backend.get_latex() # save graph to latex file os.chdir(TEX_FOLDER) with open(TEX_FILENAME, 'w') as f: f.write(s) # texfile = os.path.join(folder, 'circuit-%d.tex'%bench_id) pdffile = TEX_FILENAME[:-3] + 'pdf' os.system('pdflatex %s' % TEX_FILENAME) openfile(pdffile)
def subproblem1(): eng = MainEngine() # Allocate qubits qubits = eng.allocate_qureg(2) # You should add quantum operations here to change the state of qubits into |01> # X|qubits[1] X | qubits[0] # Submit all your operations eng.flush() # Get the amplitudes list amplitudes = np.array(eng.backend.cheat()[1]) print("p1:{}".format(amplitudes)) # Here we return the amplitudes without measures and you do not need to care about the warnings All(Measure) | qubits return amplitudes
def test_ibm5qubitmapper_toomanyqubits(): backend = DummyEngine(save_commands=True) connectivity = {(2, 1), (4, 2), (2, 0), (3, 2), (3, 4), (1, 0)} eng = MainEngine( backend=backend, engine_list=[ _ibm5qubitmapper.IBM5QubitMapper(), SwapAndCNOTFlipper(connectivity), ], ) qubits = eng.allocate_qureg(6) All(H) | qubits CNOT | (qubits[0], qubits[1]) with pytest.raises(RuntimeError): eng.flush()
def ADD_test(x = [0,1,0,1,1,1,1,1], y = [1,0,1,1,0,0,1,1], z = [0]): print('Addition of two 8 bit numbers' ) eng = MainEngine() #<least ---significance---most> print('x: ',x) print('y: ',y,' (205 in binary)') x = list_to_reg(x, eng) #one extra bit needed for addition y = list_to_reg(y,eng) z = list_to_reg(z, eng) ADD(x,y,z) All(Measure) | x+z+y eng.flush() print('x value: ',get_int(x)) print('(sum) value: ',get_int(y+z)) print('')
def energy_objective(packed_amplitudes, qubit_hamiltonian, n_qubits, n_electrons): compiler_engine = uccsd_trotter_engine() wavefunction = compiler_engine.allocate_qureg(n_qubits) for i in range(n_electrons): X | wavefunction[i] evolution_operator = uccsd_singlet_evolution(packed_amplitudes, n_qubits, n_electrons) evolution_operator | wavefunction compiler_engine.flush() energy = compiler_engine.backend.get_expectation_value( qubit_hamiltonian, wavefunction) All(Measure) | wavefunction compiler_engine.flush() return energy
def alternating_bits_oracle(eng, qubits, output): """ Marks the solution string 1,0,1,0,...,0,1 by flipping the output qubit, conditioned on qubits being equal to the alternating bit-string. Args: eng (MainEngine): Main compiler engine the algorithm is being run on. qubits (Qureg): n-qubit quantum register Grover search is run on. output (Qubit): Output qubit to flip in order to mark the solution. """ with Compute(eng): All(X) | qubits[1::2] with Control(eng, qubits): X | output Uncompute(eng)
def test_modmultiplier(eng): qureg = eng.allocate_qureg(4) init(eng, qureg, 4) MultiplyByConstantModN(3, 7) | qureg assert 1.0 == pytest.approx(abs(eng.backend.cheat()[1][5])) init(eng, qureg, 5) # reset init(eng, qureg, 7) MultiplyByConstantModN(4, 13) | qureg assert 1.0 == pytest.approx(abs(eng.backend.cheat()[1][2])) All(Measure) | qureg
def Cleanup(eng, Y_reg, D_reg, L_reg, A_reg): print("Running Locate") # Get registers of database D_reg_Y = [qubit for qubit in D_reg if (D_reg.index(qubit) % (m + n) >= m)] # Initialize auxiliary register B B_reg = eng.allocate_qureg(n) All(X) | B_reg for i in range(q): # Get registers of database D_reg_Y_i = [qubit for qubit in D_reg_Y if (D_reg_Y.index(qubit) >= n * i \ and D_reg_Y.index(qubit) < n * (i + 1))] # Compute difference in Y values for j in range(n): C(X, 1) | (Y_reg[j], B_reg[j]) C(X, 1) | (D_reg_Y_i[j], B_reg[j]) # Check if D_i equals the query C(X, n + 1) | ([L_reg[i]] + B_reg, A_reg) # Uncompute B for j in range(n): C(X, 1) | (Y_reg[j], B_reg[j]) C(X, 1) | (D_reg_Y_i[j], B_reg[j]) # Clean up All(X) | B_reg del B_reg print("Finished Locate") return A_reg
def subtract_quantum(eng, quint_a, quint_b): """ Subtracts two quantum integers, i.e., |a>|b>|c> -> |a>|b-a> (only works if quint_a and quint_b are the same size) """ assert (len(quint_a) == len(quint_b)) n = len(quint_a) + 1 All(X) | quint_b for i in range(1, n - 1): CNOT | (quint_a[i], quint_b[i]) for j in range(n - 3, 0, -1): CNOT | (quint_a[j], quint_a[j + 1]) for k in range(0, n - 2): with Control(eng, [quint_a[k], quint_b[k]]): X | (quint_a[k + 1]) for l in range(n - 2, 0, -1): CNOT | (quint_a[l], quint_b[l]) with Control(eng, [quint_a[l - 1], quint_b[l - 1]]): X | quint_a[l] for m in range(1, n - 2): CNOT | (quint_a[m], quint_a[m + 1]) for n in range(0, n - 1): CNOT | (quint_a[n], quint_b[n]) All(X) | quint_b
def test_simulator_amplitude(sim, mapper): engine_list = [LocalOptimizer()] if mapper is not None: engine_list.append(mapper) eng = MainEngine(sim, engine_list=engine_list) qubits = eng.allocate_qureg(6) All(X) | qubits All(H) | qubits eng.flush() bits = [0, 0, 1, 0, 1, 0] assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(1. / 8.) bits = [0, 0, 0, 0, 1, 0] assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(-1. / 8.) bits = [0, 1, 1, 0, 1, 0] assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(-1. / 8.) All(H) | qubits All(X) | qubits Ry(2 * math.acos(0.3)) | qubits[0] eng.flush() bits = [0] * 6 assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(0.3) bits[0] = 1 assert (eng.backend.get_amplitude(bits, qubits) == pytest.approx( math.sqrt(0.91))) All(Measure) | qubits # raises if not all qubits are in the list: with pytest.raises(RuntimeError): eng.backend.get_amplitude(bits, qubits[:-1]) # doesn't just check for length: with pytest.raises(RuntimeError): eng.backend.get_amplitude(bits, qubits[:-1] + [qubits[0]]) extra_qubit = eng.allocate_qubit() eng.flush() # there is a new qubit now! with pytest.raises(RuntimeError): eng.backend.get_amplitude(bits, qubits)
def test_addition_with_control_carry(eng): qunum_a = eng.allocate_qureg(4) # 4-qubit number qunum_b = eng.allocate_qureg(4) # 4-qubit number control_bit = eng.allocate_qubit() qunum_c = eng.allocate_qureg(2) X | qunum_a[1] # qunum is now equal to 2 All(X) | qunum_b[0:4] # qunum is now equal to 15 X | control_bit with Control(eng, control_bit): AddQuantum | (qunum_a, qunum_b, qunum_c) # qunum_a and ctrl don't change, qunum_b and qunum_c are now both equal # to 1 so in binary together 10001 (2 + 15 = 17) eng.flush() assert 1.0 == pytest.approx(eng.backend.get_probability([0, 1, 0, 0], qunum_a)) assert 1.0 == pytest.approx(eng.backend.get_probability([1, 0, 0, 0], qunum_b)) assert 1.0 == pytest.approx(eng.backend.get_probability([1], control_bit)) assert 1.0 == pytest.approx(eng.backend.get_probability([1, 0], qunum_c)) All(Measure) | qunum_a All(Measure) | qunum_b
def test_2qubitsPh_andfunction_eigenvectors(): rule_set = DecompositionRuleSet(modules=[pe, dqft]) eng = MainEngine(backend=Simulator(), engine_list=[ AutoReplacer(rule_set), ]) results = np.array([]) for i in range(100): autovector = eng.allocate_qureg(2) X | autovector[0] ancillas = eng.allocate_qureg(3) QPE(two_qubit_gate) | (ancillas, autovector) All(Measure) | ancillas fasebinlist = [int(q) for q in ancillas] fasebin = ''.join(str(j) for j in fasebinlist) faseint = int(fasebin, 2) phase = faseint / (2.**(len(ancillas))) results = np.append(results, phase) All(Measure) | autovector eng.flush() num_phase = (results == 0.125).sum() assert num_phase / 100. >= 0.34, "Statistics phase calculation are not correct (%f vs. %f)" % ( num_phase / 100., 0.34)
def test_modadder(eng): qureg = eng.allocate_qureg(4) init(eng, qureg, 4) AddConstantModN(3, 6) | qureg assert 1.0 == pytest.approx(abs(eng.backend.cheat()[1][1])) init(eng, qureg, 1) # reset init(eng, qureg, 7) AddConstantModN(10, 13) | qureg assert 1.0 == pytest.approx(abs(eng.backend.cheat()[1][4])) All(Measure) | qureg
def test_simulator_set_wavefunction(sim, mapper): engine_list = [LocalOptimizer()] if mapper is not None: engine_list.append(mapper) eng = MainEngine(sim, engine_list=engine_list) qubits = eng.allocate_qureg(2) wf = [0., 0., math.sqrt(0.2), math.sqrt(0.8)] with pytest.raises(RuntimeError): eng.backend.set_wavefunction(wf, qubits) eng.flush() eng.backend.set_wavefunction(wf, qubits) assert pytest.approx(eng.backend.get_probability('1', [qubits[0]])) == .8 assert pytest.approx(eng.backend.get_probability('01', qubits)) == .2 assert pytest.approx(eng.backend.get_probability('1', [qubits[1]])) == 1. All(Measure) | qubits
def estimate_average_fidelity(self, channel, ntimes, epsilon, cheat=False): r""" Estimate the average fidelity by epsilon-approximate unitary two design. Parameters ---------- channel : callable This is a function that takes engine and register and implements the noisy quantum channel (e.g. a gate). ntimes : int The number of trials to sample. epsilon : float The approximation to the unitary two design. cheat : bool TODO Returns ------- float : The average fidelity of the quantum circuit. """ # Set engine to all zero. # Number of times it is zero. ntimes_zero = 0. for _ in range(0, ntimes): # Set register to zero. self.set_register_to_zero(cheat=cheat) # Apply the approximate unitary two design. random_phase = self.approximate_unitary_two_design(epsilon) # Apply the quantum channel channel(self.eng, self.register) # Apply the inverse of the approximate unitary two design. self.inverse_of_unitary_two_design(random_phase) # Measure in computational basis All(Measure) | self.register self.eng.flush() result = np.array([int(x) for x in self.register], dtype=np.int) if np.all(result == 0.): ntimes_zero += 1 self.eng.flush() return ntimes_zero / ntimes
def test_simulator_arithmetic(mapper): class Offset(BasicMathGate): def __init__(self, amount): BasicMathGate.__init__(self, lambda x: (x + amount, )) class Sub(BasicMathGate): def __init__(self): BasicMathGate.__init__(self, lambda x, y: (x, y - x)) engine_list = [] if mapper is not None: engine_list.append(mapper) sim = ClassicalSimulator() eng = MainEngine(sim, engine_list) a = eng.allocate_qureg(4) b = eng.allocate_qureg(5) sim.write_register(a, 9) sim.write_register(b, 17) Offset(2) | a assert sim.read_register(a) == 11 assert sim.read_register(b) == 17 Offset(3) | b assert sim.read_register(a) == 11 assert sim.read_register(b) == 20 Offset(32 + 5) | b assert sim.read_register(a) == 11 assert sim.read_register(b) == 25 Sub() | (a, b) assert sim.read_register(a) == 11 assert sim.read_register(b) == 14 Sub() | (a, b) Sub() | (a, b) assert sim.read_register(a) == 11 assert sim.read_register(b) == 24 # also test via measurement: All(Measure) | a + b eng.flush() for i in range(len(a)): assert int(a[i]) == ((11 >> i) & 1) for i in range(len(b)): assert int(b[i]) == ((24 >> i) & 1)
def test_inverse_division(eng): qunum_a = eng.allocate_qureg(5) qunum_b = eng.allocate_qureg(5) qunum_c = eng.allocate_qureg(5) All(X) | [qunum_a[0], qunum_a[3]] X | qunum_c[2] with Compute(eng): DivideQuantum | (qunum_a, qunum_b, qunum_c) Uncompute(eng) eng.flush() assert 1.0 == pytest.approx(eng.backend.get_probability([1, 0, 0, 1, 0], qunum_a)) assert 1.0 == pytest.approx(eng.backend.get_probability([0, 0, 0, 0, 0], qunum_b)) assert 1.0 == pytest.approx(eng.backend.get_probability([0, 0, 1, 0, 0], qunum_c))
def MUL_test(): print('testing multiplication circuit...') #___________________initial__________________ eng = MainEngine() #<least ---significance---most> a = list_to_reg([0,1,1],eng) #7 n = len(a) b = list_to_reg([1,1,1],eng)#7 z = list_to_reg([0 for _ in range(2*n)],eng) fixed_MUL(a,b,z,eng = eng) All(Measure) | a+b+z eng.flush() print('a value: ',get_int(a)) print('prod ',get_int(z)) print([int(i) for i in a+b+z]) print('')
def oracle(eng, qubits, output, expected): """ Args: eng (MainEngine): Main compiler engine the algorithm is being run on. qubits (Qureg): n-qubit quantum register Grover search is run on. output (Qubit): Output qubit to flip in order to mark the solution expected - bit-string solution. """ qubits1 = [qubits[elem[0]] for elem in enumerate(expected) if elem[1]==0 ] with Compute(eng): All(X) | qubits1 with Control(eng, qubits): X | output Uncompute(eng)
def test_adder(eng): qureg = eng.allocate_qureg(4) init(eng, qureg, 4) AddConstant(3) | qureg assert 1.0 == pytest.approx(abs(eng.backend.cheat()[1][7])) init(eng, qureg, 7) # reset init(eng, qureg, 2) # check for overflow -> should be 15+2 = 1 (mod 16) AddConstant(15) | qureg assert 1.0 == pytest.approx(abs(eng.backend.cheat()[1][1])) All(Measure) | qureg
def test_bellpair() -> None: circ = Circuit(2) circ.H(0) circ.CX(0, 1) eng = MainEngine() qureg = eng.allocate_qureg(circ.n_qubits) tk_to_projectq(eng, qureg, circ) eng.flush() p1 = eng.backend.get_probability([0, 0], qureg) p2 = eng.backend.get_probability([0, 1], qureg) p3 = eng.backend.get_probability([1, 0], qureg) p4 = eng.backend.get_probability([1, 1], qureg) assert p2 == 0 assert p3 == 0 assert isclose(p1, 0.5, abs_tol=eps) assert isclose(p4, 0.5, abs_tol=eps) All(Measure) | qureg # pylint: disable=expression-not-assigned
def test_simulator_expectation(sim, mapper): engine_list = [] if mapper is not None: engine_list.append(mapper) eng = MainEngine(sim, engine_list=engine_list) qureg = eng.allocate_qureg(3) op0 = QubitOperator('Z0') expectation = sim.get_expectation_value(op0, qureg) assert 1.0 == pytest.approx(expectation) X | qureg[0] expectation = sim.get_expectation_value(op0, qureg) assert -1.0 == pytest.approx(expectation) H | qureg[0] op1 = QubitOperator('X0') expectation = sim.get_expectation_value(op1, qureg) assert -1.0 == pytest.approx(expectation) Z | qureg[0] expectation = sim.get_expectation_value(op1, qureg) assert 1.0 == pytest.approx(expectation) X | qureg[0] S | qureg[0] Z | qureg[0] X | qureg[0] op2 = QubitOperator('Y0') expectation = sim.get_expectation_value(op2, qureg) assert 1.0 == pytest.approx(expectation) Z | qureg[0] expectation = sim.get_expectation_value(op2, qureg) assert -1.0 == pytest.approx(expectation) op_sum = QubitOperator('Y0 X1 Z2') + QubitOperator('X1') H | qureg[1] X | qureg[2] expectation = sim.get_expectation_value(op_sum, qureg) assert 2.0 == pytest.approx(expectation) op_sum = QubitOperator('Y0 X1 Z2') + QubitOperator('X1') X | qureg[2] expectation = sim.get_expectation_value(op_sum, qureg) assert 0.0 == pytest.approx(expectation) op_id = 0.4 * QubitOperator(()) expectation = sim.get_expectation_value(op_id, qureg) assert 0.4 == pytest.approx(expectation) All(Measure) | qureg
def test_simulator_emulation(sim): eng = MainEngine(sim, []) qubit1 = eng.allocate_qubit() qubit2 = eng.allocate_qubit() qubit3 = eng.allocate_qubit() with Control(eng, qubit3): Plus2Gate() | (qubit1 + qubit2) assert 1. == pytest.approx(sim.cheat()[1][0]) X | qubit3 with Control(eng, qubit3): Plus2Gate() | (qubit1 + qubit2) assert 1. == pytest.approx(sim.cheat()[1][6]) All(Measure) | (qubit1 + qubit2 + qubit3)
def alternating_bits_oracle_modified(eng, qubits, output, phi): """ Marks the solution string 0,1,0,... by applying phase gate to the output bits, conditioned on qubits being equal to the alternating bit-string. Args: eng (MainEngine): Main compiler engine the algorithm is being run on. qubits (Qureg): n-qubit quantum register Grover search is run on. output (Qubit): Output qubit to mark the solution by a phase gate with parameter phi. """ with Compute(eng): All(X) | qubits[1::2] with Control(eng, qubits): Rz(phi) | output Ph(phi/2) | output Uncompute(eng)
def test_unitary_functional_measurement(): eng = MainEngine(UnitarySimulator()) qubits = eng.allocate_qureg(5) # entangle all qubits: H | qubits[0] for qb in qubits[1:]: CNOT | (qubits[0], qb) eng.flush() All(Measure) | qubits bit_value_sum = sum([int(qubit) for qubit in qubits]) assert bit_value_sum == 0 or bit_value_sum == 5 qb1 = WeakQubitRef(engine=eng, idx=qubits[0].id) qb2 = WeakQubitRef(engine=eng, idx=qubits[1].id) with pytest.raises(ValueError): eng.backend._handle(Command(engine=eng, gate=Measure, qubits=([qb1],), controls=[qb2]))
def test_division(eng): qunum_a = eng.allocate_qureg(5) qunum_b = eng.allocate_qureg(5) qunum_c = eng.allocate_qureg(5) All(X) | [qunum_a[0], qunum_a[3]] # qunum_a is now equal to 9 X | qunum_c[2] # qunum_c is now 4 DivideQuantum | (qunum_a, qunum_b, qunum_c) eng.flush() assert 1.0 == pytest.approx( eng.backend.get_probability([1, 0, 0, 0, 0], qunum_a)) # remainder assert 1.0 == pytest.approx( eng.backend.get_probability([0, 1, 0, 0, 0], qunum_b)) assert 1.0 == pytest.approx( eng.backend.get_probability([0, 0, 1, 0, 0], qunum_c))