def test_ring_of_disagrees(): """ Tests the known analytic solution to p=1 QAOA of the Ring of Disagrees See https://arxiv.org/pdf/1805.03265.pdf (section 5.4.5) """ n_qubits = 8 hamiltonian = ring_of_disagrees(n_qubits) p = 1 # Known optimal angles betas = [np.pi/8] gammas = [np.pi/4] params = (betas,gammas) params_std = StandardParams([hamiltonian, p], params) cost_fn = QAOACostFunctionOnWFSim(hamiltonian, params=params_std) exp_val = cost_fn(params_std.raw()) assert np.isclose(exp_val, -6)
def test_StandardParams(): params = StandardParams.linear_ramp_from_hamiltonian(hamiltonian, 2, time=2) assert set(params.reg) == {0, 1, q1} assert np.allclose(params.x_rotation_angles, [[0.75] * 3, [0.25] * 3]) assert np.allclose(params.z_rotation_angles, [[0.125], [0.375]]) assert np.allclose(params.zz_rotation_angles, [[0.25, -0.5], [0.75, -1.5]]) assert [params.qubits_singles ] == [term.get_qubits() for term in hamiltonian if len(term) == 1] # Test updating and raw output raw = np.random.rand(len(params)) params.update_from_raw(raw) assert np.allclose(raw, params.raw())
def test_non_fourier_params_are_consistent(): """ Check that StandardParams, StandardWithBiasParams and ExtendedParams give the same rotation angles, given the same data""" p1 = StandardParams.linear_ramp_from_hamiltonian(hamiltonian, 2, time=2) p2 = ExtendedParams.linear_ramp_from_hamiltonian(hamiltonian, 2, time=2) p3 = StandardWithBiasParams.linear_ramp_from_hamiltonian(hamiltonian, 2, time=2) assert np.allclose(p1.x_rotation_angles, p2.x_rotation_angles) assert np.allclose(p2.x_rotation_angles, p3.x_rotation_angles) assert np.allclose(p1.z_rotation_angles, p2.z_rotation_angles) assert np.allclose(p2.z_rotation_angles, p3.z_rotation_angles) assert np.allclose(p1.zz_rotation_angles, p2.zz_rotation_angles) assert np.allclose(p2.zz_rotation_angles, p3.zz_rotation_angles)
def test_StandardParams_plot(): ham_no_bias = PauliTerm("Z", 0) ham_no_bias *= PauliTerm("Z", 1) next_term = PauliTerm("Z", 0, -2.0) next_term *= PauliTerm("Z", 2) ham_no_bias += next_term p = 5 params = StandardParams.linear_ramp_from_hamiltonian(hamiltonian, p) fig, ax = plt.subplots() params.plot(ax=ax) # plt.show() p = 8 params = StandardParams((hamiltonian, p), ([0.1] * p, [0.2] * p)) fig, ax = plt.subplots() params.plot(ax=ax) # plt.show() p = 2 params = StandardParams((ham_no_bias, p), ([5] * p, [10] * p)) fig, ax = plt.subplots() params.plot(ax=ax)
def test_parameter_empty(): p = ExtendedParams.empty((hamiltonian, 4)) assert isinstance(p, ExtendedParams) assert p.betas.shape == (4, 3) assert p.gammas_singles.shape == (4, 1) assert p.gammas_pairs.shape == (4, 2) p = StandardParams.empty((hamiltonian, 4)) assert isinstance(p, StandardParams) assert p.betas.shape == (4, ) assert p.gammas.shape == (4, ) p = StandardWithBiasParams.empty((hamiltonian, 4)) assert isinstance(p, StandardWithBiasParams) assert p.betas.shape == (4, ) assert p.gammas_singles.shape == (4, ) assert p.gammas_pairs.shape == (4, ) p = AnnealingParams.empty((hamiltonian, 4, 2.0)) assert isinstance(p, AnnealingParams) assert p.schedule.shape == (4, ) p = FourierParams.empty((hamiltonian, 4, 2)) assert isinstance(p, FourierParams) assert p.u.shape == (2, ) assert p.v.shape == (2, ) p = FourierWithBiasParams.empty((hamiltonian, 4, 2)) assert isinstance(p, FourierWithBiasParams) assert p.u_singles.shape == (2, ) assert p.u_pairs.shape == (2, ) assert p.v.shape == (2, ) p = FourierExtendedParams.empty((hamiltonian, 4, 2)) assert isinstance(p, FourierExtendedParams) assert p.u_singles.shape == (2, 1) assert p.u_pairs.shape == (2, 2) assert p.v.shape == (2, 3)
def test_standard_to_standard_with_bias(): params = StandardParams.empty((hamiltonian, 4)) params2 = standard_to_standard_w_bias(params) assert np.allclose(params.x_rotation_angles, params2.x_rotation_angles) assert np.allclose(params.z_rotation_angles, params2.z_rotation_angles) assert np.allclose(params.zz_rotation_angles, params2.zz_rotation_angles)
# parameters method = "Nelder-Mead" # BFGS did not work very well when run as qvm p_max = 5 # depends on speed [could be lower if time does not allow 5] nshots = 100 # depends on speed [possibly needs some tweaking] output = pd.DataFrame() for p in range(1, p_max + 1): print('p=', p, '/', p_max) if p > 1: betas = next_angles(betas) gammas = next_angles(gammas) parameters = (betas, gammas) params = StandardParams([H, p], parameters) # NOTE - the optimiser will reach its maximum number of iterations, but for the parameters being used here, # the choice maxiter=200 seems to be more than sufficient to get to the optimum with high probability. cost_function = QAOACostFunctionOnQVM(-1 * H, params, qc, nshots=nshots) # minimizing with VQE res = minimize(cost_function, params.raw(), tol=1e-3, method=method, options={ "disp": True, "maxiter": 200 })