0

numpy linalg.eig アルゴリズムのこの非常に奇妙な動作を見つけました。

実行する場合

>>> import numpy as np
>>> a = np.array([[1., 0., 0., 0., 0., 0., 0., 0.],
... [0., -1., -0.5, 0., -0.5, 0., 0., 0.], 
... [0., -0.5, 0., 0., 0., 0., 0., 0.], 
... [0., 0., 0., 0., 0., 0., -0.5, 0.], 
... [0., -0.5, 0., 0., 0., 0., 0., 0.], 
... [0., 0., 0., 0., 0., 0., -0.5, 0.],  
... [0., 0., 0., -0.5, 0., -0.5, -1., 0.], 
... [0., 0., 0., 0., 0., 0., 0., 1.]])
>>> np.linalg.eig(a)
(array([-1.366,  0.366, -1.366,  0.366,  0.   ,  0.   ,  1.   ,  1.   ]),
array([[ 0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  1.   ,  0.   ],
   [-0.   ,  0.   , -0.822,  0.426,  0.   ,  0.   ,  0.   ,  0.   ],
   [ 0.   ,  0.   , -0.301, -0.581,  0.13 ,  0.   ,  0.   ,  0.   ],
   [-0.325, -0.628, -0.123, -0.237, -0.695, -0.707,  0.   ,  0.   ],
   [ 0.   ,  0.   , -0.301, -0.581, -0.13 , -0.   ,  0.   ,  0.   ],
   [-0.325, -0.628, -0.123, -0.237,  0.695,  0.707,  0.   ,  0.   ],
   [-0.888,  0.46 , -0.336,  0.174, -0.   , -0.   ,  0.   ,  0.   ],
   [ 0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  1.   ]]))

上記の固有ベクトル (列) が間違っています。

正しい答えは、

>>> np.linalg.eigh(a)
(array([-1.366, -1.366, -0.   ,  0.   ,  0.366,  0.366,  1.   ,  1.   ]),
 array([[-0.   ,  0.   ,  0.   ,  0.   ,  0.   , -0.   ,  1.   ,  0.   ],
   [-0.   , -0.888,  0.   ,  0.   ,  0.   , -0.46 ,  0.   ,  0.   ],
   [-0.   , -0.325,  0.   , -0.707,  0.   ,  0.628,  0.   ,  0.   ],
   [-0.325,  0.   , -0.707,  0.   , -0.628, -0.   ,  0.   ,  0.   ],
   [ 0.   , -0.325,  0.   ,  0.707,  0.   ,  0.628,  0.   ,  0.   ],
   [-0.325,  0.   ,  0.707,  0.   , -0.628, -0.   ,  0.   ,  0.   ],
   [-0.888,  0.   ,  0.   ,  0.   ,  0.46 , -0.   ,  0.   ,  0.   ],
   [-0.   ,  0.   ,  0.   ,  0.   ,  0.   , -0.   ,  0.   ,  1.   ]]))

eig アルゴリズムがこのような単純な行列を対角化できないことに本当に驚きました!

この行為を報告する必要がありますか?

編集

numpy バ​​ージョン 1.6.2

4

2 に答える 2

1

ここに示されているすべての結果は正しいです。

行列には固有値 = -1.366 と 0.366 の 2 つの 2D サブスペースがあるためです。また、2D 部分空間では、線形独立固有ベクトルのさまざまな線形結合を選択できます。

于 2012-08-30T18:16:28.207 に答える
1

私にはすべてがうまく見えます:

import numpy as np

a = np.array([[1., 0., 0., 0., 0., 0., 0., 0.],
              [0., -1., -0.5, 0., -0.5, 0., 0., 0.], 
              [0., -0.5, 0., 0., 0., 0., 0., 0.], 
              [0., 0., 0., 0., 0., 0., -0.5, 0.], 
              [0., -0.5, 0., 0., 0., 0., 0., 0.], 
              [0., 0., 0., 0., 0., 0., -0.5, 0.],  
              [0., 0., 0., -0.5, 0., -0.5, -1., 0.], 
              [0., 0., 0., 0., 0., 0., 0., 1.]])

fns = np.linalg.eig, np.linalg.eigh
for fn in fns:
    print fn
    ww, vv = fn(a)
    for i in range(len(ww)):
        w = ww[i]
        v = vv[:,i]
        print i, np.allclose(np.dot(a, v),w*v),
    print

生産する

<function eig at 0xb5b570d4>
0 True 1 True 2 True 3 True 4 True 5 True 6 True 7 True
<function eigh at 0xb5b5710c>
0 True 1 True 2 True 3 True 4 True 5 True 6 True 7 True
于 2012-08-30T18:19:18.140 に答える