What is the difference between qml.measure and qml.PauliZ?

Hello,
qml.measure measures the qubit in the computational basis, which is the Pauli Z basis, I would say. But why do I get different results with qml.expval(op=measurement) and qml.expval(qml.PauliZ(wires=0)?
Below you can find a minimal working example:

import pennylane as qml
from pennylane import numpy as np


device = qml.device('default.qubit', wires=1)

@qml.qnode(device)
def circuit_pauli_z(params):
    qml.RX(params, wires=0)
    return qml.expval(qml.PauliZ(wires=0))


@qml.qnode(device)
def circuit_measure(params):
    qml.RX(params, wires=0)
    measurement = qml.measure(wires=0)

    return qml.expval(op=measurement)


params = 0.75 * np.pi

result_pauli_z = circuit_pauli_z(params)
result_measurement = circuit_measure(params)

print(result_pauli_z)
print(result_measurement)

which gives:

-0.7071067811865475
0.8535533905932737

From my understanding, the first result is the expected one. But what is the second output (the one from qml.measure?

Hey @nilserik! Great question.

Indeed, qml.expval(op=m0) averages over computational basis measurements (pauli Z basis), but in the 0/1 notation, not ±1 notation. You can see this with finite shots and sample:

device = qml.device('default.qubit', wires=1, shots=100)

@qml.qnode(device)
def circuit_measure():
    qml.Hadamard(0)
    measurement = qml.measure(wires=0)

    return qml.expval(op=measurement), qml.sample(measurement)

result_measurement = circuit_measure()
print(result_measurement)
(tensor(0.39, requires_grad=True), tensor([0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0,
        0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0,
        1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0,
        0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0,
        1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1], requires_grad=True))

So, to answer your question, qml.expval(qml.Z(0)) and qml.expval(op=measurement) here are the exact same thing… up to a linear transformation of multiplying by 2 and substracting one :sweat_smile:.

This could definitely be clearer in the documentation for qml.measure. I’ll make sure to make this obvious!

Hi @isaacdevlugt, thanks for your reply. This clarifies everything :grinning:!

1 Like

Another thing to say here is that qml.measure(0) and qml.Projector([1], wires=0) are similar, since qml.measure is really the |1><1| observable behind the scenes. So qml.expval(qml.measure(wire)) and qml.expval(qml.Projector([1], wire)) should be the same :slight_smile:

Here’s the PR for the docstring fix: Choice of computational basis convention for `qml.measure` is clear in its docstring by isaacdevlugt · Pull Request #5474 · PennyLaneAI/pennylane · GitHub

Cool, I really appreciate your effort! :slightly_smiling_face:

1 Like