示例#1
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)
    def test_mul(self):
        new_tensor = self.polynomial_tensor_a * self.polynomial_tensor_b
        self.assertEqual(new_tensor, self.polynomial_tensor_axb)

        new_tensor_1 = self.polynomial_tensor_a * 2.
        new_tensor_2 = 2. * self.polynomial_tensor_a

        self.assertEqual(
            new_tensor_1,
            PolynomialTensor({
                (): self.constant * 2.,
                (1, 0): self.one_body_a * 2.,
                (1, 1, 0, 0): self.two_body_a * 2.
            }))
        self.assertEqual(
            new_tensor_2,
            PolynomialTensor({
                (): self.constant * 2.,
                (1, 0): self.one_body_a * 2.,
                (1, 1, 0, 0): self.two_body_a * 2.
            }))
        self.assertEqual(get_fermion_operator(new_tensor_1),
                         get_fermion_operator(self.polynomial_tensor_a) * 2.)
        self.assertEqual(get_fermion_operator(new_tensor_2),
                         get_fermion_operator(self.polynomial_tensor_a) * 2.)
示例#3
0
 def test_multiply(self):
     n_qubits = 5
     op1 = random_diagonal_coulomb_hamiltonian(n_qubits)
     op2 = op1 * 1.5
     op3 = 1.5 * op1
     self.assertEqual(
         get_fermion_operator(op1) * 1.5, get_fermion_operator(op2),
         get_fermion_operator(op3))
示例#4
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))
        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)))
    def test_hermiticity(self):
        n_qubits = 5

        # Real case
        iop = random_interaction_operator(n_qubits, True)
        ferm_op = get_fermion_operator(iop)
        self.assertTrue(is_hermitian(ferm_op))

        # Complex case
        iop = random_interaction_operator(n_qubits, False)
        ferm_op = get_fermion_operator(iop)
        self.assertTrue(is_hermitian(ferm_op))
    def test_integration_random_diagonal_coulomb_hamiltonian(self):
        hamiltonian1 = normal_ordered(
            get_fermion_operator(
                random_diagonal_coulomb_hamiltonian(n_qubits=7)))
        hamiltonian2 = normal_ordered(
            get_fermion_operator(
                random_diagonal_coulomb_hamiltonian(n_qubits=7)))

        reference = normal_ordered(commutator(hamiltonian1, hamiltonian2))
        result = commutator_ordered_diagonal_coulomb_with_two_body_operator(
            hamiltonian1, hamiltonian2)

        self.assertTrue(result.isclose(reference))
