Closed chstem closed 1 year ago
Hi @chstem and thanks for the report. The error is due to using the deprecated ExpvalCost
class. In PennyLane-0.28.0
you should get the following warning:
UserWarning: ExpvalCost is deprecated, use qml.expval() instead.
I modified the code accordingly and it now returns the gradients as expected. Here is the list of the changes made to the original code where the line numbers are for the modified code copied below. Please feel free to let us know if you have any questions. Thanks!
Added @qml.qnode(dev)
to line 60 to create a QNode.
Added return qml.expval(H)
to line 70 to return the expectation value of the Hamiltonian.
Removed creating the cost function with ExpvalCost
in line 74 and used circuit_full, as the cost function directly, in circuit_gradient
in line 75. Your circuit has a wires arg which should be defined when you call circuit_gradient
in line 82.
Modified code:
import pennylane as qml
from pennylane import qchem
import openfermion as openfermion
from openfermion.chem import MolecularData
from openfermionpyscf import run_pyscf
from openfermion.transforms import get_fermion_operator
from openfermion.transforms import jordan_wigner
print('----------------')
### packages/libraries info
print('pennylane version:', qml.__version__)
print('OpenFermion version:', openfermion.__version__)
print('----------------')
### define input parameters
system = 'system.xyz' #structure file
basis = 'sto-3g'
multiplicity = 1
charge = 0
active_indices = [1, 2, 3, 4, 5]
occupied_indices = [0]
active_orbitals = 2 * len(active_indices)
active_fermions = 2
# generate a molecule with OpenFermion
molecule = MolecularData(geometry=[('Li', (0.0, 0.0, -0.40)),
('H' , (0.0, 0.0, 1.19))],
basis=basis,
multiplicity=multiplicity,
charge=charge)
molecule = run_pyscf(molecule, run_scf=False)
### generate a Hamiltonian for the VQE approach
fermionic_H = get_fermion_operator(
molecule.get_molecular_hamiltonian(occupied_indices=occupied_indices,
active_indices=active_indices))
H = jordan_wigner(fermionic_H)
number_qubits = openfermion.utils.count_qubits(H)
print('Hamiltonian has {} qubits'.format(number_qubits))
# translate OpenFermion generated Hamiltonian to Pennylane
H = qchem.import_operator(H, format='openfermion')
# sepcifying the backend
dev = qml.device('default.qubit', wires=number_qubits)
# generating the hf reference state and all the single and double excitations for UCCSD
def hf_state(active_fermions):
for i in range(active_fermions):
qml.PauliX(i)
singles, doubles = qchem.excitations(active_fermions, number_qubits)
# constructing the variational ansatz
@qml.qnode(dev)
def circuit_full(params, wires, excitations):
hf_state(active_fermions) #global variable
for i, excitation in enumerate(excitations):
if len(excitation) == 4:
qml.DoubleExcitation(params[i], wires=excitation)
else:
qml.SingleExcitation(params[i], wires=excitation)
return qml.expval(H)
# ground state energy as optimization objective
# cost_fn = qml.ExpvalCost(circuit_full, H, dev, optimize=True)
circuit_gradient = qml.grad(circuit_full, argnum=0)
# Compute gradients for all double excitations.
# We initialize the parameter values to zero such that
# the gradients are computed with respect to the Hartree-Fock state.
params = [0.] * len(doubles)
grads = circuit_gradient(params, number_qubits, excitations=doubles)
for i in range(len(doubles)):
print(f'Excitation : {doubles[i]}, Gradient: {grads[i]}')
Thank you for the fixes. It works very well.
Expected behavior
As part of a custom VQE implementation, I am calculating some gradients. The provided source code works up to
pennylane==0.26
Output:
Actual behavior
Using
pennylane==0.28
(same for 0.27), the example outputs:and throws an error (see below).
Additional information
No response
Source code
Tracebacks
System information
Existing GitHub issues