7

1つの分散行列が対角であるかどうかをテストする必要があります。そうでない場合は、コレスキーLDL分解を行います。しかし、テストするための最も信頼性が高く、最速の方法は、行列の対角線ですか?私はFortranを使用しています。

最初に頭に浮かぶのは、行列のすべての要素の合計を取り、その合計から対角要素を差し引くことです。答えが0の場合、行列は対角です。より良いアイデアはありますか?

Fortranで私は書きます

!A is my matrix
k=0.0d0
do i in 1:n #n is the number of rows/colums
k = k + A(i,i)
end do

if(abs(sum(A)-k) < epsilon(k)*sum(A)) then
#do cholesky LDL, which I have to write myself, haven't found any subroutines for that  in Lapack or anywhere else
end if
4

2 に答える 2

11

すべての非対角要素をトラバースし、それらがゼロに近いかどうかをテストする方がはるかに優れています (不等式の浮動小数点数を比較すると、丸めエラーが発生しやすく、誤った結果につながる可能性があります)。

まず、違反している要素を見つけたら、すぐにトラバースを停止できます。違反しているマトリックスが一般的である場合、これにより時間を大幅に短縮できます。

第 2 に、コンパイラによるループ展開が改善され (Fortran コンパイラは優れた最適化戦略で知られています)、命令間の依存関係が少ないため、オンチップ実行が高速化される可能性があります。

これに加えて、提案されたアルゴリズムはオーバーフローとエラーの蓄積を起こしやすく、「トラバース アンド テスト」アルゴリズムはそうではないという事実を追加します。

于 2009-06-02T05:37:28.340 に答える
0

マトリックスでゼロ以外の値を検索する

logical :: not_diag
integer :: i, j

not_diag = .false.

outer: do i = 2, size(A,1)
  do j = i, size(A, 2)
    if (A(i,j) > PRECISION) then
      not_diag = .true.
      exit outer
    end if
  end
end outer

if (not_diag) then
  ! DO LDL' decomposition
end if

倍精度 LAPACK ルーチンを使用するには、最初の 's' を 'd' に置き換えます。したがって、spotrf は dpotrf になります

http://www.netlib.org/lapack/double/

于 2009-06-16T09:49:30.733 に答える