【问题标题】:How to make the eigenvalues and eigenvectors stay real instead of complex?如何使特征值和特征向量保持真实而不是复杂?
【发布时间】:2018-07-19 14:38:21
【问题描述】:

我尝试将n*100*100 3d 矩阵K 对角化numpy.linalg.eig 并获得特征值w 和特征向量v。矩阵是100*100,但我想用广播来做,这就是我设置的数字n。而且矩阵不是厄米矩阵。

w,v=np.linalg.eig(K)

一开始我尝试n=1000,我得到了真正的特征值和特征向量,即xxxxxxxxxe+xx,但是当我尝试n=2000时,wv的元素显示xxxxxxxxxe+xx+0.j。由于+0.j,在使用wv做进一步计算时给出了复数。

  1. 我以为是浮点数计算的算法错误,但为什么呢?
  2. numpy.linalg 是否使用 LAPACK?这可能是 LAPACK 的错误吗?
  3. 如何摆脱+0.j

【问题讨论】:

  • 矩阵是对称的/厄米矩阵吗?你怎么知道它有真正的特征值?
  • 好问题,我也在想办法。它不是厄米特,但没有广播,只是对角化一个100*100 矩阵总是给出真正的特征值和向量。如果我同时对 2000 个100*100 矩阵进行对角化,它会显示+0.j 虚部。
  • 如果虚部为零,那么为什么不使用output.real
  • +0.j 表示特征值的虚部是 0 ?还是仅仅意味着它们是复数?
  • 您可以尝试使用numpy.set_printoptions() 切换打印精度。由于 double 的精度有限,0.j 后面可能会隐藏一个非常小的、不重要的虚数部分。您可以使用numpy.real 将其丢弃。要检查删除复杂部分是否不会损坏特征向量 v 和特征值 w,您可以计算残差 ||w v - K.v|| 的范数并将其与范数 ||v|| 进行比较。

标签: python numpy matrix complex-numbers eigenvalue


【解决方案1】:

根据文档,numpy.linalg.eig 使用(用于实际参数)LAPACK 例程 DGEEV,它不对输入矩阵(除了是真实的)做任何假设。如果矩阵在浮点精度内足够对称,则返回的特征值的复数部分将为零(DGEEV 的输出参数 WI)。但是,由于精度有限,您可能会得到一些虚假的复杂部分。

编辑:

  1. 如果您确定您的矩阵只有实特征值,您可以使用numpy.real 去除复杂部分或使用专门用于对称矩阵的numpy.linalg.eigh

  2. 至于numpy.linalg.eignumpy/linalg/linalg.py中的相关部分是:

    w, vt = _umath_linalg.eig(a, signature=signature, extobj=extobj)
    
    if not isComplexType(t) and all(w.imag == 0.0):
        w = w.real
        vt = vt.real
        result_t = _realType(result_t)
    else:
        result_t = _complexType(result_t)
    

所以测试是一个严格的比较all(w.imag == 0.0),然后才用w = w.real将特征值转换为实数。

【讨论】:

  • 谢谢,我正在求解一个矩阵微分方程。 +0.j 表示特征值的虚部是0?
猜你喜欢
  • 2020-06-07
  • 1970-01-01
  • 2014-05-11
  • 2019-04-16
  • 1970-01-01
  • 2018-08-06
  • 2018-01-25
  • 1970-01-01
  • 2015-06-30
相关资源
最近更新 更多