示例#7
0
def decompose_hamiltonian(mol_name,
                          hf_data,
                          mapping="jordan_wigner",
                          docc_mo_indices=None,
                          active_mo_indices=None):
    r"""Decomposes the electronic Hamiltonian into a linear combination of Pauli operators using
    OpenFermion tools.

    **Example usage:**

    >>> decompose_hamiltonian('h2', './pyscf/sto-3g/', mapping='bravyi_kitaev')
    (-0.04207897696293986+0j) [] + (0.04475014401986122+0j) [X0 Z1 X2] +
    (0.04475014401986122+0j) [X0 Z1 X2 Z3] +(0.04475014401986122+0j) [Y0 Z1 Y2] +
    (0.04475014401986122+0j) [Y0 Z1 Y2 Z3] +(0.17771287459806262+0j) [Z0] +
    (0.17771287459806265+0j) [Z0 Z1] +(0.1676831945625423+0j) [Z0 Z1 Z2] +
    (0.1676831945625423+0j) [Z0 Z1 Z2 Z3] +(0.12293305054268105+0j) [Z0 Z2] +
    (0.12293305054268105+0j) [Z0 Z2 Z3] +(0.1705973832722409+0j) [Z1] +
    (-0.2427428049645989+0j) [Z1 Z2 Z3] +(0.1762764080276107+0j) [Z1 Z3] +
    (-0.2427428049645989+0j) [Z2]

    Args:
        mol_name (str): name of the molecule
        hf_data (str): path to the directory containing the file with the Hartree-Fock
            electronic structure
        mapping (str): optional argument to specify the fermion-to-qubit mapping
            Input values can be ``'jordan_wigner'`` or ``'bravyi_kitaev'``
        docc_mo_indices (list): indices of doubly-occupied molecular orbitals, i.e.,
            the orbitals that are not correlated in the many-body wave function
        active_mo_indices (list): indices of active molecular orbitals, i.e., the orbitals used to
            build the correlated many-body wave function

    Returns:
        transformed_operator: instance of the QubitOperator class representing the electronic
        Hamiltonian
    """

    # loading HF data from a hdf5 file
    molecule = MolecularData(
        filename=os.path.join(hf_data.strip(), mol_name.strip()))

    # getting the terms entering the second-quantized Hamiltonian
    terms_molecular_hamiltonian = molecule.get_molecular_hamiltonian(
        occupied_indices=docc_mo_indices, active_indices=active_mo_indices)

    # generating the fermionic Hamiltonian
    fermionic_hamiltonian = get_fermion_operator(terms_molecular_hamiltonian)

    mapping = mapping.strip().lower()

    if mapping not in ("jordan_wigner", "bravyi_kitaev"):
        raise TypeError(
            "The '{}' transformation is not available. \n "
            "Please set 'mapping' to 'jordan_wigner' or 'bravyi_kitaev'.".
            format(mapping))

    # fermionic-to-qubit transformation of the Hamiltonian
    if mapping == "bravyi_kitaev":
        return bravyi_kitaev(fermionic_hamiltonian)

    return jordan_wigner(fermionic_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
示例#9
0
 def test_random_quadratic(self):
     n_qubits = 5
     quad_ham = random_quadratic_hamiltonian(n_qubits, True)
     ferm_op = get_fermion_operator(quad_ham)
     self.assertTrue(
         jordan_wigner(ferm_op) == jordan_wigner(
             get_diagonal_coulomb_hamiltonian(ferm_op)))
示例#10
0
def get_qubit_hamiltonian(mol,
                          geometry,
                          basis,
                          charge=0,
                          multiplicity=1,
                          qubit_transf='bk'):
    '''
    Generating qubit hamiltonina of the given molecules with specified geometry, basis sets, charge and multiplicity
    Give its qubit form using specified transformation
    '''
    g = get_molecular_data(mol, geometry)
    mol = MolecularData(g, basis, multiplicity, charge)
    mol = run_pyscf(mol)

    ham = mol.get_molecular_hamiltonian()
    hamf = get_fermion_operator(ham)

    if qubit_transf == 'bk':
        hamq = bravyi_kitaev(hamf)
    elif qubit_transf == 'jw':
        hamq = jordan_wigner(hamf)
    else:
        raise (ValueError(qubit_transf, 'Unknown transformation specified'))

    return hamq
示例#11
0
 def test_majorana_form(self):
     """Test getting the Majorana form."""
     majorana_matrix, majorana_constant = self.quad_ham_npc.majorana_form()
     # Convert the Majorana form to a FermionOperator
     majorana_op = FermionOperator((), majorana_constant)
     normalization = 1. / numpy.sqrt(2.)
     for i in range(2 * self.n_qubits):
         if i < self.n_qubits:
             left_op = majorana_operator((i, 0), normalization)
         else:
             left_op = majorana_operator((i - self.n_qubits, 1),
                                         normalization)
         for j in range(2 * self.n_qubits):
             if j < self.n_qubits:
                 right_op = majorana_operator(
                     (j, 0), majorana_matrix[i, j] * normalization)
             else:
                 right_op = majorana_operator(
                     (j - self.n_qubits, 1),
                     majorana_matrix[i, j] * normalization)
             majorana_op += .5j * left_op * right_op
     # Get FermionOperator for original Hamiltonian
     fermion_operator = normal_ordered(
         get_fermion_operator(self.quad_ham_npc))
     self.assertTrue(normal_ordered(majorana_op) == fermion_operator)
def exp_hamiltoniantrot_H2(time, atomic_distance, trotter_order):
    """
    Here we are using some packages related to quantum chemistry to obtain
    hamiltonian of H2 molecule. The we are translating this hamiltonian into
    sequence of pyquil gates. And finally, we are trotterazing the exponent
    of the hamiltonian (exp(-iHt)) of our system and returning the obtained
    pyquil program

    :param time: is t in the exp(iHt). Note the + sign.
    :param atomic_distance: the distance between to H atoms in H2 molecule

    :return: program of the Trotter-Suzuki decomposition of
             hamiltonian exp(iHt) for H2 molecule
    """

    geometry = [['H', [0, 0, 0]],
                ['H', [0, 0, atomic_distance]]]  # H--H distance = 0.74angstrom
    basis = 'sto-3g'
    multiplicity = 1  # (2S+1)
    charge = 0
    h2_molecule = MolecularData(geometry, basis, multiplicity, charge)
    h2_molecule = run_pyscf(h2_molecule)

    h2_qubit_hamiltonian = jordan_wigner(get_fermion_operator(h2_molecule.get_molecular_hamiltonian()))
    pyquil_h2_qubit_hamiltonian = qubitop_to_pyquilpauli(h2_qubit_hamiltonian)

    return trotterization(pyquil_h2_qubit_hamiltonian, float(time), trotter_order)
示例#13
0
 def test_exception(self):
     n_qubits = 6
     random_operator = get_fermion_operator(
         random_interaction_operator(n_qubits))
     bad_term = ((2, 1), (3, 1))
     random_operator += FermionOperator(bad_term)
     with self.assertRaises(OperatorSpecificationError):
         chemist_operator = chemist_ordered(random_operator)
示例#14
0
 def test_convert_forward_back(self):
     n_qubits = 6
     random_operator = get_fermion_operator(
         random_interaction_operator(n_qubits))
     chemist_operator = chemist_ordered(random_operator)
     normalized_chemist = normal_ordered(chemist_operator)
     difference = normalized_chemist - normal_ordered(random_operator)
     self.assertAlmostEqual(0., difference.induced_norm())
示例#15
0
def decompose(hf_file, mapping="jordan_wigner", core=None, active=None):
    r"""Decomposes the molecular Hamiltonian into a linear combination of Pauli operators using
    OpenFermion tools.

    This function uses OpenFermion functions to build the second-quantized electronic Hamiltonian
    of the molecule and map it to the Pauli basis using the Jordan-Wigner or Bravyi-Kitaev
    transformation.

    Args:
        hf_file (str): absolute path to the hdf5-formatted file with the
            Hartree-Fock electronic structure
        mapping (str): Specifies the transformation to map the fermionic Hamiltonian to the
            Pauli basis. Input values can be ``'jordan_wigner'`` or ``'bravyi_kitaev'``.
        core (list): indices of core orbitals, i.e., the orbitals that are
            not correlated in the many-body wave function
        active (list): indices of active orbitals, i.e., the orbitals used to
            build the correlated many-body wave function

    Returns:
        QubitOperator: an instance of OpenFermion's ``QubitOperator``

    **Example**

    >>> decompose('./pyscf/sto-3g/h2', mapping='bravyi_kitaev')
    (-0.04207897696293986+0j) [] + (0.04475014401986122+0j) [X0 Z1 X2] +
    (0.04475014401986122+0j) [X0 Z1 X2 Z3] +(0.04475014401986122+0j) [Y0 Z1 Y2] +
    (0.04475014401986122+0j) [Y0 Z1 Y2 Z3] +(0.17771287459806262+0j) [Z0] +
    (0.17771287459806265+0j) [Z0 Z1] +(0.1676831945625423+0j) [Z0 Z1 Z2] +
    (0.1676831945625423+0j) [Z0 Z1 Z2 Z3] +(0.12293305054268105+0j) [Z0 Z2] +
    (0.12293305054268105+0j) [Z0 Z2 Z3] +(0.1705973832722409+0j) [Z1] +
    (-0.2427428049645989+0j) [Z1 Z2 Z3] +(0.1762764080276107+0j) [Z1 Z3] +
    (-0.2427428049645989+0j) [Z2]
    """

    # loading HF data from the hdf5 file
    molecule = MolecularData(filename=hf_file.strip())

    # getting the terms entering the second-quantized Hamiltonian
    terms_molecular_hamiltonian = molecule.get_molecular_hamiltonian(
        occupied_indices=core, active_indices=active
    )

    # generating the fermionic Hamiltonian
    fermionic_hamiltonian = get_fermion_operator(terms_molecular_hamiltonian)

    mapping = mapping.strip().lower()

    if mapping not in ("jordan_wigner", "bravyi_kitaev"):
        raise TypeError(
            "The '{}' transformation is not available. \n "
            "Please set 'mapping' to 'jordan_wigner' or 'bravyi_kitaev'.".format(mapping)
        )

    # fermionic-to-qubit transformation of the Hamiltonian
    if mapping == "bravyi_kitaev":
        return bravyi_kitaev(fermionic_hamiltonian)

    return jordan_wigner(fermionic_hamiltonian)
def run_simulation(bond_lengths):
    # Load saved file for H3.
    basis = 'sto-3g'
    spin = 2

    # Set Hamiltonian parameters.
    active_space_start = 1
    active_space_stop = 3

    # Set calculation parameters.
    run_scf = 1
    run_mp2 = 1
    run_cisd = 0
    run_ccsd = 0
    run_fci = 1
    delete_input = True
    delete_output = True

    # Begin Running Simulation, Convert distance_counter to angstroms
    geometry = [('H', (0., 0., bond_lengths[1][-1] * 0.529177249)),
                ('H', (0., 0., bond_lengths[2][-1] * 0.529177249)),
                ('H', (0., 0., bond_lengths[3][-1] * 0.529177249))]

    # Generate and populate instance of MolecularData.
    molecule = MolecularData(geometry, basis, spin, description="h3")

    molecule = run_pyscf(molecule,
                         run_scf=run_scf,
                         run_mp2=run_mp2,
                         run_cisd=run_cisd,
                         run_ccsd=run_ccsd,
                         run_fci=run_fci)

    # Use a Jordan-Wigner encoding, and compress to remove 0 imaginary components
    molecular_hamiltonian = molecule.get_molecular_hamiltonian(
        occupied_indices=range(active_space_start),
        active_indices=range(active_space_start, active_space_stop))

    fermion_hamiltonian = get_fermion_operator(molecular_hamiltonian)
    qubit_hamiltonian = jordan_wigner(fermion_hamiltonian)
    qubit_hamiltonian.compress()
    compiler_engine = uccsd_trotter_engine()
    initial_energy = energy_objective(opt_amplitudes)

    # Run VQE Optimization to find new CCSD parameters
    opt_result = minimize(energy_objective,
                          opt_amplitudes,
                          method="CG",
                          options={'disp': True})

    opt_energy, opt_amplitudes = opt_result.fun, opt_result.x

    return ({
        "Name": molecule.name,
        "UCCSD Energy": opt_energy,
        "FCI Energy": molecule.fci_energy
    })
示例#17
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 get_BK_ham(distance, basis="sto-3g", multiplicity=1, charge=1):
    geometry = [["He", [0, 0, 0]], ["H", [0, 0, distance]]]
    description = str(distance)
    molecule = MolecularData(geometry, basis, multiplicity, charge,
                             description)
    molecule = run_pyscf(molecule, run_fci=1)
    bk_hamiltonian = get_sparse_operator(
        bravyi_kitaev(
            get_fermion_operator(molecule.get_molecular_hamiltonian())))
    return bk_hamiltonian
示例#19
0
def get_qubit_hamiltonian(g, basis, charge=0, spin=1, qubit_transf='jw'):

    ## Create OpenFermion molecule
    #mol = gto.Mole()
    #mol.atom = g
    #mol.basis = basis
    #mol.spin = spin
    #mol.charge = charge
    #mol.symmetry = False
    ##mol.max_memory = 1024
    #mol.build()

    multiplicity = spin + 1  # spin here is 2S ?
    mol = MolecularData(g, basis, multiplicity, charge)
    #mol.load()

    # Convert to PySCF molecule and run SCF
    print("Running run_pyscf...")
    print(f"Time: {time()}")
    print("=" * 20)
    mol = run_pyscf(mol)

    # Freeze some orbitals?
    occupied_indices = range(183)
    active_indices = range(183, 183+5)

    # Get Hamiltonian
    print("Running get_molecular_hamiltonian...")
    print(f"Time: {time()}")
    print("=" * 20)
    ham = mol.get_molecular_hamiltonian(
            occupied_indices=occupied_indices,
            active_indices=active_indices)

    import pdb; pdb.set_trace()

    print("Running get_fermion_operator...")
    print(f"Time: {time()}")
    print("=" * 20)
    hamf = get_fermion_operator(ham)

    print(f"Running {qubit_transf}...")
    print(f"Time: {time()}")
    print("=" * 20)

    if qubit_transf == 'bk':
        hamq = bravyi_kitaev(hamf)
    elif qubit_transf == 'jw':
        hamq = jordan_wigner(hamf)
    else:
        raise(ValueError(qubit_transf, 'Unknown transformation specified'))

    return remove_complex(hamq)
示例#20
0
def full_ham_terms(spacing,dead_space = range(1),active_space = range(1,4)):
    molecule=molecule_data(spacing)

    molecular_hamiltonian = molecule.get_molecular_hamiltonian(
    occupied_indices=dead_space,
    active_indices=active_space)

    fermion_hamiltonian = get_fermion_operator(molecular_hamiltonian)
    qubit_hamiltonian = bravyi_kitaev(fermion_hamiltonian)
    qubit_hamiltonian.compress()
    terms_dict=qubit_hamiltonian.terms
    return terms_dict
示例#21
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
示例#22
0
def energy_levels(separation):
    g = [('H', (0., 0., 0.)), ('H', (0., 0., separation))]
    d = str(separation)
    m = MolecularData(g,
                      basis,
                      multiplicity,
                      description=d,
                      data_directory=data_directory)
    run_psi4(m, run_fci=True, delete_output=True)
    _, s = get_ground_state(
        get_sparse_operator(
            normal_ordered(
                get_fermion_operator(
                    m.get_molecular_hamiltonian(
                        active_indices=range(active_spatial_orbitals))))))
    h = normal_ordered(
        get_fermion_operator(
            m.get_molecular_hamiltonian(
                active_indices=range(active_spatial_orbitals +
                                     virtual_spatial_orbitals))))
    o = vqse_operators(s)
    return generalized_eigenvalues(h_matrix(h, o, s), s_matrix(o, s))
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