1

Buffer.BlockCopy を使用して、ベクトル (1D 配列) X から N x M 行列 (2D 配列) Y を作成しています。

double[] X = new double[N];
double[,] Y = new double[N, M];
for (int i = 0; i < N; ii++)
{
    X[ii] = ii;
}

for (int targetRow = 0; targetRow < N; targetRow++)
{
    Buffer.BlockCopy
    (
        X,                                                              // source vector
        targetRow * sizeof(double),                                     // source vector offset
        Y,                                                              // target 2D array
        (targetRow * M) * sizeof(double),                               // target array offset
        ((N - targetRow) > M ? M : (N - targetRow)) * sizeof(double)    // count
    );
}

Buffer.BlockCopy を使用して、その行列の転置も作成したいと思います。コードのカウント部分を理解するのに苦労しています。

double[,] YT = new double[M, N];
for (int targetRow = 0; targetRow < N; targetRow++)
{
    Buffer.BlockCopy
    (
        X,                                   // source vector
        targetRow * sizeof(double),          // source vector offset
        YT,                                  // target (destination) 2D array
        (targetRow * N) * sizeof(double),    // target array offset
        (N - targetRow) * sizeof(double)     // count
    );
}

私はいくつかのバリエーションを試しましたが、しばらくの間これを見つめてきました. どんな提案でも大歓迎です。ループを使用しないことをお勧めします。あなたが提供できるかもしれない提案や助けをありがとう.

問題は、M 行で停止する必要がある Buffer.BlockCopy で転置を作成するために、X の N 行すべてをトラバースする必要があることです。

編集:

私はそれを理解したと思います: Buffer.BlockCopy は次のように読む必要があります:

double[,] YT = new double[M, N];
for (int targetRow = 0; targetRow < M; targetRow++)
{
    Buffer.BlockCopy
    (
        X,                                   // source vector
        targetRow * sizeof(double),          // source vector offset
        YT,                                  // target (destination) 2D array
        (targetRow * N) * sizeof(double),    // target array offset
        (N - targetRow) * sizeof(double)     // count
    );
}
4

1 に答える 1

0

N×M行列がこのように行ごとに順番に格納されている場合

A = [R1C1, R1C2, .. , R1CM, R2C1, R2C2, .. , R2CM, ... , RNC1, RNC2 , .. , RNCM]

次に、インデックスを指定するk=0..N*M-1と、行番号と列番号が次のように検出されます

i = k/M;  // row #
j = k%M;  // col #

kシーケンシャル マトリックスのインデックスを生成するには、次のようにしますk = M*i+j。たとえば、列を持つ配列の 3 行目 ( i=2) と 5 列目 ( )はであるため、その値を含める必要があります。j=4M=10k=10*2+4 = 24A[24]

転置された要素のインデックスは ですk_t = N*j+i = N*(k%M)+(k/M)。たとえば、上記の値を使用すると (行N=7を使用)、k_t = 7*4+2 = 30

だからあなたが必要Aとする転置を作成するにはB[k_t] = A[k]

for(k=0; k<N*M; k++)
{
    B[N*(k%M)+(k/M)] = A[k];
}

これを使用するにBlockCopy()は、 でスケーリングする必要がありますsizeof(double)

于 2013-11-13T23:36:09.543 に答える