如何在不使用numpy和scipy的情况下找到特征向量和特征值?

3

我需要在Python中计算特征值和特征向量。NumPy和SciPy都无法使用,它们都写了“非法指令(核心已转储)”的错误信息。我发现解决这个问题需要检查我的blas / lapack。因此,我想也许有更简单的方法是编写/找到一个小函数来解决特征值问题。是否有人知道是否存在这样的解决方案?


有不止一种方法,但大多数情况下,您最终会执行矩阵分解/对角化,如果没有适当的数值计算库,很难以简洁的方式完成。此外,每种直接的方法都存在病态问题,如果没有一些优化,就无法保证您会得到与真实解决方案相近的结果。 - zero323
我也想要一个解决方案。我需要计算小矩阵(4x4)的特征值,因此速度不是一个大问题。由于技术原因我不能使用numpy/scipy(无法安装),只能使用纯Python。我不想自己实现算法(我还不如在纸上解决然后实现结果方程!)。一定有一个简单的代码片段可以用! - jdm
3个回答

2

您可以使用Python计算机代数系统sympy来使用Berkowitz方法解决特征值问题,而无需使用本地库。虽然速度不快,但如果您只有少量小矩阵,则不会成为问题。

例子:

>>> from sympy import Matrix
>>> m = Matrix([[10,2,3], [3,12,5], [5,5,8]])
>>> print m.eigenvals()
# this gets the eigenvalues along with their multiplicity
{10 - (-77/2 + sqrt(1019751)*I/18)**(1/3) - 50/(3*(-77/2 + sqrt(1019751)*I/18)**(1/3)): 1,
 10 - (-77/2 + sqrt(1019751)*I/18)**(1/3)*(-1/2 + sqrt(3)*I/2) - 50/(3*(-77/2 + sqrt(1019751)*I/18)**(1/3)*(-1/2 + sqrt(3)*I/2)): 1,
 10 - 50/(3*(-77/2 + sqrt(1019751)*I/18)**(1/3)*(-1/2 - sqrt(3)*I/2)) - (-77/2 + sqrt(1019751)*I/18)**(1/3)*(-1/2 - sqrt(3)*I/2): 1}
>>> print map(complex, m.eigenvals().keys())
[(8.374025140524024+2.117582368135751e-22j), (3.8835463038416105-2.117582368135751e-22j), (17.742428555634365-1.0587911840678754e-22j)]

# check with numpy
>>> import numpy as np
>>> print np.linalg.eigvals(np.array(m.tolist(), dtype=float))
array([ 17.74242856,   8.37402514,   3.8835463 ])

谢谢,它有效了!我实际上成功安装了numpy(尽管我必须处理过时的Python和库版本的混乱),但下次可能会有用。 - jdm

2
任何有效的解决方案都会在内部使用相同的blas / lapack库。我仍然认为修复您的库不会太难。
但是,如果您觉得更容易,可以自己实现其中任何一个特征值算法。我想最容易实现的可能是幂法算法,但我怀疑它是否有效。

0
编写一个解决特征值问题的程序需要的工作量大约是修复库不匹配问题的100倍。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接