def test_opdm_func_vals(): # coverage: ignore rhf_objective, molecule, parameters, obi, tbi = make_h6_1_3() qubits = [cirq.GridQubit(0, x) for x in range(molecule.n_orbitals)] np.random.seed(43) sampler = cirq.Simulator(dtype=np.complex128) opdm_func = OpdmFunctional(qubits=qubits, sampler=sampler, constant=molecule.nuclear_repulsion, one_body_integrals=obi, two_body_integrals=tbi, num_electrons=molecule.n_electrons // 2) assert isinstance(opdm_func, OpdmFunctional) data = opdm_func.calculate_data(parameters) assert isinstance(data, dict) assert list(data.keys()) == [ 'z', 'xy_even', 'xy_odd', 'qubits', 'qubit_permutations', 'circuits', 'circuits_with_measurement' ] opdm_from_data = compute_opdm(data, return_variance=False) opdm_from_obj, var_dict = opdm_func.calculate_rdm(parameters) assert isinstance(var_dict, dict) assert np.linalg.norm(opdm_from_data - opdm_from_obj) < 1.0E-2 assert np.isclose(opdm_func.energy_from_opdm(opdm_from_data), rhf_objective.energy_from_opdm(opdm_from_data)) rdm_gen = RDMGenerator(opdm_func) rdm_gen.opdm_generator(parameters) assert len(rdm_gen.noisy_opdms) == 1 assert len(rdm_gen.variance_dicts) == 1
def test_energy_from_opdm(): """Build test assuming sampling functions work""" rhf_objective, molecule, parameters, obi, tbi = make_h6_1_3() unitary, energy, _ = rhf_func_generator(rhf_objective) parameters = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]) initial_opdm = np.diag([1] * 3 + [0] * 3) final_opdm = unitary(parameters) @ initial_opdm @ unitary( parameters).conj().T test_energy = energy_from_opdm(final_opdm, constant=molecule.nuclear_repulsion, one_body_tensor=obi, two_body_tensor=tbi) true_energy = energy(parameters) assert np.allclose(test_energy, true_energy)
def test_rhf_func_gen(): rhf_objective, molecule, parameters, _, _ = make_h6_1_3() ansatz, energy, _ = rhf_func_generator(rhf_objective) assert np.isclose(molecule.hf_energy, energy(parameters)) ansatz, energy, _, opdm_func = rhf_func_generator(rhf_objective, initial_occ_vec=[1] * 3 + [0] * 3, get_opdm_func=True) assert np.isclose(molecule.hf_energy, energy(parameters)) test_opdm = opdm_func(parameters) u = ansatz(parameters) initial_opdm = np.diag([1] * 3 + [0] * 3) final_odpm = u @ initial_opdm @ u.T assert np.allclose(test_opdm, final_odpm) result = rhf_minimization(rhf_objective, initial_guess=parameters) assert np.allclose(result.x, parameters)
def test_global_gradient_h4(): """ Test the gradient at the solution given by psi4 """ # first get molecule rhf_objective, molecule, params, _, _ = make_h6_1_3() # molecule = h4_linear_molecule(1.0) nocc = molecule.n_electrons // 2 occ = list(range(nocc)) virt = list(range(nocc, molecule.n_orbitals)) qubits = cirq.LineQubit.range(molecule.n_orbitals) u = sp.linalg.expm( rhf_params_to_matrix(params, len(qubits), occ=occ, virt=virt)) circuit = cirq.Circuit(prepare_slater_determinant(qubits, u[:, :nocc].T)) simulator = cirq.Simulator(dtype=np.complex128) wf = simulator.simulate(circuit).final_state.reshape((-1, 1)) opdm_alpha = get_opdm(wf, molecule.n_orbitals) opdm = np.zeros((molecule.n_qubits, molecule.n_qubits), dtype=np.complex128) opdm[::2, ::2] = opdm_alpha opdm[1::2, 1::2] = opdm_alpha grad = rhf_objective.global_gradient_opdm(params, opdm_alpha) # get finite difference gradient finite_diff_grad = np.zeros(9) epsilon = 0.0001 for i in range(9): params_epsilon = params.copy() params_epsilon[i] += epsilon u = sp.linalg.expm( rhf_params_to_matrix(params_epsilon, len(qubits), occ=occ, virt=virt)) circuit = cirq.Circuit( prepare_slater_determinant(qubits, u[:, :nocc].T)) wf = simulator.simulate(circuit).final_state.reshape((-1, 1)) opdm_pepsilon = get_opdm(wf, molecule.n_orbitals) energy_plus_epsilon = rhf_objective.energy_from_opdm(opdm_pepsilon) params_epsilon[i] -= 2 * epsilon u = sp.linalg.expm( rhf_params_to_matrix(params_epsilon, len(qubits), occ=occ, virt=virt)) circuit = cirq.Circuit( prepare_slater_determinant(qubits, u[:, :nocc].T)) wf = simulator.simulate(circuit).final_state.reshape((-1, 1)) opdm_pepsilon = get_opdm(wf, molecule.n_orbitals) energy_minus_epsilon = rhf_objective.energy_from_opdm(opdm_pepsilon) finite_diff_grad[i] = (energy_plus_epsilon - energy_minus_epsilon) / (2 * epsilon) assert np.allclose(finite_diff_grad, grad, atol=epsilon) # random parameters now params = np.random.randn(9) u = sp.linalg.expm( rhf_params_to_matrix(params, len(qubits), occ=occ, virt=virt)) circuit = cirq.Circuit(prepare_slater_determinant(qubits, u[:, :nocc].T)) simulator = cirq.Simulator(dtype=np.complex128) wf = simulator.simulate(circuit).final_state.reshape((-1, 1)) opdm_alpha = get_opdm(wf, molecule.n_orbitals) opdm = np.zeros((molecule.n_qubits, molecule.n_qubits), dtype=np.complex128) opdm[::2, ::2] = opdm_alpha opdm[1::2, 1::2] = opdm_alpha grad = rhf_objective.global_gradient_opdm(params, opdm_alpha) # get finite difference gradient finite_diff_grad = np.zeros(9) epsilon = 0.0001 for i in range(9): params_epsilon = params.copy() params_epsilon[i] += epsilon u = sp.linalg.expm( rhf_params_to_matrix(params_epsilon, len(qubits), occ=occ, virt=virt)) circuit = cirq.Circuit( prepare_slater_determinant(qubits, u[:, :nocc].T)) wf = simulator.simulate(circuit).final_state.reshape((-1, 1)) opdm_pepsilon = get_opdm(wf, molecule.n_orbitals) energy_plus_epsilon = rhf_objective.energy_from_opdm(opdm_pepsilon) params_epsilon[i] -= 2 * epsilon u = sp.linalg.expm( rhf_params_to_matrix(params_epsilon, len(qubits), occ=occ, virt=virt)) circuit = cirq.Circuit( prepare_slater_determinant(qubits, u[:, :nocc].T)) wf = simulator.simulate(circuit).final_state.reshape((-1, 1)) opdm_pepsilon = get_opdm(wf, molecule.n_orbitals) energy_minus_epsilon = rhf_objective.energy_from_opdm(opdm_pepsilon) finite_diff_grad[i] = (energy_plus_epsilon - energy_minus_epsilon) / (2 * epsilon) assert np.allclose(finite_diff_grad, grad, atol=epsilon)