2013-04-20 3 views
4

Я хочу выполнить умножение матрицы блоков (разделите matirix на несколько sxs-матриц и умножьте соответствующие блоки). Я написал код следующим образом образец кода архитектуры книги Хеннеси:Умножение матричной матрицы

for(int jj=0;jj<=(n/s);jj += s){ 
      for(int kk=1;kk<=(n/s);kk += s){ 
        for(int i=1;i<=(n/s);i++){ 
          for(int j = jj; j<=((jj+s-1)>(n/s)?(n/s):(jj+s-1)); j++){ 
            temp = 0; 
            for(int k = kk; k<=((kk+s-1)>(n/s)?(n/s):(kk+s-1)); k++){ 
              temp += b[i][k]*a[k][j]; 
            } 
            c[j][i] += temp; 
          } 
        } 
      } 
    } 

Здесь пхп есть размер исходной матрицы. a, b имеют одинаковый размер. Я разделяю матрицы a, b на блоки размера sxs. В моей программе я дал размер блока равным 4. Я положил все элементы a, b как 5, константу и n = 1000. Однако я получаю неправильные значения в моем результате. Я здесь что-то не так? Застрял на этом за последние 2 часа. Можете ли вы, ребята, помочь, если это возможно. Код ссылки в книге, как это:

for (jj = 0; jj <= size; jj += N) { 
    for (kk = 1; kk <= size; kk += N) { 
     for (i = 1; i <= size; i++) { 
      for (j = jj; j <= findMin(jj+N-1, size); j++) { 
       temp = 0; 
       for (k = kk; k <= findMin(kk+N-1, size); k++) { 
        temp += B[i][k] * A[j][k]; 
       } 
       C[j][i] += temp; 
      } 
     } 
    } 
} 

Здесь S = N и размер = п/с

+1

Вы можете отогнать это в небольшой образец кода с помощью ввода, который создает проблему и объясняет, что вы ожидаете от ответа? –

+0

Голосование, чтобы закрыть, как почему этот код не работает. –

ответ

4
for(int jj=0;jj<N;jj+= s){ 
     for(int kk=0;kk<N;kk+= s){ 
       for(int i=0;i<N;i++){ 
         for(int j = jj; j<((jj+s)>N?N:(jj+s)); j++){ 
           temp = 0; 
           for(int k = kk; k<((kk+s)>N?N:(kk+s)); k++){ 
             temp += a[i][k]*b[k][j]; 
           } 
           c[i][j] += temp; 
         } 
       } 
     } 
} 

AxB размер N

1

На первый взгляд я удивлен увидеть как 0 и 1, начиная индексы и < = для тестов завершения цикла. Книги с кодом fortran или matlab иногда имеют 1 основанную на индексировании, тогда как c/C++ использует индексирование на основе 0.

Вы также можете реализовывать и/или проверять внутренние два для циклов отдельно, поскольку они предназначены для одноблочного умножения матрицы.

Я бы оставил функцию findMin отдельной, а не вставлял ее в цикл теста.

2

Ошибка указана в этой строке. У вас есть

temp += b[i][k]*a[k][j]; 

и вы должны иметь

temp += b[i][k]*a[j][k]; 

вместо этого.

Было бы лучше, если бы вы могли бы поставить этот кусок в функции вместо этой строки:

((jj+s-1)>(n/s)?(n/s):(jj+s-1)); 
+0

Спасибо. Я положил его туда, потому что вызов функции так много раз не подходит для производительности. И спасибо за указание на ошибку. –

+1

@JustinCarrey «вызывающая функция так много раз не хороша для производительности», это неверно. Первоначальная удобочитаемость, производительность, только если это явно проблема. – Andrei

+0

полностью согласен с @Andrei. Если вас действительно беспокоит, вы можете использовать ключевое слово «inline». Btw. В этом случае компилятор будет использовать его для вас, поэтому вам даже не нужно ничего делать. –