Exemplo n.º 1
0
    def setUp(self):
        geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))]
        basis = 'sto-3g'
        multiplicity = 1
        filename = os.path.join(DATA_DIRECTORY, 'H2_sto-3g_singlet_0.7414')
        self.molecule = MolecularData(geometry,
                                      basis,
                                      multiplicity,
                                      filename=filename)
        self.molecule.load()

        # Get molecular Hamiltonian.
        self.molecular_hamiltonian = self.molecule.get_molecular_hamiltonian()

        # Get FCI RDM.
        self.fci_rdm = self.molecule.get_molecular_rdm(use_fci=1)
        # Get explicit coefficients.
        self.nuclear_repulsion = self.molecular_hamiltonian.constant
        self.one_body = self.molecular_hamiltonian.one_body_tensor
        self.two_body = self.molecular_hamiltonian.two_body_tensor

        # Get fermion Hamiltonian.
        self.fermion_hamiltonian = normal_ordered(
            get_fermion_operator(self.molecular_hamiltonian))

        # Get qubit Hamiltonian.
        self.qubit_hamiltonian = jordan_wigner(self.fermion_hamiltonian)

        # Get the sparse matrix.
        self.hamiltonian_matrix = get_sparse_operator(
            self.molecular_hamiltonian)
def lih_hamiltonian():
    """
    Generate test Hamiltonian from LiH.

    Args:
        None

    Return:

        hamiltonian: FermionicOperator

        spectrum: List of energies.
    """
    geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))]
    active_space_start = 1
    active_space_stop = 3
    molecule = MolecularData(geometry, 'sto-3g', 1, description="1.45")
    molecule.load()

    molecular_hamiltonian = molecule.get_molecular_hamiltonian(
        occupied_indices=range(active_space_start),
        active_indices=range(active_space_start, active_space_stop))

    hamiltonian = get_fermion_operator(molecular_hamiltonian)
    spectrum = eigenspectrum(hamiltonian)

    return hamiltonian, spectrum
def test_mrd_return_type():
    filename = os.path.join(DATA_DIRECTORY, "H2_sto-3g_singlet_0.7414.hdf5")
    molecule = MolecularData(filename=filename)
    reduced_ham = make_reduced_hamiltonian(molecule.get_molecular_hamiltonian(),
                                           molecule.n_electrons)

    assert isinstance(reduced_ham, InteractionOperator)
Exemplo n.º 4
0
    def test_consistency(self):
        """Test consistency with JW for FermionOperators."""
        # Random interaction operator
        n_qubits = 5
        iop = random_interaction_operator(n_qubits, real=False)
        op1 = jordan_wigner(iop)
        op2 = jordan_wigner(get_fermion_operator(iop))

        self.assertEqual(op1, op2)

        # Interaction operator from molecule
        geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))]
        basis = 'sto-3g'
        multiplicity = 1

        filename = os.path.join(DATA_DIRECTORY, 'H1-Li1_sto-3g_singlet_1.45')
        molecule = MolecularData(geometry,
                                 basis,
                                 multiplicity,
                                 filename=filename)
        molecule.load()

        iop = molecule.get_molecular_hamiltonian()
        op1 = jordan_wigner(iop)
        op2 = jordan_wigner(get_fermion_operator(iop))

        self.assertEqual(op1, op2)
Exemplo n.º 5
0
def test_erpa_eom_ham_lih():
    filename = os.path.join(DATA_DIRECTORY, "H1-Li1_sto-3g_singlet_1.45.hdf5")
    molecule = MolecularData(filename=filename)
    reduced_ham = make_reduced_hamiltonian(
        molecule.get_molecular_hamiltonian(), molecule.n_electrons)
    rha_fermion = get_fermion_operator(reduced_ham)
    permuted_hijkl = np.einsum('ijlk', reduced_ham.two_body_tensor)
    opdm = np.diag([1] * molecule.n_electrons + [0] *
                   (molecule.n_qubits - molecule.n_electrons))
    tpdm = 2 * wedge(opdm, opdm, (1, 1), (1, 1))
    rdms = InteractionRDM(opdm, tpdm)
    dim = 3  # so we don't do the full basis.  This would make the test long
    full_basis = {}  # erpa basis.  A, B basis in RPA language
    cnt = 0
    # start from 1 to make test shorter
    for p, q in product(range(1, dim), repeat=2):
        if p < q:
            full_basis[(p, q)] = cnt
            full_basis[(q, p)] = cnt + dim * (dim - 1) // 2
            cnt += 1
    for rkey in full_basis.keys():
        p, q = rkey
        for ckey in full_basis.keys():
            r, s = ckey
            for sigma, tau in product([0, 1], repeat=2):
                test = erpa_eom_hamiltonian(permuted_hijkl, tpdm,
                                            2 * q + sigma, 2 * p + sigma,
                                            2 * r + tau, 2 * s + tau).real
                qp_op = FermionOperator(
                    ((2 * q + sigma, 1), (2 * p + sigma, 0)))
                rs_op = FermionOperator(((2 * r + tau, 1), (2 * s + tau, 0)))
                erpa_op = normal_ordered(
                    commutator(qp_op, commutator(rha_fermion, rs_op)))
                true = rdms.expectation(get_interaction_operator(erpa_op))
                assert np.isclose(true, test)
