MATLABバックスラッシュ演算子は、正方行列の


36

いくつかのコードを「ストック」MATLABコードと比較していました。その結果には驚きました。

サンプルコードを実行しました(スパースマトリックス)

n = 5000;
a = diag(rand(n,1));
b = rand(n,1);
disp('For a\b');
tic;a\b;toc;
disp('For LU');
tic;LULU;toc;
disp('For Conj Grad');
tic;conjgrad(a,b,1e-8);toc;
disp('Inv(A)*B');
tic;inv(a)*b;toc;

結果 :

    For a\b
    Elapsed time is 0.052838 seconds.

    For LU
    Elapsed time is 7.441331 seconds.

    For Conj Grad
    Elapsed time is 3.819182 seconds.

    Inv(A)*B
    Elapsed time is 38.511110 seconds.

密行列の場合:

n = 2000;
a = rand(n,n);
b = rand(n,1);
disp('For a\b');
tic;a\b;toc;
disp('For LU');
tic;LULU;toc;
disp('For Conj Grad');
tic;conjgrad(a,b,1e-8);toc;
disp('For INV(A)*B');
tic;inv(a)*b;toc;

結果:

For a\b
Elapsed time is 0.575926 seconds.

For LU
Elapsed time is 0.654287 seconds.

For Conj Grad
Elapsed time is 9.875896 seconds.

Inv(A)*B
Elapsed time is 1.648074 seconds.

一体どれほどすごいのですか?


1
MATLABの組み込みのバックスラッシュ、つまり線形方程式システムの直接ソルバーは、スパース行列に対してマルチフロンタル法を使用しているため、A \ Bは非常に優れています。
シュハオカオ

1
cise.ufl.edu/research/sparseにある Tim Davisのコードを使用します。また、些細な問題を抱えているとすごさはなくなります
-stali

1
「LULU」とは何ですか?LU分解とそれに続く直接解決の優れた実装だと思うのはなぜですか?
ジェドブラウン

3
@Nunoxic どのような実装ですか?自分で書きましたか?高性能の高密度線形代数は、通常はアルゴリズム的によく理解されていますが、現代のハードウェアに効率的に実装することは容易ではありません。最適なBLAS / Lapack実装は、そのサイズのマトリックスでピークに近づくはずです。また、あなたのコメントから、LUとGaussian Eliminationは異なるアルゴリズムであるとの印象を受けています。
ジェドブラウン

1
インテル®MKLを使用して記述されたFortranコードを呼び出します。
調査

回答:


37

Matlabでは、 '\'コマンドは、マトリックスAの構造に依存し、Aのプロパティのチェック(小さなオーバーヘッド)を含むアルゴリズムを呼び出します。

  1. Aがスパースでバンド化されている場合、バンド化ソルバーを使用します。
  2. Aが上三角行列または下三角行列の場合、後方置換アルゴリズムを使用します。
  3. Aが対称で、実数の正の対角要素を持つ場合、コレスキー分解を試みます。Aがスパースの場合、最初に並べ替えを使用して、塗りつぶしを最小限にします。
  4. 上記の基準がいずれも満たされない場合は、部分ピボットを使用したガウス消去法を使用して一般的な三角分解を行います。
  5. Aがスパースの場合、UMFPACKライ​​ブラリを使用します。
  6. Aが正方でない場合、未決定のシステムに対してQR分解に基づくアルゴリズムを使用します。

オーバーヘッドを削減するには、Matlabでlinsolveコマンドを使用し、これらのオプションの中から適切なソルバーを自分で選択することができます。


すべての要素が非ゼロ(高レベルの密度)である10000x10000の非構造化密行列を扱っていると仮定すると、最善の策は何でしょうか?密な行列に対して機能する1つのアルゴリズムを分離したいと思います。LU、QR、またはガウス消去ですか?
調査

1
Aの構造を利用してパフォーマンスを向上させることができない最も一般的なケースに対応する、ガウス消去法が呼び出されるステップ4のように聞こえます。したがって、これは基本的にLU分解であり、後続の1つは前方への置換、後方への置換ステップが続く。
アランP. Engsig-Karup

ありがとう!それは私に考える方向を与えてくれると思います。現在、このような非構造化問題を解決するには、ガウス消去法が最適です。それは正しいですか?
調査

37

a\b特定のマトリックスで何が行われるかを確認spparms('spumoni',1)する場合は、どのアルゴリズムに感銘を受けたかを正確に設定して把握できます。例えば:

spparms('spumoni',1);
A = delsq(numgrid('B',256));
b = rand(size(A,2),1);
mldivide(A,b);  % another way to write A\b

出力します

sp\: bandwidth = 254+1+254.
sp\: is A diagonal? no.
sp\: is band density (0.01) > bandden (0.50) to try banded solver? no.
sp\: is A triangular? no.
sp\: is A morally triangular? no.
sp\: is A a candidate for Cholesky (symmetric, real positive diagonal)? yes.
sp\: is CHOLMOD's symbolic Cholesky factorization (with automatic reordering) successful? yes.
sp\: is CHOLMOD's numeric Cholesky factorization successful? yes.
sp\: is CHOLMOD's triangular solve successful? yes.

