web-dev-qa-db-ja.com

Ax = B ==>エラーの形式の行列を解く:行列は特異に近いか、正しくスケーリングされていません

Ax = Bの形式のシステムを解決できません。

システムの解決策は

x = inv(A)*B

ただし、これは機能しません。

上記のコード行を試すと、次のエラーメッセージが表示されます。

Warning: Matrix is close to singular or badly scaled.
     Results may be inaccurate. RCOND = 1.156482e-018. 

Matlabが、指定した行列の反転に問題があるようです。 inv(A)* Aと入力して、逆関数が正しく機能していることを確認しようとしました

これで単位行列が得られるはずですが、同じエラーといくつかのゴミ番号が表示されました。

これは私が使用しているA行列です:

A = [5/2   1/2  -1     0     0    -1/2  -1/2   0     0
     1/2   1/2   0     0     0    -1/2  -1/2   0     0 
    -1     0     5/2  -1/2  -1     0     0    -1/2   1/2
     0     0    -1/2   1/2   0     0     0     1/2  -1/2
     0     0    -1     0     3/2  -1/2   1/2   0     0
    -1/2  -1/2   0     0    -1/2   2     0    -1     0  
    -1/2  -1/2   0     0     1/2   0     1     0     0 
     0     0    -1/2   1/2   0    -1     0     2     0 
     0     0     1/2  -1/2   0     0     0     0     1]

これが機能しない理由についてのアイデアはありますか?また、Aをスパース行列(sparse(A))に変換してから、inverseコマンドを実行しようとしました。サイコロはありません。

12
Tushar Garg

問題は確かにあなたの数学にあります。指定した行列は完全なランクではないため、反転できません。手動で確認することもできますが(時間をかけていません)、MATLABは既に警告を表示してこれを指摘しています。

浮動小数点数を使用しているため、これにより他の微妙な問題が発生する場合があります。その1つは、det(A)の結果で確認できます。これは、1e-16の順序、つまり、マシンの精度または実際には0です。

rank関数:rank(A) = 8を実行すると、この行列がフルランクではないことがわかります。 9x9行列の場合、これは確かに、行列がdoubleに対して反転可能でないことを意味します(rank関数がマシンの精度を説明するため)。

手動計算に対応する結果を取得するためにMATLABを使用したい場合は、Symbolic Toolboxとそのvpa(可変精度演算)を使用して、考えられる数値問題を回避できますが、計算は遅くなります。

B = [5  1 -2  0  0 -1 -1  0  0;
     1  1  0  0  0 -1 -1  0  0;
    -2  0  5 -1 -2  0  0 -1  1;
     0  0 -1  1  0  0  0  1 -1;
     0  0 -2  0  3 -1  1  0  0;
    -1 -1  0  0 -1  4  0 -2  0;
    -1 -1  0  0  1  0  2  0  0;
     0  0 -1  1  0 -2  0  4  0;
     0  0  1 -1  0  0  0  0  2];
A = B/2;
size(A)    % = [9 9]
det(A)     % = -1.38777878078145e-17
rank(A)    % = 8
C = vpa(A);
det(C)     % = 0.0
rank(C)    % = 8

VPAと浮動小数点の両方で、ランクは8、サイズは[9 9]であり、行列式は実質的に0です。つまり、単数形または可逆ではありません。いくつかのエントリを変更すると、マトリックスが規則的(非特異)になる可能性がありますが、動作が保証されず、別の問題が解決されます。

xの実際の問題A*x=bを解決するには、mldivide(バックスラッシュ演算子)またはMoore-Penrose疑似逆行列を使用してみます。

x1 = A\b;
x2 = pinv(A)*b;

ただし、そのようなシステムには固有のソリューションがないため、疑似逆演算子とバックスラッシュ演算子の両方が非常に異なるソリューションを返す可能性がある(そしてこの場合は)ことを覚えておいてください。

20
Egon

それはまさにそれが言うことを意味します。行列は 単数形、つまり実際には反転できない です。すべての行列ができるわけではありません。

幾何学的な用語では、1つの9次元オブジェクトを別の9次元オブジェクトに変換しますが、1つの次元を完全に平坦化するマトリックスがあります。元に戻すことはできません。物事をその方向にどれだけ引き出すかを知る方法はありません。

11
Karl Knechtel

行列is単数、以下のB = 2 * Aを考えます:

B = [5  1 -2  0  0 -1 -1  0  0;
     1  1  0  0  0 -1 -1  0  0;
    -2  0  5 -1 -2  0  0 -1  1;
     0  0 -1  1  0  0  0  1 -1;
     0  0 -2  0  3 -1  1  0  0;
    -1 -1  0  0 -1  4  0 -2  0;
    -1 -1  0  0  1  0  2  0  0;
     0  0 -1  1  0 -2  0  4  0;
     0  0  1 -1  0  0  0  0  2]

det(B)

0
2
Alex

反復ソルバーであるbicgstab(A,b,tol,maxit)は、特異行列Aの特異線形システムA * x = bを解くことができました。

size(A)=[162, 162] 
rank(A)=14 
cond(A)=4.1813e+132 

私が使用した:

tol=1e-10; 
maxit=100;

上記(svd\invpinvgmresを含む)はどれも私にとってはうまくいきませんでしたが、bicgstabうまくいきました。 bicgstabは、反復4で、相対残差1.1e-11の解に収束しました。スパース行列に対しては高速に動作します。

こちらのドキュメントをご覧ください: https://uk.mathworks.com/help/matlab/ref/bicgstab.html

1
Feruza