2

大きな行列 (約 1000*1000 またはそれ以上) の固有値と固有ベクトルを計算する必要があります。Matlab は非常に高速に動作しますが、精度を保証するものではありません。私はこれがかなり正確である必要があり (約 1e-06 エラーは問題ありません)、妥当な時間内 (1 時間か 2 時間で問題ありません) です。

私の行列は対称的でかなりまばらです。正確な値は、対角線上、主対角線の下の対角線、およびその上の対角線上にあるものです。例:

マトリックスの例

これどうやってするの?C++ は私にとって最も便利です。

4

3 に答える 3

5

MATLAB は精度を保証しません

私はこの主張は不合理だと思います。MATLAB の高度に洗練された計算アルゴリズムよりも (大幅に) 正確な実装を見つけることができると言う根拠は何ですか?

そして... MATLAB の を使用eigすると、以下は 0.5 秒未満で計算されます。

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

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

早いですよね!

これはかなり正確である必要があります (約 1e-06 エラーで問題ありません)。

固有値を正確に解くことは、特性多項式の根を見つけることに関連していることを思い出してください。この特定の 1000x1000 マトリックスは非常に 悪条件です:

>> cond(A)

ans =
    1.6551e+003

一般的な経験則では、条件数が 10 kの場合、最大でk桁の精度が失われる可能性があります (算術法による精度の損失により数値法で失われるものに加えて)。

したがって、あなたの場合、結果はおおよその誤差 10 -3まで正確であると予想されます。

于 2013-10-29T08:16:23.523 に答える
4

サード パーティのライブラリを使用することに抵抗がない場合は、Armadillo線形代数ライブラリを使用して大きな成功を収めました。

以下の例でarmaは、 は彼らが使用したい名前空間、vecはベクトル、matは行列です。

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

データを直接シリアル化することもMATLAB、その逆も可能です。

于 2013-10-29T03:39:18.690 に答える
3

あなたのシステムは三重対角であり、(対称)テプリッツ行列です。eig固有値とMatlabには、そのような行列を処理する特別なケースがあると思います。この場合、固有値の閉形式解があります(参照 (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++ に変換できるはずです (または、Matlabcodgenを使用して、これまたは を使用する C/C++ コードを生成しますeig)。ただし、マトリックスはまだ悪条件です。精度の見積もりは最悪の場合であることを覚えておいてください。

于 2013-10-29T16:18:00.780 に答える