如何计算numpy特征值和特征向量

时间:2015-02-25 19:17:11

标签: python numpy

我使用numpy来计算对称方阵的特征值和特征向量。我的阵列是:

L = [[ 2. -1. -1.  0.  0.  0.]
     [-1.  3.  0. -1.  0. -1.]
     [-1.  0.  2. -1.  0.  0.]
     [ 0. -1. -1.  3. -1.  0.]
     [ 0.  0.  0. -1.  2. -1.]
     [ 0. -1.  0.  0. -1.  2.]]

执行numpy.linalg.eig(L)时的结果显示在下面

特征值:

[ 5.00000000e+00,   
  3.96872205e-16,   
  1.00000000e+00,
  2.00000000e+00,   
  3.00000000e+00,   
  3.00000000e+00 ]

本征向量:

[[ -2.88675135e-01   4.08248290e-01  -5.00000000e-01  4.08248290e-01   -4.36632863e-01   4.44614891e-01]
 [  5.77350269e-01   4.08248290e-01  -3.34129212e-16  4.08248290e-01   -1.08813217e-01  -5.41271705e-01]
 [  2.88675135e-01   4.08248290e-01  -5.00000000e-01  4.08248290e-01    5.45446080e-01   9.66568140e-02]
 [ -5.77350269e-01   4.08248290e-01   1.06732810e-16  4.08248290e-01   -1.08813217e-01  -5.41271705e-01]
 [  2.88675135e-01   4.08248290e-01   5.00000000e-01  4.08248290e-01   -4.36632863e-01   4.44614891e-01]
 [ -2.88675135e-01   4.08248290e-01   5.00000000e-01 -4.08248290e-01    5.45446080e-01   9.66568140e-02]]

结果与analytically计算它们时得到的结果很接近(如果已标准化),但在特征值和特征向量中似乎都会引入一些错误。有没有办法绕过这些错误使用numpy?

这些错误来自哪里? numpy使用什么算法?

2 个答案:

答案 0 :(得分:8)

如果您想要分析推导的精度,则需要使用symbolic computation,这是Wolfram Alpha,Mathematica和相关系统使用的。在Python中,您可能希望查看SymPy,例如。

嵌入到您正在使用的NumPy包中的numerical computation固有地受到floating point numerical representations的小错误和变迁的影响。这种误差和近似值在数值计算中是不可避免的。

以下是一个例子:

from sympy import Matrix, pretty

L = Matrix([[ 2, -1, -1,  0,  0,  0,],
     [-1,  3,  0, -1,  0, -1,],
     [-1,  0,  2, -1,  0,  0,],
     [ 0, -1, -1,  3, -1,  0,],
     [ 0,  0,  0, -1,  2, -1,],
     [ 0, -1,  0,  0, -1,  2,]])

print "eigenvalues:"
print pretty(L.eigenvals())
print
print "eigenvectors:"
print pretty(L.eigenvects(), num_columns=132)

收率:

eigenvalues:
{0: 1, 1: 1, 2: 1, 3: 2, 5: 1}

eigenvectors:
⎡⎛0, 1, ⎡⎡1⎤⎤⎞, ⎛1, 1, ⎡⎡-1⎤⎤⎞, ⎛2, 1, ⎡⎡1 ⎤⎤⎞, ⎛3, 2, ⎡⎡1 ⎤, ⎡0 ⎤⎤⎞, ⎛5, 1, ⎡⎡1 ⎤⎤⎞⎤
⎢⎜      ⎢⎢ ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥  ⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟⎥
⎢⎜      ⎢⎢1⎥⎥⎟  ⎜      ⎢⎢0 ⎥⎥⎟  ⎜      ⎢⎢1 ⎥⎥⎟  ⎜      ⎢⎢-1⎥  ⎢-1⎥⎥⎟  ⎜      ⎢⎢-2⎥⎥⎟⎥
⎢⎜      ⎢⎢ ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥  ⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟⎥
⎢⎜      ⎢⎢1⎥⎥⎟  ⎜      ⎢⎢-1⎥⎥⎟  ⎜      ⎢⎢-1⎥⎥⎟  ⎜      ⎢⎢0 ⎥  ⎢1 ⎥⎥⎟  ⎜      ⎢⎢-1⎥⎥⎟⎥
⎢⎜      ⎢⎢ ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥  ⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟⎥
⎢⎜      ⎢⎢1⎥⎥⎟  ⎜      ⎢⎢0 ⎥⎥⎟  ⎜      ⎢⎢-1⎥⎥⎟  ⎜      ⎢⎢-1⎥  ⎢-1⎥⎥⎟  ⎜      ⎢⎢2 ⎥⎥⎟⎥
⎢⎜      ⎢⎢ ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥  ⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟⎥
⎢⎜      ⎢⎢1⎥⎥⎟  ⎜      ⎢⎢1 ⎥⎥⎟  ⎜      ⎢⎢-1⎥⎥⎟  ⎜      ⎢⎢1 ⎥  ⎢0 ⎥⎥⎟  ⎜      ⎢⎢-1⎥⎥⎟⎥
⎢⎜      ⎢⎢ ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥  ⎢  ⎥⎥⎟  ⎜      ⎢⎢  ⎥⎥⎟⎥
⎣⎝      ⎣⎣1⎦⎦⎠  ⎝      ⎣⎣1 ⎦⎦⎠  ⎝      ⎣⎣1 ⎦⎦⎠  ⎝      ⎣⎣0 ⎦  ⎣1 ⎦⎦⎠  ⎝      ⎣⎣1 ⎦⎦⎠⎦

虽然ASCII漂亮的打印机,嗯,努力提供甚至准好看的输出,你可以看到你正在获得符号计算,精确输出。如果您正在使用IPython并将其设置为显示LaTeX输出,那么您将get a nicer display

答案 1 :(得分:4)

看起来它正在使用LAPACK中的迭代方法。它汇集到一个解决方案。如果它不收敛,则抛出异常。

因为你知道矩阵是对称的,所以你可以用eigh做得更好。 http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.eigh.html

文档页面: http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.eig.html

源代码:https://github.com/numpy/numpy/blob/v1.9.1/numpy/linalg/linalg.py#L982