Search code examples
pythonnumpyeigenvalueeigenvector

Incorrect eigenvectors but correct eigenvalues by QR algorithm with numpy of python


I made a very simple QR algorithm code that returns eigenvalues and eigenvectors. In many cases, it works well. However, in some cases, it returns incorrect eigenvectors although the eigenvalues are correct.

For example, a matrix of: [[52,30,49,28],[30,50,8,44],[49,8,46,16],[28,44,16,22]], the process returns correct eigenvalues and eigenvectors. But, in a case of: [[1,-2,0,5],[0,7,1,5],[0,4,4,0],[0,0,0,2]], it returns incorrect eigenvectors with correct eigenvalues. I checked the correct values by 'eigh' function and all the correct eigenvalues and eigenvectors are real number. So, it is not the problem of complex numbers. I cannot understand why this happens.

import numpy as np 

def process(self, mat: List[List[float]]):
    check = True
    a = mat[:]
    residual = 0.00001
    eigenValues = []
    eigenVectors = np.eye(len(mat))

    while check:
        check = False
        q, r = np.linalg.qr(a)
        a = np.dot(r, q)
        eigenVectors = np.dot(eigenVectors, q)

        for i in range(len(mat)):
            for j in range(i):
                if abs(a[i][j]) > residual: check = True

    for i in range(len(a)): eigenValues.append(a[i][i])

    print(eigenValues) #[1.0, 8.000000054834647, 2.9999999451653365, 2.0]
    print(eigenVectors) #[[1.0, 0.0, 0.0, 0.0], 
                          [0.0, 0.7071067941112008, -0.7071067682618934, 0.0], 
                          [0.0, 0.7071067682618939, 0.7071067941112008, 0.0], 
                          [0.0, 0.0, 0.0, 1.0]]
    # The correct eigenvectors are 
       [[ 1.         -0.19802951  0.23570226  0.90744251],
        [ 0.          0.69310328 -0.23570226 -0.1814885 ],
        [ 0.          0.69310328  0.94280904  0.362977  ],
        [ 0.          0.          0.          0.1088931 ]]

Is it a problem that comes from the Household reflection algorithm that the 'numpy.linalg.qr' adopts? Do I have to apply the Givens rotation? Or, is it the matter of my QR algorithm code?


Solution

  • QR algorithm is known to be able to get both the eigenvalue and eigenvector when the input matrix is symmetric but for the asymmetric case, there is no such promise.

    Hence, your first input matrix works because it is symmetrical.

    Your second input matrix is not symmetrical.