Member 14915155 Ответов: 2

Как сделать матричное умножение на части в C++


Мне нужна помощь, я не могу представить себе код C++ для этого.
Я должен решить матричный мульт. A*B=C и A-это 256x128 элементов, А B-128x256 элементов, поэтому C-это 256x256 элементов.
Но чтобы решить эту проблему, мне нужно создать "секции" матрицы A и B (например, Asection=4x128 и Bsection 128x4 и этот мульт. даст Csection=4x4 матрицу), а затем mult. Asection со следующим разделом B (Bsection закончен на колонке 4, поэтому следующий раздел 128x4, но начинается в колонке 5). И этот новый мульт. даст следующий Csection и т. д.
Эта ссылка имеет представление о проблеме

Imgur: магия интернета[^]

Дело в том, что на самом деле A B и C-это не "матрицы", а векторы, поэтому A=[0,1,2....127(здесь заканчивается первая строка),128,129....255 (2-я строка и т. д. до 32768 элементов)], то же самое для B и C. (pd: я знаю, что векторы-это матрицы, но вы знаете, что я имею в виду).

Я сделал код, но только для простого матричного мульта, у A есть 2048 элементов и B тоже (64x32 и 32x64). Это структура мульта в моей первоначальной задаче, и она может быть первой "секцией" C, но я не знаю, как поместить остальные секции C.

Что я уже пробовал:

for (int i = 0; i < 64; i++)
{
for (int j = 0; j < 64; j++)
{
for (int k = 0; k < 32; k++)
{
С[Я * 64 + Дж] += а[я * 32 + К] * Б[Дж * 32 + к];

}
}
}

0x01AA

Для меня ваш код выглядит прекрасно. "Секции" 'C' вычисляются по 'i*64', пока вы делаете это: 'C[i*64+j]'. Или что я упускаю?

2 Ответов

Рейтинг:
2

0x01AA

Предисловие
Конечно, в c++ возможны гораздо более элегантные решения. Это в том случае, если вы реализуете матрицу классов (и вектор). Но это был не твой вопрос.

Пробная реализация в соответствии с вашим вопросом
Вот такая реализация полностью непроверенный, но я думаю, что из-за некоторых многозначительных названий более легко понять и, надеюсь, исправить. И еще: я предполагаю, что матрицы содержат двойные значения. Измените тип в соответствии с вашими потребностями.

void MatrixMul(double A[], int ARows, int ACols,
               double B[], int BRows, int BCols,
               double C[])
{
    // Assertion test. For matrix multiplication the left hand column count needs to match the right hand row count.  
    if (ACols != BRows)
    {
      throw(*new Exception("Dimension Error"));
    }

   int CRows= ARows; // Result Rows
   int CCols= BCols; // Result Cols

   for(int CRowIx= 0; CRowIx < CRows; CRowIx++)
   {
      for(int CColIx= 0; CColIx < CCols; CColIx++)
      {
         double Sum= 0.0; // Assuming the matrices hold double values. 
         for(int k= 0; k < ACols; k++)
         {
            // sum+= B[k][CColIx] * A[CRowIx][k];
            Sum+= B[k * BCols + CColIx] * A[CRowIx * ACols + k];
         }
         // C[CRowIx][CColIx]= sum;
         C[CRowIx * CCols + CColIx]= Sum;
     }
   }
}


Записи
Конечно, необходимо больше проверять диапазон индексов, чтобы сделать его безопасным для" нарушения доступа".

Надеюсь, это поможет.


0x01AA

Бу-у-у, надеюсь, я наконец-то закончила со всеми исправлениями :румянец:. Или со словами Траппатони: "Ich habe fertig" здесь Траппатони - ич хабе фертиг! Die legendäre Pressekonferenz vom 10.03.1998 - YouTube[^] :-)

Sandeep Mewara

+5!

0x01AA

Большое спасибо. Надеюсь, я не перепутал строки и столбцы, как обычно делаю в своем коде :-)

Sandeep Mewara

:-Д ... ну, в основном это не так...далее, Эй, вы никогда не можете сбрасывать со счетов усилия.

0x01AA

спасибо снова

Stefan_Lang

По-моему, все в порядке, но если вы укажете на "значимые имена", возможно, вам следует пройти весь путь и написать имена, а не выбирать аббревиатуры, например column_index, а не ColIx. В то время как ваша версия может быть воспринята достаточно хорошо, моя требует значительно меньше усилий, чтобы прочитать и понять.

А написание длинных имен-это не проблема в век современных функций автозаполнения! ;-)

Что касается вашего страха перепутать строки и столбцы, то лучше всего использовать матричную библиотеку, такую как Eigen, или же реализовать матричный класс самостоятельно с функциями явного выбора конкретной строки или столбца - тогда это практически невозможно испортить, и вам не нужно каждый раз помнить, как хранятся данные.

0x01AA

Спасибо Вам за ваши отзывы.

Рейтинг:
0

Richard MacCutchan

Вы можете создавать матричные объекты в памяти, просто используя 2-мерные массивы. Итак, для вашего примера вы бы закодировали:

#define A_ROWS   256
#define A_COLS   128
#define B_ROWS   A_COLS
#define B_COLS   A_ROWS

int A[A_ROWS][A_COLS];
int B[B_ROWS][B_COLS];

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