Query regarding saving measurement probabilities

I am trying to save probability(to use it to calculate expectation value) after measuring one out of three qubits in a circuit and then performing some other operations on remaining two qubits. But can’t do that. Every time getting error message.
Example of the code that I tried is as follows:

import pennylane as qml
from pennylane import numpy as np
dev = qml.device("default.qubit", wires=3)
@qml.qnode(dev)
def func(theta):
    qml.Y(0)
    qml.RX(theta,wires=1)
    qml.RZ(theta,wires=2)
    m_0 = qml.measure([2])
    s2=qml.probs(wires=[2])
    m_1 = qml.measure([1], reset=True)
    return s2
print(func(0.8))

Error message:
ValueError: ops operation measure(wires=[1]) must occur prior to measurements. Please place earlier in the queue.
Is it not possible to measure some of the qubits in a circuit(say n out of m with n<m), use the expectation value of those measurements(on n qubits) and using rest of the qubits(m-n) for some other operations?
I came across some qml.cond command in the documentation where one can perform some operations on one qubit(say 2nd qubit) conditioned on measurement outcome of the measured qubit(say 1st qubit). But as per my requirement the operations that I need to perform on 2nd qubit do not depend on the measurement outcome from 1st qubit.
Version of Pennylane used:0.37.0(as seen after running qml.about()).

It will be really helpful if I can get some way out to resolve my issue.
Thanks in advance.

Hi @Kaushiki_Mukherjee , welcome to the Forum!

Indeed qml.probs cannot be used in the middle of the circuit. For mid-circuit measurements you should use qml.measure.

Is there a reason why you cannot use qml.probs in the return statement as shown below?

import pennylane as qml
from pennylane import numpy as np
dev = qml.device("default.qubit", wires=3)

@qml.qnode(dev)
def func(theta):
    qml.Y(0)
    qml.RX(theta,wires=1)
    qml.RZ(theta,wires=2)
    m_0 = qml.measure([2])
    m_1 = qml.measure([1], reset=True)
    return qml.probs(wires=[2])
print(func(0.8))

Alternatively you can calculate expectation values (and other measurements) directly from m_0 if you want as seen below:

import pennylane as qml
from pennylane import numpy as np
dev = qml.device("default.qubit", wires=3)

@qml.qnode(dev)
def func(theta):
    qml.Y(0)
    qml.RX(theta,wires=1)
    qml.RZ(theta,wires=2)
    m_0 = qml.measure([2])
    m_1 = qml.measure([1], reset=True)
    return (
        qml.sample(m_0), qml.expval(m_0), qml.expval(qml.Z(wires=2)), qml.probs(op=m_0), qml.counts(op=m_0),
    )
sample,expval_m0,expval_Z,probs,counts = func(0.8, shots=1000)

print('sample \n',sample,'\n expval_m0 \n',expval_m0,'\n expval_Z \n',expval_Z,'\n probs \n',probs,'\n counts \n',counts, sep='\n')

Important note

Computational basis measurements are performed using the 0, 1 convention rather than the ±1 convention. So, for example, expval(qml.measure(0)) and expval(qml.Z(0)) will give different answers.

I hope this helps!

@CatalinaAlbornoz
Thanks for your response. Actually I am trying to build circuit for RNN model(as shown in the attachment) from paper:arXiv:2012.11242. There the whole set of qubits is divided into 2 parts(n1 and n2,say). At any time step(t1,say), different operations are performed on both parts and then one of those parts(n1,say) is measured and expectation value of measurements are collected and then n1 qubits are reset. While the other set of qubits(n2), after being operated, are not measured. Instead those transformed qubits along with the reset n1 qubits are again measured at next time step t2. This is why I need the mid-circuit measurements. Can I somehow use pennylane to design any such type of circuit?
Thanks in advance.

Hi @Kaushiki_Mukherjee ,

Thank you for the additional details.

Just to clarify, if you’re looking to get expectation values it means averaging over many shots.

I made a modification to my previous code to show how it can do what you’re looking for.

If you look at the code and the circuit diagram below you’ll notice that the first qubit is measured and then reset, so you can keep applying gates to it. At the end we return the expectation value of these measurements using the 0,1 convention.

I hope this helps!

import pennylane as qml
from pennylane import numpy as np
dev = qml.device("default.qubit", wires=2)

@qml.qnode(dev)
def circuit(theta):
    # Apply gates
    qml.RX(theta,wires=0)
    qml.RZ(theta,wires=1)

    # Measure and reset first qubit
    m_0 = qml.measure([0], reset=True)

    # Apply gates
    qml.RX(theta,wires=0)
    qml.RZ(theta,wires=1)
    
    # Measure and reset first qubit
    m_1 = qml.measure([0], reset=True)

    # Apply gates
    qml.RX(theta,wires=0)
    qml.RZ(theta,wires=1)

    # Measure second qubit using 0,1 convention
    m_2 = qml.measure([1])

    # Return the expectation value for the measurements
    return qml.expval(m_0), qml.expval(m_1), qml.expval(m_2)

print(circuit(0.8))

qml.draw_mpl(circuit, style='pennylane')(0.8)

Thanks for your help. Using your code, I can now construct a part of the repetitive block of the circuit.

1 Like