3

C++ では、6x6 行列の行列式を非常に高速に計算する必要があります。

これは、2x2 マトリックスに対してこれを行う方法です。

double det2(double A[2][2]) {
   return A[0][0]*A[1][1] - A[0][1]*A[1][0];
}

6x6 行列の行列式に同様の関数が必要ですが、6 が含まれているため、手で書きたくありません! = 720 項で、各項は行列の 6 つの要素の積です。

したがって、ライプニッツの式を使用したいと思います。

static int perms6[720][6];
static int signs6[720];
double det6(double A[6][6]) {
  double sum = 0.0;
  for(int i = 0; i < 720; i++) {
     int j0 = perms6[i][0];
     int j1 = perms6[i][1];
     int j2 = perms6[i][2];
     int j3 = perms6[i][3];
     int j4 = perms6[i][4];
     int j5 = perms6[i][5];
     sum += signs6[i]*A[0]*A[j0]*A[1]*A[j1]*A[2]*A[j2]*A[3]*A[j3]*A[4]*A[j4]*A[5]*A[j5];
  }
  return sum; 
}

順列と記号を見つけるにはどうすればよいですか?

関数がさらに高速になるように、コンパイラにもっと多くの作業 (C マクロやテンプレート メタプログラミングなど) を実行させる方法はありますか?

編集:次のコード(Eigen)の時間を計測しました:

Matrix<double,6,6>  A;
// ... fill A

for(long i = 0; i < 1e6; i++) {
    PartialPivLU< Matrix<double,6,6> > LU(A);
    double d = LU.determinant();
}

1.25秒まで。したがって、LU またはガウス分解を使用することは、間違いなく私の使用には十分高速です!

4

2 に答える 2

4

ガウス法を使用して行列を上三角にします。すべての演算について、行列式がどのように変更されるか (変更されずに定数を乗算するか) を知ってdおり、それは で機能しO(n^3)ます。その後、主対角線に数字を掛けて、すべてdの積に削除するだけです

于 2013-08-17T10:34:13.327 に答える
3

Eigenを使用してください。例はここにあります。

于 2013-08-17T10:51:03.130 に答える