Opt.step() function is not changing

Hello, I want to optimize a cost function that takes de distance between two desity matrices, one of them being the result of a circuit. But using np.linalg.norm() seems not to work correctly, since the opt.step() function gives me the same parameter at each step:

import pennylane as qml
from pennylane import numpy as np

@qml.qnode(device, interface="autograd")

def circuit(params):
    qml.Barrier(wires = range(4))
    qml.Barrier(wires = range(4))
    return qml.density_matrix(wires=range(4))

def cost_func(params):
    densityMatrix = circuit(params)
    fidelity = np.linalg.norm(np.array(densityMatrix-((1/16.)*(np.identity(16))), dtype=float))
    return fidelity

The optimization is

init_params = np.array([np.pi/2,5,0], requires_grad=True)
opt = qml.GradientDescentOptimizer(stepsize=0.05)

steps = 5
params = init_params 

for i in range(steps):
    params = opt.step(cost,params)
    print(params, cost(params))

As you can check the print() shows the same parameters. This also happens for different initial conditions, and different steps, and also if a define my norm function manually. What could be the problem here? Thanks in advance.

Hi @Krys, thank you for your question.

I think your optimization landscape in this case is just very flat. If you try for example using the Adam optimizer you notice that it does try to optimize something but doesn’t manage to do much.

opt = qml.AdamOptimizer()

And if you print the value of the fidelity for very different values of the parameters you see that the fidelity is almost the same.

v_params = [[-np.pi/2,5.0,0.0],[-np.pi/2,5.0,-1.0],[np.pi/2,5.0,-0.01],[np.pi/2,-5.0,0.0]]
res = [qml.math.fidelity(circuit(params),((1/16.)*(np.identity(16)))) for params in v_params]

So I’d say that the issue is in the circuit itself or the cost function. You can explore alternatives to how to make your cost function less flat.

I hope this can help you!