Multiple amplitude encoding in one circuit and printing the expectation value

Hi, I am trying to encode two different quantum states to two different set of qubits in Pennylane circuit using @merge_amplitude_embedding. My code is the following:

import pennylane as qml
from pennylane.templates.embeddings import AmplitudeEmbedding
from pennylane.transforms import merge_amplitude_embedding

def Outcome(params):
@merge_amplitude_embedding
def qfunc(params):

    qml.AmplitudeEmbedding([0,1,0,0], wires = [0,1])
    qml.AmplitudeEmbedding([0,1], wires = 2)
    
    qml.RX(params[0], wires=0)
    qml.IsingXX(params[1], wires=[0,1])

    
    return qml.probs(wires = 1)

dev = qml.device("default.qubit", wires = 3)
qnode = qml.QNode(qfunc(params), dev)
qnode()
print(qnode)

x = Outcome([0.5, 0.3])
print(x)

When I run it, I get the following error:

Traceback (most recent call last):
File “/home/sreetama/Downloads/QCNN-main/symmetric_QCNN/RGB/merge_encoding_test.py”, line 23, in
x = Outcome([0.5, 0.3])
File “/home/sreetama/Downloads/QCNN-main/symmetric_QCNN/RGB/merge_encoding_test.py”, line 19, in Outcome
qnode = qml.QNode(qfunc(params), dev)
File “/home/sreetama/anaconda3/lib/python3.9/site-packages/pennylane/qnode.py”, line 373, in init
if “shots” in inspect.signature(func).parameters:
File “/home/sreetama/anaconda3/lib/python3.9/inspect.py”, line 3111, in signature
return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
File “/home/sreetama/anaconda3/lib/python3.9/inspect.py”, line 2860, in from_callable
return _signature_from_callable(obj, sigcls=cls,
File “/home/sreetama/anaconda3/lib/python3.9/inspect.py”, line 2259, in _signature_from_callable
raise TypeError(‘{!r} is not a callable object’.format(obj))
TypeError: probs(wires=[1]) is not a callable object

How to eliminate it? Any help is appreciated.

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

I think there’s just a small misunderstanding regarding how wrapping works. The line

qnode = qml.QNode(qfunc(params), dev)

is problematic because qfunc is the function you want to wrap as a QNode, but you are passing in the output of qfunc given the params, which is not a function — it’s a scalar! This is at the heart of the error you’re seeing.

Here’s the solution:

import pennylane as qml
from pennylane.transforms import merge_amplitude_embedding

@merge_amplitude_embedding
def qfunc(params):
    qml.AmplitudeEmbedding([0,1,0,0], wires = [0,1])
    qml.AmplitudeEmbedding([0,1], wires = 2)
    qml.RX(params[0], wires=0)
    qml.IsingXX(params[1], wires=[0,1])
    return qml.probs(wires = [1])

dev = qml.device("default.qubit", wires = 3)
qnode = qml.QNode(qfunc, dev)
print(qnode([0.5, 0.3]))
# [0.02233176 0.97766824]

Note:

qnode = qml.QNode(qfunc, dev) # qfunc is the function you want to wrap.

I should say also that you can alleviate any confusion here by decorating with @qml.qnode as well:

import pennylane as qml
from pennylane.transforms import merge_amplitude_embedding

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

@qml.qnode(dev)
@merge_amplitude_embedding
def qfunc(params):
    qml.AmplitudeEmbedding([0,1,0,0], wires = [0,1])
    qml.AmplitudeEmbedding([0,1], wires = 2)
    qml.RX(params[0], wires=0)
    qml.IsingXX(params[1], wires=[0,1])
    return qml.probs(wires = [1])

print(qnode([0.5, 0.3]))

Thank you very much, it solved my issue!

Awesome! Glad to hear :rocket: