4

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!

sams-studio
  • 631
  • 3
  • 10

1 Answers1

0

To find the linearly independent eigenvectors, you could try Matrix.rref() which specifies the reduced row-echelon form of the matrix formed by eigenvectors.

Consider a matrix which is not diagonalizable, i.e., its eigenspace is not full rank

array([[0., 1., 0.],
       [0., 0., 1.],
       [0., 0., 0.]])

We can find its linearly independent eigenvectors using rref()

A = np.diag(np.ones(2), 1) 
v = np.linalg.eig(A)[1]
result = sympy.Matrix(np.round(v, decimals=100)).rref()
v[:, result[1]]

which returns

array([[1.],
       [0.],
       [0.]])

See also: python built-in function to do matrix reduction

Find a linearly independent set of vectors that spans the same substance of R^3 as that spanned

Lorry
  • 382
  • 2
  • 7