def test_automatic_deallocation_of_qubit_in_uncompute(): # Test that automatic uncomputation deallocates qubit # which was created during compute context. backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[DummyEngine()]) with _compute.Compute(eng): ancilla = eng.allocate_qubit() assert ancilla[0].id != -1 Rx(0.6) | ancilla # Test that ancilla qubit has been register in MainEngine.active_qubits assert ancilla[0] in eng.active_qubits _compute.Uncompute(eng) # Test that ancilla id has been set to -1 assert ancilla[0].id == -1 # Test that ancilla is not anymore in active qubits assert not ancilla[0] in eng.active_qubits assert backend.received_commands[1].gate == Rx(0.6) assert backend.received_commands[2].gate == Rx(-0.6)
def test_toffoli_size_of_increment(): backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[ AutoReplacerEx( DecompositionRuleSet(modules=[ multi_not_rules, increment_rules, addition_rules, swap2cnot, ])), LimitedCapabilityEngine(allow_toffoli=True), ]) controls = eng.allocate_qureg(40) target = eng.allocate_qureg(35) _ = eng.allocate_qureg(2) Increment & controls | target assert 1000 < len(backend.received_commands) < 10000
def test_simulator_kqubit_exception(sim): m1 = Rx(0.3).matrix m2 = Rx(0.8).matrix m3 = Ry(0.1).matrix m4 = Rz(0.9).matrix.dot(Ry(-0.1).matrix) m = numpy.kron(m4, numpy.kron(m3, numpy.kron(m2, m1))) class KQubitGate(BasicGate): @property def matrix(self): return m eng = MainEngine(sim, []) qureg = eng.allocate_qureg(3) with pytest.raises(Exception): KQubitGate() | qureg with pytest.raises(Exception): H | qureg
def _expectation_value( self, circuit: Circuit, hamiltonian: projectq.ops.QubitOperator, valid_check: bool = True, ) -> complex: if valid_check and not self.valid_circuit(circuit): raise ValueError( "Circuits do not satisfy all required predicates for this backend" ) sim = Simulator() fwd = ForwarderEngine(sim) eng = MainEngine(backend=sim, engine_list=[fwd]) qureg = eng.allocate_qureg(circuit.n_qubits) tk_to_projectq(eng, qureg, circuit) eng.flush() energy = eng.backend.get_expectation_value(hamiltonian, qureg) return complex(energy)
def test_recognize_individual_terms(): saving_backend = DummyEngine(save_commands=True) eng = MainEngine(backend=saving_backend, engine_list=[]) wavefunction = eng.allocate_qureg(5) op1 = QubitOperator("X1 Y2", 0.5) op2 = QubitOperator("Y2 X4", -0.5) op3 = QubitOperator("X2", 1.0) TimeEvolution(1.0, op1 + op2) | wavefunction TimeEvolution(1.0, op2) | wavefunction TimeEvolution(1.0, op3) | wavefunction cmd1 = saving_backend.received_commands[5] cmd2 = saving_backend.received_commands[6] cmd3 = saving_backend.received_commands[7] assert not te.rule_individual_terms.gate_recognizer(cmd1) assert te.rule_individual_terms.gate_recognizer(cmd2) assert te.rule_individual_terms.gate_recognizer(cmd3)
def test_toffoli_size_of_addition(): backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[ AutoReplacerEx( DecompositionRuleSet(modules=[ addition_rules, increment_rules, multi_not_rules, swap2cnot, ])), LimitedCapabilityEngine(allow_toffoli=True), ]) src = eng.allocate_qureg(50) dst = eng.allocate_qureg(100) Add | (src, dst) assert 5000 < len(backend.received_commands) < 7000
def test_quantumsubtraction(): sim = Simulator() eng = MainEngine( sim, [AutoReplacer(rule_set), InstructionFilter(no_math_emulation)]) qureg_a = eng.allocate_qureg(5) qureg_b = eng.allocate_qureg(5) init(eng, qureg_a, 5) init(eng, qureg_b, 7) SubtractQuantum() | (qureg_a, qureg_b) assert 1. == pytest.approx( eng.backend.get_probability([1, 0, 1, 0, 0], qureg_a)) assert 1. == pytest.approx( eng.backend.get_probability([0, 1, 0, 0, 0], qureg_b))
def test_phase_majority_from_python(): dormouse = pytest.importorskip('dormouse') def maj(a, b, c): return (a and b) or (a and c) or (b and c) # pragma: no cover sim = Simulator() main_engine = MainEngine(sim) qureg = main_engine.allocate_qureg(3) All(H) | qureg PhaseOracle(maj) | qureg main_engine.flush() assert np.array_equal(np.sign(sim.cheat()[1]), [1., 1., 1., -1., 1., -1., -1., -1.]) All(Measure) | qureg
def _initialize_register(num_bit, mode='simulator'): ''' use an engine instead of current one. ''' import projectq.setups.default # create a main compiler engine with a specific backend: if mode == 'graphical': backend = CircuitDrawer() elif mode == 'simulator': backend = Simulator() else: raise eng = MainEngine(backend) # initialize register qureg = eng.allocate_qureg(num_bit) return qureg
def test_or_one_qubit(): saving_backend = DummyEngine(save_commands=True) eng = MainEngine(backend=saving_backend, engine_list=[]) qubit = eng.allocate_qubit() hamiltonian = QubitOperator("Z0", 2) te.TimeEvolution(2.1, hamiltonian) | qubit[0] te.TimeEvolution(3, hamiltonian) | (qubit[0],) eng.flush() cmd1 = saving_backend.received_commands[1] assert cmd1.gate.hamiltonian.isclose(hamiltonian) assert cmd1.gate.time == pytest.approx(2.1) assert len(cmd1.qubits) == 1 and len(cmd1.qubits[0]) == 1 assert cmd1.qubits[0][0].id == qubit[0].id cmd2 = saving_backend.received_commands[2] assert cmd2.gate.hamiltonian.isclose(hamiltonian) assert cmd2.gate.time == pytest.approx(3) assert len(cmd2.qubits) == 1 and len(cmd2.qubits[0]) == 1 assert cmd2.qubits[0][0].id == qubit[0].id
def test_ffft_2modes_properly_applied(self): eng_ft_0 = MainEngine() reg_ft_0 = eng_ft_0.allocate_qureg(2) eng_ffft_recursive = MainEngine() reg_ffft_recursive = eng_ffft_recursive.allocate_qureg(2) ffft(eng_ffft_recursive, reg_ffft_recursive, 2) fourier_transform_0(reg_ft_0, 0, 1) eng_ffft_recursive.flush() eng_ft_0.flush() All(Measure) | reg_ffft_recursive All(Measure) | reg_ft_0 self.assertTrue(numpy.allclose( ordered_wavefunction(eng_ffft_recursive), ordered_wavefunction(eng_ft_0)))
def test_toffoli_size_of_bit_rotate(): rec = DummyEngine(save_commands=True) eng = MainEngine(backend=rec, engine_list=[ AutoReplacerEx( DecompositionRuleSet(modules=[ swap2cnot, multi_not_rules, reverse_bits_rules, rotate_bits_rules ])), LimitedCapabilityEngine(allow_toffoli=True), ]) controls = eng.allocate_qureg(50) target = eng.allocate_qureg(100) RotateBitsGate(-3) & controls | target RotateBitsGate(+1) & controls | target[1:] assert 500 < len(rec.received_commands) < 5000
def run(self, circuit: Circuit, shots: int, fit_to_constraints=True) -> np.ndarray: state = self.get_state(circuit, fit_to_constraints) fwd = ForwarderEngine(self._backend) eng = MainEngine(backend=self._backend, engine_list=[fwd]) qb_results = [] qureg = eng.allocate_qureg(circuit.n_qubits) for _ in range(shots): self._backend.set_wavefunction(state, qureg) All(Measure) | qureg eng.flush() results = (list(map(int, qureg))) qb_results.append(results) return np.asarray(qb_results)
def test_set_explicit_initial_state(self): """ This shows how to set the initial state of the qubits in a circuit. """ initial_statevector = [ complex(0, 0), complex(0, 0), complex(1, 0), complex(0, 0), complex(0, 0), complex(0, 0), complex(0, 0), complex(0, 0) ] engine = MainEngine() qubits = engine.allocate_qureg(3) # Set the initial state to 2, which is |010> (this can also be an entire state vector if you need to get fine-grained # or set up superpositions) engine.flush() engine.backend.set_wavefunction(initial_statevector, qubits) print(engine.backend.cheat())
def test_auto_replacer_decomposition_chooser(fixture_gate_filter): # Supply a decomposition chooser which always chooses last rule. def test_decomp_chooser(cmd, decomposition_list): return decomposition_list[-1] backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[ _replacer.AutoReplacer(rule_set, test_decomp_chooser), fixture_gate_filter ]) assert len(rule_set.decompositions[TestGate.__class__.__name__]) == 2 assert len(backend.received_commands) == 0 qb = eng.allocate_qubit() TestGate | qb eng.flush() assert len(backend.received_commands) == 3 assert backend.received_commands[1].gate == H
def check_quantum_permutation_circuit(register_size, permutation_func, actions, engine_list=()): """ Args: register_size (int): permutation_func (function(register_sizes: tuple[int], register_vals: tuple[int]) : tuple[int]): actions (function(eng: MainEngine, registers: list[Qureg])): engine_list (list[projectq.cengines.BasicEngine]): """ sim = Simulator() rec = DummyEngine(save_commands=True) eng = MainEngine(backend=sim, engine_list=list(engine_list) + [rec]) reg = eng.allocate_qureg(register_size) All(H) | reg for i in range(len(reg)): Rz(math.pi / 2**i) | reg[i] pre_state = np.array(sim.cheat()[1]) # Simulate. rec.received_commands = [] actions(eng, [reg]) actions = list(rec.received_commands) post_state = np.array(sim.cheat()[1]) for q in reg: Measure | q denom = math.sqrt(len(pre_state)) pre_state *= denom post_state *= denom for i in range(len(pre_state)): j = permutation_func([register_size], [i]) & ((1 << len(reg)) - 1) if not (abs(post_state[j] - pre_state[i]) < 0.000000001): print(commands_to_ascii_circuit(actions)) print("Input", i) print("Expected Output", j) print("Input Amp at " + str(i), pre_state[i]) print("Actual Amp at " + str(j), post_state[j]) assert abs(post_state[j] - pre_state[i]) < 0.000000001
def test_auto_replacer_use_inverse_decomposition(): # Check that if there is no decomposition for the gate, that # AutoReplacer runs the decomposition for the inverse gate in reverse # Create test gate and inverse class NoMagicGate(BasicGate): pass class MagicGate(BasicGate): def get_inverse(self): return NoMagicGate() def decompose_no_magic_gate(cmd): qb = cmd.qubits Rx(0.6) | qb H | qb def recognize_no_magic_gate(cmd): return True rule_set.add_decomposition_rule( DecompositionRule(NoMagicGate, decompose_no_magic_gate, recognize_no_magic_gate)) def magic_filter(self, cmd): if cmd.gate == MagicGate(): return False return True backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[ _replacer.AutoReplacer(rule_set), _replacer.InstructionFilter(magic_filter) ]) assert len(backend.received_commands) == 0 qb = eng.allocate_qubit() MagicGate() | qb eng.flush() for cmd in backend.received_commands: print(cmd) assert len(backend.received_commands) == 4 assert backend.received_commands[1].gate == H assert backend.received_commands[2].gate == Rx(-0.6)
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. == pytest.approx(expectation) X | qureg[0] expectation = sim.get_expectation_value(op0, qureg) assert -1. == pytest.approx(expectation) H | qureg[0] op1 = QubitOperator('X0') expectation = sim.get_expectation_value(op1, qureg) assert -1. == pytest.approx(expectation) Z | qureg[0] expectation = sim.get_expectation_value(op1, qureg) assert 1. == 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. == pytest.approx(expectation) Z | qureg[0] expectation = sim.get_expectation_value(op2, qureg) assert -1. == 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. == pytest.approx(expectation) op_sum = QubitOperator('Y0 X1 Z2') + QubitOperator('X1') X | qureg[2] expectation = sim.get_expectation_value(op_sum, qureg) assert 0. == pytest.approx(expectation) op_id = .4 * QubitOperator(()) expectation = sim.get_expectation_value(op_id, qureg) assert .4 == pytest.approx(expectation)
def test_simulator_functional_entangle(sim): eng = MainEngine(sim, []) qubits = eng.allocate_qureg(5) # entangle all qubits: H | qubits[0] for qb in qubits[1:]: CNOT | (qubits[0], qb) # check the state vector: assert .5 == pytest.approx(abs(sim.cheat()[1][0])**2) assert .5 == pytest.approx(abs(sim.cheat()[1][31])**2) for i in range(1, 31): assert 0. == pytest.approx(abs(sim.cheat()[1][i])) # unentangle all except the first 2 for qb in qubits[2:]: CNOT | (qubits[0], qb) # entangle using Toffolis for qb in qubits[2:]: Toffoli | (qubits[0], qubits[1], qb) # check the state vector: assert .5 == pytest.approx(abs(sim.cheat()[1][0])**2) assert .5 == pytest.approx(abs(sim.cheat()[1][31])**2) for i in range(1, 31): assert 0. == pytest.approx(abs(sim.cheat()[1][i])) # uncompute using multi-controlled NOTs with Control(eng, qubits[0:-1]): X | qubits[-1] with Control(eng, qubits[0:-2]): X | qubits[-2] with Control(eng, qubits[0:-3]): X | qubits[-3] CNOT | (qubits[0], qubits[1]) H | qubits[0] # check the state vector: assert 1. == pytest.approx(abs(sim.cheat()[1][0])**2) for i in range(1, 32): assert 0. == pytest.approx(abs(sim.cheat()[1][i])) Measure | qubits
def test_8mode_ffft_with_external_swaps_on_single_logical_state(self): n_qubits = 8 grid = Grid(dimensions=1, length=n_qubits, scale=1.0) eng = MainEngine() register = eng.allocate_qureg(n_qubits) state_index = 157 prepare_logical_state(register, state_index) ffft(eng, register, n_qubits) Ph(3 * numpy.pi / 4) | register[0] eng.flush() wvfn = ordered_wavefunction(eng) fermion_operator = prepare_integer_fermion_operator(state_index) # Swap 01234567 to 45670123 for fourier_transform. Additionally, # the FFFT's ordering is 04261537, so swap 04261537 to 01234567, # and then 01234567 to 45670123. swap_mode_list = ([1, 3, 5, 2, 4, 1, 3, 5] + [3, 2, 4, 1, 3, 5, 0, 2, 4, 6, 1, 3, 5, 2, 4, 3]) for mode in swap_mode_list: fermion_operator = normal_ordered(fermion_operator) fermion_operator = swap_adjacent_fermionic_modes( fermion_operator, mode) ffft_result = fourier_transform(fermion_operator, grid, spinless=True) ffft_result = normal_ordered(ffft_result) # After the FFFT, swap 45670123 -> 01234567. swap_mode_list = [3, 2, 4, 1, 3, 5, 0, 2, 4, 6, 1, 3, 5, 2, 4, 3] for mode in swap_mode_list: ffft_result = swap_adjacent_fermionic_modes(ffft_result, mode) converted_wvfn = numpy.zeros(2**n_qubits, dtype=complex) for term in ffft_result.terms: index = sum(2**site[0] for site in term) converted_wvfn[index] = ffft_result.terms[term] All(Measure) | register self.assertTrue(numpy.allclose(wvfn, converted_wvfn))
def test_backend_get_probabilities_method(matplotlib_setup): class MyBackend(BasicEngine): def get_probabilities(self, qureg): return {'000': 0.5, '111': 0.5} def is_available(self, cmd): return True def receive(self, command_list): for cmd in command_list: if not isinstance(cmd.gate, FlushGate): assert isinstance(cmd.gate, AllocateQubitGate) eng = MainEngine(backend=MyBackend(), verbose=True) qureg = eng.allocate_qureg(3) eng.flush() _, _, prob = histogram(eng.backend, qureg) assert prob['000'] == 0.5 assert prob['111'] == 0.5
def test_recognize_correct_gates(): saving_backend = DummyEngine(save_commands=True) eng = MainEngine(backend=saving_backend) qubit = eng.allocate_qubit() ctrl_qubit = eng.allocate_qubit() eng.flush() Rx(0.3) | qubit with Control(eng, ctrl_qubit): Rx(0.4) | qubit eng.flush(deallocate_qubits=True) assert rx2rz._recognize_RxNoCtrl(saving_backend.received_commands[3]) assert not rx2rz._recognize_RxNoCtrl(saving_backend.received_commands[4])
def test_4mode_ffft_with_external_swaps_all_logical_states(self): n_qubits = 4 grid = Grid(dimensions=1, length=n_qubits, scale=1.0) for i in range(2**n_qubits): eng = MainEngine() register = eng.allocate_qureg(n_qubits) prepare_logical_state(register, i) ffft(eng, register, n_qubits) Ph(3 * numpy.pi / 4) | register[0] eng.flush() wvfn = ordered_wavefunction(eng) fermion_operator = prepare_integer_fermion_operator(i) # Reorder the modes for correct input to the FFFT. # Swap 0123 to 2301 for fourier_transform. Additionally, the # FFFT's ordering is 0213, so connect 0213 -> 0123 -> 2301. swap_mode_list = [1] + [1, 0, 2, 1] for mode in swap_mode_list: fermion_operator = normal_ordered(fermion_operator) fermion_operator = swap_adjacent_fermionic_modes( fermion_operator, mode) ffft_result = fourier_transform(fermion_operator, grid, spinless=True) ffft_result = normal_ordered(ffft_result) swap_mode_list = [1, 0, 2, 1] # After FFFT, swap 2301 -> 0123 for mode in swap_mode_list: ffft_result = swap_adjacent_fermionic_modes(ffft_result, mode) converted_wvfn = numpy.zeros(2**n_qubits, dtype=complex) for term in ffft_result.terms: index = sum(2**site[0] for site in term) converted_wvfn[index] = ffft_result.terms[term] All(Measure) | register self.assertTrue(numpy.allclose(wvfn, converted_wvfn))
def test_simulator_functional_measurement(sim): 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 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_modmultiplier(): sim = Simulator() eng = MainEngine(sim, [AutoReplacer(), InstructionFilter(no_math_emulation)]) qureg = eng.allocate_qureg(4) init(eng, qureg, 4) MultiplyByConstantModN(3, 7) | qureg assert 1. == pytest.approx(abs(sim.cheat()[1][5])) init(eng, qureg, 5) # reset init(eng, qureg, 7) MultiplyByConstantModN(4, 13) | qureg assert 1. == pytest.approx(abs(sim.cheat()[1][2])) Measure | qureg
def test_auto_replacer_searches_parent_class_for_rule(): class DerivedSomeGate(SomeGateClass): pass def test_gate_filter_func(self, cmd): if (cmd.gate == X or cmd.gate == H or isinstance(cmd.gate, ClassicalInstructionGate)): return True return False i_filter = _replacer.InstructionFilter(test_gate_filter_func) backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[_replacer.AutoReplacer(rule_set), i_filter]) qb = eng.allocate_qubit() DerivedSomeGate() | qb eng.flush() received_gate = backend.received_commands[1].gate assert received_gate == X or received_gate == H
def test_modadder(): sim = Simulator() eng = MainEngine(sim, [AutoReplacer(), InstructionFilter(no_math_emulation)]) qureg = eng.allocate_qureg(4) init(eng, qureg, 4) AddConstantModN(3, 6) | qureg assert 1. == pytest.approx(abs(sim.cheat()[1][1])) init(eng, qureg, 1) # reset init(eng, qureg, 7) AddConstantModN(10, 13) | qureg assert 1. == pytest.approx(abs(sim.cheat()[1][4])) Measure | qureg
def test_qubit_lines_classicalvsquantum1(): drawer = _drawer.CircuitDrawer() eng = MainEngine(drawer, []) old_tolatex = _drawer.to_latex _drawer.to_latex = lambda x: x qubit1 = eng.allocate_qubit() H | qubit1 Measure | qubit1 X | qubit1 circuit_lines = drawer.get_latex() _drawer.to_latex = old_tolatex settings = _to_latex.get_default_settings() code = _to_latex._body(circuit_lines, settings) assert code.count("edge[") == 4
def test_qureg_measure_exception(): eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) qureg = _qubit.Qureg() for qubit_id in [0, 1]: qubit = _qubit.Qubit(eng, qubit_id) qureg.append(qubit) with pytest.raises(Exception): qureg.__bool__() with pytest.raises(Exception): qureg.__int__()
def test_qubit(matplotlib_setup): sim = Simulator() eng = MainEngine(sim) qubit = eng.allocate_qubit() eng.flush() _, _, prob = histogram(sim, qubit) assert prob["0"] == pytest.approx(1) assert prob["1"] == pytest.approx(0) H | qubit eng.flush() _, _, prob = histogram(sim, qubit) assert prob["0"] == pytest.approx(0.5) Measure | qubit eng.flush() _, _, prob = histogram(sim, qubit) assert prob["0"] == pytest.approx(1) or prob["1"] == pytest.approx(1)
def run_circuit(self, circuit): """Run a circuit and return a single Result. Args: circuit (dict): JSON circuit from qobj circuits list Returns: dict: A dictionary of results which looks something like:: { "data": { #### DATA CAN BE A DIFFERENT DICTIONARY FOR EACH BACKEND #### "counts": {'00000': XXXX, '00001': XXXXX}, "time" : xx.xxxxxxxx }, "status": --status (string)-- } Raises: SimulatorError: if an error occurred. """ # pylint: disable=expression-not-assigned,pointless-statement ccircuit = circuit['compiled_circuit'] self._number_of_qubits = ccircuit['header']['number_of_qubits'] self._number_of_clbits = ccircuit['header']['number_of_clbits'] self._statevector = 0 self._classical_state = 0 cl_reg_index = [] # starting bit index of classical register cl_reg_nbits = [] # number of bits in classical register clbit_index = 0 qobj_quregs = OrderedDict(_get_register_specs( ccircuit['header']['qubit_labels'])) eng = MainEngine(backend=self._sim) for cl_reg in ccircuit['header']['clbit_labels']: cl_reg_nbits.append(cl_reg[1]) cl_reg_index.append(clbit_index) clbit_index += cl_reg[1] # let circuit seed override qobj default if 'config' in circuit: if 'seed' in circuit['config']: if circuit['config']['seed'] is not None: self._sim._simulator = CppSim(circuit['config']['seed']) outcomes = [] start = time.time() for _ in range(self._shots): self._statevector = np.zeros(1 << self._number_of_qubits, dtype=complex) self._statevector[0] = 1 # initialize starting state self._classical_state = 0 unmeasured_qubits = list(range(self._number_of_qubits)) projq_qureg_dict = OrderedDict(((key, eng.allocate_qureg(size)) for key, size in qobj_quregs.items())) qureg = [qubit for sublist in projq_qureg_dict.values() for qubit in sublist] # Do each operation in this shot for operation in ccircuit['operations']: if 'conditional' in operation: mask = int(operation['conditional']['mask'], 16) if mask > 0: value = self._classical_state & mask while (mask & 0x1) == 0: mask >>= 1 value >>= 1 if value != int(operation['conditional']['val'], 16): continue # Check if single gate if operation['name'] in ['U', 'u3']: params = operation['params'] qubit = qureg[operation['qubits'][0]] Rz(params[2]) | qubit Ry(params[0]) | qubit Rz(params[1]) | qubit elif operation['name'] in ['u1']: params = operation['params'] qubit = qureg[operation['qubits'][0]] Rz(params[0]) | qubit elif operation['name'] in ['u2']: params = operation['params'] qubit = qureg[operation['qubits'][0]] Rz(params[1] - np.pi/2) | qubit Rx(np.pi/2) | qubit Rz(params[0] + np.pi/2) | qubit elif operation['name'] == 't': qubit = qureg[operation['qubits'][0]] T | qubit elif operation['name'] == 'h': qubit = qureg[operation['qubits'][0]] H | qubit elif operation['name'] == 's': qubit = qureg[operation['qubits'][0]] S | qubit elif operation['name'] in ['CX', 'cx']: qubit0 = qureg[operation['qubits'][0]] qubit1 = qureg[operation['qubits'][1]] CX | (qubit0, qubit1) elif operation['name'] in ['id', 'u0']: pass # Check if measure elif operation['name'] == 'measure': qubit_index = operation['qubits'][0] qubit = qureg[qubit_index] clbit = operation['clbits'][0] Measure | qubit bit = 1 << clbit self._classical_state = ( self._classical_state & (~bit)) | (int(qubit) << clbit) # check whether we already measured this qubit if operation['qubits'][0] in unmeasured_qubits: unmeasured_qubits.remove(operation['qubits'][0]) # Check if reset elif operation['name'] == 'reset': qubit = operation['qubits'][0] raise SimulatorError('Reset operation not yet implemented ' 'for ProjectQ C++ backend') elif operation['name'] == 'barrier': pass else: backend = self._configuration['name'] err_msg = '{0} encountered unrecognized operation "{1}"' raise SimulatorError(err_msg.format(backend, operation['name'])) for ind in unmeasured_qubits: qubit = qureg[ind] Measure | qubit eng.flush() # Turn classical_state (int) into bit string state = format(self._classical_state, 'b') outcomes.append(state.zfill(self._number_of_clbits)) # Return the results counts = dict(Counter(outcomes)) data = {'counts': _format_result( counts, cl_reg_index, cl_reg_nbits)} if self._shots == 1: # TODO: deprecated -- remove in v0.6 data['statevector'] = self._statevector data['quantum_state'] = self._statevector data['classical_state'] = self._classical_state end = time.time() return {'name': circuit['name'], 'seed': self._seed, 'shots': self._shots, 'data': data, 'status': 'DONE', 'success': True, 'time_taken': (end-start)}
# From http://dataespresso.com/en/2018/07/22/Tutorial-Generating-random-numbers-with-a-quantum-computer-Python/ from projectq.ops import H, Measure from projectq import MainEngine """ This Function creates a new qubit, applies a Hadamard gate to put it in superposition, and then measures the qubit to get a random 1 or 0. """ def get_random_number(quantum_engine): qubit = quantum_engine.allocate_qubit() H | qubit Measure | qubit random_number = int(qubit) return random_number # This list is used to store our random numbers random_numbers_list = [] # initialises a new quantum backend quantum_engine = MainEngine() # for loop to generate 10 random numbers for i in range(10): # calling the random number function and append the return to the list random_numbers_list.append(get_random_number(quantum_engine)) # Flushes the quantum engine from memory quantum_engine.flush() print('Random numbers', random_numbers_list)
from projectq import MainEngine # import the main compiler engine # import the operations we want to perform (Hadamard and measurement) from projectq.ops import H, Measure eng = MainEngine() # create a default compiler (the back-end is a simulator) qubit = eng.allocate_qubit() # allocate 1 qubit H | qubit # apply a Hadamard gate Measure | qubit # measure the qubit eng.flush() # flush all gates (and execute measurements) print("Measured {}".format(int(qubit))) # output measurement result