예제 #1
0
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
예제 #2
0
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)
예제 #3
0
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)
예제 #4
0
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)