Problems trying to plot the classical Fisher information with Pennylane

I'm working with pennylane. My goal is to plot CFI(Classical Fisher Information)with following quantum state.

With the above equation I set gamma as 0. Then It becomes:

If gamma is not equal to zero, it needs to be normalized like: sqrt(coeff_0_state^2 + coeff_1_state^2)

So, I expect to get following plot.

The red line is the correct result when gamma = 0

But I got following

With the following code:

import pennylane as qml
import scipy as sp
from pennylane import numpy as np
from pennylane import math as m
import matplotlib.pyplot as plt

# Variable for plot
N = 1000
tau_CFI = np.linspace(-0.001, 3.0, N)

# == Generate coeff ==
def With_norm(theta, gamma):
coeff = np.array([ ((1+np.exp(-1.j * theta))/2) * (np.sqrt(1-gamma)) , (1-np.exp(-1.j * theta))/2 ]) / (1-gamma * (np.cos(theta)**2) )

norm = np.linalg.norm(coeff)
# norm_sp = sp.linalg.norm(coeff)
# norm_new = qml.math.sqrt(qml.math.real(coeff[0])**2 + qml.math.imag(coeff[0])**2 + qml.math.real(coeff[1])**2 + qml.math.imag(coeff[1])**2)

# print(norm_new == norm)
# return norm
return coeff / norm

def Without_norm(theta):
gamma = 0
coeff = np.array([ ((1+np.exp(-1.j * theta))/2) * (np.sqrt(1-gamma)) , (1-np.exp(-1.j * theta))/2 ]) / (1-gamma * (np.cos(theta)**2) )

norm_new = qml.math.sqrt(qml.math.real(coeff[0])**2 + qml.math.imag(coeff[0])**2 + qml.math.real(coeff[1])**2 + qml.math.imag(coeff[1])**2)
# norm = np.linalg.norm(coeff)
norm = 1

return coeff / norm

# With_norm(np.pi,0)

# == Generate Q_node ==

dev_with_norm = qml.device('default.qubit', wires = 1)
@qml.qnode(dev_with_norm)
def circuit_with_norm(theta):

qml.QubitStateVector(With_norm(theta, 0), wires=range(1))

return qml.probs()
# return qml.density_matrix(wires=0)

dev_without = qml.device('default.qubit', wires = 1)
@qml.qnode(dev_without)
def circuit_without(theta):

qml.QubitStateVector(Without_norm(theta), wires=range(1))

return qml.probs()
# return qml.density_matrix(wires=0)

# circuit_without(np.pi/2)

# == Compare with CFI plot ==
N = 1000
tau_CFI = np.linspace(-0.001, 3.0, N)

CFI_without = np.zeros(N)
CFI_with = np.zeros(N)

for i in range(len(tau_CFI)):
CFI_with[i] = qml.qinfo.classical_fisher(circuit_with_norm)(tau_CFI[i])
CFI_without[i] = qml.qinfo.classical_fisher(circuit_without)(tau_CFI[i])

plt.subplot(211)
plt.plot(tau_CFI, CFI_with)
plt.title('With normalized')
plt.xlabel('Time')
plt.ylabel('Probability_0_state')
# plt.legend()
plt.grid()

print('== print out CFI ==')
plt.subplot(212)
plt.plot(tau_CFI, CFI_without)
plt.title('Without normalized')
plt.xlabel('Time')
plt.ylabel('Probability_0_state')
plt.grid()



'With_normalized' I calculate the state vector coefficient with 'np.linalg.norm' for normalization. And 'Without_normalized' I normalized the coefficient just by dividing with constant 1.

Since gamma = 0 they should be made the same result. But I don't know why the result of the CFI which is normalized by 'np.linalg.norm' shows different.(It should be constant 1)

• Just to be sure, the expected output is a constant 1, as is the case for the without case? Looks like there is a problem in tracing the gradient through np.linalg.norm. Commented Aug 31, 2023 at 14:56
There seems to be a bug in classical_fisher in combination with np.linalg.norm. I opened an issue here, should be resolved soon (fingers crossed). For the meantime I suggest you use np.sqrt(np.sum(np.abs(coeffs)**2)), this works as expected.