qml.qinfo.transforms.relative_entropy

relative_entropy(qnode0, qnode1, wires0, wires1)[source]

Compute the relative entropy for two QNode returning a state() (a state can be a state vector or a density matrix, depending on the device) acting on quantum systems with the same size.

\[S(\rho\,\|\,\sigma)=-\text{Tr}(\rho\log\sigma)-S(\rho)=\text{Tr}(\rho\log\rho)-\text{Tr}(\rho\log\sigma) =\text{Tr}(\rho(\log\rho-\log\sigma))\]

Roughly speaking, quantum relative entropy is a measure of distinguishability between two quantum states. It is the quantum mechanical analog of relative entropy.

Parameters
  • qnode0 (QNode) – A QNode returning a state().

  • qnode1 (QNode) – A QNode returning a state().

  • wires0 (Sequence[int]) – the subsystem of the first QNode

  • wires1 (Sequence[int]) – the subsystem of the second QNode

Returns

A function that takes as input the joint arguments of the two QNodes, and returns the relative entropy from their output states.

Return type

func

Example

Consider the following QNode:

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

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

The qml.qinfo.relative_entropy transform can be used to compute the relative entropy between the output states of the QNode:

>>> relative_entropy_circuit = qml.qinfo.relative_entropy(circuit, circuit, wires0=[0], wires1=[0])

The returned function takes two tuples as input, the first being the arguments to the first QNode and the second being the arguments to the second QNode:

>>> x, y = np.array(0.4), np.array(0.6)
>>> relative_entropy_circuit((x,), (y,))
tensor(0.01775001, requires_grad=True)

This transform is fully differentiable:

def wrapper(x, y):
    return relative_entropy_circuit((x,), (y,))
>>> wrapper(x, y)
tensor(0.01775001, requires_grad=True)
>>> qml.grad(wrapper)(x, y)
(tensor(-0.16458856, requires_grad=True),
 tensor(0.16953273, requires_grad=True))