Issue using jagged array as input when training

When running opt.step_and_cost on a circuit which takes an jagged array as input ( where the input is a list of unitary matrices of different sizes), I am getting the following error: ValueError: array is not broadcastable to correct shape. To have the unitary matrices in the circuit, I am using qml.QubitUnitary. Why is this happening?

Hey @Mushahid_Khan! Welcome to the forum :rocket:!

Are you able to share your code that reproduces that error? It will help me point out what’s happening and show you how to correct it :slight_smile:

Hi here is the code :slight_smile: Sorry i don’t know how to upload the code as code here. Its showing it as just text without proper indendentation.

Here mps_unitaries is a list of unitary matrices:

dev = qml.device(“default.qubit”, wires=16)
@qml.qnode(dev)
def circuit(weights):
for wire in range(15):
unitary = mps_unitaries[wire]
n_qubits = int(np.log2(unitary.shape[0]))
u_wires = [wire] + list(range(wire+1, wire+16))
qml.QubitUnitary(unitary, wires=u_wires)

return qml.probs(wires=range(n_wires))

Thank you so much

Hey @Mushahid_Khan, thanks for the reply! I need your entire code in order to try to replicate your error and attempt to provide a fix :grin:. There are lots of parts missing (e.g., the function mps_unitaries). Are you able to provide the full code that produces the error you’re getting?

Hi I dont have access to those methods, but to put simply, mps_unitaries is an array filled with unitaries U that we see on the circuit. They are unitaries of different shape ranging from 4 by 4 to 32 by 32.

Are you optimizing circuit? If so, weights isn’t getting called, which is what I assume you want to differentiate over :thinking:.

Anyway, there’s a lot missing besides mps_unitaries, like your optimization steps, the definition of weights, etc. I’ll need to see everything to try and replicate your error :). Since you don’t have access to mps_unitaries, can you adapt your code to try and reproduce the error from this:

import pennylane as qml
from pennylane import numpy as np

n_wires = 5

dev = qml.device("default.qubit", wires=n_wires)

mat = qml.RX.compute_matrix(np.pi/4)
num_unitaries = 4
random_wires = np.random.randint(2, 5, size=num_unitaries)

unitaries = []

for i in range(num_unitaries):
    num_wires = random_wires[i]
    tmp = mat # accumulate tensor products here

    for w in range(num_wires - 1):
        tmp = np.kron(tmp, mat)
    
    unitaries.append(tmp)

@qml.qnode(dev)
def circuit():
    for u, w in zip(unitaries, random_wires):
        qml.QubitUnitary(u, wires=range(w))

    return qml.probs(wires=range(n_wires))

Here, all I’m doing is inserting a bunch of RX gate unitaries as a substitute for mps_unitaries, although I’m not 100% sure if the intention is true to what you’re trying to accomplish.