def test_phase_majority(): sim = Simulator() main_engine = MainEngine(sim) qureg = main_engine.allocate_qureg(3) All(H) | qureg PhaseOracle(0xe8) | 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 test_local_optimizer_flush_gate(): local_optimizer = _optimize.LocalOptimizer(m=4) backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[local_optimizer]) # Test that it caches for each qubit 3 gates qb0 = eng.allocate_qubit() qb1 = eng.allocate_qubit() H | qb0 H | qb1 assert len(backend.received_commands) == 0 eng.flush() # Two allocate gates, two H gates and one flush gate assert len(backend.received_commands) == 5
def get_state(self, circuit: Circuit, fit_to_constraints=True) -> list: c = circuit.copy() if fit_to_constraints: Transform.RebaseToProjectQ().apply(c) fwd = ForwarderEngine(self._backend) eng = MainEngine(backend=self._backend, engine_list=[fwd]) qureg = eng.allocate_qureg(c.n_qubits) tk_to_projectq(eng, qureg, c) eng.flush() state = self._backend.cheat( )[1] #`cheat()` returns tuple:(a dictionary of qubit indices, statevector) All(Measure) | qureg return state #list of complex numbers
def test_high_level_gate_set(): mod_list = projectq.setups.ibm16.get_engine_list() saving_engine = DummyEngine(save_commands=True) mod_list = mod_list[:6] + [saving_engine] + mod_list[6:] eng = MainEngine(DummyEngine(), engine_list=mod_list) qureg = eng.allocate_qureg(3) AddConstant(3) | qureg QFT | qureg eng.flush() received_gates = [cmd.gate for cmd in saving_engine.received_commands] assert sum([1 for g in received_gates if g == QFT]) == 1 assert get_inverse(QFT) not in received_gates assert AddConstant(3) not in received_gates
def test_ibmcnotmapper_invalid_circuit(): backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[_ibmcnotmapper.IBMCNOTMapper()]) qb0 = eng.allocate_qubit() qb1 = eng.allocate_qubit() qb2 = eng.allocate_qubit() qb3 = eng.allocate_qubit() CNOT | (qb1, qb2) CNOT | (qb0, qb1) with pytest.raises(Exception): CNOT | (qb3, qb2) eng.flush()
def test_auto_replacer_default_chooser(fixture_gate_filter): # Test that default decomposition_chooser takes always first rule. backend = DummyEngine(save_commands=True) eng = MainEngine( backend=backend, engine_list=[_replacer.AutoReplacer(rule_set), 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 == X
def test_local_optimizer_mergeable_gates(): local_optimizer = _optimize.LocalOptimizer(m=4) backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[local_optimizer]) # Test that it merges mergeable gates such as Rx qb0 = eng.allocate_qubit() for _ in range(10): Rx(0.5) | qb0 assert len(backend.received_commands) == 0 eng.flush() # Expect allocate, one Rx gate, and flush gate assert len(backend.received_commands) == 3 assert backend.received_commands[1].gate == Rx(10 * 0.5)
def test_recognize_correct_gates(): """Test that recognize_RzNoCtrl recognizes ctrl qubits""" saving_backend = DummyEngine(save_commands=True) eng = MainEngine(backend=saving_backend) qubit = eng.allocate_qubit() ctrl_qubit = eng.allocate_qubit() eng.flush() Rz(0.3) | qubit with Control(eng, ctrl_qubit): Rz(0.4) | qubit eng.flush(deallocate_qubits=True) assert rz2rx._recognize_RzNoCtrl(saving_backend.received_commands[3]) assert not rz2rx._recognize_RzNoCtrl(saving_backend.received_commands[4])
def test_simulator_send(): sim = Simulator() backend = DummyEngine(save_commands=True) eng = MainEngine(backend, [sim]) qubit = eng.allocate_qubit() H | qubit Measure | qubit del qubit eng.flush() assert len(backend.received_commands) == 5
def test_auto_replacer_priorize_controlstate_rule(): # Check that when a control state is given and it has negative control, # Autoreplacer prioritizes the corresponding decomposition rule before anything else. # (Decomposition rule should have name _decompose_controlstate) # Create test gate and inverse class ControlGate(BasicGate): pass def _decompose_controlstate(cmd): S | cmd.qubits def _decompose_random(cmd): H | cmd.qubits def control_filter(self, cmd): if cmd.gate == ControlGate(): return False return True rule_set.add_decomposition_rule( DecompositionRule(BasicGate, _decompose_random)) backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[ _replacer.AutoReplacer(rule_set), _replacer.InstructionFilter(control_filter) ]) assert len(backend.received_commands) == 0 qb = eng.allocate_qubit() ControlGate() | qb eng.flush() assert len(backend.received_commands) == 3 assert backend.received_commands[1].gate == H rule_set.add_decomposition_rule( DecompositionRule(BasicGate, _decompose_controlstate)) backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[ _replacer.AutoReplacer(rule_set), _replacer.InstructionFilter(control_filter) ]) assert len(backend.received_commands) == 0 qb = eng.allocate_qubit() ControlGate() | qb eng.flush() assert len(backend.received_commands) == 3 assert backend.received_commands[1].gate == S
def subproblem4(): eng = MainEngine() qubits = eng.allocate_qureg(3) # You should add quantum operations here to change the state of qubits into |101>+|010> H | qubits[1] CX | (qubits[1], qubits[0]) CX | (qubits[1], qubits[2]) eng.flush() amplitudes = np.array(eng.backend.cheat()[1]) All(Measure) | qubits print("p4:{}".format(amplitudes)) return amplitudes
def run_test(self, description, iterations, prep_function): """ Runs a unit test of the teleportation protocol with the provided state preparation function. Parameters: description (str): A description of the test, for logging. iterations (int): The number of times to run the program. prep_function (function): The function that can prepare (and un-prepare) the desired state to be teleported. """ print(f"Running test: {description}") engine = MainEngine() original_qubit = engine.allocate_qubit() transfer_qubit = engine.allocate_qubit() reproduction_qubit = engine.allocate_qubit() # Try teleportation using all 4 of the Bell states for the entangled transfer qubit pair for entanglement_state in range(0, 4): for i in range(0, iterations): # Prepare the original qubit in the desired state, and the transfer qubits that will be used to teleport it prep_function(original_qubit) self.prepare_transfer_qubits(entanglement_state, transfer_qubit, reproduction_qubit) # Teleport the original qubit, turning the remote reproduction qubit's state into the original state (original_measurement, transfer_measurement) = self.measure_message_parameters(original_qubit, transfer_qubit) self.reproduce_original(entanglement_state, original_measurement, transfer_measurement, reproduction_qubit) # Run the adjoint preparation function on the reproduction qubit, and measure it. # If it is now in the original state, this should turn it back into |0> every time. with Dagger(engine): prep_function(reproduction_qubit) # Make sure the result qubit is 0 Measure | reproduction_qubit if int(reproduction_qubit) != 0: self.fail(f"Test {description} failed with entanglement state {entanglement_state}. " + f"Resulting state {result} had a 1 for the result, which means " + "the qubit wasn't teleported properly.") reset([original_qubit, transfer_qubit, reproduction_qubit]) engine.flush() print(f"Entanglement state {entanglement_state} passed."); print("Passed!") print()
def test_ibm_backend_functional_test(monkeypatch): correct_info = ('{"qasms": [{"qasm": "\\ninclude \\"' 'qelib1.inc\\";\\nqreg q[3];\\ncreg c[3];\\nh q[0];\\ncx' ' q[0], q[2];\\ncx q[0], q[1];\\ntdg q[0];\\nsdg q[0];\\' 'nbarrier q[0], q[2], q[1];\\nu3(0.2, -pi/2, pi/2) q[0];' '\\nmeasure q[0] -> c[0];\\nmeasure q[2] -> c[2];\\nmeas' 'ure q[1] -> c[1];"}], "shots": 1024, "maxCredits": 5,' ' "backend": {"name": "simulator"}}') # patch send def mock_send(*args, **kwargs): assert json.loads(args[0]) == json.loads(correct_info) return {'date': '2017-01-19T14:28:47.622Z', 'data': {'time': 14.429004907608032, 'counts': {'00111': 396, '00101': 27, '00000': 601}, 'qasm': ('...')}} monkeypatch.setattr(_ibm, "send", mock_send) backend = _ibm.IBMBackend(verbose=True) # no circuit has been executed -> raises exception with pytest.raises(RuntimeError): backend.get_probabilities([]) rule_set = DecompositionRuleSet(modules=[projectq.setups.decompositions]) engine_list = [TagRemover(), LocalOptimizer(10), AutoReplacer(rule_set), TagRemover(), IBMCNOTMapper(), LocalOptimizer(10)] eng = MainEngine(backend=backend, engine_list=engine_list) unused_qubit = eng.allocate_qubit() qureg = eng.allocate_qureg(3) # entangle the qureg Entangle | qureg Tdag | qureg[0] Sdag | qureg[0] Barrier | qureg Rx(0.2) | qureg[0] del unused_qubit # measure; should be all-0 or all-1 Measure | qureg # run the circuit eng.flush() prob_dict = eng.backend.get_probabilities([qureg[0], qureg[2], qureg[1]]) assert prob_dict['111'] == pytest.approx(0.38671875) assert prob_dict['101'] == pytest.approx(0.0263671875) with pytest.raises(RuntimeError): eng.backend.get_probabilities(eng.allocate_qubit())
def MUL_resources(number_of_bits = 16): print('getting costs of ' + str(number_of_bits) + ' unsigned multiplication...') #___________________initial__________________ resource_counter = ResourceCounter() eng = MainEngine(resource_counter) a = [0 for i in range(number_of_bits)] b = [0 for i in range(number_of_bits)] n = len(a) z = list_to_reg([0 for _ in range(2*n)],eng) a = list_to_reg( a, eng) #one extra bit (in most significant) needed for addition b = list_to_reg(b, eng) fixed_MUL(a,b,z, eng = eng) eng.flush() print(resource_counter)
def CRightShift_resources(k): #___________________initial__________________ resource_counter = ResourceCounter() eng = MainEngine(resource_counter) control = list_to_reg([0],eng) m = k #case when mantissa is 13 bits x = list_to_reg([0 for i in range(m)],eng) x = x[::-1]#for right swap print('Getting resources for ' + str(len(x)) + ' controlled shift by 1 circuit.') for i in range(0,m-1): C(Swap,1)|(control,x[i],x[i+1] ) Measure | control Measure | x #for tex purposes eng.flush() print(resource_counter)
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 test_recognize(): saving_backend = DummyEngine(save_commands=True) eng = MainEngine(backend=saving_backend, engine_list=[]) ctrl_qureg = eng.allocate_qureg(2) qureg = eng.allocate_qureg(2) with Control(eng, ctrl_qureg): QubitOperator("X0 Y1") | qureg with Control(eng, ctrl_qureg[0]): QubitOperator("X0 Y1") | qureg eng.flush() cmd0 = saving_backend.received_commands[4] cmd1 = saving_backend.received_commands[5] assert not qubitop2onequbit._recognize_qubitop(cmd0) assert qubitop2onequbit._recognize_qubitop(cmd1)
def test_simulator_time_evolution(sim): N = 9 # number of qubits time_to_evolve = 1.1 # time to evolve for eng = MainEngine(sim, []) qureg = eng.allocate_qureg(N) # initialize in random wavefunction by applying some gates: for qb in qureg: Rx(random.random()) | qb Ry(random.random()) | qb eng.flush() # Use cheat to get initial start wavefunction: qubit_to_bit_map, init_wavefunction = copy.deepcopy(eng.backend.cheat()) Qop = QubitOperator op = 0.3 * Qop("X0 Y1 Z2 Y3 X4") op += 1.1 * Qop(()) op += -1.4 * Qop("Y0 Z1 X3 Y5") op += -1.1 * Qop("Y1 X2 X3 Y4") TimeEvolution(time_to_evolve, op) | qureg eng.flush() qbit_to_bit_map, final_wavefunction = copy.deepcopy(eng.backend.cheat()) Measure | qureg # Check manually: def build_matrix(list_single_matrices): res = list_single_matrices[0] for i in range(1, len(list_single_matrices)): res = scipy.sparse.kron(res, list_single_matrices[i]) return res id_sp = scipy.sparse.identity(2, format="csr", dtype=complex) x_sp = scipy.sparse.csr_matrix([[0., 1.], [1., 0.]], dtype=complex) y_sp = scipy.sparse.csr_matrix([[0., -1.j], [1.j, 0.]], dtype=complex) z_sp = scipy.sparse.csr_matrix([[1., 0.], [0., -1.]], dtype=complex) gates = [x_sp, y_sp, z_sp] res_matrix = 0 for t, c in op.terms.items(): matrix = [id_sp] * N for idx, gate in t: matrix[qbit_to_bit_map[qureg[idx].id]] = gates[ord(gate) - ord('X')] matrix.reverse() res_matrix += build_matrix(matrix) * c res_matrix *= -1j * time_to_evolve init_wavefunction = numpy.array(init_wavefunction, copy=False) final_wavefunction = numpy.array(final_wavefunction, copy=False) res = scipy.sparse.linalg.expm_multiply(res_matrix, init_wavefunction) assert numpy.allclose(res, final_wavefunction)
def circuit_no_ancilla(param=0, sigma=0, M=1): Engine = MainEngine() q1 = Engine.allocate_qureg(1) q2 = Engine.allocate_qureg(1) Rx(param) | q1 Rx(param) | q2 # [R * c-Pi * R^\dag * P * R * c-Pi * R^\dag * P] for _ in range(M): Z | q1 Z | q2 DaggeredGate(Rx(param)) | q1 DaggeredGate(Rx(param)) | q2 Rzz(pi / 2) | (q1, q2) Rz(pi / 2) | q1 Rz(pi / 2) | q2 Rx(param) | q1 Rx(param) | q2 Z | q1 Z | q2 DaggeredGate(Rx(param)) | q1 DaggeredGate(Rx(param)) | q2 Rzz(pi / 2) | (q1, q2) Rz(pi / 2) | q1 Rz(pi / 2) | q2 Rx(param) | q1 Rx(param) | q2 DaggeredGate(Rx(param)) | q1 DaggeredGate(Rx(param)) | q2 Measure | q1 Measure | q2 Engine.flush() return (int(q1), int(q2))
def process_circuits( self, circuits: Iterable[Circuit], n_shots: Optional[int] = None, valid_check: bool = True, **kwargs: KwargTypes, ) -> List[ResultHandle]: """ See :py:meth:`pytket.backends.Backend.process_circuits`. Supported kwargs: `seed`. """ circuit_list = list(circuits) if valid_check: self._check_all_circuits(circuit_list) handle_list = [] for circuit in circuit_list: sim = Simulator(rnd_seed=kwargs.get("seed")) fwd = ForwarderEngine(sim) eng = MainEngine(backend=sim, engine_list=[fwd]) qureg = eng.allocate_qureg(circuit.n_qubits) tk_to_projectq(eng, qureg, circuit, True) eng.flush() state = np.array( eng.backend.cheat()[1], dtype=complex ) # `cheat()` returns tuple:(a dictionary of qubit indices, statevector) handle = ResultHandle(str(uuid4())) try: phase = float(circuit.phase) coeff = np.exp(phase * np.pi * 1j) state *= coeff except ValueError: warning( "Global phase is dependent on a symbolic parameter, so cannot " "adjust for phase") implicit_perm = circuit.implicit_qubit_permutation() # reverse qubits as projectq state is dlo res_qubits = [ implicit_perm[qb] for qb in sorted(circuit.qubits, reverse=True) ] measures = circuit.n_gates_of_type(OpType.Measure) if measures == 0 and n_shots is not None: backres = self.empty_result(circuit, n_shots=n_shots) else: backres = BackendResult(q_bits=res_qubits, state=state) self._cache[handle] = {"result": backres} handle_list.append(handle) return handle_list
def deutsch_jozsa(f): # Determine number of qubits needed N = len(f) n = int(np.log2(N)) # Check we can simulate on our local simulator if n > 28: # 28 qubits = 4GB of RAM print('Number of qubits required =', n, 'which is too large to simulate.') return 0 # Initialise qubits engine = MainEngine() qubits = engine.allocate_qureg(n) ancilla = engine.allocate_qubit() # Start with qubits in equal superposition and ancilla in |-> All(H) | qubits X | ancilla H | ancilla # Apply oracle U_f which flips the phase of every state |x> with f(x) = 1 for i in range(N): if f[i] == '1': # Then we need to flip the phase state = bin(i)[2:].zfill(n) for j in range(n): if state[j] == '0': X | qubits[j] with Control(engine, qubits): X | ancilla for j in range(n): if state[j] == '0': X | qubits[j] # Apply Hadamards to working qubits All(H) | qubits # Measure all the qubits and output result All(Measure) | qubits Measure | ancilla engine.flush() y = 0 for i in range(n): y = y + 2**i*int(qubits[i]) if y == 0: print('Function is constant.') else: print('Function is balanced.')
def ADD_resources(number_of_bits = 16): print('getting costs of ' + str(number_of_bits) + ' bit addition...') #___________________initial__________________ resource_counter = ResourceCounter() eng = MainEngine(resource_counter) a = [0 for i in range(number_of_bits)] b = [0 for i in range(number_of_bits)] a = list_to_reg( a, eng) #one extra bit (in most significant) needed for addition z = list_to_reg([0],eng) b = list_to_reg(b, eng) #___________________circuit___________________ ADD(a,b,z) #___________________measure___________________ eng.flush() print(resource_counter)
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 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 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 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 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_body(): drawer = _drawer.CircuitDrawer() eng = MainEngine(drawer, []) old_tolatex = _drawer.to_latex _drawer.to_latex = lambda x: x qubit1 = eng.allocate_qubit() qubit2 = eng.allocate_qubit() qubit3 = eng.allocate_qubit() H | qubit1 H | qubit2 CNOT | (qubit1, qubit2) X | qubit2 Measure | qubit2 CNOT | (qubit2, qubit1) Z | qubit2 C(Z) | (qubit1, qubit2) C(Swap) | (qubit1, qubit2, qubit3) SqrtX | qubit1 SqrtSwap | (qubit1, qubit2) get_inverse(SqrtX) | qubit1 C(SqrtSwap) | (qubit1, qubit2, qubit3) get_inverse(SqrtSwap) | (qubit1, qubit2) C(Swap) | (qubit3, qubit1, qubit2) C(SqrtSwap) | (qubit3, qubit1, qubit2) del qubit1 eng.flush() circuit_lines = drawer.get_latex() _drawer.to_latex = old_tolatex settings = _to_latex.get_default_settings() settings['gates']['AllocateQubitGate']['draw_id'] = True code = _to_latex._body(circuit_lines, settings) # swap draws 2 nodes + 2 lines each, so is sqrtswap gate, csqrtswap, # inv(sqrt_swap), and cswap. assert code.count("swapstyle") == 36 # CZ is two phases plus 2 from CNOTs + 2 from cswap + 2 from csqrtswap assert code.count("phase") == 8 assert code.count("{{{}}}".format(str(H))) == 2 # 2 hadamard gates assert code.count("{$\Ket{0}") == 3 # 3 qubits allocated # 1 cnot, 1 not gate, 3 SqrtSwap, 1 inv(SqrtSwap) assert code.count("xstyle") == 7 assert code.count("measure") == 1 # 1 measurement assert code.count("{{{}}}".format(str(Z))) == 1 # 1 Z gate assert code.count("{red}") == 3
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_auto_replacer_no_rule_found(): # Check that exception is thrown if no rule is found # For both the cmd and it's inverse (which exists) def h_filter(self, cmd): if cmd.gate == H: return False return True h_filter = _replacer.InstructionFilter(h_filter) backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[_replacer.AutoReplacer(rule_set), h_filter]) qubit = eng.allocate_qubit() with pytest.raises(_replacer.NoGateDecompositionError): H | qubit eng.flush()
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