Codercise V.3.3 - Numbering partition

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

Hi!
Such a coincidence. Another user asked almost the same question.
Check the answer I gave them. Hope it helps.