Entanglement entropy

I want to calculate entanglement entropy of a quantum circuit (6 qubits) , please help with the code

@CatalinaAlbornoz

Hi @VQX,

You can use qml.math.vn_entropy to compute the Von Neumann entropy from a state vector or density matrix on a given subsystem.

You can also use qml.qinfo.transforms.vn_entropy to compute the Von Neumann entropy from a QNode returning a state().

I’m not sure whether or not this calculates what you need so please make sure to check the documentation for each function in detail to make sure.

1 Like

Hello,
Make follow from here: How make compute Fidelity, Entangling power and Expresibility? · Issue #4182 · PennyLaneAI/pennylane · GitHub
How can make entropy value when returning expectation values?
Thanks you!

Hey @wing_chen! Welcome to the forum :muscle:

How can make entropy value when returning expectation values?

You can calculate the entropy of a subsystem from transforming a QNode returning a state:

import pennylane as qml

dev = qml.device("default.qubit", wires=2)
@qml.qnode(dev)
def circuit(x):
    qml.IsingXX(x, wires=[0, 1])
    return qml.state()

print(qml.qinfo.vn_entropy(circuit, wires=[0])(np.pi/2))
# 0.6931472

But I return expectation value during training, want to save entropy value with the PQC parameters when training terminates.

In that case, you can create separate QNodes that evaluate both like this:

import pennylane as qml

def circuit(x):
    qml.IsingXX(x, wires=[0, 1])

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

@qml.qnode(dev)
def circuit_state(x):
    circuit(x)
    return qml.state()

@qml.qnode(dev)
def circuit_expval(x):
    circuit(x)
    return qml.expval(qml.PauliZ(0))

vn = lambda x, wires : qml.qinfo.vn_entropy(circuit_state, wires=wires)(x)

print(circuit_state(0.1))
print(circuit_expval(0.1))
print(vn(0.1, [0]))

'''
[0.99875026+0.j         0.        +0.j         0.        +0.j
 0.        -0.04997917j]
0.9950041652780258
0.017463060045757477
'''

So I need to run two circuit during QNN training? I really do not understand.

HI @wing_chen! Yes as Isaac pointed out above, you’ll need two versions of the same circuit if you also want the expectation values. The reason is that qml.qinfo.vn_entropy can only act on circuits that return qml.state, but you can’t return the state and the expectation value at the same time in a single circuit. Feel free to give us more details on what you’re trying to do so we can help you further!

I want make record of entropy during training of circle in the transfer learning model for differenr ciruits.

Hi @wing_chen,

I’m not sure whether this will work or not but maybe you can try taking a snapshot right before the measurement. This way you will have the state and you can use qml.math.vn_entropy().

I recommend that you try this for a tiny example first. Let me know if it works!

Hello, if you use a 4 qubit quantum circuit and use von Neumann entropy to evaluate entanglement, and the dividing point is 2, what should be the upper limit of the obtained von Neumann entropy value?

import pennylane as qml
from pennylane import numpy as np

def circuit6(weights, wires):
  qml.RY(weights[0], wires=wires[0])
  qml.RY(weights[1], wires=wires[1])
  qml.RY(weights[2], wires=wires[2])
  qml.RY(weights[3], wires=wires[3])

  qml.CNOT(wires=[wires[0], wires[1]])
  qml.CNOT(wires=[wires[1], wires[2]])
  qml.CNOT(wires=[wires[2], wires[3]])
  qml.CNOT(wires=[wires[3], wires[0]])

def von_neumann_entropy(rho):
    """Calculate the Von Neumann entropy of a density matrix."""
    eigvals = np.linalg.eigvalsh(rho)
    offset = np.finfo(float).eps
    return -np.sum(eigvals * np.log2(np.maximum(eigvals, offset)))

def evaluate_circuit_entanglement(num_wires, num_runs, circuit):
    """Evaluate the average entanglement entropy of a circuit."""
    dev = qml.device("default.qubit", wires=num_wires)

    total_entanglement = []
    for _ in range(num_runs):
        weights = np.random.uniform(0, 2 * np.pi, 4)  # Adjust size as necessary

        @qml.qnode(dev)
        def entanglement_qnode(weights):
            circuit(weights, wires=range(num_wires))
            return qml.density_matrix(range(num_wires // 2)) # Only consider middle split

        rho = entanglement_qnode(weights)
        entanglement = von_neumann_entropy(rho)
        total_entanglement.append(entanglement)

    return np.mean(total_entanglement), np.std(total_entanglement)

# Example usage
average_entanglement, std_deviation = evaluate_circuit_entanglement(4, 100, circuit6)
print(f"Average entanglement: {average_entanglement}, Standard Deviation: {std_deviation}")

Hey @zj-lucky! Welcome back :slight_smile:

If you partially trace out a 2-qubit subsystem and evaluate the VN entropy, the extreme cases are:

  • Maximum entanglement: if the two parts of your bipartite system are maximally entangled with their compliments, then when you partially trace out one subsystem the resulting density operator will be a multiple of the identity. This results in:
\begin{align*} \rho &= \frac{1}{2^N} \mathbb{I} \\ S(\rho) &= -\text{Tr}(\rho \log \rho) \\ &= -\text{Tr}\left(\frac{1}{2^N} \mathbb{I} \log\left(\frac{1}{2^N} \mathbb{I} \right)\right) \\ &= -\sum_{i = 1}^{2^N} \frac{1}{2^N} \log \frac{1}{2^N} \\ &= -\log \frac{1}{2^N} \\ &= N \log 2 \\ \end{align*}
  • Pure states: if the state is pure, then the VN entropy will be equal to 0 (you try!)

Hope this helps :slight_smile:

1 Like