Measuring purity of a quantum state

I’m trying to measure the purity of an input quantum state p (ie. Tr(p^2)). According to this stack overflow post, we just prepare 2 copies of the input state and perform the swap operation on them, then measure the output. So this is the code I’ve come up with:

However, pennylane doesn’t seem to support the SWAP operator as an observable. How should I do the measurement at the end of the circuit?

Hi @jkwan314 ,

I think you have a confusion between the state and the density matrix of the state. The purity is the trace of the density matrix squared. And you also have the following relationship where a is the vector representing the quantum state.
image

Maybe something like the following code is what you’re looking for.

import pennylane as qml
from pennylane import numpy as np

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

@qml.qnode(dev)
def circuit():
    qml.Hadamard(wires=0)
    qml.CNOT(wires=[0, 1])
    qml.BitFlip(0.2, wires=0)
    return qml.state()

state = circuit()
print("State: ",state)

purity = 0.5+0.5*np.linalg.norm(state)**2

print(f"Purity = {purity:.4f}")

If you comment the qml.BitFlip line you will notice that the purity becomes 1.

Is this what you were looking for?

Hi @CatalinaAlbornoz ,

Thanks for your reply. I was just a bit confused about the implementation of the circuit. If a is the vector representing the quantum state, then why do we need to perform the CNOT and the BitFlip? Also, could I get a source for the equation you posted above?

Hi @jkwan314 ,

You can find the equation in Wikipedia.

We actually released version 0.28 of PennyLane yesterday and it includes a Purity transform :grinning:. You can learn more about it in our release blog.

This transform creates a function that can be used to find the purity of your state.

This is how the code would look:

# Create a default.mixed device
dev = qml.device("default.mixed", wires=2)

# Create a qnode
@qml.qnode(dev)
def noisy_circuit(p):
    # Add some gates
    qml.Hadamard(wires=0)
    qml.CNOT(wires=[0, 1])
    # Add some noise (optional)
    qml.BitFlip(p, wires=0)
    # Return the state of the system
    return qml.state()

# Use the purity transform to calculate the purity for a specific value of the parameter p.
qml.qinfo.transforms.purity(noisy_circuit, wires=[0, 1])(0.2) # In this case p=0.2

Let me describe the code step by step:
1 - You need to use the default.mixed device because you will be working with mixed states. If they were all pure then the purity would always be 1 and you wouldn’t need to calculate it.
2 - You create a qnode. All of your qubits start in the |0⟩ state so you need to add some gates to change the state.
3 - If you want a pure state you don’t add any noise. However if you add noise such as BitFlip then the purity will no longer be 1.
4 - You need to return the state of the circuit. This means that you’re not measuring, you’re getting the state.
5 - The purity transform takes your qnode and computes the purity of a sub-system from a given state. To find the purity of the overall state, we include all wires in the wires argument. Then we apply this transform to a specific value of the parameter(s), which in this case is 0.2.

Please let me know if this is clearer or if you have any further questions!

1 Like

Hi @CatalinaAlbornoz , do you know if this purity function has been added to the latest version of pennylane on the xanadu quantum codebook? I can’t seem to use it…

Hi @jkwan314 ,

I’m not being able to replicate your error. The codebook is in fact using the latest version of PennyLane. You don’t need to use the purity function though, but it shouldn’t pop up this error. Do you still see this error? And if so, on what node? And using what code?

1 Like

Never mind, it works on my end now! Must have been updated sometime in between your response and my question.

I’m glad it works now @jkwan314 !