My demo is to put pure states generated by single qubit rotation gates into qml.math.relative_entropy() function. According to the official script qml.math.relative_entropy — PennyLane 0.38.0 documentation, for two different pure states, the returned value should be inf. However, my demo returns me either a value or nan.
Demo is here:
import tensorflow as tf
import pennylane as qml
import numpy as np
dev = qml.device("default.qubit", wires=1)
@qml.qnode(dev)
def circuit0(theta1,theta2):
qml.RX(theta1, 0)
qml.RZ(theta2, 0)
return qml.density_matrix([0])
theta1 = np.random.uniform(0,np.pi,size=(1))
theta2 = np.random.uniform(0,2*np.pi,size=(1))
data = circuit0(theta1,theta2)
data = tf.reshape(data,[1,2,2])
for i in range(9):
theta1 = np.random.uniform(0,np.pi,size=(1))
theta2 = np.random.uniform(0,2*np.pi,size=(1))
new = circuit0(theta1,theta2)
new = tf.reshape(new,[1,2,2])
data = tf.concat([data,new],0)
for i in range(10):
for j in range(10):
print(i,j,qml.math.vn_entropy(data[i,:,:], indices=[0]),qml.math.vn_entropy(data[j,:,:], indices=[0]),qml.math.relative_entropy(data[i,:,:],data[j,:,:],check_state=True))
This is the output. As you can see the returned vn_entropy results are correct but the relative_entropy results are wrong (either nan or a number, and I deleted unneccessary results to make it easier to read)
1 0 tf.Tensor(4.5408119547162706e-15, shape=(), dtype=float64) tf.Tensor(1.1102230246251564e-16, shape=(), dtype=float64) tf.Tensor(nan, shape=(), dtype=float64)
1 1 tf.Tensor(4.5408119547162706e-15, shape=(), dtype=float64) tf.Tensor(4.5408119547162706e-15, shape=(), dtype=float64) tf.Tensor(-2.3665827156630354e-30, shape=(), dtype=float64)
1 2 tf.Tensor(4.5408119547162706e-15, shape=(), dtype=float64) tf.Tensor(8.521795631430148e-15, shape=(), dtype=float64) tf.Tensor(27.09213385576561, shape=(), dtype=float64)
1 3 tf.Tensor(4.5408119547162706e-15, shape=(), dtype=float64) tf.Tensor(-0.0, shape=(), dtype=float64) tf.Tensor(nan, shape=(), dtype=float64)
1 4 tf.Tensor(4.5408119547162706e-15, shape=(), dtype=float64) tf.Tensor(1.5581232509178702e-15, shape=(), dtype=float64) tf.Tensor(33.24765625394799, shape=(), dtype=float64)
1 5 tf.Tensor(4.5408119547162706e-15, shape=(), dtype=float64) tf.Tensor(2.2204460492503126e-16, shape=(), dtype=float64) tf.Tensor(nan, shape=(), dtype=float64)
1 6 tf.Tensor(4.5408119547162706e-15, shape=(), dtype=float64) tf.Tensor(-0.0, shape=(), dtype=float64) tf.Tensor(nan, shape=(), dtype=float64)
1 7 tf.Tensor(4.5408119547162706e-15, shape=(), dtype=float64) tf.Tensor(-2.220446049250313e-16, shape=(), dtype=float64) tf.Tensor(nan, shape=(), dtype=float64)
1 8 tf.Tensor(4.5408119547162706e-15, shape=(), dtype=float64) tf.Tensor(-2.220446049250313e-16, shape=(), dtype=float64) tf.Tensor(nan, shape=(), dtype=float64)
1 9 tf.Tensor(4.5408119547162706e-15, shape=(), dtype=float64) tf.Tensor(-0.0, shape=(), dtype=float64) tf.Tensor(nan, shape=(), dtype=float64)
qml.about() outputs are
Name: PennyLane
Version: 0.37.0
Summary: PennyLane is a cross-platform Python library for quantum computing, quantum machine learning, and quantum chemistry. Train a quantum computer the same way as a neural network.
Home-page: https://github.com/PennyLaneAI/pennylane
Author:
Author-email:
License: Apache License 2.0
Location: /root/miniconda3/envs/tc/lib/python3.9/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, packaging, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml, typing-extensions
Required-by: PennyLane_Lightning
Platform info: Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.35
Python version: 3.9.18
Numpy version: 1.24.3
Scipy version: 1.13.1
Installed devices:
- default.clifford (PennyLane-0.37.0)
- default.gaussian (PennyLane-0.37.0)
- default.mixed (PennyLane-0.37.0)
- default.qubit (PennyLane-0.37.0)
- default.qubit.autograd (PennyLane-0.37.0)
- default.qubit.jax (PennyLane-0.37.0)
- default.qubit.legacy (PennyLane-0.37.0)
- default.qubit.tf (PennyLane-0.37.0)
- default.qubit.torch (PennyLane-0.37.0)
- default.qutrit (PennyLane-0.37.0)
- default.qutrit.mixed (PennyLane-0.37.0)
- default.tensor (PennyLane-0.37.0)
- null.qubit (PennyLane-0.37.0)
- lightning.qubit (PennyLane-Lightning-0.37.0)
None
After looking into the source code, I find out the problem located at the ‘_compute_relative_entropy(rho, sigma, base=None)’ method in quantum.py.
The ‘qml.math.linalg.eigh()’ function returns eigenvalues either slightly bigger than zero or smaller than zero.
When the eigenvalue is smaller than zero, then after putting it into the np.log it returns nan.
When the eigenvalue is bigger than zero, then the results of np.log is a value instead of inf as it should be when the input is zero.
Hope my findings can provide some insights into this problem.