def test_measure_bitstrings(forest): device = NxDevice(nx.complete_graph(2)) qc_pyqvm = QuantumComputer(name='testy!', qam=PyQVM(n_qubits=2), device=device, compiler=DummyCompiler()) qc_forest = QuantumComputer(name='testy!', qam=QVM(connection=forest, gate_noise=[0.00] * 3), device=device, compiler=DummyCompiler()) prog = Program(I(0), I(1)) meas_qubits = [0, 1] sym_progs, flip_array = _symmetrization(prog, meas_qubits, symm_type=-1) results = _measure_bitstrings(qc_pyqvm, sym_progs, meas_qubits, num_shots=1) # test with pyQVM answer = [ np.array([[0, 0]]), np.array([[0, 1]]), np.array([[1, 0]]), np.array([[1, 1]]) ] assert all([np.allclose(x, y) for x, y in zip(results, answer)]) # test with regular QVM results = _measure_bitstrings(qc_forest, sym_progs, meas_qubits, num_shots=1) assert all([np.allclose(x, y) for x, y in zip(results, answer)])
def test_qpu_run(): config = PyquilConfig() if config.qpu_url and config.qpu_compiler_url: g = nx.Graph() g.add_node(0) device = NxDevice(g) qc = QuantumComputer( name="pyQuil test QC", qam=QPU(endpoint=config.qpu_url, user="******"), device=device, compiler=QPUCompiler( quilc_endpoint=config.quilc_url, qpu_compiler_endpoint=config.qpu_compiler_url, device=device, ), ) bitstrings = qc.run_and_measure(program=Program(X(0)), trials=1000) assert bitstrings[0].shape == (1000, ) assert np.mean(bitstrings[0]) > 0.8 bitstrings = qc.run(qc.compile(Program(X(0)))) assert bitstrings.shape == (0, 0) else: pytest.skip( "QPU or compiler-server not available; skipping QPU run test.")
def test_for_negative_probabilities(): # trivial program to do state tomography on prog = Program(I(0)) # make TomographyExperiment expt_settings = [ExperimentSetting(zeros_state([0]), pt) for pt in [sI(0), sX(0), sY(0), sZ(0)]] experiment_1q = TomographyExperiment(settings=expt_settings, program=prog) # make a quantum computer object device = NxDevice(nx.complete_graph(1)) qc_density = QuantumComputer( name="testy!", qam=PyQVM(n_qubits=1, quantum_simulator_type=ReferenceDensitySimulator), device=device, compiler=DummyCompiler(), ) # initialize with a pure state initial_density = np.array([[1.0, 0.0], [0.0, 0.0]]) qc_density.qam.wf_simulator.density = initial_density try: list(measure_observables(qc=qc_density, tomo_experiment=experiment_1q, n_shots=3000)) except ValueError as e: # the error is from np.random.choice by way of self.rs.choice in ReferenceDensitySimulator assert str(e) != "probabilities are not non-negative" # initialize with a mixed state initial_density = np.array([[0.9, 0.0], [0.0, 0.1]]) qc_density.qam.wf_simulator.density = initial_density try: list(measure_observables(qc=qc_density, tomo_experiment=experiment_1q, n_shots=3000)) except ValueError as e: assert str(e) != "probabilities are not non-negative"
def test_readout_symmetrization(forest): device = NxDevice(nx.complete_graph(3)) noise_model = decoherence_noise_with_asymmetric_ro(gates=gates_in_isa(device.get_isa())) qc = QuantumComputer( name='testy!', qam=QVM(connection=forest, noise_model=noise_model), device=device, compiler=DummyCompiler() ) prog = Program(I(0), X(1), MEASURE(0, 0), MEASURE(1, 1)) prog.wrap_in_numshots_loop(1000) bs1 = qc.run(prog) avg0_us = np.mean(bs1[:, 0]) avg1_us = 1 - np.mean(bs1[:, 1]) diff_us = avg1_us - avg0_us assert diff_us > 0.03 bs2 = qc.run_symmetrized_readout(prog, 1000) avg0_s = np.mean(bs2[:, 0]) avg1_s = 1 - np.mean(bs2[:, 1]) diff_s = avg1_s - avg0_s assert diff_s < 0.05
def compile_rigetti(num_qubits, topology, program): if topology.lower() == 'ring': edge_list = [] for i in range(0, num_qubits): edge_list.append((i, (i + 1) % num_qubits)) topology = nx.from_edgelist(edge_list) device = NxDevice(topology) compiler = LocalQVMCompiler("http://localhost:6000", device) my_qc = QuantumComputer(name='my_qc', qam=QVM(connection=ForestConnection()), device=device, compiler=compiler) executable = compiler.quil_to_native_quil( program) #create QC compatible specification depth = compute_depth_rigetti(executable) volume = len(executable) - 3 #subtract extra directives print(executable) q2_count = two_qubit_count(executable) out_str = str(executable) out_str = out_str + ("#DEPTH: %s |VOL.: %s |2Q GATE COUNT: %s\n" % (depth, volume, q2_count)) print("DEPTH: %s |VOL.: %s |2Q GATE COUNT: %s" % (depth, volume, q2_count)) print() print() return out_str
def test_reset(forest): device = NxDevice(nx.complete_graph(3)) qc = QuantumComputer(name='testy!', qam=QVM(connection=forest), device=device, compiler=DummyCompiler()) p = Program(Declare(name='theta', memory_type='REAL'), Declare(name='ro', memory_type='BIT'), RX(MemoryReference('theta'), 0), MEASURE(0, MemoryReference('ro'))).wrap_in_numshots_loop(1000) qc.run(executable=p, memory_map={'theta': [np.pi]}) aref = ParameterAref(name='theta', index=0) assert qc.qam._variables_shim[aref] == np.pi assert qc.qam._executable == p assert qc.qam._memory_results["ro"].shape == (1000, 1) assert all([bit == 1 for bit in qc.qam._memory_results["ro"]]) assert qc.qam.status == 'done' qc.reset() assert qc.qam._variables_shim == {} assert qc.qam._executable is None assert qc.qam._memory_results["ro"] is None assert qc.qam.status == 'connected'
def test_qc_joint_expectation(forest): device = NxDevice(nx.complete_graph(2)) qc = QuantumComputer( name="testy!", qam=QVM(connection=forest), device=device, compiler=DummyCompiler() ) # |01> state program p = Program() p += RESET() p += X(0) p.wrap_in_numshots_loop(10) # ZZ experiment sz = ExperimentSetting( in_state=sZ(0) * sZ(1), out_operator=sZ(0) * sZ(1), additional_expectations=[[0], [1]] ) e = Experiment(settings=[sz], program=p) results = qc.experiment(e) # ZZ expectation value for state |01> is -1 assert np.isclose(results[0].expectation, -1) assert np.isclose(results[0].std_err, 0) assert results[0].total_counts == 40 # Z0 expectation value for state |01> is -1 assert np.isclose(results[0].additional_results[0].expectation, -1) assert results[0].additional_results[1].total_counts == 40 # Z1 expectation value for state |01> is 1 assert np.isclose(results[0].additional_results[1].expectation, 1) assert results[0].additional_results[1].total_counts == 40
def test_qc(): from pyquil.api import ForestConnection, QuantumComputer from pyquil.api._compiler import _extract_attribute_dictionary_from_program from pyquil.api._qac import AbstractCompiler from pyquil.device import NxDevice from pyquil.gates import I class BasicQVMCompiler(AbstractCompiler): def quil_to_native_quil(self, program: Program): return basic_compile(program) def native_quil_to_executable(self, nq_program: Program): return PyQuilExecutableResponse( program=nq_program.out(), attributes=_extract_attribute_dictionary_from_program(nq_program)) try: qc = QuantumComputer( name='testing-qc', qam=QVM(connection=ForestConnection(), random_seed=52), device=NxDevice(nx.complete_graph(2)), compiler=BasicQVMCompiler(), ) qc.run_and_measure(Program(I(0)), trials=1) return qc except (RequestException, TimeoutError) as e: return pytest.skip("This test requires a running local QVM: {}".format(e))
def test_device_stuff(): topo = nx.from_edgelist([(0, 4), (0, 99)]) qc = QuantumComputer( name='testy!', qam=None, # not necessary for this test device=NxDevice(topo), compiler=DummyCompiler()) assert nx.is_isomorphic(qc.qubit_topology(), topo) isa = qc.get_isa(twoq_type='CPHASE') assert sorted(isa.edges)[0].type == 'CPHASE' assert sorted(isa.edges)[0].targets == [0, 4]
def test_run(forest): device = NxDevice(nx.complete_graph(3)) qc = QuantumComputer(name='testy!', qam=QVM(connection=forest, gate_noise=[0.01] * 3), device=device, compiler=DummyCompiler()) bitstrings = qc.run( Program(H(0), CNOT(0, 1), CNOT(1, 2), MEASURE(0, 0), MEASURE(1, 1), MEASURE(2, 2)).wrap_in_numshots_loop(1000)) assert bitstrings.shape == (1000, 3) parity = np.sum(bitstrings, axis=1) % 3 assert 0 < np.mean(parity) < 0.15
def test_run_pyqvm_noiseless(): device = NxDevice(nx.complete_graph(3)) qc = QuantumComputer(name='testy!', qam=PyQVM(n_qubits=3), device=device, compiler=DummyCompiler()) bitstrings = qc.run( Program(H(0), CNOT(0, 1), CNOT(1, 2), MEASURE(0, 0), MEASURE(1, 1), MEASURE(2, 2)).wrap_in_numshots_loop(1000)) assert bitstrings.shape == (1000, 3) parity = np.sum(bitstrings, axis=1) % 3 assert np.mean(parity) == 0
def test_run_pyqvm_noiseless(): device = NxDevice(nx.complete_graph(3)) qc = QuantumComputer( name="testy!", qam=PyQVM(n_qubits=3), device=device, compiler=DummyCompiler() ) prog = Program(H(0), CNOT(0, 1), CNOT(1, 2)) ro = prog.declare("ro", "BIT", 3) for q in range(3): prog += MEASURE(q, ro[q]) bitstrings = qc.run(prog.wrap_in_numshots_loop(1000)) assert bitstrings.shape == (1000, 3) parity = np.sum(bitstrings, axis=1) % 3 assert np.mean(parity) == 0
def test_run_with_parameters(forest): device = NxDevice(nx.complete_graph(3)) qc = QuantumComputer(name='testy!', qam=QVM(connection=forest), device=device, compiler=DummyCompiler()) bitstrings = qc.run(executable=Program( Declare(name='theta', memory_type='REAL'), Declare(name='ro', memory_type='BIT'), RX(MemoryReference('theta'), 0), MEASURE(0, MemoryReference('ro'))).wrap_in_numshots_loop(1000), memory_map={'theta': [np.pi]}) assert bitstrings.shape == (1000, 1) assert all([bit == 1 for bit in bitstrings])
def test_run_pyqvm_noisy(): device = NxDevice(nx.complete_graph(3)) qc = QuantumComputer( name='testy!', qam=PyQVM(n_qubits=3, post_gate_noise_probabilities={'relaxation': 0.01}), device=device, compiler=DummyCompiler()) bitstrings = qc.run( Program(H(0), CNOT(0, 1), CNOT(1, 2), MEASURE(0, 0), MEASURE(1, 1), MEASURE(2, 2)).wrap_in_numshots_loop(1000)) assert bitstrings.shape == (1000, 3) parity = np.sum(bitstrings, axis=1) % 3 assert 0 < np.mean(parity) < 0.15
def __init__(self, data, label, shuffle=False, qpu=False): weights = np.load(data) n_graphs = len(weights) # read labels from file, or as single label if os.path.exists(label): labels = np.load(label) else: labels = [label for _ in range(n_graphs)] if shuffle: self._shuffled_order = np.random.permutation(n_graphs) weights = weights[self._shuffled_order] labels = labels[self._shuffled_order] self.pset = AllProblems(weights, labels) self.num_qubits = self.pset.num_variables() qubits = list(range(self.num_qubits)) angles = np.linspace(0, 2 * np.pi, NUM_ANGLES, endpoint=False) self.instrs = [ CNOT(q0, q1) for q0, q1 in product(qubits, qubits) if q0 != q1 ] self.instrs += [ op(theta, q) for q, op, theta in product(qubits, [RX, RY, RZ], angles) ] self.action_space = gym.spaces.Discrete(len(self.instrs)) obs_len = NUM_SHOTS * self.num_qubits + len(self.pset.problem(0)) self.observation_space = gym.spaces.Box(np.full(obs_len, -1.0), np.full(obs_len, 1.0), dtype=np.float32) self.reward_threshold = 0.8 self.qpu = qpu if qpu: self._qc = get_qc(QPU_NAME) else: self._qc = QuantumComputer( name="qvm", qam=PyQVM(n_qubits=self.num_qubits), device=NxDevice(nx.complete_graph(self.num_qubits)), compiler=MinimalPyQVMCompiler(), ) self.reset()
def get_test_qc(n_qubits): class BasicQVMCompiler(AbstractCompiler): def quil_to_native_quil(self, program: Program): return basic_compile(program) def native_quil_to_executable(self, nq_program: Program): return PyQuilExecutableResponse( program=nq_program.out(), attributes=_extract_attribute_dictionary_from_program( nq_program)) return QuantumComputer( name='testing-qc', qam=PyQVM(n_qubits=n_qubits, seed=52), device=NxDevice(nx.complete_graph(n_qubits)), compiler=BasicQVMCompiler(), )
def get_ion_qc(num_qubits): """Constructs a quantum computer object that represents the QSCOUT hardware. Unlike the builtin Quil counterparts, it can't run quantum programs, but it can still be used as a compilation target and thus used to generate Jaqal code (which can then be submitted to be run on the actual QSCOUT device). :param int num_qubits: How many qubits in the trap will be used. :returns: The quantum computer object for compilation. :rtype: pyquil.api.QuantumComputer """ device = get_ion_device(num_qubits) return QuantumComputer( name="QSCOUT-%d" % num_qubits, qam=get_ion_qam(), device=device, compiler=IonCompiler(device), )
def test_run_with_parameters(forest): device = NxDevice(nx.complete_graph(3)) qc = QuantumComputer( name="testy!", qam=QVM(connection=forest), device=device, compiler=DummyCompiler() ) bitstrings = qc.run( executable=Program( Declare(name="theta", memory_type="REAL"), Declare(name="ro", memory_type="BIT"), RX(MemoryReference("theta"), 0), MEASURE(0, MemoryReference("ro")), ).wrap_in_numshots_loop(1000), memory_map={"theta": [np.pi]}, ) assert bitstrings.shape == (1000, 1) assert all([bit == 1 for bit in bitstrings])
def test_qc_expectation_larger_lattice(forest): device = NxDevice(nx.complete_graph(4)) qc = QuantumComputer(name='testy!', qam=QVM(connection=forest), device=device, compiler=DummyCompiler()) q0 = 2 q1 = 3 # bell state program p = Program() p += RESET() p += H(q0) p += CNOT(q0, q1) p.wrap_in_numshots_loop(10) # XX, YY, ZZ experiment sx = ExperimentSetting(in_state=sZ(q0) * sZ(q1), out_operator=sX(q0) * sX(q1)) sy = ExperimentSetting(in_state=sZ(q0) * sZ(q1), out_operator=sY(q0) * sY(q1)) sz = ExperimentSetting(in_state=sZ(q0) * sZ(q1), out_operator=sZ(q0) * sZ(q1)) e = TomographyExperiment(settings=[sx, sy, sz], program=p) results = qc.experiment(e) # XX expectation value for bell state |00> + |11> is 1 assert np.isclose(results[0].expectation, 1) assert np.isclose(results[0].std_err, 0) assert results[0].total_counts == 40 # YY expectation value for bell state |00> + |11> is -1 assert np.isclose(results[1].expectation, -1) assert np.isclose(results[1].std_err, 0) assert results[1].total_counts == 40 # ZZ expectation value for bell state |00> + |11> is 1 assert np.isclose(results[2].expectation, 1) assert np.isclose(results[2].std_err, 0) assert results[2].total_counts == 40
def test_qc_expectation_on_qvm_that_requires_executable(forest): # regression test for https://github.com/rigetti/forest-tutorials/issues/2 device = NxDevice(nx.complete_graph(2)) qc = QuantumComputer( name="testy!", qam=QVM(connection=forest, requires_executable=True), device=device, compiler=DummyCompiler(), ) p = Program() theta = p.declare("theta", "REAL") p += RESET() p += RY(theta, 0) p.wrap_in_numshots_loop(10000) sx = ExperimentSetting(in_state=sZ(0), out_operator=sX(0)) e = Experiment(settings=[sx], program=p) thetas = [-np.pi / 2, 0.0, np.pi / 2] results = [] # Verify that multiple calls to qc.experiment with the same experiment backed by a QVM that # requires_exectutable does not raise an exception. for theta in thetas: results.append(qc.experiment(e, memory_map={"theta": [theta]})) assert np.isclose(results[0][0].expectation, -1.0, atol=0.01) assert np.isclose(results[0][0].std_err, 0) assert results[0][0].total_counts == 20000 # bounds on atol and std_err here are a little loose to try and avoid test flakiness. assert np.isclose(results[1][0].expectation, 0.0, atol=0.1) assert results[1][0].std_err < 0.01 assert results[1][0].total_counts == 20000 assert np.isclose(results[2][0].expectation, 1.0, atol=0.01) assert np.isclose(results[2][0].std_err, 0) assert results[2][0].total_counts == 20000
def test_set_initial_state(client_configuration: QCSClientConfiguration): # That is test the assigned state matrix in ReferenceDensitySimulator is persistent between # rounds of run. rho1 = np.array([[0.0, 0.0], [0.0, 1.0]]) # run prog prog = Program(I(0)) ro = prog.declare("ro", "BIT", 1) prog += MEASURE(0, ro[0]) # make a quantum computer object device = NxQuantumProcessor(nx.complete_graph(1)) qc_density = QuantumComputer( name="testy!", qam=PyQVM(n_qubits=1, quantum_simulator_type=ReferenceDensitySimulator), compiler=DummyCompiler(quantum_processor=device, client_configuration=client_configuration), ) qc_density.qam.wf_simulator.set_initial_state(rho1).reset() out = [qc_density.run(prog).readout_data['ro'] for _ in range(0, 4)] ans = [np.array([[1]]), np.array([[1]]), np.array([[1]]), np.array([[1]])] assert all([np.allclose(x, y) for x, y in zip(out, ans)]) # Run and measure style progRAM = prog.copy().wrap_in_numshots_loop(10) results = qc_density.run(qc_density.compile(progRAM)) ans = {0: np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])} assert np.allclose(results.readout_data['ro'][0], ans[0]) # test reverting ReferenceDensitySimulator to the default state rho0 = np.array([[1.0, 0.0], [0.0, 0.0]]) qc_density.qam.wf_simulator.set_initial_state(rho0).reset() assert np.allclose(qc_density.qam.wf_simulator.density, rho0) assert np.allclose(qc_density.qam.wf_simulator.initial_density, rho0)
def test_set_initial_state(): # That is test the assigned state matrix in ReferenceDensitySimulator is persistent between # rounds of run. rho1 = np.array([[0.0, 0.0], [0.0, 1.0]]) # run prog prog = Program(I(0)) ro = prog.declare("ro", "BIT", 1) prog += MEASURE(0, ro[0]) # make a quantum computer object device = NxDevice(nx.complete_graph(1)) qc_density = QuantumComputer( name="testy!", qam=PyQVM(n_qubits=1, quantum_simulator_type=ReferenceDensitySimulator), device=device, compiler=DummyCompiler(), ) qc_density.qam.wf_simulator.set_initial_state(rho1).reset() out = [qc_density.run(prog) for _ in range(0, 4)] ans = [np.array([[1]]), np.array([[1]]), np.array([[1]]), np.array([[1]])] assert all([np.allclose(x, y) for x, y in zip(out, ans)]) # Run and measure style progRAM = Program(I(0)) results = qc_density.run_and_measure(progRAM, trials=10) ans = {0: np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])} assert np.allclose(results[0], ans[0]) # test reverting ReferenceDensitySimulator to the default state rho0 = np.array([[1.0, 0.0], [0.0, 0.0]]) qc_density.qam.wf_simulator.set_initial_state(rho0).reset() assert np.allclose(qc_density.qam.wf_simulator.density, rho0) assert np.allclose(qc_density.qam.wf_simulator.initial_density, rho0)
def vqe_run(self, variational_state_evolve, hamiltonian, initial_params, gate_noise=None, measurement_noise=None, jacobian=None, qc=None, disp=False, samples=None, return_all=False, callback=None, max_meas=np.inf): """ 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 qc: (optional) QuantumComputer object. :param disp: (optional, bool/callable) display level. If True then each iteration expectation and parameters are printed at each optimization iteration. If callable, called after each iteration. The signature: ``disp(xk, state)`` where ``xk`` is the current parameter vector. and ``state`` is the current expectation value. :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. """ """ if (disp is not None and disp is not True and disp is not False): self._disp_fun = disp else: pass """ if samples is not None and max_meas <= samples: raise ValueError('Need more than one fun eval.') self._disp_fun = print iteration_params = [] expectation_vals = [] expectation_vars = [] fun_evals = 0 meas = 0 restarts = 0 callback_idx = [] # Problem: expectation_vals did not (for Nelder-Mead in # scipy.optimize) correspond to objective_function( self._current_expectation = None self._current_variance = None if qc is None: qubits = hamiltonian.get_qubits() qc = QuantumComputer(name=f"{len(qubits)}q-noisy-qvm", qam=QVM(gate_noise=gate_noise, measurement_noise=measurement_noise)) else: self.qc = qc coeffs = np.array([term.coefficient for term in hamiltonian.terms]) sample_list = calc_samples(samples, coeffs) 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, tmp_vars = self.expectation(pyquil_prog, hamiltonian, sample_list, qc) self._current_variance = tmp_vars self._current_expectation = mean_value # store for printing # Save params, exp_val and exp_var iteration_params.append(params) expectation_vals.append(mean_value) expectation_vars.append(tmp_vars) nonlocal fun_evals, meas fun_evals += 1 if samples is not None: meas += samples if meas >= max_meas: raise RestartError # attempt restart and break while below return mean_value def print_current_iter(iter_vars): self._disp_fun('\nFunction evaluations: {}'.format(fun_evals)) self._disp_fun("Parameters: {} ".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("E => {}".format(self._current_expectation)) # using self.minimizer arguments = funcsigs.signature(self.minimizer).parameters.keys() if callback is None: def callback(*args, **kwargs): pass def wrap_callbacks(iter_vars, *args, **kwargs): # save values callback_idx.append(fun_evals-1) # display if disp is True: print_current_iter(iter_vars) # call VQE's callback callback(iteration_params, expectation_vals, expectation_vars) if 'callback' in arguments: self.minimizer_kwargs['callback'] = wrap_callbacks args = [objective_function, initial_params] args.extend(self.minimizer_args) if 'jac' in arguments: self.minimizer_kwargs['jac'] = jacobian results = OptResults() result = None while meas < max_meas: break_ = True try: result = self.minimizer(*args, **self.minimizer_kwargs) except BreakError: results.status = -1 results.message = 'Stopped by BreakError.' except RestartError as e: restarts += 1 break_ = False args[1] = iteration_params[int(np.argmin(expectation_vals))] if e.samples is not None: samples = e.samples sample_list = calc_samples(samples, coeffs) else: results.status = 0 results.message = 'Minimizer stopped naturally.' if hasattr(result, 'status'): if result.status != 0: self._disp_fun( "Classical optimization exited with an error index: %i" % result.status) if hasattr(result, 'x'): results.x = result.x results.fun = result.fun else: results.x = result results.fun = expectation_vals[-1] if break_: break else: results.status = 1 results.message = 'Exceeded maximum number of measurements.' if disp: print(f"Exceeded maximum of {max_meas} measurements" f"and terminated.") # Save results in case of Break- or RestartError if not hasattr(results, 'x'): idx = int(np.argmin(expectation_vals)) results.x = iteration_params[idx] results.fun = expectation_vals[idx] if return_all: # Convert to ndarray for better indexing options (se bellow) iteration_params = np.array(iteration_params) expectation_vals = np.array(expectation_vals) expectation_vars = np.array(expectation_vars) # From each time callback is called results.iteration_params = iteration_params[callback_idx] results.expectation_vals = expectation_vals[callback_idx] results.expectation_vars = expectation_vars[callback_idx] # From every function evaluation results.iteration_params_all = iteration_params results.expectation_vals_all = expectation_vals results.expectation_vars_all = expectation_vars results.fun_evals = fun_evals results.meas = meas results.restarts = restarts # Return last model from bayes if hasattr(result, 'models') and hasattr(result, 'space'): results.bayes_special = [result.models[-1], result.space] # x_gp = results.x # if isinstance(x_gp, np.ndarray): # x_gp = [x_gp.tolist()] # x_gp = result.space.transform(x_gp) # try: # Ugly code (seems like we get an index error here) # gp = result.models[-1] # except: # print('Failed on gp = result.models[-1] in vqe_override') # fun, var = gp.predict(x_gp, return_std=True) # results.var = var return results
topology = nx.from_edgelist([ (10, 2), (10, 4), (10, 6), (10, 8), ]) device = NxDevice(topology) class MyLazyCompiler(AbstractCompiler): def quil_to_native_quil(self, program, *, protoquil=None): return program def native_quil_to_executable(self, nq_program): return nq_program my_qc = QuantumComputer( name='my-qvm', qam=QVM(connection=ForestConnection()), device=device, compiler=MyLazyCompiler(), ) nx.draw(my_qc.qubit_topology()) plt.title('5qcm', fontsize=18) plt.show() my_qc.run_and_measure(Program(X(10)), trials=5)
def quantum_computer(qam: QAM, compiler: AbstractCompiler) -> QuantumComputer: return QuantumComputer( name='mocked', qam=qam, compiler=compiler, )
def vqe_run(self, variational_state_evolve, hamiltonian, initial_params, gate_noise=None, measurement_noise=None, jacobian=None, qc=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 qc: (optional) QuantumComputer 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 qc is None: qubits = hamiltonian.get_qubits() qc = QuantumComputer(name=f"{len(qubits)}q-noisy-qvm", qam=QVM(gate_noise=gate_noise, measurement_noise=measurement_noise)) else: self.qc = qc 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, qc) 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