NumPy eigh()给出了不正确的特征向量

时间:2017-07-20 19:33:41

标签: python numpy linear eigenvector

我一直在使用NumPy来做一些线性代数,但是我遇到了eigh()似乎返回错误的特征向量的问题。 Here是我正在使用的对称矩阵(481乘481)。请查看以下代码:

import numpy as np

c = np.load('C.npy')
eigenvectors_h = np.linalg.eigh(c)[1]
c.dot(eigenvectors_h[:, 0]) / eigenvectors_h[:, 0]

c是真实的,绝对是对称的,因为np.allclose(c, c.T)会返回True

我没有得到一个由特征值组成的数组重复481次,而是看到了什么看起来像随机数:

-1.03913672e+04   1.70145524e-15  -6.30342977e-16  -5.80181781e-15
2.43586988e-15   1.02142854e-13  -1.59100453e-13   6.34768223e-14
1.47793139e-14   5.19832084e-15   1.23786159e-14  -6.89332604e-14
3.35120474e-14  -5.55497774e-14   3.35912194e-14   2.41599711e-14
-8.10853045e-15   3.39728566e-14   1.66605768e-14  -4.62536283e-14
4.78158644e-15   1.05840004e-14   2.49968277e-14   6.37161752e-14
-8.29049452e-15   7.69540224e-13  -1.41737099e-14  -2.04904903e-14
-2.02649833e-14   8.75614182e-15  -6.43718154e-14  -6.71884701e-15
2.89567850e-15  -1.93639427e-14   2.05961830e-15  -2.82825321e-14
-2.99156760e-14  -1.17149803e-14  -1.00413883e-13   2.81365540e-15
-1.47420105e-14  -1.54638301e-14   2.97770540e-14   9.42616109e-14
-2.18819275e-13   6.23156105e-13  -1.14148906e-14   1.97147438e-14
-5.04103330e-14  -1.39415849e-13  -6.78032159e-14  -2.18085326e-14
-1.36511305e-14   3.09529929e-14  -9.42922227e-15  -1.80013713e-14
-3.34989389e-14  -1.31399506e-15   3.86915434e-14   7.43430828e-15
3.00681063e-14   3.15599077e-15   1.77696288e-14  -5.33198194e-15
-3.03304561e-14   1.74254787e-13  -3.31735946e-14   3.02816694e-14
-1.79965325e-14  -6.03794643e-13  -2.70964350e-14   1.13476801e-14
-1.31756179e-14   1.23490868e-14   1.31665400e-14  -4.82723158e-15
-6.80123679e-14   1.01616264e-13  -3.26409876e-14   5.00897081e-15
8.01025834e-14  -5.50605097e-13   3.03059609e-15   5.55524078e-14
1.76830600e-14   5.82590991e-14  -4.07471685e-14  -1.74936332e-14
3.67006376e-14   1.23210295e-14   4.54025070e-14  -1.37452957e-13
5.68932273e-15   3.59057575e-14   7.52501521e-15  -8.21274824e-15
2.86056181e-13   2.12632482e-14   9.50056403e-14   2.80131245e-14
...

但是,它适用于eig()

eigenvectors = np.linalg.eig(c)[1]
c.dot(eigenvectors[:, 0]) / eigenvectors[:, 0] #[126.56622721] * 481

我想使用eigh()因为它似乎更快并且返回实际值而不是复杂值,但它似乎不起作用。谁能解释为什么这是我做错了什么?

自包含示例

此示例演示了自包含代码中的相同行为(使用基本上为等级1的随机矩阵,除了数字工件)。

import numpy as np
u = np.random.uniform(size=(100,))
c = np.outer(u, u)

eigenvectors_h = np.linalg.eigh(c)[1]
print(c.dot(eigenvectors_h[:, 0]) / eigenvectors_h[:, 0])

eigenvectors = np.linalg.eig(c)[1]
print(c.dot(eigenvectors[:, 0]) / eigenvectors[:, 0])

1 个答案:

答案 0 :(得分:5)

.wrapperHeader没有任何问题,只有eigh。你会得到类似的"随机"数字,如果您使用列表末尾的特征向量测试eig:尝试

eig

以下是发生的事情:

  1. 矩阵的大多数特征值与0无法区分,它们的大小为1e-16或更小。
  2. 方法print(c.dot(eigenvectors[:, -10]) / eigenvectors[:, -10]) 首先返回最小特征值(及其特征向量)。
  3. 方法eigh首先返回最大特征值(及其特征向量)。
  4. 您只测试返回的第一个特征向量。
  5. 因此,您发现eigeig的行为存在差异。

    实际上,您的矩阵似乎是低秩+数值噪声。所以小的特征值应该是0,在这种情况下,特征向量的计算基本上是一个乐透;这是一个巨大的线性子空间,几乎被矩阵杀死,来自该子空间的任何东西都可以作为特征向量传递。乘法eigh的结果只是一堆数值噪声。

    道德:不要忘记全貌。

    c*eigenvector