-
Notifications
You must be signed in to change notification settings - Fork 27
Open
Description
Suppose I have an OpenFermion InteractionOperator and I want to measure its energy on a FQE wave function.
It appears there are two routs to do this:
-
Convert the
InteractionOperatorto aFermionOperatorand then to a FQESparseHamiltonian(btw, it would be nice if there was a more direct way to do this) -
Get the tensors from the
InteractionOperatorand feed them into FQE'sget_restricted_hamiltonian()
Naively I would have thought that this should yield the same result, but this does not seem to be the case, not even in the HartreeFock state as the following "minimal" example shows (just to be sure I am also constructing the InteractionOperator in two different ways):
import fqe
import numpy as np
import openfermion as of
from openfermion.chem.molecular_data import spinorb_from_spatial
def integrals_to_coefficients(one_body_integrals, two_body_integrals):
return spinorb_from_spatial(one_body_integrals, two_body_integrals/2)
nact = 2
nalpha = 1
nbeta = 1
core_energy = 0.12345134
one_body_integrals = np.array([[-1.37560394, -0.26984563],
[-0.26984563, 1.09725617]])
two_body_integrals = np.array([[[[-0.56763992, 0.24989089],
[ 0.24989089, -0.50890225]],
[[ 0.24989089, -0.50890225],
[ 0.45668102, -0.21692285]]],
[[[ 0.24989089, 0.45668102],
[-0.50890225, -0.21692285]],
[[-0.50890225, -0.21692285],
[-0.21692285, -1.23529049]]]])
# make InteractionOperator manually
one_body_coefficients, two_body_coefficients = integrals_to_coefficients(one_body_integrals, two_body_integrals)
interaction_operator1 = of.InteractionOperator(core_energy, one_body_coefficients, two_body_coefficients)
# make InteractionOperator via MolecularData
molecule = of.MolecularData(
geometry=[['?', [0, 0, 0]]],
basis='cc-pvdz',
multiplicity=nalpha-nbeta+1,
)
molecule.n_orbitals = nact
molecule.n_qubits = 2 * molecule.n_orbitals
molecule.nuclear_repulsion = core_energy
molecule.one_body_integrals = one_body_integrals
molecule.two_body_integrals = two_body_integrals
interaction_operator2 = molecule.get_molecular_hamiltonian()
wfn = fqe.Wavefunction([[nalpha+nbeta, nalpha-nbeta, nact]])
wfn.set_wfn(strategy="hartree-fock")
for interaction_operator in [interaction_operator1, interaction_operator2]:
# btw: Is there a better way to transform an InteractionOperator into a FermionOperator?
fermion_operator = of.FermionOperator()
for key in interaction_operator:
fermion_operator += of.FermionOperator(key, interaction_operator[key])
fermion_operator = fqe.hamiltonians.sparse_hamiltonian.SparseHamiltonian(fermion_operator)
print("SparseHamiltonian energy: ", wfn.expectationValue(fermion_operator))
fermion_operator = fqe.get_restricted_hamiltonian(
([interaction_operator.one_body_tensor,
interaction_operator.two_body_tensor]),
e_0=interaction_operator.constant)
print("get_restricted_hamiltonian() energy:", wfn.expectationValue(fermion_operator))
The output I get is:
SparseHamiltonian energy: (-3.19539646+0j)
get_restricted_hamiltonian() energy: (1.26736786+0j)
SparseHamiltonian energy: (-3.19539646+0j)
get_restricted_hamiltonian() energy: (1.26736786+0j)
Am I doing something wrong?
Metadata
Metadata
Assignees
Labels
No labels