Exemplo n.º 6
0
def get_molecular_data(interaction_operator,
                       geometry=None,
                       basis=None,
                       multiplicity=None,
                       n_electrons=None,
                       reduce_spin=True,
                       data_directory=None):
    """Output a MolecularData object generated from an InteractionOperator

    Args:
        interaction_operator(InteractionOperator): two-body interaction
            operator defining the "molecular interaction" to be simulated.
        geometry(string or list of atoms):
        basis(string):  String denoting the basis set used to discretize the
            system.
        multiplicity(int): Spin multiplicity desired in the system.
        n_electrons(int): Number of electrons in the system
        reduce_spin(bool): True if one wishes to perform spin reduction on
            integrals that are given in interaction operator.  Assumes
            spatial (x) spin structure generically.

    Returns:
        molecule(MolecularData):
            Instance that captures the
            interaction_operator converted into the format that would come
            from an electronic structure package adorned with some meta-data
            that may be useful.
    """

    n_spin_orbitals = interaction_operator.n_qubits

    # Introduce bare molecular operator to fill
    molecule = MolecularData(geometry=geometry,
                             basis=basis,
                             multiplicity=multiplicity,
                             data_directory=data_directory)

    molecule.nuclear_repulsion = interaction_operator.constant

    # Remove spin from integrals and put into molecular operator
    if reduce_spin:
        reduction_indices = list(range(0, n_spin_orbitals, 2))
    else:
        reduction_indices = list(range(n_spin_orbitals))

    molecule.n_orbitals = len(reduction_indices)

    molecule.one_body_integrals = interaction_operator.one_body_tensor[
        numpy.ix_(reduction_indices, reduction_indices)]
    molecule.two_body_integrals = interaction_operator.two_body_tensor[
        numpy.ix_(reduction_indices, reduction_indices, reduction_indices,
                  reduction_indices)]

    # Fill in other metadata
    molecule.overlap_integrals = numpy.eye(molecule.n_orbitals)
    molecule.n_qubits = n_spin_orbitals
    molecule.n_electrons = n_electrons
    molecule.multiplicity = multiplicity

    return molecule
def test_constant_one_body():
    filename = os.path.join(DATA_DIRECTORY, "H2_sto-3g_singlet_0.7414.hdf5")
    molecule = MolecularData(filename=filename)
    reduced_ham = make_reduced_hamiltonian(molecule.get_molecular_hamiltonian(),
                                           molecule.n_electrons)

    assert numpy.isclose(reduced_ham.constant, molecule.nuclear_repulsion)
    assert numpy.allclose(reduced_ham.one_body_tensor, 0)
Exemplo n.º 8
0
    def test_one_body_square_decomposition(self):

        # Initialize H2 InteractionOperator.
        n_qubits = 4
        filename = os.path.join(THIS_DIRECTORY, 'data',
                                'H2_sto-3g_singlet_0.7414')
        molecule = MolecularData(filename=filename)
        molecule_interaction = molecule.get_molecular_hamiltonian()
        get_fermion_operator(molecule_interaction)

        two_body_coefficients = molecule_interaction.two_body_tensor

        # Decompose.
        eigenvalues, one_body_squares, _, _ = (low_rank_two_body_decomposition(
            two_body_coefficients, truncation_threshold=0))
        rank = eigenvalues.size
        for l in range(rank):
            one_body_operator = FermionOperator()
            for p, q in itertools.product(range(n_qubits), repeat=2):
                term = ((p, 1), (q, 0))
                coefficient = one_body_squares[l, p, q]
                one_body_operator += FermionOperator(term, coefficient)
            one_body_squared = one_body_operator**2

            # Get the squared one-body operator via one-body decomposition.
            if abs(eigenvalues[l]) < 1e-6:
                with self.assertRaises(ValueError):
                    prepare_one_body_squared_evolution(one_body_squares[l])
                continue
            else:
                density_density_matrix, basis_transformation_matrix = (
                    prepare_one_body_squared_evolution(one_body_squares[l]))
            two_body_operator = FermionOperator()
            for p, q in itertools.product(range(n_qubits), repeat=2):
                term = ((p, 1), (p, 0), (q, 1), (q, 0))
                coefficient = density_density_matrix[p, q]
                two_body_operator += FermionOperator(term, coefficient)

            # Confirm that the rotations diagonalize the one-body squares.
            hopefully_diagonal = basis_transformation_matrix.dot(
                numpy.dot(
                    one_body_squares[l],
                    numpy.transpose(
                        numpy.conjugate(basis_transformation_matrix))))
            diagonal = numpy.diag(hopefully_diagonal)
            difference = hopefully_diagonal - numpy.diag(diagonal)
            self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference)))
            density_density_alternative = numpy.outer(diagonal, diagonal)
            difference = density_density_alternative - density_density_matrix
            self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference)))

            # Test spectra.
            one_body_squared_spectrum = eigenspectrum(one_body_squared)
            two_body_spectrum = eigenspectrum(two_body_operator)
            difference = two_body_spectrum - one_body_squared_spectrum
            self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference)))
Exemplo n.º 9
0
    def test_molecular_operator_consistency(self):

        # Initialize H2 InteractionOperator.
        n_qubits = 4
        filename = os.path.join(THIS_DIRECTORY, 'data',
                                'H2_sto-3g_singlet_0.7414')
        molecule = MolecularData(filename=filename)
        molecule_interaction = molecule.get_molecular_hamiltonian()
        molecule_operator = get_fermion_operator(molecule_interaction)

        constant = molecule_interaction.constant
        one_body_coefficients = molecule_interaction.one_body_tensor
        two_body_coefficients = molecule_interaction.two_body_tensor

        # Perform decomposition.
        eigenvalues, one_body_squares, one_body_corrections, trunc_error = (
            low_rank_two_body_decomposition(two_body_coefficients))
        self.assertAlmostEqual(trunc_error, 0.)

        # Build back operator constant and one-body components.
        decomposed_operator = FermionOperator((), constant)
        for p, q in itertools.product(range(n_qubits), repeat=2):
            term = ((p, 1), (q, 0))
            coefficient = (one_body_coefficients[p, q] +
                           one_body_corrections[p, q])
            decomposed_operator += FermionOperator(term, coefficient)

        # Build back two-body component.
        for l in range(one_body_squares.shape[0]):
            one_body_operator = FermionOperator()
            for p, q in itertools.product(range(n_qubits), repeat=2):
                term = ((p, 1), (q, 0))
                coefficient = one_body_squares[l, p, q]
                if abs(eigenvalues[l]) > 1e-6:
                    self.assertTrue(is_hermitian(one_body_squares[l]))
                one_body_operator += FermionOperator(term, coefficient)
            decomposed_operator += eigenvalues[l] * (one_body_operator**2)

        # Test for consistency.
        difference = normal_ordered(decomposed_operator - molecule_operator)
        self.assertAlmostEqual(0., difference.induced_norm())

        # Decompose with slightly negative operator that must use eigen
        molecule = MolecularData(filename=filename)
        molecule.two_body_integrals[0, 0, 0, 0] -= 1

        eigenvalues, one_body_squares, one_body_corrections, trunc_error = (
            low_rank_two_body_decomposition(two_body_coefficients))
        self.assertAlmostEqual(trunc_error, 0.)

        # Check for property errors
        with self.assertRaises(TypeError):
            eigenvalues, one_body_squares, _, trunc_error = (
                low_rank_two_body_decomposition(two_body_coefficients + 0.01j,
                                                truncation_threshold=1.,
                                                final_rank=1))
 def __init__(self,
              geometry=None,
              basis=None,
              multiplicity=None,
              charge=0,
              description="",
              filename="",
              data_directory=None):
     MolecularData.__init__(self, geometry, basis, multiplicity, charge,
                            description, filename, data_directory)
     self._pyscf_data = {}
Exemplo n.º 11
0
def lih_hamiltonian():
    geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))]
    active_space_start = 1
    active_space_stop = 3
    molecule = MolecularData(geometry, 'sto-3g', 1, description="1.45")
    molecule.load()
    molecular_hamiltonian = molecule.get_molecular_hamiltonian(
        occupied_indices=range(active_space_start),
        active_indices=range(active_space_start, active_space_stop))
    hamiltonian = get_fermion_operator(molecular_hamiltonian)
    ground_state_energy = eigenspectrum(hamiltonian)[0]
    return hamiltonian, ground_state_energy
Exemplo n.º 12
0
 def setUp(self):
     geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))]
     basis = 'sto-3g'
     multiplicity = 1
     filename = os.path.join(DATA_DIRECTORY, 'H2_sto-3g_singlet_0.7414')
     self.molecule = MolecularData(geometry,
                                   basis,
                                   multiplicity,
                                   filename=filename)
     self.molecule.load()
     self.cisd_energy = self.molecule.cisd_energy
     self.rdm = self.molecule.get_molecular_rdm()
     self.hamiltonian = self.molecule.get_molecular_hamiltonian()
Exemplo n.º 13
0
def LiH_sto3g():
    """ Generates the Hamiltonian for LiH in
        the STO-3G basis, at a distance of
        1.45 A.
    """
    geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))]
    molecule = MolecularData(geometry, 'sto-3g', 1, description="1.45")
    molecule.load()
    molecular_hamiltonian = molecule.get_molecular_hamiltonian()
    hamiltonian = get_fermion_operator(molecular_hamiltonian)
    num_electrons = molecule.n_electrons
    num_orbitals = 2 * molecule.n_orbitals

    return hamiltonian, num_orbitals, num_electrons
