Optimization error

when I tried to optimize a quantum circuit using:
params = opt.step(circuit, my_init_params)

I got this error:
TypeError: Grad only applies to real scalar-output functions. Try jacobian or elementwise_grad.

what is wrong??

Hi @EMY91,

For gradient descent optimization, the function you are optimizing must be scalar-valued, that is, it must return only a single real value, for example:

@qml.qnode(dev)
def circuit(params):
    qml.RX(params[0], wires=0)
    qml.RY(params[1], wires=0)
    return qml.expval.PauliZ(0) #single value

my_init_params = [0.1, 0.2]
opt = qml.GradientDescentOptimizer()
params = opt.step(circuit, my_init_params)

If the function to be optimized is instead vector-valued (it returns more than one real value), then you will run into the issue above:

@qml.qnode(dev)
def circuit(params):
    qml.RX(params[0], wires=0)
    qml.RY(params[1], wires=0)
    return qml.expval.PauliZ(0), qml.expval.PauliX(1) #list of values

my_init_params = [0.1, 0.2]
opt = qml.GradientDescentOptimizer()
params = opt.step(circuit, my_init_params)

TypeError: Grad only applies to real scalar-output functions. Try jacobian or elementwise_grad.

So always make sure that the cost function you are optimized is scalar-valued.

1 Like

Hello, if I want to apply the gradient descent to a bell state which involves 2 wires, should I have the following code:
return qml.expval(qml.PauliZ('wire1')), qml.expval(qml.PauliZ('wire2'))

but it will contain two values. So what should I do ?

Hi @alanspace, you can construct a cost function that returns a scalar value given the two quantum outputs, that represents the quantity that you want to minimize.

So, for example, if you would like to minimize the expectation value on wire1, and maximize the expectation on wire2, you could do something like this:

def cost(weights):
    expval1, expval2 = qnode(weights)
    return expval1 - expval2