I am confused why PennyLane returns Error: Grad only applies to real scalar-output functions. Try jacobian, elementwise_grad or holomorphic_grad.
In my computer I get the solution
State |01110>: Probability 0.47365
State |01111>: Probability 0.00000
State |10000>: Probability 0.00000
State |10001>: Probability 0.47365
State |10010>: Probability 0.00008
This is my code:
numbers = [1,3,4,7,13]
total_sum = sum(numbers)
# Number of qubits needed (each number is represented by a qubit)
n_wires = len(numbers)
# Define the mixer Hamiltonian
mixer_h = qml.Hamiltonian([1.0] * n_wires, [qml.PauliX(i) for i in range(n_wires)])
dev = qml.device('default.qubit', wires=n_wires)
# Define the hyperparameters for the optimizer:
p=20
params=np.ones((p, 2),requires_grad=True) * 0.5
step_size=0.001
max_steps=150
# ------------------ QAOA Layer ------------------
def qaoa_layer(params, cost_h):
qml.qaoa.cost_layer(params[0], cost_h)
qml.qaoa.mixer_layer(params[1], mixer_h)
def qaoa_circuit(params, p, cost_h):
for w in range(n_wires):
qml.Hadamard(wires=w)
qml.layer(qaoa_layer, p, params, cost_h=cost_h)
# ------------------ QNodes ------------------
@qml.qnode(dev)
def cost_function(params, p, cost_h):
qaoa_circuit(params, p, cost_h)
return qml.expval(cost_h) # scalar output for optimization
@qml.qnode(dev)
def probability_circuit(params, p, cost_h):
qaoa_circuit(params, p, cost_h)
return qml.probs(wires=range(n_wires)) # vector output for final result
# -------------------------------------------
def build_cost_number_partition(numbers):
"""Function to build the cost Hamiltonian of a number partition problem.
Args:
numbers (list): A list with the numbers we want to divide in two groups with equal sums.
Returns:
(qml.Hamiltonian): The cost Hamiltonian of the number partition problem
"""
##################
# YOUR CODE HERE #
##################
k = len(numbers)
coeffs = []
observables = []
for i in range(k):
for j in range(k):
coeffs.append(numbers[i] * numbers[j])
observables.append(qml.PauliZ(i) @ qml.PauliZ(j))
return qml.Hamiltonian(coeffs, observables)
cost_h = build_cost_number_partition(numbers)
def optimizer_number_partition(params,p,step_size,max_steps,cost_h):
"""Optimizer to adjust the parameters.
Args:
params (np.array): An array with the trainable parameters of the QAOA ansatz.
p (int): Number of layers of the QAOA ansatz.
step_size (float): Learning rate of the gradient descent optimizer
max_steps (int): Number of iterations of the optimizer.
cost_h (qml.Hamiltonian): The cost Hamiltonian.
Returns:
(np.array): An array with the optimized parameters of the QAOA ansatz.
"""
optimizer = qml.AdamOptimizer(step_size)
for _ in range(max_steps):
params, _,_ = optimizer.step(cost_function, params,p,cost_h)
return params
def QAOA_number_partition(params,p,step_size,max_steps,cost_h):
"""QAOA Algorithm to solve the number partition problem.
Args:
params (np.array): An array with the trainable parameters of the QAOA ansatz.
p (int): Number of layers of the QAOA ansatz.
step_size (float): Learning rate of the gradient descent optimizer
max_steps (int): Number of iterations of the optimizer.
cost_h (qml.Hamiltonian): The cost Hamiltonian.
Returns:
(np.tensor): A tensor with the final probabilities of measuring the quantum states.
(np.array): The optimized parameters of the QAOA.
"""
##################
# YOUR CODE HERE #
##################
best_params = optimizer_number_partition(params, p, step_size, max_steps, cost_h)
probs = probability_circuit(best_params, p, cost_h)
return probs, best_params
Any help. it is greatly appreciated