Can someone provide me with an example about how to implement VQE with OpenFermion, for example, use the UCCSD ansatz to get the ground state energy of LiH. I have checked some code, but none of them is up to date (deprecated). Also, there is no demo code in the official document for VQE implementation.

Also, can somebody show me how to calculate energy with 1-electron and 2-electron reduced density matrix with OpenFermion using the following formula (A14).

enter image description here


1 Answer 1


I recommend using OpenFermion in conjunction with QCOR, a quantum programming language being developed at Oak Ridge National Laboratory. This tool offers python bindings and has abstractions for variational quantum algorithms. Here's an example showing QCOR with OpenFermion. Although I don't know anything about the LiH Hamiltonian, here's an example using QCOR with OpenFermion to do VQE to find the ground state of the Hubbard Hamiltonian:

from openfermion.hamiltonians import fermi_hubbard
from openfermion.ops import FermionOperator as FOp
from openfermion.ops import QubitOperator
from openfermion.transforms import jordan_wigner, normal_ordered
from openfermion.linalg import get_sparse_operator, get_ground_state, eigenspectrum
from openfermion.utils import hermitian_conjugated, commutator, count_qubits
from qcor import *
import numpy as np
from types import MethodType

#Define openFermion model
Nlat = 2 #number of lattice sites
x_dimension = 2 #two sites like this *--*
y_dimension = 1
tunneling = 1.0 #t
coulomb = 3 
nfill = 1.0
chemical_potential = nfill*coulomb/2.0
periodic = 1
spinless = 0 #spinfull case
hubbard_r = fermi_hubbard(x_dimension, y_dimension, tunneling, coulomb, chemical_potential, spinless = 0)
print(f'  {Nlat:d} site Hubbard model: {len(hubbard_r.terms):d} terms in the Hamiltonian')
#perform jordan wigner transform
hubbard_rjw = jordan_wigner(hubbard_r)

sparse_operator = get_sparse_operator(hubbard_rjw, n_qubits = Nlat*2)
gs = get_ground_state(sparse_operator)
E0 = gs[0]
#define the quantum circuit (kernel) for your "ansatz" or initial guess wavefunction, this is factorized UCC ansatz
#exp_i_theta does implicit first order trotterization
def ansatz(q: qreg, x: List[float], exp_args: List[FermionOperator]):
    for i, exp_arg in enumerate(exp_args):
        exp_i_theta(q, x[i], exp_args[i])
# Create OpenFermion operators for our quantum kernel...
exp_args_openfermion = [FOp('2^ 3^ 1 0') - FOp('0^ 1^ 3 2'),
                        FOp('2^ 0') - FOp('0^ 2'), 
                        FOp('3^ 1') - FOp('1^ 3')]
# We need to translate OpenFermion ops into qcor Operators to use with kernels...
exp_args_qcor = [createOperator('fermion', fop) for fop in exp_args_openfermion]

# translates arguments between quantum kernel and optimizer
def ansatz_translate(self, q: qreg, x: List[float]):
    ret_dict = {}    
    ret_dict["q"] = q
    ret_dict["x"] = x
    ret_dict["exp_args"] = exp_args_qcor
    return ret_dict
ansatz.translate = MethodType(ansatz_translate, qjit)
n_params = len(exp_args_qcor)
x_init  = np.random.rand(n_params).tolist()
ansatz.print_kernel(qalloc(4), [1.0, 1.0, 1.0], exp_args_qcor)
u_mat = ansatz.as_unitary_matrix(qalloc(4), [1.0, 1.0, 1.0], exp_args_qcor)
print("unitary mat: ", u_mat)
#VQE is an example of an "objectiveFunction", where we seek to minimize <U(x)|H|U(x)>
obj = createObjectiveFunction(ansatz, hubbard_rjw, n_params, {'gradient-strategy': 'parameter-shift'})
optimizer = createOptimizer('nlopt', {'algorithm': 'l-bfgs', 'initial-parameters':x_init})
results = optimizer.optimize(obj)
  • $\begingroup$ Thanks for reply! It seems to me that openfermioon is like a pakage for constructing quantum chemistry objectives (like molecule and Hamiltonian) and get information from the objectives. Therefore, to implement a VQE algorithm, one should use additional pakages, like QCOR here. But for me, qiskit is a better option, becuase I am planning to implement the algorithm with a real device and test my quantum error mitigation algorithm. So, is there a way to bind openfermion with qiskit? $\endgroup$ Commented Jan 27, 2021 at 7:41
  • $\begingroup$ QCOR also has access to real backends as well. In fact it is abstracted so you can send jobs to IBM, Rigetti, and others. You do this by setting the command line argument, such as: -qpu ibm[ibm:ibmq_backend], assuming you have qiskit installed and backend credentials. $\endgroup$
    – Cuhrazatee
    Commented Jan 27, 2021 at 17:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.