Mid Circuit Measurement in PennyLane

So I am trying to understand how to do mid circuit measurements. I dont have so much an error in my code but rather that I cant make something work.
As an example here is a simple preperation of a bell state:

import pennylane as qml

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

@qml.qnode(device=dev)
def func(x):
    qml.Hadamard(0)
    qml.CNOT(wires=[0,1])
    return qml.state()

I would like to perform a measurement of qubit 0 for example, save that measurement and then continue operating on my circuit. I have tried using the qml.measure method, also together with the conditional method qml.cond(qml.measure(0), qml.Identity)(1), but apparently, although the conditional gate is shown in the circuit, the qml.state() that is returned is still in the bell state and not a collapsed state, as it should be due to the measurement.

I have also tried using qml.Projector in order to avoid measuring but that also didnt Project the qubit into the state i desired.

I would really appreciate if someone could explain to me how i can measure a qubit in the middle of a circuit and store the measured value in pennylane. As said the methods i found didnt seem to collapse the wavefunction, so i believe they didnt really measure the qubit.

Thank you very much

Hey @CLEconomides! Welcome to the forum :muscle:

I think you found a bug :bug:! Speaking to some folks internally, it looks like this is a non-trivial one to fix. That said, can you create an issue on our Github repo? Our dev team will look at the requirements to fix it, and if there is a good fix we will work on implementing it (or you can too :nerd_face:).

In the mean time, it probably makes sense for you to return qml.density_matrix instead of qml.state. Let me know if that works as a temporary workaround :slight_smile:

Hi Isaac, thank you for your quick reply!!
when using again the circuit:
dev = qml.device(‘default.qubit’, wires=2)
@qml.qnode(device=dev)
def func():
qml.Hadamard(0)
qml.CNOT(wires=[0,1])
qml.measure(wires=0)
return qml.density_matrix(wires=1)

the density matrix p = [[0.5+0.j 0. +0.j], [0. +0.j 0.5+0.j]] of qubit 1 is still wrong because it give it a 50% chance to be 0 or 1. While we should know, due to the measurement in qubit 0, what qubit 1 should be. Also the qml.probs() method didnt work either.

From your post yesterday i understood that you thought it was a bug of the qml.state() method (since you suggested i could try the density matrix). I personally (without much knowledge of Computer Science as a physicist) believe that it is a bug of qml.measure if it is a bug.

I will also post it on the Pennylane Github.

1 Like

This turned out to be a very valuable forum post @CLEconomides! The alternative I gave you indeed won’t work upon further inspection :frowning_face:. I was going to propose another workaround where you just return 4 projector expectation values:

    return [qml.expval(qml.Projector(states[i], wires=[0, 1])) for i in range(4)]

however, this doesn’t work either! It will work if there is one projector expectation value returned, but not multiple. There’s a gap in coverage with our new QNode return system and qml.Projector, evidently. This warrants another issue to be made — I took care of that one :slight_smile:

Outside of creating four QNodes that use the same quantum function but have four different returns, I’m not sure there’s an immediate alternative :sweat:. Our team will try to figure this out for you and update you as we make progress :raised_hands:

I’ve just encountered exactly the same problem…
Has this problem been fixed?

Hi @3157974051, welcome to the Forum!

Can you please post the output for qml.about()? I’m not sure whether this particular issue has been fixed but I do know that we’ve made improvements to mid-circuit measurements so the first step is to make sure you have the latest PennyLane version. :smiley:

Hi @3157974051 and @CLEconomides,

This issue is no longer present in default.qubit or lightning.qubit :raised_hands: .
However it will still occur on any device that relies on split_non_commuting .

Please let us know if you’re still facing issues with this!