I am trying to replace the SPSA optimizer in the VQE tutorial of pennylane by the bayesian optimizer of scikit-opimize.
When running the code below I get the error "func should return a scalar".
I think this is not actually the problem since my func, wrapped_cost
, returns a scalar which I also print. But I have no idea what the real problem is.
import pennylane as qml
from pennylane import qchem
from pennylane import numpy as np
from skopt import gp_minimize
niter_spsa = 200
true_energy = -1.136189454088
seednum=10
num_params=3
devicename="default.qubit"
#setup hamiltonian
symbols = ["H", "H"]
coordinates = np.array([0.0, 0.0, -0.6614, 0.0, 0.0, 0.6614])
h2_ham, num_qubits = qchem.molecular_hamiltonian(symbols, coordinates)
# Variational ansatz for H_2
def circuit(params, wires): #has 3 parameters
qml.BasisState(np.array([1, 1, 0, 0]), wires=wires)
for i in wires:
qml.Rot(*params[i], wires=i)
qml.CNOT(wires=[2, 3])
qml.CNOT(wires=[2, 0])
qml.CNOT(wires=[3, 1])
dev=qml.device(devicename, wires=num_qubits)
def exp_val_circuit(params):
circuit(params, range(dev.num_wires))
return qml.expval(h2_ham)
##
cost_spsa = qml.QNode(exp_val_circuit, dev)
def wrapped_cost(params): # Wrapping the cost function and flattening the parameters to be compatible with noisyopt which assumes a flat array of input parameters
return cost_spsa(np.asarray(params).reshape(num_qubits, num_params))
##callback for documentation =^intermediate_results in (3)
def callback_fn(xk):
cost_val = wrapped_cost(xk)
##set initial parameters
np.random.seed(seednum)
init_params = np.random.normal(0, np.pi, (num_qubits, 3), requires_grad=True)
params = list(init_params.copy().reshape(num_qubits * num_params)) #flatten and convert to list (func of gp_minimize takes list as input)
testlist=[i for i in range(12)]
print("Test for wrapped_cost: ",wrapped_cost(testlist), " with tensor list params: ",wrapped_cost(params))
##do optimization
res = gp_minimize(
wrapped_cost,
[(2.0,4.0),(-5.0,0.0),(-6.0,-4.0),(0.0,6.0),
(0.0,2.0),(-3.0,-2.0),(0.0,2.0),(-3.0,0.0),
(-2.0,2.0),(-4.0,0.0),(0.0,2.0),(1.0,4.0)], #search space chosen on basis of observed parameters in minimizeSPSA for seed 10
n_calls=20, #number of calls to the function to be evaluated
n_initial_points=20, #number of evaluations of the function before approximating it with base_estimator
random_state=0, #seed
verbose=True,
callback=callback_fn
)
```