Exemplo n.º 14
0
def test_h2_rpa():
    filename = os.path.join(DATA_DIRECTORY, "H2_sto-3g_singlet_0.7414.hdf5")
    molecule = MolecularData(filename=filename)
    reduced_ham = make_reduced_hamiltonian(
        molecule.get_molecular_hamiltonian(), molecule.n_electrons)
    hf_opdm = np.diag([1] * molecule.n_electrons + [0] *
                      (molecule.n_qubits - molecule.n_electrons))
    hf_tpdm = 2 * wedge(hf_opdm, hf_opdm, (1, 1), (1, 1))

    pos_spectrum, xy_eigvects, basis = singlet_erpa(
        hf_tpdm, reduced_ham.two_body_tensor)
    assert np.isclose(pos_spectrum, 0.92926444)  # pyscf-rpa value
    assert isinstance(xy_eigvects, np.ndarray)
    assert isinstance(basis, dict)
Exemplo n.º 15
0
def test_rhf_min():
    filename = os.path.join(DATA_DIRECTORY, "H2_sto-3g_singlet_0.7414.hdf5")
    molecule = MolecularData(filename=filename)

    overlap = molecule.overlap_integrals
    mo_obi = molecule.one_body_integrals
    mo_tbi = molecule.two_body_integrals
    rotation_mat = molecule.canonical_orbitals.T.dot(overlap)
    obi = general_basis_change(mo_obi, rotation_mat, (1, 0))
    tbi = general_basis_change(mo_tbi, rotation_mat, (1, 1, 0, 0))
    hff = HartreeFockFunctional(one_body_integrals=obi,
                                two_body_integrals=tbi,
                                overlap=overlap,
                                n_electrons=molecule.n_electrons,
                                model='rhf',
                                nuclear_repulsion=molecule.nuclear_repulsion)
    result = rhf_minimization(hff)
    assert isinstance(result, OptimizeResult)

    result2 = rhf_minimization(hff,
                               initial_guess=np.array([0]),
                               sp_options={
                                   'maxiter': 100,
                                   'disp': False
                               })
    assert isinstance(result2, OptimizeResult)
    assert np.isclose(result2.fun, result.fun)
Exemplo n.º 16
0
    def __init__(self,
                 name,
                 geometry,
                 multiplicity,
                 charge,
                 n_orbitals,
                 n_electrons,
                 basis='sto-3g',
                 frozen_els=None):
        self.name = name
        self.multiplicity = multiplicity
        self.charge = charge
        self.basis = basis
        self.geometry = geometry

        self.molecule_data = MolecularData(geometry=self.geometry,
                                           basis=basis,
                                           multiplicity=self.multiplicity,
                                           charge=self.charge)

        self.molecule_psi4 = run_psi4(
            self.molecule_data, run_fci=True)  # old version of openfermion

        # Hamiltonian transforms
        self.molecule_ham = self.molecule_psi4.get_molecular_hamiltonian()
        self.hf_energy = self.molecule_psi4.hf_energy.item(
        )  # old version of openfermion
        self.fci_energy = self.molecule_psi4.fci_energy.item(
        )  # old version of openfermion

        # TODO: the code below corresponds to the most recent version in the opefermion documentation.
        #  However it has problems with ray???
        # calculate_molecule_psi4 = run_pyscf(self.molecule_data, run_scf=True, run_cisd=True, run_fci=True)
        # self.molecule_ham = calculate_molecule_psi4.get_molecular_hamiltonian()
        # self.hf_energy = calculate_molecule_psi4.hf_energy
        # self.fci_energy = float(calculate_molecule_psi4.fci_energy)
        # del calculate_molecule_psi4

        self.energy_eigenvalues = None  # use this only if calculating excited states

        if frozen_els is None:
            self.n_electrons = n_electrons
            self.n_orbitals = n_orbitals
            self.n_qubits = n_orbitals
            self.fermion_ham = get_fermion_operator(self.molecule_ham)
        else:
            self.n_electrons = n_electrons - len(frozen_els['occupied'])
            self.n_orbitals = n_orbitals - len(frozen_els['occupied']) - len(
                frozen_els['unoccupied'])
            self.n_qubits = self.n_orbitals
            self.fermion_ham = freeze_orbitals(
                get_fermion_operator(self.molecule_ham),
                occupied=frozen_els['occupied'],
                unoccupied=frozen_els['unoccupied'],
                prune=True)
        self.jw_qubit_ham = jordan_wigner(self.fermion_ham)

        # this is used only for calculating excited states. list of [term_index, term_state]
        self.H_lower_state_terms = None
def test_d2_to_g2():
    # this should test for correctness
    filename = os.path.join(DATA_DIRECTORY, "H1-Li1_sto-3g_singlet_1.45.hdf5")
    molecule = MolecularData(filename=filename)
    molecule.load()
    opdm = molecule.fci_one_rdm
    tpdm = molecule.fci_two_rdm
    phdm = map_two_pdm_to_particle_hole_dm(tpdm, opdm)

    db = tpdm_to_phdm_mapping(molecule.n_qubits)
    topdm = Tensor(tensor=opdm, name='ck')
    ttpdm = Tensor(tensor=np.einsum('ijlk', tpdm), name='cckk')
    tphdm = Tensor(tensor=np.einsum('ijlk', phdm), name='ckck')
    mt = MultiTensor(tensors=[topdm, ttpdm, tphdm], dual_basis=db)
    A, _, b = mt.synthesize_dual_basis()
    vec_rdms = mt.vectorize_tensors()
    assert np.isclose(np.linalg.norm(A.dot(vec_rdms) - b), 0)
