 # Input tensor representing qubits of size 2**n_qubits for qnode function

Hey all,

I recently started using pennylane and am very excited about the QML framework it offers.

I have been trying to make a simple QML layer for which the inputs are different quantum states. So lets say we are working with two qubits I would like to put as input to the model a 2**n_qubits = **2 = 4 dimensional normalized tensor representing the quantum state.
Is there any way in which it is possible to define the qnode functions like this?

From what I have been able to do it seems necessary to input a tensor which has the same dimension as the number of qubits to represent the quantum state. If I understand correctly this would be the two dimensional tensor where for instance [1,-1] would represent the state |01>.
But then I can find no way to distinguish between the states
|phi> = 1/sqrt(2) (|00> + |01>) and |phi> = 1/sqrt(2) (|00> - |01>) which I would like to be able to do in order to mimick input an oracle function might create.

Hi @m.schalkers,

If you want to initialize the quantum circuit in a specific state, you can do so using the QubitStateVector operation. It takes as input a 2^n-dimensional array specifying the coefficients of each basis state, where n is the number of qubits you want to initialize in that state.

For example, if you wanted to initialize the a two-qubit system in the state \tfrac{1}{\sqrt{2}}(|00\rangle + |01\rangle), you can use

state = np.array([np.sqrt(2), np.sqrt(2), 0, 0])
QubitStateVector(state, wires=[0, 1])


If you want to initialize in state \tfrac{1}{\sqrt{2}}(|00\rangle - |01\rangle) you can instead use

state = np.array([np.sqrt(2), -np.sqrt(2), 0, 0])
QubitStateVector(state, wires=[0, 1])


In short, you don’t need to specify the state as a tensor, but rather as an array of coefficients. Hope that helps!

I did find the QubitStateVector function to initialize a quantum state. But my problem comes when I then try to input this created state into a qnode function (where we use this qnode function as a TorchLayer).

So I would like to do something as follows:

import pennylane as qml
from pennylane import numpy as np

dev = qml.device('default.qubit', wires = 2)

@qml.qnode(dev)
def make_State(s=None):
qml.QubitStateVector(s,wires=[0,1])
return qml.probs([0,1])

state = np.array([0.j,0.j,1+0.j,0.j])
print("printing state", state)
print("printing res of make state", made_state)

@qml.qnode(dev)
def perform_gate_on_state(s=None):
qml.CNOT(wires=[0,1])
return qml.probs([0,1])

print("printing res of perform_gate_on_state gives ", altered_state)


Where the idea is that I wish to be able to perform some quantum operations on a given quantum state \phi \in C^{2^{n\_qubits}} . Because if I am restricted to putting a quantum state of n_qubits into the function expressed as a vector x \in R^{n\_qubits} I loose information.

I hope the question is more clear now.

Hi @m.schalkers,

The two QNodes you have defined in your example code are independent. Therefore when you evaluate perform_gate_on_state() it just applies a CNOT to the default initial state of a QNode. Instead, you need to again instruct the new QNode to prepare your desired state. The following code should do the trick:

import pennylane as qml
from pennylane import numpy as np

dev = qml.device('default.qubit', wires = 2)
qml.enable_tape()

@qml.qnode(dev)
def make_state(s):
qml.QubitStateVector(s,wires=[0,1])
return qml.state()

state = [0,0,1,0]

@qml.qnode(dev)
def perform_gate_on_state(s):
qml.QubitStateVector(s, wires=[0,1])
qml.CNOT(wires=[0,1])
return qml.state()

print("output state is", altered_state)


Note that the command qml.enable_tape() is needed to return the state from the QNode. See the latest release notes for more details. Also, I’ve used a state with real coefficients in the example, but you can pass arbitrary states with complex coefficients.

Let me know if you have more questions!

1 Like

Hi @jmarrazola,

Thanks a lot, this was exactly the information I was looking for!

1 Like