2013-11-13 2 views
1

Я использую Buffer.BlockCopy создать N х M матрицу (2D массив) Y из вектора (1D массив) X.C#: Можно ли создать транспонирование матрицы с использованием Buffer.BlockCopy

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 
    ); 
} 

Я пробовал несколько вариантов, и я смотрел на это некоторое время. Любые предложения будут ценны. Я бы предпочел не использовать цикл. Благодарим вас за любые предложения или помощь, которые вы можете предоставить.

Проблема заключается в том, что мне нужно пройти все N строк X еще до создания транспонирования в Buffer.BlockCopy Мне нужно остановиться на M строк.

EDIT:

Я думаю, что я понял это: 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 
    ); 
} 
+0

Где находится 'XX'? – ja72

+0

Приношу свои извинения, он должен читать X, а не XX. – PBrenek

+0

Элементы в транспонированной матрице не расположены последовательно, поэтому вы не можете копировать с помощью «BlockCopy». – ja72

ответ

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=4) для массива с столбцами M=10: k=10*2+4 = 24, поэтому A[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).

+0

Благодарим вас за ответ. Я не хочу прокручиваться так, как указано. Кроме того, отредактированная версия Buffer.BlockCopy, которую я разместил ниже вопроса, работает. Я понял это, когда понял, что мне нужны только M строк. – PBrenek

+0

Я исправил некоторую ошибку в вычислении индекса. Попробуй еще раз. – ja72

 Смежные вопросы

  • Нет связанных вопросов^_^