Exemplo n.º 18
0
    def setUp(self):
        # Set up molecule.
        geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))]
        basis = 'sto-3g'
        multiplicity = 1
        filename = os.path.join(THIS_DIRECTORY, 'data',
                                'H1-Li1_sto-3g_singlet_1.45')
        self.molecule = MolecularData(geometry,
                                      basis,
                                      multiplicity,
                                      filename=filename)
        self.molecule.load()

        # Get molecular Hamiltonian
        self.molecular_hamiltonian = self.molecule.get_molecular_hamiltonian()
        self.molecular_hamiltonian_no_core = (
            self.molecule.get_molecular_hamiltonian(
                occupied_indices=[0],
                active_indices=range(1, self.molecule.n_orbitals)))

        # Get FCI RDM.
        self.fci_rdm = self.molecule.get_molecular_rdm(use_fci=1)

        # Get explicit coefficients.
        self.nuclear_repulsion = self.molecular_hamiltonian.constant
        self.one_body = self.molecular_hamiltonian.one_body_tensor
        self.two_body = self.molecular_hamiltonian.two_body_tensor

        # Get fermion Hamiltonian.
        self.fermion_hamiltonian = normal_ordered(
            get_fermion_operator(self.molecular_hamiltonian))

        # Get qubit Hamiltonian.
        self.qubit_hamiltonian = jordan_wigner(self.fermion_hamiltonian)

        # Get explicit coefficients.
        self.nuclear_repulsion = self.molecular_hamiltonian.constant
        self.one_body = self.molecular_hamiltonian.one_body_tensor
        self.two_body = self.molecular_hamiltonian.two_body_tensor

        # Get matrix form.
        self.hamiltonian_matrix = get_sparse_operator(
            self.molecular_hamiltonian)
        self.hamiltonian_matrix_no_core = get_sparse_operator(
            self.molecular_hamiltonian_no_core)
 def test_oqdm_to_opdm(self):
     for file in filter(lambda x: x.endswith(".hdf5"),
                        os.listdir(DATA_DIRECTORY)):
         molecule = MolecularData(
             filename=os.path.join(DATA_DIRECTORY, file))
         if molecule.fci_one_rdm is not None:
             true_oqdm = numpy.eye(molecule.n_qubits) - molecule.fci_one_rdm
             test_opdm = map_one_hole_dm_to_one_pdm(true_oqdm)
             assert numpy.allclose(test_opdm, molecule.fci_one_rdm)
    def setUp(self):

        # Set up molecule.
        geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))]
        basis = 'sto-3g'
        multiplicity = 1
        filename = os.path.join(DATA_DIRECTORY, 'H2_sto-3g_singlet_0.7414')
        molecule = MolecularData(geometry,
                                 basis,
                                 multiplicity,
                                 filename=filename)
        molecule.load()
        self.n_fermions = molecule.n_electrons
        self.n_orbitals = molecule.n_qubits

        # Get molecular Hamiltonian.
        molecular_hamiltonian = molecule.get_molecular_hamiltonian()
        self.fermion_hamiltonian = get_fermion_operator(molecular_hamiltonian)
