I am having some issues with scipy's eigh
function returning negative eigenvalues for positive semidefinite matrices. Below is a MWE.
The hess_R
function returns a positive semidefinite matrix (it is the sum of a rank one matrix and a diagonal matrix, both with nonnegative entries).
import numpy as np
from scipy import linalg as LA
def hess_R(x):
d = len(x)
H = np.ones(d*d).reshape(d,d) / (1 - np.sum(x))**2
H = H + np.diag(1 / (x**2))
return H.astype(np.float64)
x = np.array([ 9.98510710e-02 , 9.00148922e-01 , 4.41547488e-10])
H = hess_R(x)
w,v = LA.eigh(H)
print w
The eigenvalues printed are
[ -6.74055241e-271 4.62855397e+016 5.15260753e+018]
If I replace np.float64
with np.float32
in the return statement of hess_R
I get
[ -5.42905303e+10 4.62854925e+16 5.15260506e+18]
instead, so I am guessing this is some sort of precision issue.
Is there a way to fix this? Technically I do not need to use eigh, but I think this is the underlying problem with my other errors (taking square roots of these matrices, getting NaNs, etc.)
LA.eig
instead of 'LA.eigh', I get different eigenvalues:[ 5.15260753e+18+0.j 3.22785571e+01+0.j 4.62855397e+16+0.j]
– PeacefulHess_R
function doensn't return an actual Hessian Matrix. soeigh
return false result in your case. – B. M.3.14000000e+02, 4.62855397e+16, 5.15260753e+18
withscipy.linalg.eigh
and1.06862038e+02, 4.62855397e+16, 5.15260753e+18
withnumpy.linalg.eigh
for your exampleH
(the difference might also be partly due to the loss of precision when you print out the float values inx
as strings). – ali_mnp.ones(d*d).reshape(d,d)
withnp.ones((d, d))
. – Warren Weckesser