def test_ref_program_pass(): ref_prog = Program().inst([X(0), Y(1), Z(2)]) fakeQVM = Mock(spec=qvm_module.SyncConnection()) inst = QAOA(fakeQVM, 2, driver_ref=ref_prog) param_prog = inst.get_parameterized_program() test_prog = param_prog([0, 0]) compare_progs(ref_prog, test_prog)
def _bv_test_helper(vec_a, b, trials=1): qubits = range(len(vec_a)) ancilla = len(vec_a) oracle = oracle_function(vec_a, b, qubits, ancilla) bv_program = bernstein_vazirani(oracle, qubits, ancilla) cxn = api.SyncConnection() results = cxn.run_and_measure(bv_program, qubits, trials) for result in results: bv_a = result[::-1] assert bv_a == list(vec_a)
def test_get_string(): qvm = qvm_module.SyncConnection() qaoa = QAOA(qvm, n_qubits=1) prog = Program() prog.inst(X(0)) qaoa.get_parameterized_program = lambda: lambda angles: prog samples = 10 bitstring, freq = qaoa.get_string(betas=None, gammas=None, samples=samples) assert len(freq) <= samples assert bitstring[0] == 1
def _find_mask_test_helper(mappings, mask=None): n = int(np.log2(len(mappings))) qvm = api.SyncConnection() qubits = range(n) ancillas = range(n, 2 * n) unitary_funct = unitary_function(mappings) oracle = oracle_function(unitary_funct, qubits, ancillas) s, iterations, simon_program = find_mask(qvm, oracle, qubits) two_to_one = check_two_to_one(qvm, oracle, ancillas, s) found_mask = int(s, 2) assert (mappings[0] == mappings[found_mask]) == two_to_one if two_to_one: assert found_mask == mask
def _oracle_test_helper(vec_a, b, x, trials=1): qubits = range(len(vec_a)) ancilla = len(vec_a) cxn = api.SyncConnection() bitstring = np.binary_repr(x, len(qubits)) p = pq.Program() for i in xrange(len(bitstring)): if bitstring[-1 - i] == '1': p.inst(X(i)) oracle = oracle_function(vec_a, b, qubits, ancilla) p += oracle results = cxn.run_and_measure(p, [ancilla], trials) a_dot_x = np.binary_repr(int(''.join(map(str, vec_a)), 2) & x).count("1") expected = (a_dot_x + b) % 2 for result in results: y = result[0] assert y == expected
def test_probabilities(): p = 1 n_qubits = 2 # known set of angles for barbell angles = [1.96348709, 4.71241069] wf = np.array([-1.17642098e-05 - 1j*7.67538040e-06, -7.67563580e-06 - 1j*7.07106781e-01, -7.67563580e-06 - 1j*7.07106781e-01, -1.17642098e-05 - 1j*7.67538040e-06]) fakeQVM = Mock(spec=qvm_module.SyncConnection()) fakeQVM.wavefunction = Mock(return_value=(Wavefunction(wf), 0)) inst = QAOA(fakeQVM, n_qubits, steps=p, rand_seed=42) true_probs = np.zeros_like(wf) for xx in range(wf.shape[0]): true_probs[xx] = np.conj(wf[xx]) * wf[xx] probs = inst.probabilities(angles) assert isinstance(probs, np.ndarray) prob_true = np.zeros((2**inst.n_qubits, 1)) prob_true[1] = 0.5 prob_true[2] = 0.5 assert np.isclose(probs, prob_true).all()
for i in output_qubits: if i > 0: U = np.dot(U, U) cU = controlled(U) name = "CONTROLLED-U{0}".format(2**i) # define the gate p.defgate(name, cU) # apply it p.inst((name, i) + tuple(U_qubits)) # Compute the QFT p = p + qft(output_qubits) # Perform the measurements for i in output_qubits: p.measure(i, reg_offset + i) return p if __name__ == '__main__': import pyquil.api as api qvm = api.SyncConnection() X = np.asarray([[0.0, 1.0], [1.0, 0.0]]) Y = np.asarray([[0.0, -1.0j], [1.0j, 0.0]]) Rx = np.exp(X * np.pi / 8) Ry = np.exp(Y * np.pi / 16) U = np.kron(Rx, Ry) p = phase_estimation(U, 3) print p print qvm.run(p, range(3 + 2), 10) print qvm.wavefunction(p)
def cxn(): c = qvm.SyncConnection() c.post_json = MockPostJson() c.post_json.return_value.text = json.dumps("Success") c.measurement_noise = 1 return c
p.inst(H(start_index)) # measure the results and store them in classical registers [0] and [1] p.measure(start_index, 0) p.measure(ancilla_index, 1) p.if_then(1, X(2)) p.if_then(0, Z(2)) p.measure(end_index, 2) return p if __name__ == '__main__': qvm = forest.SyncConnection() # initialize qubit 0 in |1> teleport_demo = Program(X(0)) teleport_demo += teleport(0, 2, 1) print("Teleporting |1> state: {}".format(qvm.run(teleport_demo, [2]))) # initialize qubit 0 in |0> teleport_demo = Program() teleport_demo += teleport(0, 2, 1) print("Teleporting |0> state: {}".format(qvm.run(teleport_demo, [2]))) # initialize qubit 0 in |+> teleport_demo = Program(H(0)) teleport_demo += teleport(0, 2, 1) print("Teleporting |+> state: {}".format(qvm.run(teleport_demo, [2], 10)))
def vqe_run(self, variational_state_evolve, hamiltonian, initial_params, gate_noise=None, measurement_noise=None, jacobian=None, qvm=None, disp=None, samples=None, return_all=False): """ functional minimization loop. :param variational_state_evolve: function that takes a set of parameters and returns a pyQuil program. :param hamiltonian: (PauliSum) object representing the hamiltonian of which to take the expectation value. :param initial_params: (ndarray) vector of initial parameters for the optimization :param gate_noise: list of Px, Py, Pz probabilities of gate being applied to every gate after each get application :param measurement_noise: list of Px', Py', Pz' probabilities of a X, Y or Z being applied before a measurement. :param jacobian: (optional) method of generating jacobian for parameters (Default=None). :param qvm: (optional, QVM) forest connection object. :param disp: (optional, bool) display level. If True then each iteration expectation and parameters are printed at each optimization iteration. :param samples: (int) Number of samples for calculating the expectation value of the operators. If `None` then faster method ,dotting the wave function with the operator, is used. Default=None. :param return_all: (optional, bool) request to return all intermediate parameters determined during the optimization. :return: (vqe.OptResult()) object :func:`OptResult <vqe.OptResult>`. The following fields are initialized in OptResult: -x: set of w.f. ansatz parameters -fun: scalar value of the objective function -iteration_params: a list of all intermediate parameter vectors. Only returned if 'return_all=True' is set as a vqe_run() option. -expectation_vals: a list of all intermediate expectation values. Only returned if 'return_all=True' is set as a vqe_run() option. """ self._disp_fun = disp if disp is not None else lambda x: None iteration_params = [] expectation_vals = [] self._current_expectation = None if samples is None: print("""WARNING: Fast method for expectation will be used. Noise models will be ineffective""") if qvm is None: qvm = api.SyncConnection(gate_noise=gate_noise, measurement_noise=measurement_noise) else: self.qvm = qvm def objective_function(params): """ closure representing the functional :param params: (ndarray) vector of parameters for generating the the function of the functional. :return: (float) expectation value """ pyquil_prog = variational_state_evolve(params) mean_value = self.expectation(pyquil_prog, hamiltonian, samples, qvm) self._current_expectation = mean_value # store for printing return mean_value def print_current_iter(iter_vars): self._disp_fun("\tParameters: {} ".format(iter_vars)) if jacobian is not None: grad = jacobian(iter_vars) self._disp_fun("\tGrad-L1-Norm: {}".format(np.max( np.abs(grad)))) self._disp_fun("\tGrad-L2-Norm: {} ".format( np.linalg.norm(grad))) self._disp_fun("\tE => {}".format(self._current_expectation)) if return_all: iteration_params.append(iter_vars) expectation_vals.append(self._current_expectation) # using self.minimizer arguments = funcsigs.signature(self.minimizer).parameters.keys() if disp is not None and 'callback' in arguments: self.minimizer_kwargs['callback'] = print_current_iter args = [objective_function, initial_params] args.extend(self.minimizer_args) if 'jac' in arguments: self.minimizer_kwargs['jac'] = jacobian result = self.minimizer(*args, **self.minimizer_kwargs) if hasattr(result, 'status'): if result.status != 0: self._disp_fun( "Classical optimization exited with an error index: %i" % result.status) results = OptResults() if hasattr(result, 'x'): results.x = result.x results.fun = result.fun else: results.x = result if return_all: results.iteration_params = iteration_params results.expectation_vals = expectation_vals return results
prog.measure(q, [q]) return prog def process_result(r): """ Convert a list of measurements to a die value. """ return reduce(lambda s, x: 2 * s + x, r, 0) BATCH_SIZE = 10 dice = {} CXN = forest.SyncConnection() def roll_die(n): """ Roll an n-sided quantum die. """ addresses = list(range(qubits_needed(n))) if not n in dice: dice[n] = die_program(n) die = dice[n] # Generate results and do rejection sampling. while True: results = CXN.run(die, addresses, BATCH_SIZE) for r in results: x = process_result(r)
import numpy as np from grove.pyqaoa.maxcut_qaoa import maxcut_qaoa import pyquil.api as qvm qvm_connection = qvm.SyncConnection() #run QAOA on a square ring w/ 4 nodes at the corners square_ring = [(0, 1), (1, 2), (2, 3), (3, 0)] #defines graph on which to run maxcut steps = 2 inst = maxcut_qaoa(graph=square_ring, steps=steps) betas, gammas = inst.get_angles() #run optimization routine on qvm t = np.hstack((betas, gammas)) param_prog = inst.get_parametrized_program() prog = param_prog(t) wf, _ = qvm_connection.wavefunction(prog) wf = wf.amplitudes #evaluate function w/ QVM, see final state for state_index in range(2**inst.n_qubits): print((inst.states[state_index], np.conj(wf[state_index], *wf[state_index]))) #wf is a numpy array of complex-valued amplitudes for each computational basis state... calculate probability #and visualize distribution
# distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ############################################################################## """ Finding a maximum cut by QAOA. """ import numpy as np import pyquil.api as api from pyquil.paulis import PauliTerm, PauliSum import networkx as nx from scipy.optimize import minimize from grove.pyqaoa.qaoa import QAOA CXN = api.SyncConnection() def print_fun(x): print x def maxcut_qaoa(graph, steps=1, rand_seed=None, connection=None, samples=None, initial_beta=None, initial_gamma=None, minimizer_kwargs=None, vqe_option=None):
""" This module runs basic Quil text files against the Forest QVM API. """ from __future__ import print_function from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter from pyquil.quil import Program import pyquil.api as forest qvm = forest.SyncConnection(endpoint='https://api.rigetti.com/qvm') help_string = "Script takes two arguments. Quil program filename is required as the first " \ "argument and number of classical registers to return is the optional second " \ "argument (defaults to 8)." def parse(): parser = ArgumentParser(__doc__, formatter_class=ArgumentDefaultsHelpFormatter) parser.add_argument('filepath', help='Quil program filename') parser.add_argument('--classical-register-num', '-n', metavar='N', default=8, type=int, help="Number of classical registers to return.") args = parser.parse_args() main(args.filepath, args.classical_register_num) def main(filepath, classical_register_num):