6

最初のスレッドに従って、cMinor からc-sharp の対称行列のコピーを効率的にします。

古典的な行列の代わりに、行列の配列実装を使用して、1 つの行ベクトルと 1 つの列ベクトルを使用して対称正方行列乗算を構築する方法について、いくつかの入力を使用すると非常に興味深いでしょう。

long s = 0;
List<double> columnVector = new List<double>(N); 
List<double> lineVector = new List<double>(N); 
//- init. vectors and symmetric square matrix m

for (int i=0; i < N; i++)
{
    for(int j=0; j < N; j++){
        s += lineVector[i] * columnVector[j] * m[i,j];
    }
}

ご意見ありがとうございます。

4

3 に答える 3

7

行ベクトルに対称行列を掛けた値は、行列の転置に列ベクトルを掛けた値に等しくなります。したがって、列ベクトルのケースのみを考慮する必要があります。

元々、 のi-th 要素y=A*xは次のように定義されています。

y[i] = SUM( A[i,j]*x[j], j=0..N-1 )

しかしAは対称であるため、合計は対角線の下と上に分割されます。

y[i] = SUM( A[i,j]*x[j], j=0..i-1) + SUM( A[i,j]*x[j], j=i..N-1 )

他の投稿から、マトリックスインデックスは

A[i,j] = A[i*N-i*(i+1)/2+j]  // j>=i
A[i,j] = A[j*N-j*(j+1)/2+i]  // j< i

N×N対称行列の場合A = new double[N*(N+1)/2];

C#コードでは、上記は次のとおりです。

int k;
for(int i=0; i<N; i++)
{
    // start sum with zero
    y[i]=0;
    // below diagonal
    k=i;
    for(int j=0; j<=i-1; j++)
    {                    
        y[i]+=A[k]*x[j];
        k+=N-j-1;
    }
    // above diagonal
    k=i*N-i*(i+1)/2+i;
    for(int j=i; j<=N-1; j++)
    {
        y[i]+=A[k]*x[j];
        k++;
    }
}

あなたが試す例:

| -7  -6  -5  -4  -3 | | -2 |   | -5 |
| -6  -2  -1   0   1 | | -1 |   | 21 |
| -5  -1   2   3   4 | |  0 | = | 42 |
| -4   0   3   5   6 | |  1 |   | 55 |
| -3   1   4   6   7 | |  7 |   | 60 |

二次形式を取得するには、乗算結果ベクトルでドット積を実行しますx·A·y = Dot(x,A*y)

于 2012-05-23T14:52:19.933 に答える
4

安全でないコードを使用すると、行列の乗算をかなり高速にすることができます。私はそれについてブログを書きました

于 2012-05-23T11:19:20.770 に答える
0

行列の乗算をできるだけ速くするのは簡単です。よく知られているライブラリを使用してください。そのようなライブラリには、非常に多くのパフォーマンス作業が行われています。あなたはそれと競争することはできません。

于 2012-05-23T12:04:31.160 に答える