Exemplo n.º 21
0
def test_gradient_lih():
    filename = os.path.join(DATA_DIRECTORY, "H1-Li1_sto-3g_singlet_1.45.hdf5")
    molecule = MolecularData(filename=filename)

    overlap = molecule.overlap_integrals
    mo_obi = molecule.one_body_integrals
    mo_tbi = molecule.two_body_integrals
    rotation_mat = molecule.canonical_orbitals.T.dot(overlap)
    obi = general_basis_change(mo_obi, rotation_mat, (1, 0))
    tbi = general_basis_change(mo_tbi, rotation_mat, (1, 1, 0, 0))

    hff = HartreeFockFunctional(one_body_integrals=obi,
                                two_body_integrals=tbi,
                                overlap=overlap,
                                n_electrons=molecule.n_electrons,
                                model='rhf',
                                nuclear_repulsion=molecule.nuclear_repulsion)

    params = np.random.randn(hff.nocc * hff.nvirt)
    u = sp.linalg.expm(
        rhf_params_to_matrix(params,
                             hff.num_orbitals,
                             occ=hff.occ,
                             virt=hff.virt))
    grad_dim = hff.nocc * hff.nvirt
    initial_opdm = np.diag([1] * hff.nocc + [0] * hff.nvirt)
    final_opdm = u.dot(initial_opdm).dot(u.conj().T)
    grad = hff.rhf_global_gradient(params, final_opdm)

    # get finite difference gradient
    finite_diff_grad = np.zeros(grad_dim)
    epsilon = 0.0001
    for i in range(grad_dim):
        params_epsilon = params.copy()
        params_epsilon[i] += epsilon
        u = sp.linalg.expm(
            rhf_params_to_matrix(params_epsilon,
                                 hff.num_orbitals,
                                 occ=hff.occ,
                                 virt=hff.virt))
        tfinal_opdm = u.dot(initial_opdm).dot(u.conj().T)
        energy_plus_epsilon = hff.energy_from_rhf_opdm(tfinal_opdm)

        params_epsilon[i] -= 2 * epsilon
        u = sp.linalg.expm(
            rhf_params_to_matrix(params_epsilon,
                                 hff.num_orbitals,
                                 occ=hff.occ,
                                 virt=hff.virt))
        tfinal_opdm = u.dot(initial_opdm).dot(u.conj().T)
        energy_minus_epsilon = hff.energy_from_rhf_opdm(tfinal_opdm)

        finite_diff_grad[i] = (energy_plus_epsilon -
                               energy_minus_epsilon) / (2 * epsilon)

    assert np.allclose(finite_diff_grad, grad, atol=epsilon)
 def test_tpdm_to_opdm(self):
     # for all files in datadirectory check if this map holds
     for file in filter(lambda x: x.endswith(".hdf5"),
                        os.listdir(DATA_DIRECTORY)):
         molecule = MolecularData(
             filename=os.path.join(DATA_DIRECTORY, file))
         if (molecule.fci_one_rdm is not None
                 and molecule.fci_two_rdm is not None):
             test_opdm = map_two_pdm_to_one_pdm(molecule.fci_two_rdm,
                                                molecule.n_electrons)
             assert numpy.allclose(test_opdm, molecule.fci_one_rdm)
def test_fci_energy():
    filename = os.path.join(DATA_DIRECTORY, "H2_sto-3g_singlet_0.7414.hdf5")
    molecule = MolecularData(filename=filename)
    reduced_ham = make_reduced_hamiltonian(molecule.get_molecular_hamiltonian(),
                                           molecule.n_electrons)
    numpy_ham = get_number_preserving_sparse_operator(
        get_fermion_operator(reduced_ham),
        molecule.n_qubits,
        num_electrons=molecule.n_electrons,
        spin_preserving=True)

    w, _ = numpy.linalg.eigh(numpy_ham.toarray())
    assert numpy.isclose(molecule.fci_energy, w[0])

    filename = os.path.join(DATA_DIRECTORY, "H1-Li1_sto-3g_singlet_1.45.hdf5")
    molecule = MolecularData(filename=filename)
    reduced_ham = make_reduced_hamiltonian(molecule.get_molecular_hamiltonian(),
                                           molecule.n_electrons)
    numpy_ham = get_number_preserving_sparse_operator(
        get_fermion_operator(reduced_ham),
        molecule.n_qubits,
        num_electrons=molecule.n_electrons,
        spin_preserving=True)

    w, _ = numpy.linalg.eigh(numpy_ham.toarray())
    assert numpy.isclose(molecule.fci_energy, w[0])
