【问题标题】:how are numpy eigenvalues and eigenvectors computed如何计算 numpy 特征值和特征向量
【发布时间】:2015-02-25 19:17:11
【问题描述】:

我正在使用 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 使用什么算法?

【问题讨论】:

  • 对我来说看起来很准确
  • 第二个特征值是3.96872205e-16而不是0。同样在3个特征向量中应该有两个0,而不是-3.34129212e-16和1.06732810e-16。
  • 这些是几乎为零的舍入误差。如果x 是您的结果,您可以使用np.where(x < 1e-15, 0, x) 消除所有这些舍入错误
  • Errrr ..... Wolfram Alpha 实际上是在分析计算它们,还是只是更好地适当地表示输出以提高人类可读性?通常,计算特征向量/特征值涉及求解与矩阵大小相同次数的多项式。 Abel-Ruffini theorem 表明在激进分子中没有解决方案。因此,对于任意 6x6 满秩矩阵,没有 解析解可以找到特征值/向量。可以证明是这样。

标签: python numpy


【解决方案1】:

如果您想要解析推导的精度,您将需要使用 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

【讨论】:

    【解决方案2】:

    看起来它正在使用 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

    【讨论】:

    • 是的,看起来它是用于eig 的 LAPACK 例程的 *geev 系列以及用于实值 eigh 的 *syevd 和 *heevd。见github.com/numpy/numpy/blob/v1.9.1/numpy/linalg/…
    • numpy.linalg.eigh 不会改变结果。似乎使用相同的数值方法
    • @igavriil 您看到的问题是因为这根本是一种数值方法。浮点计算会带来一些不准确性。如果您需要精确的算术,则必须使用 sympy,如另一个答案中所建议的那样。这回答了“numpy 如何计算特征值和特征向量?” eigh在适用的情况下应该会更准确,但它仍然是一种带有浮点误差的数值方法。
    猜你喜欢
    • 2011-12-11
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多