Можете ли вы использовать существующие пакеты линейной алгебры? Если вы имеете дело с примитивными типами, например, double
BLAS, вероятно, является наиболее оптимальным способом для go, но может иметь крутой кривой обучения. Для высокооптимизированной, но очень удобной библиотеки Eigen - один из моих любимых вариантов для таких задач в c ++.
Я очень рекомендую использовать существующий пакет линейной алгебры (даже не обязательно Я упомянул). Было бы легче выбросить sh ваших идей, поскольку фактическая реализация позаботилась о пакете. Не говоря уже о том, что такие пакеты существуют годами (несколько десятилетий в случае BLAS) и должны быть очень ОЧЕНЬ хороши в таких задачах. Если вы действительно не знаете, что делаете (имейте в виду очень очень конкретную задачу c с конкретными оптимизациями c, в которые вы можете кодировать) Я сомневаюсь, что вы можете оптимизировать так же легко, как и эти библиотеки, самостоятельно (если вообще) , Даже тогда, есть анализ затрат и выгод, чтобы рассмотреть: собираюсь ли я делать это сам по себе, сколько времени займет существующий хороший пакет?
Хотя я настоятельно рекомендую не делать это самостоятельно, если Вы обязательно должны сделать это сами, один вопрос, который неясен: все ли блоки одинакового размера? Кроме того, в какой форме хранятся матрицы, столбец или мажор строки? Предполагаемые блоки одинакового размера, и у вас есть основная форма строки, эскиз того, что вы могли бы сделать, это перебрать блоки и перевести умножение блочных блоков в обобщенную c функцию умножения матриц. Я сбрасываю double*&
и прохожу только указатели double*
. operator[]
должен позаботиться о ссылке на правильное местоположение, но проверьте, что я правильно выполнил арифметику c внутри []
, а также:
РЕДАКТИРОВАТЬ: Если A
и B
сохраняя только верхние блоки tri angular Я исправил код
//Assuming all blocks are the same size
//Assuming matrix stored in row major form
#define NUMBER_OF_BLOCKS = MATRIX_SIZE/BLOCK_SIZE
void block_mult2(double* A, double* B, double* C){
for(size_t i=0; i<NUMBER_OF_BLOCKS; i++)
for(size_t j=0; j<NUMBER_OF_BLOCKS; j++)
for(size_t k=0; k<NUMBER_OF_BLOCKS; k++)
mult2(A[min(i,j)*BLOCK_SIZE*NUMBER_OF_BLOCKS + max(i,j)*BLOCK_SIZE],
B[min(j,k)*BLOCK_SIZE*NUMBER_OF_BLOCKS + max(j,k)*BLOCK_SIZE],
C[i*BLOCK_SIZE*NUMBER_OF_BLOCKS + k*BLOCK_SIZE]);
return;
}
void mult2(double* A, double* B, double* C){
for(size_t i=0; i<BLOCK_SIZE; i++)
for(size_t j=0; j<BLOCK_SIZE; j++)
for(size_t k=0; k<BLOCK_SIZE; k++)
C[i*BLOCK_SIZE+k] = A[min(i,j)*BLOCK_SIZE+max(i,j)]*B[min(j,k)*BLOCK_SIZE+max(j,k)];
return;
}
Не могу не подчеркнуть, насколько я рекомендую вам отбросить все это и потратить немного времени на изучение пакета линейной алгебры. Вы избавите себя от множества технических вопросов (например, только что возникших: правильно ли я сделал арифметику указателей c?), И вы могли бы использовать этот пакет для еще многих задач. Думаю, это пойдет на пользу вашей общей работе.