Exemplo n.º 24
0
def test_generate_hamiltonian():
    filename = os.path.join(DATA_DIRECTORY, "H1-Li1_sto-3g_singlet_1.45.hdf5")
    molecule = MolecularData(filename=filename)
    mo_obi = molecule.one_body_integrals
    mo_tbi = molecule.two_body_integrals
    mol_ham = generate_hamiltonian(mo_obi, mo_tbi, constant=0)
    assert isinstance(mol_ham, InteractionOperator)
    assert np.allclose(mol_ham.one_body_tensor[::2, ::2], mo_obi)
    assert np.allclose(mol_ham.one_body_tensor[1::2, 1::2], mo_obi)
    assert np.allclose(mol_ham.two_body_tensor[::2, ::2, ::2, ::2],
                       0.5 * mo_tbi)
    assert np.allclose(mol_ham.two_body_tensor[1::2, 1::2, 1::2, 1::2],
                       0.5 * mo_tbi)
    def test_tqdm_conversions_lih_sto3g(self):
        filename = "H1-Li1_sto-3g_singlet_1.45.hdf5"
        molecule = MolecularData(
            filename=os.path.join(DATA_DIRECTORY, filename))
        true_tqdm = self.tqdm_lih_sto3g

        test_tqdm = map_two_pdm_to_two_hole_dm(molecule.fci_two_rdm,
                                               molecule.fci_one_rdm)
        assert numpy.allclose(true_tqdm, test_tqdm)

        true_oqdm = numpy.eye(molecule.n_qubits) - molecule.fci_one_rdm
        test_oqdm = map_two_hole_dm_to_one_hole_dm(
            true_tqdm, molecule.n_qubits - molecule.n_electrons)
        assert numpy.allclose(true_oqdm, test_oqdm)

        test_tpdm = map_two_hole_dm_to_two_pdm(true_tqdm, molecule.fci_one_rdm)
        assert numpy.allclose(test_tpdm, molecule.fci_two_rdm)
    def test_phdm_conversions_h2_sto3g(self):
        filename = "H2_sto-3g_singlet_1.4.hdf5"
        molecule = MolecularData(
            filename=os.path.join(DATA_DIRECTORY, filename))
        true_phdm = self.phdm_h2_sto3g

        test_phdm = map_two_pdm_to_particle_hole_dm(molecule.fci_two_rdm,
                                                    molecule.fci_one_rdm)
        assert numpy.allclose(test_phdm, true_phdm)

        test_opdm = map_particle_hole_dm_to_one_pdm(true_phdm,
                                                    molecule.n_electrons,
                                                    molecule.n_qubits)
        assert numpy.allclose(test_opdm, molecule.fci_one_rdm)

        test_tpdm = map_particle_hole_dm_to_two_pdm(true_phdm,
                                                    molecule.fci_one_rdm)
        assert numpy.allclose(test_tpdm, molecule.fci_two_rdm)
    def test_tqdm_conversions_h2_631g(self):
        # construct the 2-hole-RDM for LiH the slow way
        # TODO: speed up this calculation by directly contracting from the wf.
        filename = "H2_6-31g_singlet_0.75.hdf5"
        molecule = MolecularData(
            filename=os.path.join(DATA_DIRECTORY, filename))
        true_tqdm = self.tqdm_h2_6_31g

        test_tqdm = map_two_pdm_to_two_hole_dm(molecule.fci_two_rdm,
                                               molecule.fci_one_rdm)
        assert numpy.allclose(true_tqdm, test_tqdm)

        true_oqdm = numpy.eye(molecule.n_qubits) - molecule.fci_one_rdm
        test_oqdm = map_two_hole_dm_to_one_hole_dm(
            true_tqdm, molecule.n_qubits - molecule.n_electrons)
        assert numpy.allclose(true_oqdm, test_oqdm)

        test_tpdm = map_two_hole_dm_to_two_pdm(true_tqdm, molecule.fci_one_rdm)
        assert numpy.allclose(test_tpdm, molecule.fci_two_rdm)
Exemplo n.º 28
0
def test_rhf_func_generator():
    filename = os.path.join(DATA_DIRECTORY, "H1-Li1_sto-3g_singlet_1.45.hdf5")
    molecule = MolecularData(filename=filename)

    overlap = molecule.overlap_integrals
    mo_obi = molecule.one_body_integrals
    mo_tbi = molecule.two_body_integrals
    rotation_mat = molecule.canonical_orbitals.T.dot(overlap)
    obi = general_basis_change(mo_obi, rotation_mat, (1, 0))
    tbi = general_basis_change(mo_tbi, rotation_mat, (1, 1, 0, 0))

    hff = HartreeFockFunctional(one_body_integrals=obi,
                                two_body_integrals=tbi,
                                overlap=overlap,
                                n_electrons=molecule.n_electrons,
                                model='rhf',
                                nuclear_repulsion=molecule.nuclear_repulsion)
    unitary, energy, gradient = rhf_func_generator(hff)
    assert isinstance(unitary, Callable)
    assert isinstance(energy, Callable)
    assert isinstance(gradient, Callable)

    params = np.random.randn(hff.nocc * hff.nvirt)
    u = unitary(params)
    assert np.allclose(u.conj().T.dot(u), np.eye(hff.num_orbitals))
    assert isinstance(energy(params), float)
    assert isinstance(gradient(params), np.ndarray)

    _, _, _, opdm_func = rhf_func_generator(hff, get_opdm_func=True)
    assert isinstance(opdm_func, Callable)
    assert isinstance(opdm_func(params), np.ndarray)
    assert np.isclose(opdm_func(params).shape[0], hff.num_orbitals)

    _, energy, _ = rhf_func_generator(hff,
                                      init_occ_vec=np.array([1, 1, 1, 1, 0,
                                                             0]))
    assert isinstance(energy(params), float)
Exemplo n.º 29
0
    def setUp(self):

        # Setup.
        geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))]
        basis = 'sto-3g'
        multiplicity = 1
        filename = os.path.join(THIS_DIRECTORY, 'data',
                                'H2_sto-3g_singlet_0.7414')
        molecule = MolecularData(geometry,
                                 basis,
                                 multiplicity,
                                 filename=filename)
        molecule.load()
        self.n_fermions = molecule.n_electrons
        self.n_orbitals = molecule.n_qubits

        # Get molecular Hamiltonian.
        self.molecular_hamiltonian = molecule.get_molecular_hamiltonian()
        self.fci_rdm = molecule.get_molecular_rdm(use_fci=1)