この場合、「\」が「CHOLMOD」を使用することになったことがわかります。


3
聞いたこともない新しいMATLAB設定に対して+1。よくやった、先生。
ジェフオックスベリー

2
どうもありがとう!にありhelp mldivideます。
-dranxo

16

疎行列の場合、Matlabは\操作にUMFPACKを使用します。これは、例では、基本的にの値を実行し、aそれらを反転し、それらの値で乗算しますb。ただし、この例b./diag(a)では、はるかに高速なを使用する必要があります。

高密度システムの場合、バックスラッシュ演算子はもう少し複雑です。いつ行われるかの簡単な説明はここに与えられます。その説明によると、あなたの例では、Matlabはa\b後方置換を使用して解決します。一般的な正方行列の場合、LU分解が使用されます。


Regd。スパース性、diag行列のinvは対角要素の逆数であるため、b。/ diag(a)は機能しますが、一般的なスパース行列でもa \ bは非常に機能します。なぜlinsolveやLULU(LUの最適化バージョン)は、その場合の密行列のa \ bよりも速くないのですか?
調査

@Nunoxic LULUは、密行列の対角性または三角性を検出するために何かをしますか?そうでない場合、その内容や構造に関係なく、すべてのマトリックスで同じ時間がかかります。
ペドロ

幾分。しかし、linsolve OPTフラグを使用して、構造について定義するすべてのものを定義しました。それでも、a \ bは高速です。
調査

@Nunoxic、ユーザー関数を呼び出すたびにオーバーヘッドが発生します。Matlabは内部でバックスラッシュのすべてを実行します。たとえば、右側の分解とその後の適用は、オーバーヘッドがほとんどないため、高速になります。また、テストでは、複数の呼び出しを使用して信頼できるタイミングを取得する必要がありますtic; for k=1:100, a\b; end; toc
ペドロ

5

経験則として、合理的な複雑さのスパース行列がある場合(つまり、5ポイントのステンシルである必要はありませんが、実際には行ごとの非ゼロの数がストークス方程式の離散化である場合があります) 5)よりはるかに大きい場合、UMFPACKなどのスパースダイレクトソルバーは、通常、問題が100,000程度の未知数より大きくない場合、反復Krylovソルバーに勝ります。

言い換えると、2次元離散化の結果生じるほとんどのスパース行列では、直接ソルバーが最速の代替手段です。100,000を超える未知数をすばやく取得する3D問題の場合のみ、反復ソルバーを使用することが不可欠になります。


3
これがどのように質問に答えるかは私には明らかではありませんが、私も前提に問題を持っています。ダイレクトソルバーは中程度のサイズの2D問題に対してうまく機能する傾向があるのは事実ですが、ダイレクトソルバーは3Dで100k未知数のかなり前に苦しむ傾向があります(頂点セパレーターは2Dよりもはるかに大きい)。さらに、ほとんどの場合(楕円演算子など)、中規模の2D問題でも反復ソルバーを直接ソルバーより高速にできると主張していますが、そのためには多大な労力が必要になる場合があります(たとえば、適切な成分を使用してマルチグリッドを実行する) 。
ジェドブラウン

1
問題がかなり小さく、暗黙的なソルバーの設計について考えたくない場合、または問題が非常に難しく(高周波Maxwellなど)、良いソルバーの設計にキャリアを捧げたくない場合、私はまばらな直接ソルバーが最適な選択肢であることに同意します。
ジェドブラウン

実際、私の問題は、優れた高密度ソルバーを設計することです。そのような特定のアプリケーションはありません(したがって、構造はありません)。私は自分のコードのいくつかを微調整し、現在使用されているものと競争力のあるものにしたかったのです。私はa \ bに興味があり、それがどのように私のコードのくだらないものを常に打ち負かすかを知りました。
調査

@JedBrown:はい、たぶん、かなりの労力で、小さな2D問題に対しても、反復ソルバーを直接ソルバーに勝つことができます。しかし、それはなぜですか?<100k未知数の問題の場合、2dのスパースダイレクトソルバーは十分に高速です。私が言いたかったのは、このような小さな問題については、時間をかけてパラメーターの最適な組み合わせをいじくり回すのに時間を費やさないでください。
ウルフギャングバンガース

5ポイントステンシルを使用した100k dofsでの「簡単な」2D問題では、スパースコレスキーと(マトリックスベースの)幾何学的マルチグリッドの実行時間の差はすでに1桁あります(〜0.05秒に対して〜0.5秒)。ステンシルが2番目の近傍(たとえば、4次離散化、非線形レオロジーの選択のためのニュートン、安定化など)を使用する場合、頂点セパレーターのサイズは約2倍になるため、直接解析のコストは約8倍になりますMGの問題依存)。多くのタイムステップまたは最適化/ UQループでは、これらの違いは重要です。
ジェドブラウン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.