Loading Molecular data¶
The most common usecase for FermionicOperator is for representing molecules from Quantum Chemistry. When using standard classical quantum chemistry software, molecules are often stored in FCIDump format, or as matrices representing one- and two-body integrals.
[1]:
import pyscf
import pyscf.mcscf
import fulqrum as fq
from fulqrum.convert import integrals_to_fq_fermionic_op
Loading an operator from an FCIDump file¶
FCIDump is a common format for dealing with molecules with real-valued coefficients. Fulqrum can directly load molecules in this format, evaluating only those terms that are unique:
[2]:
fop = fq.FermionicOperator.from_fcidump("./data/fcidump_Fe4S4_MO.txt")
Parsing ./data/fcidump_Fe4S4_MO.txt
[3]:
fop.size()
[3]:
2476008
Importantly, because only unique terms are present in the final operator, the Extended Jordan-Wigner transformation necessary to bring the operator into a QubitOperator is much faster.
Loading a molecule from integrals¶
It is also possible to load molecules from the integrals generated by programs such as PySCF. This is done using the integrals_to_fq_fermionic_op routine. For example, generating the integrals from PySCF looks like:
[4]:
# Build N2 molecule
mol = pyscf.gto.Mole()
mol.build(
atom=[["N", (0, 0, 0)], ["N", (1.0, 0, 0)]],
basis="6-31g",
)
# Define active space
n_frozen = 2
active_space = range(n_frozen, mol.nao_nr())
# Get molecular integrals
scf = pyscf.scf.RHF(mol).run()
num_orbitals = len(active_space)
n_electrons = int(sum(scf.mo_occ[active_space]))
num_elec_a = (n_electrons + mol.spin) // 2
num_elec_b = (n_electrons - mol.spin) // 2
cas = pyscf.mcscf.CASCI(scf, num_orbitals, (num_elec_a, num_elec_b))
mo = cas.sort_mo(active_space, base=0)
hcore, nuclear_repulsion_energy = cas.get_h1cas(mo) # hcore: one-body integrals
eri = pyscf.ao2mo.restore(1, cas.get_h2cas(mo), num_orbitals) # eri: two-body integrals
converged SCF energy = -108.835236570774
From which we can load an operator using the one- and two-body integrals, along with a constant term, if any
[5]:
fop2 = integrals_to_fq_fermionic_op(one_body_integrals=hcore, two_body_integrals=eri)
[6]:
fop2.size()
[6]:
21520
[ ]: