From linear algebra we know that the eigenvectors of any symmetric matrix (let's call it A
) are orthonormal, meaning if M
is the matrix of all eigenvectors, we should obtain |det(M)| = 1
. I had hoped to see this in numpy.linalg.eig
, but got the following behaviour:
import numpy as np
def get_det(A, func, decimals=12):
eigenvectors = func(A)[1]
return np.round(np.absolute(np.linalg.det(eigenvectors)), decimals=decimals)
n = 100
x = np.meshgrid(* 2 * [np.linspace(0, 2 * np.pi, n)])
A = np.sin(x[0]) + np.sin(x[1])
A += A.T # This step is redundant; just to convince everyone that it's symmetric
print(get_det(A, np.linalg.eigh), get_det(A, np.linalg.eig))
Output
>>> 1.0 0.0
As you can see, numpy.linalg.eigh
gives the correct result, while numpy.linalg.eig
apparently returns a near non-invertible matrix. I presume that it comes from the fact that it has a degenerate eigenvalue (which is 0 in this case) and the corresponding eigenspace is not orthonormal and therefore the total determinant is not 1. In the following example, where there's (usually) no degenerate eigenvalue, the results are indeed the same:
import numpy as np
n = 100
A = np.random.randn(n, n)
A += A.T
print(get_det(A, np.linalg.eigh), get_det(A, np.linalg.eig))
Output
>>> 1.0 1.0
Now, regardless of whether my guess was correct or not (i.e. the difference between eig
and eigh
comes from the degeneracy of the eigenvalues), I would like to know if there is a way to get a full dimensional eigenvector matrix (i.e. the one that maximises the determinant) using numpy.linalg.eig
, because I'm now working with a near-symmetric matrix, but not entirely symmetric, and it gives me a lot of problems if the eigenvector matrix is not invertible. Thank you for your help in advance!