def test_aqt_retrieve(monkeypatch): # patch send def mock_retrieve(*args, **kwargs): return [0, 6, 0, 6, 0, 0, 0, 6, 0, 6] monkeypatch.setattr(_aqt, "retrieve", mock_retrieve) backend = _aqt.AQTBackend( retrieve_execution="a3877d18-314f-46c9-86e7-316bc4dbe968", verbose=True) eng = MainEngine(backend=backend, engine_list=[]) unused_qubit = eng.allocate_qubit() qureg = eng.allocate_qureg(2) # entangle the qureg Ry(math.pi / 2) | qureg[0] Rx(math.pi / 2) | qureg[0] Rx(math.pi / 2) | qureg[0] Ry(math.pi / 2) | qureg[0] Rxx(math.pi / 2) | (qureg[0], qureg[1]) Rx(7 * math.pi / 2) | qureg[0] Ry(7 * math.pi / 2) | qureg[0] Rx(7 * math.pi / 2) | qureg[1] del unused_qubit # measure; should be all-0 or all-1 All(Measure) | qureg # run the circuit eng.flush() prob_dict = eng.backend.get_probabilities([qureg[0], qureg[1]]) assert prob_dict['11'] == pytest.approx(0.4) assert prob_dict['00'] == pytest.approx(0.6) # Unknown qubit and no mapper invalid_qubit = [Qubit(eng, 10)] with pytest.raises(RuntimeError): eng.backend.get_probabilities(invalid_qubit)
def test_simulator_probability(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(H) | qubits eng.flush() bits = [0, 0, 1, 0, 1, 0] for i in range(6): assert eng.backend.get_probability(bits[:i], qubits[:i]) == pytest.approx(0.5**i) extra_qubit = eng.allocate_qubit() with pytest.raises(RuntimeError): eng.backend.get_probability([0], extra_qubit) del extra_qubit All(H) | qubits Ry(2 * math.acos(math.sqrt(0.3))) | qubits[0] eng.flush() assert eng.backend.get_probability([0], [qubits[0]]) == pytest.approx(0.3) Ry(2 * math.acos(math.sqrt(0.4))) | qubits[2] eng.flush() assert eng.backend.get_probability([0], [qubits[2]]) == pytest.approx(0.4) assert eng.backend.get_probability([0, 0], qubits[:3:2]) == pytest.approx(0.12) assert eng.backend.get_probability([0, 1], qubits[:3:2]) == pytest.approx(0.18) assert eng.backend.get_probability([1, 0], qubits[:3:2]) == pytest.approx(0.28) All(Measure) | qubits
def test_decomposition(angle): for basis_state in ([1, 0], [0, 1]): correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(modules=[ry2rz]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(ry_decomp_gates), test_dummy_eng, ], ) correct_qb = correct_eng.allocate_qubit() Ry(angle) | correct_qb correct_eng.flush() test_qb = test_eng.allocate_qubit() Ry(angle) | test_qb test_eng.flush() assert correct_dummy_eng.received_commands[1].gate == Ry(angle) assert test_dummy_eng.received_commands[1].gate != Ry(angle) 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_simulator_probability(sim): eng = MainEngine(sim) qubits = eng.allocate_qureg(6) All(H) | qubits eng.flush() bits = [0, 0, 1, 0, 1, 0] for i in range(6): assert (eng.backend.get_probability( bits[:i], qubits[:i]) == pytest.approx(0.5**i)) extra_qubit = eng.allocate_qubit() with pytest.raises(RuntimeError): eng.backend.get_probability([0], extra_qubit) del extra_qubit All(H) | qubits Ry(2 * math.acos(math.sqrt(0.3))) | qubits[0] eng.flush() assert eng.backend.get_probability([0], [qubits[0]]) == pytest.approx(0.3) Ry(2 * math.acos(math.sqrt(0.4))) | qubits[2] eng.flush() assert eng.backend.get_probability([0], [qubits[2]]) == pytest.approx(0.4) assert (eng.backend.get_probability([0, 0], qubits[:3:2]) == pytest.approx(0.12)) assert (eng.backend.get_probability([0, 1], qubits[:3:2]) == pytest.approx(0.18)) assert (eng.backend.get_probability([1, 0], qubits[:3:2]) == pytest.approx(0.28)) Measure | qubits
def _decompose_arb1qubit(cmd): """ Use Z-Y decomposition of Nielsen and Chuang (Theorem 4.1). An arbitrary one qubit gate matrix can be writen as U = [[exp(j*(a-b/2-d/2))*cos(c/2), -exp(j*(a-b/2+d/2))*sin(c/2)], [exp(j*(a+b/2-d/2))*sin(c/2), exp(j*(a+b/2+d/2))*cos(c/2)]] where a,b,c,d are real numbers. Then U = exp(j*a) Rz(b) Ry(c) Rz(d). If the matrix is element of SU(2) (determinant == 1), then we can choose a = 0. """ matrix = cmd.gate.matrix.tolist() a, b_half, c_half, d_half = _find_parameters(matrix) qb = cmd.qubits eng = cmd.engine with Control(eng, cmd.control_qubits): if Rz(2 * d_half) != Rz(0): Rz(2 * d_half) | qb if Ry(2 * c_half) != Ry(0): Ry(2 * c_half) | qb if Rz(2 * b_half) != Rz(0): Rz(2 * b_half) | qb if a != 0: Ph(a) | qb
def test_decomposition(): for basis_state_index in range(0, 16): basis_state = [0] * 16 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=[cnu2toffoliandcu]) 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_qureg = correct_eng.allocate_qureg(3) correct_eng.flush() test_qb = test_eng.allocate_qubit() test_ctrl_qureg = test_eng.allocate_qureg(3) test_eng.flush() correct_sim.set_wavefunction(basis_state, correct_qb + correct_ctrl_qureg) test_sim.set_wavefunction(basis_state, test_qb + test_ctrl_qureg) with Control(test_eng, test_ctrl_qureg[:2]): Rx(0.4) | test_qb with Control(test_eng, test_ctrl_qureg): Ry(0.6) | test_qb with Control(test_eng, test_ctrl_qureg): X | test_qb with Control(correct_eng, correct_ctrl_qureg[:2]): Rx(0.4) | correct_qb with Control(correct_eng, correct_ctrl_qureg): Ry(0.6) | correct_qb with Control(correct_eng, correct_ctrl_qureg): X | correct_qb test_eng.flush() correct_eng.flush() assert len(correct_dummy_eng.received_commands) == 9 assert len(test_dummy_eng.received_commands) == 25 for fstate in range(16): binary_state = format(fstate, '04b') test = test_sim.get_amplitude(binary_state, test_qb + test_ctrl_qureg) correct = correct_sim.get_amplitude(binary_state, correct_qb + correct_ctrl_qureg) assert correct == pytest.approx(test, rel=1e-12, abs=1e-12) All(Measure) | test_qb + test_ctrl_qureg All(Measure) | correct_qb + correct_ctrl_qureg test_eng.flush(deallocate_qubits=True) correct_eng.flush(deallocate_qubits=True)
def test_aqt_backend_functional_test(monkeypatch): correct_info = { 'circuit': '[["Y", 0.5, [1]], ["X", 0.5, [1]], ["X", 0.5, [1]], ' '["Y", 0.5, [1]], ["MS", 0.5, [1, 2]], ["X", 3.5, [1]], ' '["Y", 3.5, [1]], ["X", 3.5, [2]]]', 'nq': 3, 'shots': 10, 'backend': {'name': 'simulator'}, } def mock_send(*args, **kwargs): assert args[0] == correct_info return [0, 6, 0, 6, 0, 0, 0, 6, 0, 6] monkeypatch.setattr(_aqt, "send", mock_send) backend = _aqt.AQTBackend(verbose=True, num_runs=10) # no circuit has been executed -> raises exception with pytest.raises(RuntimeError): backend.get_probabilities([]) mapper = BasicMapperEngine() res = {} for i in range(4): res[i] = i mapper.current_mapping = res eng = MainEngine(backend=backend, engine_list=[mapper]) unused_qubit = eng.allocate_qubit() qureg = eng.allocate_qureg(2) # entangle the qureg Ry(math.pi / 2) | qureg[0] Rx(math.pi / 2) | qureg[0] Rx(math.pi / 2) | qureg[0] Ry(math.pi / 2) | qureg[0] Rxx(math.pi / 2) | (qureg[0], qureg[1]) Rx(7 * math.pi / 2) | qureg[0] Ry(7 * math.pi / 2) | qureg[0] Rx(7 * math.pi / 2) | qureg[1] All(Barrier) | qureg del unused_qubit # measure; should be all-0 or all-1 All(Measure) | qureg # run the circuit eng.flush() prob_dict = eng.backend.get_probabilities([qureg[0], qureg[1]]) assert prob_dict['11'] == pytest.approx(0.4) assert prob_dict['00'] == pytest.approx(0.6) # Unknown qubit and no mapper invalid_qubit = [WeakQubitRef(eng, 10)] with pytest.raises(RuntimeError): eng.backend.get_probabilities(invalid_qubit) with pytest.raises(RuntimeError): eng.backend.get_probabilities(eng.allocate_qubit())
def initializeState(qreg, theta): Rx(np.pi) | qreg[0] Ry(np.pi / 2.0) | qreg[1] Rx(2.5*np.pi) | qreg[0] CNOT | (qreg[1], qreg[0]) Rz(theta) | qreg[0] CNOT | (qreg[1], qreg[0]) Ry(2.5*np.pi) | qreg[1] Rx(np.pi/2) | qreg[0]
def active_fun(self, train_or_test): """ :param train_or_test: bool, True or False :return: loss """ if train_or_test == 'train': x_epoch = self.train_x y_epoch = self.train_y return_test_label = False elif train_or_test == 'test': x_epoch = self.test_x y_epoch = self.test_y return_test_label = True else: print('error!!!') y_sim = [] for encoded_data in x_epoch: self.eng.backend.set_wavefunction(self.init_wavefun, self.qureg) for w in range(2): # represent the data with same weight for i in range(len(encoded_data[0])): if encoded_data[w][i]: X | self.qureg[self.n_qubits1data * w + i] with Control(self.eng, self.qureg[self.n_qubits1data * w + i]): Ry(2 * encoded_data[-1] * self.alpha[w] / 2**i) | self.qureg[-2] # add bios Ry(2 * self.alpha[-1]) | self.qureg[-2] with Control(self.eng, self.qureg[-2]): Y | self.qureg[-1] Rz(-np.pi / 2) | self.qureg[2] Ry(-2 * self.alpha[-1]) | self.qureg[-2] for w in range(2): # represent the data with same weight for i in range(len(encoded_data[0])): with Control(self.eng, self.qureg[self.n_qubits1data * w + i]): Ry(-2 * encoded_data[-1] * self.alpha[w] / 2**i) | self.qureg[-2] self.eng.flush() # self.eng.backend.collapse_wavefunction([self.qureg[-2]], [0]) result = self.eng.backend.get_probability('0', [self.qureg[-1]]) Measure | self.qureg y_sim.append(np.arccos(np.sqrt(result)) / (np.pi / 2)) # y_sim.append(result) loss = self.cal_loss(y_epoch, y_sim) if return_test_label: return loss, y_sim else: return loss
def _decompose_cnot2rxx_P(cmd): """ Decompose CNOT gate into Rxx gate. """ # Labelled 'P' for 'plus' because decomposition ends with a Ry(+pi/2) ctrl = cmd.control_qubits Ry(-math.pi / 2) | ctrl[0] Ph(math.pi / 4) | ctrl[0] Rx(-math.pi / 2) | ctrl[0] Rx(math.pi / 2) | cmd.qubits[0][0] Rxx(math.pi / 2) | (ctrl[0], cmd.qubits[0][0]) Ry(math.pi / 2) | ctrl[0]
def _decompose_cnot2rxx_M(cmd): # pylint: disable=invalid-name """Decompose CNOT gate into Rxx gate.""" # Labelled 'M' for 'minus' because decomposition ends with a Ry(-pi/2) ctrl = cmd.control_qubits Ry(math.pi / 2) | ctrl[0] Ph(7 * math.pi / 4) | ctrl[0] Rx(-math.pi / 2) | ctrl[0] Rx(-math.pi / 2) | cmd.qubits[0][0] Rxx(math.pi / 2) | (ctrl[0], cmd.qubits[0][0]) Ry(-1 * math.pi / 2) | ctrl[0]
def apply_zyz(qureg, id, beta, delta, gamma): if delta == 0. and gamma == 0.: Rz(2 * beta) | qureg[id] elif beta == 0. and gamma == np.pi / 2.: Ry(2 * gamma) | qureg[id] Rz(2 * delta) | qureg[id] else: Rz(2 * beta) | qureg[id] Ry(2 * gamma) | qureg[id] Rz(2 * delta) | qureg[id]
def cal_mat(self): C = np.array(Rz(self.theta[0]).matrix) B = np.array(Ry(self.theta[1]).matrix) A = np.dot(np.linalg.inv(np.array(Rz(self.theta[0]).matrix)), np.linalg.inv(np.array(Ry(self.theta[1]).matrix))) gates = [A, X.matrix, B, X.matrix, C] mat = np.array([[1, 0], [0, 1]]) for g in gates: mat = np.dot(mat, g) # print(mat) return mat
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() Ry(0.3) | qubit with Control(eng, ctrl_qubit): Ry(0.4) | qubit eng.flush(deallocate_qubits=True) assert ry2rz._recognize_RyNoCtrl(saving_backend.received_commands[3]) assert not ry2rz._recognize_RyNoCtrl(saving_backend.received_commands[4])
def cost(param, target_state, p, eng): ''' VQE core part ''' tolerance=0.001 assert np.abs(sum([np.abs(i)**2 for i in target_state])-1)<tolerance, "Invalid Target State" n=int(np.log2(len(target_state))) assert len(param)==3*n*p param=param.reshape((n,3*p)) count = 0 all_string = bitstring(n) qureg = eng.allocate_qureg(n) All(H) | qureg for m in range(p): for i in range(n): Rx(param[i, 3*m+0]) | qureg[i] Ry(param[i, 3*m+1]) | qureg[i] Rz(param[i, 3*m+2]) | qureg[i] CNOT | (qureg[n-1], qureg[0]) for i in range(n-1): CNOT | (qureg[i], qureg[i+1]) eng.flush() for i in range(len(target_state)): count += target_state[i] * eng.backend.get_amplitude(all_string[i], qureg) All(Measure) | qureg return 1-np.abs(count)
def complex_algorithm(eng, qreg): All(H) | qreg with Control(eng, qreg[0]): All(X) | qreg[1:] All(Ry(math.pi / 4)) | qreg[1:] with Control(eng, qreg[-1]): All(X) | qreg[1:-1]
def d_cal(vec1, vec2): """ a function that calculate the euclid distance in a quantum way :param vec1: a list form vector, like [1, 2, 3, 5], totally 2^n elements :param vec2: a list form vector, with the same shape of vec1 :return: distance between vec1 and vec2 """ # first normalize the two vectors: norm1 = np.linalg.norm(np.array(vec1)) norm2 = np.linalg.norm(np.array(vec2)) print(norm1, norm2) theta = np.arcsin(abs(norm1 / np.sqrt(norm1**2 + norm2**2))) u_wavefun = vec1 / norm1 v_wavefun = vec2 / norm2 wavefun = (np.kron(np.array([1, 0]), np.array(u_wavefun)) + np.kron(np.array([0, 1]), np.array(v_wavefun))) / np.sqrt(2) # print(wavefun) # projectq setup eng = projectq.MainEngine() qureg = eng.allocate_qureg(int(np.log2(len(vec1))) + 1) eng.flush() eng.backend.set_wavefunction(wavefun, qureg) H | qureg[-1] Ry(2 * theta - np.pi / 2) | qureg[-1] eng.flush() prop = eng.backend.get_probability('1', [qureg[-1]]) Measure | qureg print(prop) return np.sqrt(2 * prop * (norm1**2 + norm2**2))
def _decompose_h2rx_M(cmd): """ Decompose the Ry gate.""" # Labelled 'M' for 'minus' because decomposition ends with a Ry(-pi/2) qubit = cmd.qubits[0] Rx(math.pi) | qubit Ph(math.pi / 2) | qubit Ry(-1 * math.pi / 2) | qubit
def _decompose_time_evolution_individual_terms(cmd): """ Implements a TimeEvolution gate with a hamiltonian having only one term. To implement exp(-i * t * hamiltonian), where the hamiltonian is only one term, e.g., hamiltonian = X0 x Y1 X Z2, we first perform local transformations to in order that all Pauli operators in the hamiltonian are Z. We then implement exp(-i * t * (Z1 x Z2 x Z3) and transform the basis back to the original. For more details see, e.g., James D. Whitfield, Jacob Biamonte & Aspuru-Guzik Simulation of electronic structure Hamiltonians using quantum computers, Molecular Physics, 109:5, 735-750 (2011). or Nielsen and Chuang, Quantum Computation and Information. """ assert len(cmd.qubits) == 1 qureg = cmd.qubits[0] eng = cmd.engine time = cmd.gate.time hamiltonian = cmd.gate.hamiltonian assert len(hamiltonian.terms) == 1 term = list(hamiltonian.terms)[0] coefficient = hamiltonian.terms[term] check_indices = set() # Check that hamiltonian is not identity term, # Previous or operator should have apply a global phase instead: assert not term == () # hamiltonian has only a single local operator if len(term) == 1: with Control(eng, cmd.control_qubits): if term[0][1] == 'X': Rx(time * coefficient * 2.) | qureg[term[0][0]] elif term[0][1] == 'Y': Ry(time * coefficient * 2.) | qureg[term[0][0]] else: Rz(time * coefficient * 2.) | qureg[term[0][0]] # hamiltonian has more than one local operator else: with Control(eng, cmd.control_qubits): with Compute(eng): # Apply local basis rotations for index, action in term: check_indices.add(index) if action == 'X': H | qureg[index] elif action == 'Y': Rx(math.pi / 2.) | qureg[index] # Check that qureg had exactly as many qubits as indices: assert check_indices == set((range(len(qureg)))) # Compute parity for i in range(len(qureg) - 1): CNOT | (qureg[i], qureg[i + 1]) Rz(time * coefficient * 2.) | qureg[-1] # Uncompute parity and basis change Uncompute(eng)
def test_store_returns_correct_qasm(self): angle = 0.1 self.__store_function_assert_equal(0, NOT, "\nx q[0]") self.__store_function_assert_equal(1, NOT, "\ncnot q[0], q[1]", count=1) self.__store_function_assert_equal(0, Swap, "\nswap q[0], q[1]") self.__store_function_assert_equal(1, X, "\ntoffoli q[0], q[1], q[1]", count=2) self.__store_function_assert_equal(1, Z, "\ncz q[0], q[1]", count=1) self.__store_function_assert_equal(0, Barrier, "\n# barrier gate q[0], q[1];") self.__store_function_assert_equal( 1, Rz(angle), "\ncr q[0],q[1],{0:.12f}".format(angle), count=1) self.__store_function_assert_equal( 1, R(angle), "\ncr q[0],q[1],{0:.12f}".format(angle), count=1) self.__store_function_assert_equal(1, Rx(angle), "\nrx q[1],{0}".format(angle)) self.__store_function_assert_equal(1, Ry(angle), "\nry q[1],{0}".format(angle)) self.__store_function_assert_equal(1, Rz(angle), "\nrz q[1],{0}".format(angle)) self.__store_function_assert_equal(0, X, "\nx q[0]") self.__store_function_assert_equal(0, Y, "\ny q[0]") self.__store_function_assert_equal(0, Z, "\nz q[0]") self.__store_function_assert_equal(0, H, "\nh q[0]") self.__store_function_assert_equal(0, S, "\ns q[0]") self.__store_function_assert_equal(0, Sdag, "\nsdag q[0]") self.__store_function_assert_equal(0, T, "\nt q[0]") self.__store_function_assert_equal(0, Tdag, "\ntdag q[0]")
def test_simulator_amplitude(sim): eng = MainEngine(sim) 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))) 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_openqasm_test_qasm_single_qubit_gates(): backend = OpenQASMEngine() eng = MainEngine(backend=backend, engine_list=[]) qubit = eng.allocate_qubit() H | qubit S | qubit T | qubit Sdag | qubit Tdag | qubit X | qubit Y | qubit Z | qubit R(0.5) | qubit Rx(0.5) | qubit Ry(0.5) | qubit Rz(0.5) | qubit Ph(0.5) | qubit NOT | qubit Measure | qubit eng.flush() qasm = [l for l in backend.circuit.qasm().split('\n')[2:] if l] assert qasm == [ 'qreg q0[1];', 'creg c0[1];', 'h q0[0];', 's q0[0];', 't q0[0];', 'sdg q0[0];', 'tdg q0[0];', 'x q0[0];', 'y q0[0];', 'z q0[0];', 'u1(0.500000000000000) q0[0];', 'rx(0.500000000000000) q0[0];', 'ry(0.500000000000000) q0[0];', 'rz(0.500000000000000) q0[0];', 'u1(-0.250000000000000) q0[0];', 'x q0[0];', 'measure q0[0] -> c0[0];' ]
def test_simulator_time_evolution(sim): N = 8 # 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") ctrl_qubit = eng.allocate_qubit() H | ctrl_qubit with Control(eng, ctrl_qubit): TimeEvolution(time_to_evolve, op) | qureg eng.flush() qbit_to_bit_map, final_wavefunction = copy.deepcopy(eng.backend.cheat()) All(Measure) | qureg + ctrl_qubit # 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) half = int(len(final_wavefunction) / 2) hadamard_f = 1. / math.sqrt(2.) # check evolution and control assert numpy.allclose(hadamard_f * res, final_wavefunction[half:]) assert numpy.allclose(final_wavefunction[:half], hadamard_f * init_wavefunction)
def XY_full_rotation(wavefunction, qsubset, parameter): """ Apply Rx(t1)Ry(t2) rotation to all the qubits with different angle """ n_qubit = len(qsubset) for i in range(len(qsubset)): Rx(parameter[i]) | wavefunction[qsubset[i]] Ry(parameter[n_qubit + i]) | wavefunction[qsubset[i]]
def cal_loss(self, phi, n): wavefun_shape = np.zeros(2**(n + 1)) wavefun_shape[0] = 1 init_wavefun = wavefun_shape self.eng.backend.set_wavefunction(init_wavefun, self.qureg) Ry(2 * phi) | self.qureg[0] with Control(self.eng, self.qureg[0]): Y | self.qureg[1] Rz(-np.pi / 2) | self.qureg[0] Ry(-2 * phi) | self.qureg[0] self.eng.flush() self.eng.backend.collapse_wavefunction([self.qureg[0]], [0]) result = self.eng.backend.get_probability('0', [self.qureg[1]]) print(result) Measure | self.qureg return np.arccos(np.sqrt(result))
def test_local_optimizer_identity_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.0) | qb0 Ry(0.0) | qb0 Rx(4 * math.pi) | qb0 Ry(4 * math.pi) | qb0 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(0.5)
def inversed_XY_full_rotation(wavefunction, qsubset, parameter): """ The inversed operation of XY_full_rotation() of the same parameter """ n_qubit = len(qsubset) for i in range(len(qsubset)): Ry(-parameter[n_qubit + i]) | wavefunction[qsubset[i]] Rx(-parameter[i]) | wavefunction[qsubset[i]]
def _decompose_h2rx_N(cmd): """ Decompose the Ry gate.""" # Labelled 'N' for 'neutral' because decomposition doesn't end with # Ry(pi/2) or Ry(-pi/2) qubit = cmd.qubits[0] Ry(math.pi / 2) | qubit Ph(3 * math.pi / 2) | qubit Rx(-1 * math.pi) | qubit
def test_ionq_retrieve(monkeypatch, mapper_factory): """Test that initializing a backend with a jobid will fetch that job's results to use as its own""" def mock_retrieve(*args, **kwargs): return { 'nq': 3, 'shots': 10, 'output_probs': { '3': 0.4, '0': 0.6 }, 'meas_mapped': [0, 1], 'meas_qubit_ids': [1, 2], } monkeypatch.setattr(_ionq_http_client, "retrieve", mock_retrieve) backend = _ionq.IonQBackend( retrieve_execution="a3877d18-314f-46c9-86e7-316bc4dbe968", verbose=True, ) eng = MainEngine(backend=backend, engine_list=[mapper_factory()]) unused_qubit = eng.allocate_qubit() qureg = eng.allocate_qureg(2) # entangle the qureg Ry(math.pi / 2) | qureg[0] Rx(math.pi / 2) | qureg[0] Rx(math.pi / 2) | qureg[0] Ry(math.pi / 2) | qureg[0] Rxx(math.pi / 2) | (qureg[0], qureg[1]) Rx(7 * math.pi / 2) | qureg[0] Ry(7 * math.pi / 2) | qureg[0] Rx(7 * math.pi / 2) | qureg[1] del unused_qubit # measure; should be all-0 or all-1 All(Measure) | qureg # run the circuit eng.flush() prob_dict = eng.backend.get_probabilities([qureg[0], qureg[1]]) assert prob_dict['11'] == pytest.approx(0.4) assert prob_dict['00'] == pytest.approx(0.6) # Unknown qubit invalid_qubit = [WeakQubitRef(eng, 10)] probs = eng.backend.get_probabilities(invalid_qubit) assert {'0': 1} == probs
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