Exemplo n.º 30
0
class LiHIntegrationTest(unittest.TestCase):
    def setUp(self):
        # Set up molecule.
        geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))]
        basis = 'sto-3g'
        multiplicity = 1
        filename = os.path.join(THIS_DIRECTORY, 'data',
                                'H1-Li1_sto-3g_singlet_1.45')
        self.molecule = MolecularData(geometry,
                                      basis,
                                      multiplicity,
                                      filename=filename)
        self.molecule.load()

        # Get molecular Hamiltonian
        self.molecular_hamiltonian = self.molecule.get_molecular_hamiltonian()
        self.molecular_hamiltonian_no_core = (
            self.molecule.get_molecular_hamiltonian(
                occupied_indices=[0],
                active_indices=range(1, self.molecule.n_orbitals)))

        # Get FCI RDM.
        self.fci_rdm = self.molecule.get_molecular_rdm(use_fci=1)

        # Get explicit coefficients.
        self.nuclear_repulsion = self.molecular_hamiltonian.constant
        self.one_body = self.molecular_hamiltonian.one_body_tensor
        self.two_body = self.molecular_hamiltonian.two_body_tensor

        # Get fermion Hamiltonian.
        self.fermion_hamiltonian = normal_ordered(
            get_fermion_operator(self.molecular_hamiltonian))

        # Get qubit Hamiltonian.
        self.qubit_hamiltonian = jordan_wigner(self.fermion_hamiltonian)

        # Get explicit coefficients.
        self.nuclear_repulsion = self.molecular_hamiltonian.constant
        self.one_body = self.molecular_hamiltonian.one_body_tensor
        self.two_body = self.molecular_hamiltonian.two_body_tensor

        # Get matrix form.
        self.hamiltonian_matrix = get_sparse_operator(
            self.molecular_hamiltonian)
        self.hamiltonian_matrix_no_core = get_sparse_operator(
            self.molecular_hamiltonian_no_core)

    def test_all(self):

        # Test reverse Jordan-Wigner.
        fermion_hamiltonian = reverse_jordan_wigner(self.qubit_hamiltonian)
        fermion_hamiltonian = normal_ordered(fermion_hamiltonian)
        self.assertTrue(self.fermion_hamiltonian == fermion_hamiltonian)

        # Test mapping to interaction operator.
        fermion_hamiltonian = get_fermion_operator(self.molecular_hamiltonian)
        fermion_hamiltonian = normal_ordered(fermion_hamiltonian)
        self.assertTrue(self.fermion_hamiltonian == fermion_hamiltonian)

        # Test RDM energy.
        fci_rdm_energy = self.nuclear_repulsion
        fci_rdm_energy += numpy.sum(self.fci_rdm.one_body_tensor *
                                    self.one_body)
        fci_rdm_energy += numpy.sum(self.fci_rdm.two_body_tensor *
                                    self.two_body)
        self.assertAlmostEqual(fci_rdm_energy, self.molecule.fci_energy)

        # Confirm expectation on qubit Hamiltonian using reverse JW matches.
        qubit_rdm = self.fci_rdm.get_qubit_expectations(self.qubit_hamiltonian)
        qubit_energy = 0.0
        for term, coefficient in qubit_rdm.terms.items():
            qubit_energy += coefficient * self.qubit_hamiltonian.terms[term]
        self.assertAlmostEqual(qubit_energy, self.molecule.fci_energy)

        # Confirm fermionic RDMs can be built from measured qubit RDMs.
        new_fermi_rdm = get_interaction_rdm(qubit_rdm)
        new_fermi_rdm.expectation(self.molecular_hamiltonian)
        self.assertAlmostEqual(fci_rdm_energy, self.molecule.fci_energy)

        # Test sparse matrices.
        energy, wavefunction = get_ground_state(self.hamiltonian_matrix)
        self.assertAlmostEqual(energy, self.molecule.fci_energy)
        expected_energy = expectation(self.hamiltonian_matrix, wavefunction)
        self.assertAlmostEqual(expected_energy, energy)

        # Make sure you can reproduce Hartree-Fock energy.
        hf_state = jw_hartree_fock_state(self.molecule.n_electrons,
                                         count_qubits(self.qubit_hamiltonian))
        hf_density = get_density_matrix([hf_state], [1.])
        expected_hf_density_energy = expectation(self.hamiltonian_matrix,
                                                 hf_density)
        expected_hf_energy = expectation(self.hamiltonian_matrix, hf_state)
        self.assertAlmostEqual(expected_hf_energy, self.molecule.hf_energy)
        self.assertAlmostEqual(expected_hf_density_energy,
                               self.molecule.hf_energy)

        # Check that frozen core result matches frozen core FCI from psi4.
        # Recore frozen core result from external calculation.
        self.frozen_core_fci_energy = -7.8807607374168
        no_core_fci_energy = numpy.linalg.eigh(
            self.hamiltonian_matrix_no_core.toarray())[0][0]
        self.assertAlmostEqual(no_core_fci_energy, self.frozen_core_fci_energy)

        # Check that the freeze_orbitals function has the same effect as the
        # as the occupied_indices option of get_molecular_hamiltonian.
        frozen_hamiltonian = freeze_orbitals(
            get_fermion_operator(self.molecular_hamiltonian), [0, 1])
        self.assertTrue(frozen_hamiltonian == get_fermion_operator(
            self.molecular_hamiltonian_no_core))