Take the following simple quantum function:
def my_quantum_function(params, wires=None):
for i in range(wires):
random_rot = params[i]
qml.RY(random_rot, wires=i)
qml.broadcast(qml.CZ, wires=range(wires), pattern="chain")
return qml.expval(qml.PauliZ(0))
Let’s say I want to make QNode objects using this function for wires=2 and wires=3. My understanding is that I can either leave the function as it is and write,
params = [np.random.uniform(0, 2*np.pi) for _ in range(wires)]
dev1 = qml.device("default.qubit", wires=2)
circuit1 = qml.QNode(my_quantum_function, dev1)
result1 = circuit1(params, wires=2)
dev2 = qml.device("default.qubit", wires=3)
circuit2 = qml.QNode(my_quantum_function, dev2)
result2 = circuit2(params, wires=3)
or, I can make two copies of the function and use the QNode decorator:
dev1 = qml.device("default.qubit", wires=2)
dev2 = qml.device("default.qubit", wires=2)
@qml.qnode(dev1)
def circuit1(params):
wires = 2
for i in range(wires):
random_rot = params[i]
qml.RY(random_rot, wires=i)
qml.broadcast(qml.CZ, wires=range(wires), pattern="chain")
return qml.expval(qml.PauliZ(0))
@qml.qnode(dev2)
def circuit2(params):
wires = 3
for i in range(wires):
random_rot = params[i]
qml.RY(random_rot, wires=i)
qml.broadcast(qml.CZ, wires=range(wires), pattern="chain")
return qml.expval(qml.PauliZ(0))
params = [np.random.uniform(0, 2*np.pi) for _ in range(wires)]
result1 = circuit1(params)
result2 = circuit2(params)
Fair enough. But let’s say I wanted to create QNode objects using this function for wires=2,3,4,…,20. What is the most idiomatic way to do this? I know QNodes collections is a way to define families of QNodes, but this still requires explicitly defining all N devices you need, which doesn’t end up saving any time, it seems. Right now what I’m doing is using the top function I gave and a for-loop, defining a new device/QNode on each iteration:
n_wires = [i+2 for i in range(19)]
for n in n_wires:
params = [np.random.uniform(0, 2*np.pi) for _ in range(n)]
dev = qml.device("default.qubit", wires=n)
circuit = qml.QNode(my_quantum_function, dev)
result = circuit(thetas, wires=n)
...
# Do some computations
...
Using the QNode decorator is the recommended approach, and QNodes can be set to mutable, but I can’t find an example in the documentation where you can adjust the number of wires on the fly. Maybe there isn’t a more elegant way to do this, but I thought I would ask!