の場合x = A\b
、バックスラッシュ演算子には、さまざまな種類の入力行列を処理するための多数のアルゴリズムが含まれています。したがって、マトリックスA
が診断され、その特性に従って実行パスが選択されます。
次のページA
では、 が非スパース行列である場合の疑似コードを説明しています。
if size(A,1) == size(A,2) % A is square
if isequal(A,tril(A)) % A is lower triangular
x = A \ b; % This is a simple forward substitution on b
elseif isequal(A,triu(A)) % A is upper triangular
x = A \ b; % This is a simple backward substitution on b
else
if isequal(A,A') % A is symmetric
[R,p] = chol(A);
if (p == 0) % A is symmetric positive definite
x = R \ (R' \ b); % a forward and a backward substitution
return
end
end
[L,U,P] = lu(A); % general, square A
x = U \ (L \ (P*b)); % a forward and a backward substitution
end
else % A is rectangular
[Q,R] = qr(A);
x = R \ (Q' * b);
end
非正方行列の場合、QR 分解が使用されます。正三角形行列の場合、単純な前方/後方置換を実行します。正定正定正定行列の場合、コレスキー分解が使用されます。それ以外の場合、一般的な正方行列にはLU 分解が使用されます。
更新: MathWorks はのドキュメント ページのアルゴリズム セクションmldivide
をいくつかの優れたフローチャートで更新しました。hereとhereを参照してください(完全な場合と疎な場合)。
これらのアルゴリズムはすべてLAPACKに対応するメソッドがあり、実際、おそらく MATLAB が行っていることです (MATLAB の最近のバージョンには、最適化されたIntel MKL実装が付属していることに注意してください)。
異なる方法を使用する理由は、最も特殊なアルゴリズムを使用して、係数行列のすべての特性を利用する連立方程式を解こうとするためです (その方が高速であるか、数値的に安定しているからです)。したがって、確かに一般的なソルバーを使用できますが、最も効率的ではありません。
実際、事前にどのようなものかがわかっている場合は、オプションを直接A
呼び出して指定することで、追加のテスト プロセスをスキップできます。linsolve
A
が長方形または特異な場合、PINV を使用して最小ノルム最小二乗解を見つけることもできます ( SVD 分解を使用して実装):
x = pinv(A)*b
上記はすべて密行列に適用されますが、疎行列はまったく別の話です。通常、このような場合には反復ソルバーが使用されます。MATLAB はUMFPACKと SuiteSpase パッケージのその他の関連ライブラリを直接ソルバーに使用していると思います。
疎行列を操作する場合、診断情報をオンにして、実行されたテストと選択されたアルゴリズムを次のように表示できspparms
ます。
spparms('spumoni',2)
x = A\b;
さらに、バックスラッシュ演算子はgpuArrayでも機能します。この場合、GPU での実行はcuBLASとMAGMAに依存します。
また、分散コンピューティング環境で動作する分散配列にも実装されます (各ワーカーが配列の一部しか持たず、おそらく行列全体を一度にメモリに格納できないコンピューターのクラスター間で分割された作業)。基礎となる実装はScaLAPACKを使用しています。
そのすべてを自分で実装したい場合、それはかなり難しい注文です:)