pythonnumpylinear-algebraeigenvalueeigenvector

Why do I get back different eigenvectors that I put in?


I am trying to build a matrix A from a set of eigenvectors and eigenvalues, and then reverse the operation to get the eigenvectors and eigenvalues back. I am not generally able to recover the eigenvalue-eigenvector combination that I start with, and I'm having trouble understanding why.

I can fully appreciate that this might be a math problem rather than a programming problem -- but I figured I would ask here as its equally possible I'm just doing something foolish with numpy.

evecs = np.array([[6.12e-32, 0.00, 1.0], [0.71, 0.71, 0.00], [-0.71,  0.71,  0.00]])
evals =np.diag(np.array([0.6, 0.3, 0.1]))
A = np.dot(np.dot(evecs, evals), np.linalg.inv(evecs))
eigenvalues, eigenvectors = np.linalg.eig(A)

This returns:

print (eigenvalues)
[0.1 0.6 0.3]

print (eigenvectors)
[[ 1.000000000000000e+00  6.095061268819254e-32  5.775657482482331e-49]
[ 0.000000000000000e+00  7.071067811865475e-01  7.071067811865475e-01]
[ 0.000000000000000e+00 -7.071067811865475e-01  7.071067811865475e-01]]

I understand that the eigenvalues came back unsorted, but still, the eigenvector corresponding with the largest eigenvalue is now:

print (eigenvectors[:,1])
[ 6.095061268819254e-32  7.071067811865475e-01 -7.071067811865475e-01]

Which is not the same as v1 = [0, 0, 1] that was sent in. Why are the eigenvectors switching axes like this? Is there some way that I can recover the original orientation of v1?

While searching around for a solution, I also read several places that computing the inverse should be avoided -- is there a better (more stable) way of moving from the eigenspace to A (and back again)?


Solution

  • In your implementation, evecs has the eigenvectors as rows but they should be columns.

    By transposing evecs, you get the desired result:

    import numpy as np
    
    evecs = np.array([[6.12e-32, 0.00, 1.0], [0.71, 0.71, 0.00], [-0.71,  0.71,  0.00]])
    evecs = evecs.T
    evals =np.diag(np.array([0.6, 0.3, 0.1]))
    A = np.dot(np.dot(evecs, evals), np.linalg.inv(evecs))
    eigenvalues, eigenvectors = np.linalg.eig(A)
    
    
    print (eigenvalues)
    print (eigenvectors)
    print (eigenvectors[:,2])
    
    [0.3 0.1 0.6]
    
    [[ 7.07106781e-01 -7.07106781e-01  6.12000000e-32]
     [ 7.07106781e-01  7.07106781e-01  7.54333276e-48]
     [ 0.00000000e+00  0.00000000e+00  1.00000000e+00]]
    
    [6.12000000e-32 7.54333276e-48 1.00000000e+00]