当前位置: 首页 > 知识库问答 >
问题:

对称块矩阵乘法

龙繁
2023-03-14

我试图乘以两个块对称矩阵(矩阵大小矩阵大小)。我想执行块矩阵乘法(将一个矩阵分成多个块大小矩阵,并将相应的块相乘)。我已经写了一些代码,但想改进它,并存储主对角线以上的块,但我没有任何想法。如果可能的话,你们能帮忙吗?

#define IND(A, x, y) A[y*MATRIX_SIZE+x]
void block_mult2(double*& A, double*& B, double*& C){
int i, j, k, i0, j0, k0;
for (i = 0; i < MATRIX_SIZE; i += BLOCK_SIZE)
for (j = 0; j < MATRIX_SIZE; j += BLOCK_SIZE)
for (k = 0; k < MATRIX_SIZE; k += BLOCK_SIZE)
    for (i0 = i; i0 < min(BLOCK_SIZE+i, MATRIX_SIZE); i0++)
        for (j0 = j; j0 < min(BLOCK_SIZE+j, MATRIX_SIZE); j0++)
            for (k0 = k; k0 < min(BLOCK_SIZE+k, MATRIX_SIZE); k0++)
                IND(C, i0, j0) += IND(A, i0, k0) * IND(B, k0, j0);
}

共有2个答案

闻鹤龄
2023-03-14
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;
                    }
            }
     }
 }

我很抱歉这个虚拟代码,但是你可以考虑N是你的块大小。

甄文彬
2023-03-14

你能使用现有的线性代数软件包吗?如果你要对付灵长类动物,比如doubleBLAS可能是最理想的方法,但可能会有一个陡峭的学习曲线。对于高度优化但非常用户友好的库,Eigen是我最喜欢的c语言任务之一。

我强烈建议使用现有的线性代数包(甚至不一定是我提到的那些)。这将使你的想法更容易充实,因为实际的实现是由包来处理的。更不用说这样的包已经存在了很多年(在BLAS的情况下是几十年),并且应该非常非常擅长这样的任务。除非你真的知道你在做什么(有一个非常非常具体的任务,你可以在代码中进行特定的优化),否则我怀疑你能像你自己一样轻松地优化这些库(如果有的话)。即便如此,还是有一个成本效益分析要考虑:我自己做这件事要花多少时间,而不是一个现有的好包?

虽然我强烈建议你不要自己动手,但如果你绝对必须自己动手,有一个问题是,所有的积木大小都一样吗?矩阵是以什么形式存储的,主要是列还是行?假设块大小相同,并且有行主形式,可以做的一个草图是迭代块,并将块乘法降级为通用矩阵乘法函数。我要把加倍*

编辑:如果AB仅存储上部三角形块,我更正了代码

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

我非常强调我建议你放弃所有这些,花点时间学习线性代数软件包。你将摆脱很多技术问题(例如:我做的指针算术正确吗?)你可以用这个软件包完成更多的任务。我认为这将有利于你的整体工作。

 类似资料:
  • 主要内容:逐元素矩阵乘法,矩阵乘积运算,矩阵点积矩阵乘法是将两个矩阵作为输入值,并将 A 矩阵的行与 B 矩阵的列对应位置相乘再相加,从而生成一个新矩阵,如下图所示: 注意:必须确保第一个矩阵中的行数等于第二个矩阵中的列数,否则不能进行矩阵乘法运算。 图1:矩阵乘法 矩阵乘法运算被称为向量化操作,向量化的主要目的是减少使用的 for 循环次数或者根本不使用。这样做的目的是为了加速程序的计算。 下面介绍 NumPy 提供的三种矩阵乘法,从而进一步

  • 问题内容: 在numpy中,我有N个3x3矩阵的数组。这将是我如何存储它们的示例(我正在提取内容): 我也有一个由3个向量组成的数组,这将是一个示例: 我似乎无法弄清楚如何通过numpy将它们相乘,从而实现如下效果: 与的形状(在投射到阵列)是。但是,由于速度的原因,列表实现是不可能的。 我尝试了各种换位的np.dot,但最终结果没有得到正确的形状。 问题答案: 使用 脚步 : 1)保持第一根轴对

  • 我想使用寄存器(逐行信息)通过向量算法创建矩阵乘法。打开外循环4次我有空洞matvec_XMM(双* a,双* x,双* y,整数n,整数磅)函数的问题,它返回了不好的结果,这是算法wchich我必须使用: 它是ma代码:

  • 特殊矩阵——对称矩阵(Symmetric Matrix) 注:压缩存储的矩阵可以分为特殊矩阵和稀疏矩阵。对于那些具有相同元素或零元素在矩阵中分布具有一定规律的矩阵,被称之为特殊矩阵。对于那些零元素数据远远多于非零元素数目,并且非零元素的分布没有规律的矩阵称之为稀疏矩阵。 1. 对称矩阵的概念 元素以主对角线为对称轴对应相等的矩阵。 2. 对称矩阵的特性 对角矩阵都是对称矩阵,对称矩阵必须是方形矩阵

  • 考虑两个矩阵A和B.如果A是mxn矩阵而B是nxp矩阵,它们可以相乘以产生mxn矩阵C.只有当A中的列数n等于数量时才可以进行矩阵乘法在B.中的行n 在矩阵乘法中,第一矩阵中的行的元素与第二矩阵中的对应列相乘。 在得到的矩阵C中的第 (i,j)位置中的每个元素是第i行的第i行中的元素与第二矩阵的第 j列中的对应元素的乘积的总和。 MATLAB中的矩阵乘法是使用*运算符执行的。 例子 (Exampl

  • 我有许多scipy稀疏矩阵(目前为CSR格式),需要与密集的numpy 1D向量相乘。该向量称为G: 每个稀疏矩阵都具有形状(163842097152),并且非常稀疏。密度约为4.0e-6。我有一个包含100个稀疏矩阵的列表,称为spmats。 我可以轻松地将每个矩阵与G相乘,如下所示: 这将产生一个形状密集向量列表(16384,)。 我的应用程序对性能相当关键,所以我尝试了另一种方法,即首先将所