如何快速准确地获得特征值和特征向量?

时间:2013-10-29 02:36:05

标签: c++ matlab linear-algebra eigenvector eigenvalue

我需要计算一个大矩阵(约1000 * 1000甚至更多)的特征值和特征向量。 Matlab的工作速度非常快,但并不能保证准确性。我需要这个非常准确(约1e-06错误是可以的)并且在合理的时间内(一两个小时没问题)。

我的矩阵是对称的,非常稀疏。确切的值是:在对角线上,在主对角线下方的对角线上,以及在它上方的对角线上。例如:

Example Matrix http://img692.imageshack.us/img692/2269/zb2u.png

我该怎么做? C ++对我来说最方便。

3 个答案:

答案 0 :(得分:5)

  

MATLAB无法保证准确性

我觉得这个说法不合理。基于什么理由,您可以找到比MATLAB高度精炼的计算算法更精确的实现?

AND ...使用MATLAB的eig,以下计算时间不到半秒:

%// Generate the input matrix
X = ones(1000);
A = triu(X, -1) + tril(X, 1) - X;

%// Compute eigenvalues
v = eig(A);

很快就好了!

  

我需要这个非常准确(约1e-06错误就可以了)

请记住,精确求解特征值与寻找特征多项式的根有关。这个特定的1000x1000矩阵非常 ill-conditioned

>> cond(A)

ans =
    1.6551e+003

A general rule of thumb是条件数为10 k 的情况,您可能会损失高达 k 的精度数字(在由于算术方法的精度损失,数值方法会丢失的顶部。)

所以在你的情况下,我希望结果准确到10 -3 的近似误差。

答案 1 :(得分:4)

如果您不反对使用第三方库,我使用Armadillo线性代数库取得了巨大成功。

对于下面的示例,arma是他们喜欢使用的命名空间,vec是一个向量,mat是一个矩阵。

arma::vec getEigenValues(arma::mat M) {
    return arma::eig_sym(M);
}

您也可以将数据直接序列化为MATLAB,反之亦然。

答案 2 :(得分:3)

您的系统是tridiagonal和(对称)Toeplitz matrix。我猜想eigen和Matlab的eig有特殊情况来处理这样的矩阵。在这种情况下有closed-form solution for the eigenvaluesreference (PDF))。在Matlab中你的矩阵就是这样:

n = size(A,1);
k = (1:n).';
v = 1-2*cos(pi*k./(n+1));

这可以通过注意特征值以1为中心进一步优化,因此只需计算其中一半:

n = size(A,1);
if mod(n,2) == 0
    k = (1:n/2).';
    u = 2*cos(pi*k./(n+1));
    v = 1+[u;-u];
else
    k = (1:(n-1)/2).';
    u = 2*cos(pi*k./(n+1));
    v = 1+[u;0;-u];
end

我不确定如何使用简单的代码获得更快更准确的效果(除了使用特征向量和优化执行细化步骤之外)。上面应该能够非常容易地翻译成C ++(或者使用Matlab的codgen生成使用它或eig的C / C ++代码。但是,你的矩阵仍然是病态的。请记住,准确性的估计是最坏的情况。