我尝试通过 numpy.linalg.eig
对角化 n*100*100
3d 矩阵 K
并获得特征值 w
和特征向量 v
。矩阵是 100*100
,但我想用广播来做,这就是我设置的数字 n
。并且矩阵不是厄尔米特矩阵。
w,v=np.linalg.eig(K)
起初,我尝试了 n=1000
,我得到了实特征值和特征向量,即 xxxxxxxxxe+xx
,但是当我尝试 n=2000
,w
和v
的元素显示xxxxxxxxxe+xx+0.j
。由于+0.j
,在使用w
和v
做进一步计算时给出了复数。
- 我认为这是因为 float 计算的算法错误,但为什么呢?
- numpy.linalg 是否使用 LAPACK?这可能是 LAPACK 的错误吗?
- 如何摆脱
+0.j
?
最佳答案
根据文档,numpy.linalg.eig
使用(对于实参)LAPACK 例程 DGEEV它不对输入矩阵做出任何假设(除了是真实的)。如果矩阵在浮点精度内足够对称,则返回的特征值的复数部分将为零(DGEEV
的输出参数 WI
)。但是,由于精度有限,您可能会得到一些虚假的复杂零件。
编辑:
如果您确定您的矩阵只有实数特征值,您可以使用
numpy.real
去掉复数部分。或使用numpy.linalg.eigh
专门用于对称矩阵。至于
numpy.linalg.eig
,numpy/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
将特征值转换为实数。
关于python - 如何使特征值和特征向量保持真实而不是复杂?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48695430/