def test_decomposition(): """ Test that this decomposition of H produces correct amplitudes Function tests each DecompositionRule in h2rx.all_defined_decomposition_rules """ decomposition_rule_list = h2rx.all_defined_decomposition_rules for rule in decomposition_rule_list: for basis_state_index in range(2): basis_state = [0] * 2 basis_state[basis_state_index] = 1. correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(rules=[rule]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine(backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(h_decomp_gates), test_dummy_eng ]) correct_qb = correct_eng.allocate_qubit() correct_eng.flush() test_qb = test_eng.allocate_qubit() test_eng.flush() correct_eng.backend.set_wavefunction(basis_state, correct_qb) test_eng.backend.set_wavefunction(basis_state, test_qb) H | correct_qb H | test_qb correct_eng.flush() test_eng.flush() assert H in (cmd.gate for cmd in correct_dummy_eng.received_commands) assert H not in (cmd.gate for cmd in test_dummy_eng.received_commands) assert correct_eng.backend.cheat()[1] == pytest.approx( test_eng.backend.cheat()[1], rel=1e-12, abs=1e-12) Measure | test_qb Measure | correct_qb
def test_cnot_decomposition(): for basis_state_index in range(0, 4): basis_state = [0] * 4 basis_state[basis_state_index] = 1.0 correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(modules=[cnot2cz]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(_decomp_gates), test_dummy_eng, ], ) test_sim = test_eng.backend correct_sim = correct_eng.backend correct_qb = correct_eng.allocate_qubit() correct_ctrl_qb = correct_eng.allocate_qubit() correct_eng.flush() test_qb = test_eng.allocate_qubit() test_ctrl_qb = test_eng.allocate_qubit() test_eng.flush() correct_sim.set_wavefunction(basis_state, correct_qb + correct_ctrl_qb) test_sim.set_wavefunction(basis_state, test_qb + test_ctrl_qb) CNOT | (test_ctrl_qb, test_qb) CNOT | (correct_ctrl_qb, correct_qb) test_eng.flush() correct_eng.flush() assert len(correct_dummy_eng.received_commands) == 5 assert len(test_dummy_eng.received_commands) == 7 for fstate in range(4): binary_state = format(fstate, '02b') test = test_sim.get_amplitude(binary_state, test_qb + test_ctrl_qb) correct = correct_sim.get_amplitude(binary_state, correct_qb + correct_ctrl_qb) assert correct == pytest.approx(test, rel=1e-12, abs=1e-12) All(Measure) | test_qb + test_ctrl_qb All(Measure) | correct_qb + correct_ctrl_qb test_eng.flush(deallocate_qubits=True) correct_eng.flush(deallocate_qubits=True)
def run_adder(a=11, b=1, param="simulation"): # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet( modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [ AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter ] # create a main compiler engine if param == "latex": drawing_engine = CircuitDrawer() eng2 = MainEngine(drawing_engine) [xa, xb] = initialisation(eng2, a, b) adder(eng2, xa, xb) measure(eng2, xa, xb) print(drawing_engine.get_latex()) else: eng = MainEngine(Simulator(), compilerengines) [xa, xb] = initialisation(eng, a, b) adder(eng, xa, xb) print(measure(eng, xa, xb))
def test_qureg(matplotlib_setup): sim = Simulator() eng = MainEngine(sim) qureg = eng.allocate_qureg(3) eng.flush() _, _, prob = histogram(sim, qureg) assert prob["000"] == pytest.approx(1) assert prob["110"] == pytest.approx(0) H | qureg[0] C(X, 1) | (qureg[0], qureg[1]) H | qureg[2] eng.flush() _, _, prob = histogram(sim, qureg) assert prob["110"] == pytest.approx(0.25) assert prob["100"] == pytest.approx(0) All(Measure) | qureg eng.flush() _, _, prob = histogram(sim, qureg) assert ( prob["000"] == pytest.approx(1) or prob["001"] == pytest.approx(1) or prob["110"] == pytest.approx(1) or prob["111"] == pytest.approx(1) ) assert prob["000"] + prob["001"] + prob["110"] + prob["111"] == pytest.approx(1)
def run(self, q_job): """Run circuits in q_job""" # Generating a string id for the job result_list = [] qobj = q_job.qobj self._validate(qobj) self._sim = Simulator(gate_fusion=True) if 'seed' in qobj['config']: self._seed = qobj['config']['seed'] self._sim._simulator = CppSim(self._seed) else: self._seed = random.getrandbits(32) self._shots = qobj['config']['shots'] start = time.time() for circuit in qobj['circuits']: result_list.append(self.run_circuit(circuit)) end = time.time() result = { 'backend': self._configuration['name'], 'id': qobj['id'], 'result': result_list, 'status': 'COMPLETED', 'success': True, 'time_taken': (end - start) } return Result(result, qobj)
def simulate_sample_period(base, modulus): sim = Simulator() eng = MainEngine(backend=sim, engine_list=[ AutoReplacerEx( DecompositionRuleSet(modules=[decompositions])), LimitedCapabilityEngine( allow_arithmetic= not DECOMPOSE_INTO_TOFFOLIS_AND_GO_VERY_VERY_SLOW, allow_toffoli=True, allow_single_qubit_gates=True), ]) n = int(math.ceil(math.log(modulus, 2))) ancilla_qureg = eng.allocate_qureg(n) for q in ancilla_qureg[:-1]: if random.random() < 0.5: X | q before = ancilla_qureg.measure() result = shor_find_period(base=base, modulus=modulus, precision=n * 2, phase_qubit=eng.allocate_qubit(), work_qureg=eng.allocate_qureg(n), ancilla_qureg=ancilla_qureg) after = ancilla_qureg.measure() assert after == before return result
def test_Ph_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(1) theta = cmath.pi * 2. * 0.125 unit = Ph(theta) ancillas = eng.allocate_qureg(3) QPE(unit) | (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.35, "Statistics phase calculation are not correct (%f vs. %f)" % ( num_phase / 100., 0.35)
def create_engine(use_QI_backend=False, api=None, num_runs=1, verbose=False, gate_fusion=False): """ Creates a new MainEngine. If use_QI_backend= True, Quantum Inspire is used as backend, else the ProjectQ default Simulator Returns engine for simulation Note: backend can be accessed via engine.backend both for QuantumInspire and ProjectQ simulators """ if use_QI_backend: assert ( api is not None), 'api must be defined if QI-backend should be used' # Set up compiler engines compiler_engines = default.get_engine_list() compiler_engines.extend([ManualMapper(lambda x: x)]) if use_QI_backend: qi_backend = QIBackend(quantum_inspire_api=api, num_runs=num_runs) engine = MainEngine(backend=qi_backend, engine_list=compiler_engines, verbose=verbose) else: sim = Simulator(gate_fusion=gate_fusion) engine = MainEngine(backend=sim, engine_list=compiler_engines, verbose=verbose) return engine
def run(x=4, N=7, param="run"): """ :param a: a<N and must be invertible mod[N] :param N: :param x: :param param: :return: |1> --> |(a**x) mod N> """ # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet(modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter] # create a main compiler engine if param == "latex": drawing_engine = CircuitDrawer() eng = MainEngine(drawing_engine) arcsinQ(eng, x, N) return drawing_engine if param == "count": eng = MainEngine(resource_counter) arcsinQ(eng, x, N) return resource_counter else: eng = MainEngine(Simulator(), compilerengines) return arcsinQ(eng, x, N)
def test_simple_test_X_eigenvectors(): rule_set = DecompositionRuleSet(modules=[pe, dqft]) eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), ], ) N = 150 results = np.array([]) for i in range(N): autovector = eng.allocate_qureg(1) X | autovector H | autovector unit = X ancillas = eng.allocate_qureg(1) QPE(unit) | (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.0**(len(ancillas))) results = np.append(results, phase) All(Measure) | autovector eng.flush() num_phase = (results == 0.5).sum() assert num_phase / N >= 0.35, "Statistics phase calculation are not correct (%f vs. %f)" % ( num_phase / N, 0.35, )
def __setstate__(self, state): # Restore instance attributes (i.e., filename and lineno). self.__dict__.update(state) # Restore the engine if self.backend == Simulator and self.seed is not None: self._engine = MainEngine(backend=Simulator(rnd_seed=self.seed)) else: self._engine = MainEngine(backend=self.backend())
def eng(): return MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(no_math_emulation) ], )
def run_inv(a=11, b=1, param="simulation"): # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet(modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter] # create a main compiler engine a1 = a b1 = b if a == 0: a1 = 1 if b == 0: b1 = 1 n = max(int(math.log(a1, 2)), int(math.log(b1, 2))) + 1 if param == "latex": drawing_engine = CircuitDrawer() eng2 = MainEngine(drawing_engine) xa = initialisation_n(eng2, a, n + 1) xb = initialisation_n(eng2, b, n + 1) # b --> phi(b) QFT | xb phi_adder(eng2, xa, xb) with Dagger(eng2): QFT | xb All(Measure) | xa All(Measure) | xb eng2.flush() print(drawing_engine.get_latex()) else: eng = MainEngine(Simulator(), compilerengines) xa = initialisation_n(eng, a, n + 1) xb = initialisation_n(eng, b, n + 1) # b --> phi(b) QFT | xb with Dagger(eng): phi_adder(eng, xa, xb) with Dagger(eng): QFT | xb All(Measure) | xa All(Measure) | xb eng.flush() n = n+1 measurements_a = [0] * n measurements_b = [0] * n for k in range(n): measurements_a[k] = int(xa[k]) measurements_b[k] = int(xb[k]) return [measurements_a, meas2int(measurements_b), measurements_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 test_adder(): sim = Simulator() eng = MainEngine(sim, [AutoReplacer(), InstructionFilter(no_math_emulation)]) qureg = eng.allocate_qureg(4) init(eng, qureg, 4) AddConstant(3) | qureg assert 1. == pytest.approx(abs(sim.cheat()[1][7])) init(eng, qureg, 7) # reset init(eng, qureg, 2) AddConstant(15) | qureg # check for overflow -> should be 15+2 = 1 (mod 16) assert 1. == pytest.approx(abs(sim.cheat()[1][1])) Measure | qureg
def test_complex_aa(): rule_set = DecompositionRuleSet(modules=[aa]) eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), ], ) system_qubits = eng.allocate_qureg(6) # Prepare the control qubit in the |-> state control = eng.allocate_qubit() X | control H | control # Creates the initial state form the Algorithm complex_algorithm(eng, system_qubits) # Get the probabilty of getting the marked state before the AA # to calculate the number of iterations eng.flush() prob000000 = eng.backend.get_probability('000000', system_qubits) prob111111 = eng.backend.get_probability('111111', system_qubits) total_amp_before = math.sqrt(prob000000 + prob111111) theta_before = math.asin(total_amp_before) # Apply Quantum Amplitude Amplification the correct number of times # Theta is calculated previously using get_probability # We calculate also the theoretical final probability # of getting the good state num_it = int(math.pi / (4.0 * theta_before) + 1) theoretical_prob = math.sin((2 * num_it + 1.0) * theta_before)**2 with Loop(eng, num_it): QAA(complex_algorithm, complex_oracle) | (system_qubits, control) # Get the probabilty of getting the marked state after the AA # to compare with the theoretical probability after the AA eng.flush() prob000000 = eng.backend.get_probability('000000', system_qubits) prob111111 = eng.backend.get_probability('111111', system_qubits) total_prob_after = prob000000 + prob111111 All(Measure) | system_qubits H | control Measure | control eng.flush() assert total_prob_after == pytest.approx( theoretical_prob, abs=1e-2 ), "The obtained probability is less than expected %f vs. %f" % ( total_prob_after, theoretical_prob, )
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_too_many_qubits(matplotlib_setup, capsys): sim = Simulator() eng = MainEngine(sim) qureg = eng.allocate_qureg(6) eng.flush() l_ref = len(capsys.readouterr().out) _, _, prob = histogram(sim, qureg) assert len(capsys.readouterr().out) > l_ref assert prob["000000"] == pytest.approx(1) All(Measure)
def test_decomposition(gate_matrix): for basis_state in ([1, 0], [0, 1]): # Create single qubit gate with gate_matrix test_gate = MatrixGate() test_gate.matrix = np.matrix(gate_matrix) correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(modules=[arb1q]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine(backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(z_y_decomp_gates), test_dummy_eng ]) correct_qb = correct_eng.allocate_qubit() correct_eng.flush() test_qb = test_eng.allocate_qubit() test_eng.flush() correct_eng.backend.set_wavefunction(basis_state, correct_qb) test_eng.backend.set_wavefunction(basis_state, test_qb) test_gate | test_qb test_gate | correct_qb test_eng.flush() correct_eng.flush() assert correct_dummy_eng.received_commands[2].gate == test_gate assert test_dummy_eng.received_commands[2].gate != test_gate for fstate in ['0', '1']: test = test_eng.backend.get_amplitude(fstate, test_qb) correct = correct_eng.backend.get_amplitude(fstate, correct_qb) assert correct == pytest.approx(test, rel=1e-12, abs=1e-12) Measure | test_qb Measure | correct_qb
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_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_sqrtswap(): for basis_state in ([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]): correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(modules=[sqrtswap2cnot]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(_decomp_gates), test_dummy_eng, ], ) test_sim = test_eng.backend correct_sim = correct_eng.backend correct_qureg = correct_eng.allocate_qureg(2) correct_eng.flush() test_qureg = test_eng.allocate_qureg(2) test_eng.flush() correct_sim.set_wavefunction(basis_state, correct_qureg) test_sim.set_wavefunction(basis_state, test_qureg) SqrtSwap | (test_qureg[0], test_qureg[1]) test_eng.flush() SqrtSwap | (correct_qureg[0], correct_qureg[1]) correct_eng.flush() assert len(test_dummy_eng.received_commands) != len( correct_dummy_eng.received_commands) for fstate in range(4): binary_state = format(fstate, '02b') test = test_sim.get_amplitude(binary_state, test_qureg) correct = correct_sim.get_amplitude(binary_state, correct_qureg) assert correct == pytest.approx(test, rel=1e-10, abs=1e-10) All(Measure) | test_qureg All(Measure) | correct_qureg test_eng.flush(deallocate_qubits=True) correct_eng.flush(deallocate_qubits=True)
def __enter__(self): ''' Enter context, Attributes: eng (MainEngine): main engine. backend ('graphical' or 'simulate'): backend used. qureg (Qureg): quantum register. ''' if self.task == 'ibm': import projectq.setups.ibm else: import projectq.setups.default # create a main compiler engine with a specific backend: if self.task == 'draw': self.backend = CircuitDrawer() # locations = {0: 0, 1: 1, 2: 2, 3:3} # swap order of lines 0-1-2. # self.backend.set_qubit_locations(locations) elif self.task == 'simulate': print( 'ProjecQ simulation in training can be slow, since in scipy context, we cached a lot gates.' ) self.backend = Simulator(gate_fusion=True) elif self.task == 'ibm': # choose device device = self.ibm_config.get( 'device', 'ibmqx2' if self.num_bit <= 5 else 'ibmqx5') # check data if self.ibm_config is None: raise if device == 'ibmqx5': device_num_bit = 16 else: device_num_bit = 5 if device_num_bit < self.num_bit: raise AttributeError( 'device %s has not enough qubits for %d bit simulation!' % (device, self.num_bit)) self.backend = IBMBackend(use_hardware=True, num_runs=self.ibm_config['num_runs'], user=self.ibm_config['user'], password=self.ibm_config['password'], device=device, verbose=True) else: raise ValueError('engine %s not defined' % self.task) self.eng = MainEngine(self.backend) # initialize register self.qureg = self.eng.allocate_qureg(self.num_bit) return self
def test_qubitop2singlequbit(): num_qubits = 4 random_initial_state = [ 0.2 + 0.1 * x * cmath.exp(0.1j + 0.2j * x) for x in range(2**(num_qubits + 1)) ] rule_set = DecompositionRuleSet(modules=[qubitop2onequbit]) test_eng = MainEngine( backend=Simulator(), engine_list=[AutoReplacer(rule_set), InstructionFilter(_decomp_gates)], ) test_qureg = test_eng.allocate_qureg(num_qubits) test_ctrl_qb = test_eng.allocate_qubit() test_eng.flush() test_eng.backend.set_wavefunction(random_initial_state, test_qureg + test_ctrl_qb) correct_eng = MainEngine() correct_qureg = correct_eng.allocate_qureg(num_qubits) correct_ctrl_qb = correct_eng.allocate_qubit() correct_eng.flush() correct_eng.backend.set_wavefunction(random_initial_state, correct_qureg + correct_ctrl_qb) qubit_op_0 = QubitOperator("X0 Y1 Z3", -1.0j) qubit_op_1 = QubitOperator("Z0 Y1 X3", cmath.exp(0.6j)) qubit_op_0 | test_qureg with Control(test_eng, test_ctrl_qb): qubit_op_1 | test_qureg test_eng.flush() correct_eng.backend.apply_qubit_operator(qubit_op_0, correct_qureg) with Control(correct_eng, correct_ctrl_qb): Ph(0.6) | correct_qureg[0] Z | correct_qureg[0] Y | correct_qureg[1] X | correct_qureg[3] correct_eng.flush() for fstate in range(2**(num_qubits + 1)): binary_state = format(fstate, '0' + str(num_qubits + 1) + 'b') test = test_eng.backend.get_amplitude(binary_state, test_qureg + test_ctrl_qb) correct = correct_eng.backend.get_amplitude( binary_state, correct_qureg + correct_ctrl_qb) assert correct == pytest.approx(test, rel=1e-10, abs=1e-10) All(Measure) | correct_qureg + correct_ctrl_qb All(Measure) | test_qureg + test_ctrl_qb correct_eng.flush() test_eng.flush()
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 __init__(self, register_size: int = 16, seed: int = None, backend=Simulator): if backend == Simulator and seed is not None: self._engine = MainEngine(backend=Simulator(rnd_seed=seed)) else: self._engine = MainEngine(backend=backend()) self.backend = backend self.seed = seed # if random numbers are needed to simulate quantum noise use this # state in the following way self._random_state.rand() self._random_state = RandomState(seed) self._qubit_register = None # defaulted to 16 because the bitcode status return # has 16 bits assigned for measurement results. self._qubit_register_size = register_size # stores control qubits self._control_qubit_indices = [] # assign projectq gate to each opcode self._parameterised_gate_dict = { Opcode['CONTROL'].value: C, Opcode['R'].value: R, Opcode['RX'].value: Rx, Opcode['RY'].value: Ry, Opcode['RZ'].value: Rz, Opcode['PIXY'].value: PiXY, Opcode['PIYZ'].value: PiYZ, Opcode['PIZX'].value: PiZX, } self._constant_gate_dict = { Opcode['H'].value: H, Opcode['S'].value: S, Opcode['SQRT_X'].value: SqrtX, Opcode['T'].value: T, Opcode['X'].value: X, Opcode['Y'].value: Y, Opcode['Z'].value: Z, Opcode['INVS'].value: DaggeredGate(S), Opcode['SX'].value: Sx, # consecutive S and X gate, needed for RC Opcode['SY'].value: Sy, # consecutive S and Y gate, needed for RC } atexit.register(self.cleanup)
def test_X_no_eigenvectors(): rule_set = DecompositionRuleSet( modules=[pe, dqft, stateprep2cnot, ucr2cnot]) eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), ], ) N = 100 results = np.array([]) results_plus = np.array([]) results_minus = np.array([]) for i in range(N): autovector = eng.allocate_qureg(1) amplitude0 = (np.sqrt(2) + np.sqrt(6)) / 4.0 amplitude1 = (np.sqrt(2) - np.sqrt(6)) / 4.0 StatePreparation([amplitude0, amplitude1]) | autovector unit = X ancillas = eng.allocate_qureg(1) QPE(unit) | (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.0**(len(ancillas))) results = np.append(results, phase) Tensor(H) | autovector if np.allclose(phase, 0.0, rtol=1e-1): results_plus = np.append(results_plus, phase) All(Measure) | autovector autovector_result = int(autovector) assert autovector_result == 0 elif np.allclose(phase, 0.5, rtol=1e-1): results_minus = np.append(results_minus, phase) All(Measure) | autovector autovector_result = int(autovector) assert autovector_result == 1 eng.flush() total = len(results_plus) + len(results_minus) plus_probability = len(results_plus) / N assert total == pytest.approx(N, abs=5) assert plus_probability == pytest.approx( 1.0 / 4.0, abs=1e-1 ), "Statistics on |+> probability are not correct (%f vs. %f)" % ( plus_probability, 1.0 / 4.0, )
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 test_comparator(): sim = Simulator() eng = MainEngine( sim, [AutoReplacer(rule_set), InstructionFilter(no_math_emulation)]) qureg_a = eng.allocate_qureg(3) qureg_b = eng.allocate_qureg(3) compare_qubit = eng.allocate_qubit() init(eng, qureg_a, 5) init(eng, qureg_b, 3) Comparator() | (qureg_a, qureg_b, compare_qubit) assert 1. == pytest.approx(eng.backend.get_probability([1], compare_qubit))
def bench_projectq(n, depth): eng = MainEngine(backend=Simulator(gate_fusion=True), engine_list=[]) qbits = eng.allocate_qureg(n) start = time.time() for level in range(depth): for q in qbits: ops.H | q ops.T | q if q != qbits[0]: ops.CNOT | (q, qbits[0]) for q in qbits: ops.Measure | q return time.time() - start