PennyLane Challenge: Keeping expectations low

Use this topic to ask your questions about the PennyLane Challenge: Keeping expectations low.

I am stuck in this. Here is my implementation. I am getting error as : ```Failed to execute run() function: ‘list’ object has no attribute ‘reshape’.

Please someone help me with the optimization. This is the last question. I will miss my spring badge.

WIRES = 2
LAYERS = 5
NUM_PARAMETERS = LAYERS * WIRES * 3

initial_params = np.random.random(NUM_PARAMETERS)

def variational_circuit(params,hamiltonian):

This is a template variational quantum circuit containing a fixed layout of gates with variable
parameters. To be used as a QNode, it must either be wrapped with the @qml.qnode decorator or
converted using the qml.QNode function.

The output of this circuit is the expectation value of a Hamiltonian, somehow encoded in
the hamiltonian argument

Args:
    - params (np.ndarray): An array of optimizable parameters of shape (30,)
    - hamiltonian (np.ndarray): An array of real parameters encoding the Hamiltonian
    whose expectation value is returned.

Returns:
    (float): The expectation value of the Hamiltonian

parameters = params.reshape((LAYERS, WIRES, 3))
qml.templates.StronglyEntanglingLayers(parameters, wires=range(WIRES))
return qml.expval(qml.Hermitian(hamiltonian, wires = [0,1]))

def optimize_circuit(params,hamiltonian):
Minimize the variational circuit and return its minimum value.
You should create a device and convert the variational_circuit function
into an executable QNode.
Next, you should minimize the variational circuit using gradient-based
optimization to update the input params.
Return the optimized value of the QNode as a single floating-point number.

Args:
    - params (np.ndarray): Input parameters to be optimized, of dimension 30
    - hamiltonian (np.ndarray): An array of real parameters encoding the Hamiltonian
    whose expectation value you should minimize.
Returns:
    float: the value of the optimized QNode




dev = qml.device('default.qubit', wires=2) # Initialize the device.

circuit = qml.QNode(variational_circuit, dev) # Instantiate the QNode from variational_circuit.

I_PARAM = params # Initial guess parameters
store_params = np.array([params]) # Store the values of the circuit parameter
cost = [circuit(params,hamiltonian)] # Store the values of the cost function



opt = qml.GradientDescentOptimizer() # Our optimizer!
max_iterations = 100 # Maximum number of calls to the optimizer 
conv_tol = 0.01 # Convergence threshold to stop our optimization procedure

for n in range(max_iterations):
    I_PARAM, prev_cost = opt.step_and_cost(circuit, I_PARAM,hamiltonian)
    cost.append(circuit(I_PARAM,hamiltonian))
    store_params.append(I_PARAM)

    conv = np.abs(cost[-1] - prev_cost)

    if conv <= conv_tol:
        break

return circuit(store_param[-1],hamiltonian) # Return the value of the minimized QNode

Hi @Dhawal_Verma, were you able to solve your issue before the deadline? I can tell that the way you’re handling the parameters might cause issues. Were you able to figure out the source of your problem?

No. I couldn’t solve the problem. The deadline is passed. I missed the badge. :sob::sob::sob:. But anyway want to learn. Can you please tell me the mistake? The updated params are in list, but it need to be np.array. I also changed it but it’s not working.

Hi @Dhawal_Verma,

I’m sorry to hear you weren’t able to get the badge. But don’t worry, other badges will come in the future!

Actually several changes are needed in your code. store_params doesn’t need to be an np.array. This will cause errors to show up.

I see other issues in your optimization loop. Basically you’re using a very basic optimization method that’s converging very slowly and it can’t get to the desired answer quickly. You will need to change the optimizer or the stepsize, plus increase the maximum number of iterations, and reduce the tolerance to about 1e-7.

Finally, there’s a very important thing to learn when using step_and_cost. The first output is actually a list containing all of the arguments of your cost function, which in this case is circuit. So the way to obtain the new iteration for the parameters is actually as shown below.

[I_PARAM,hamiltonian], prev_cost = opt.step_and_cost(circuit, I_PARAM,hamiltonian) 

Now with all of these changes you should be able to solve the challenge. I hope this helps!