Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 递归块矩阵乘法_C_Algorithm_Matrix Multiplication - Fatal编程技术网

C 递归块矩阵乘法

C 递归块矩阵乘法,c,algorithm,matrix-multiplication,C,Algorithm,Matrix Multiplication,尝试递归地实现块矩阵乘法。它适用于2x2的矩阵,但如果增加到4x4等大小,则答案会大不相同 循环的结果为3 1.53 0.89 0.53 1.33 1.75 1.09 0.72 1.17 1.78 1.43 0.57 1.69 1.73 1.04 0.62 1.51 递归结果 1.34 1.49 0.30 1.45 2.02 1.93 0.79 1.30 2.70 2.75 0.87 2.21 1.81 1.84 0.59 1.47 如果矩阵中的块数大于4,我将块分为四个较大的

尝试递归地实现块矩阵乘法。它适用于2x2的矩阵,但如果增加到4x4等大小,则答案会大不相同

循环的结果为3

1.53 0.89 0.53 1.33 
1.75 1.09 0.72 1.17 
1.78 1.43 0.57 1.69 
1.73 1.04 0.62 1.51 
递归结果

1.34 1.49 0.30 1.45 
2.02 1.93 0.79 1.30 
2.70 2.75 0.87 2.21 
1.81 1.84 0.59 1.47
如果矩阵中的块数大于4,我将块分为四个较大的块,然后取平方根得到新的维数,就像这样,然后进行8次递归调用

void myRecMat(float** MatrixA, float** MatrixB, float** MatrixC, int srA, int scA, int srB, int scB, int srC, int scC, int blocks,int dim){
 if(blocks > 4) 
{ blocks=blocks/4;
      int newDim = dim/2;

        myRecMat(MatrixA,MatrixB,MatrixC, srA,scA,srB,scB,srC,scC,blocks,newDim);
        myRecMat(MatrixA,MatrixB,MatrixC, srA,scA+newDim,srB+newDim,scB,srC,scC,blocks,newDim);
        myRecMat(MatrixA,MatrixB,MatrixC, srA,scA,srB,scB+newDim,srC,scC+newDim,blocks,newDim);
        myRecMat(MatrixA,MatrixB,MatrixC, srA,scA+newDim,srB+newDim,scB,srC+newDim,scC,blocks,newDim);
        myRecMat(MatrixA,MatrixB,MatrixC, srA+newDim,scA,srB,scB,srC+newDim,scC,blocks,newDim);
        myRecMat(MatrixA,MatrixB,MatrixC, srA+newDim,scA+newDim,srB+newDim,scB,srC+newDim,scC,blocks,newDim);
        myRecMat(MatrixA,MatrixB,MatrixC, srA+newDim,scA+newDim,srB,scB+newDim,srC+newDim,scC+newDim,blocks,newDim);
        myRecMat(MatrixA,MatrixB,MatrixC, srA+newDim,scA+newDim,srB+newDim,scB+newDim,srC+newDim,scC+newDim,blocks,newDim); }                   
else
{
 int i,j,k,endR,endC;
 endR=srC+dim;
 endC=scC+dim;


 for(i=srC; i< endR; i++)
        for(j=scC;j< endC;j++)
            for(k=0; k<newDim; k++) 
                    c[i][j] += a[i][k]*b[k][j];

}
}
void myRecMat(float**MatrixA,float**MatrixB,float**MatrixC,int srA,int scA,int srB,int scB,int srC,int scC,int blocks,int dim){
如果(块>4)
{块=块/4;
int newDim=dim/2;
myRecMat(MatrixA、MatrixB、MatrixC、srA、scA、srB、scB、srC、scC、blocks、newDim);
myRecMat(MatrixA、MatrixB、MatrixC、srA、scA+newDim、srB+newDim、scB、srC、scC、blocks、newDim);
myRecMat(MatrixA、MatrixB、MatrixC、srA、scA、srB、scB+newDim、srC、scC+newDim、blocks、newDim);
myRecMat(MatrixA、MatrixB、MatrixC、srA、scA+newDim、srB+newDim、scB、srC+newDim、scC、blocks、newDim);
myRecMat(MatrixA、MatrixB、MatrixC、srA+newDim、scA、srB、scB、srC+newDim、scC、blocks、newDim);
myRecMat(MatrixA、MatrixB、MatrixC、srA+newDim、scA+newDim、srB+newDim、scB、srC+newDim、scC、blocks、newDim);
myRecMat(MatrixA、MatrixB、MatrixC、srA+newDim、scA+newDim、srB、scB+newDim、srC+newDim、scC+newDim、blocks、newDim);
myRecMat(MatrixA、MatrixB、MatrixC、srA+newDim、scA+newDim、srB+newDim、scB+newDim、srC+newDim、scC+newDim、blocks、newDim);}
其他的
{
int i,j,k,endR,endC;
endR=srC+dim;
endC=scC+dim;
对于(i=srC;i对于(k=0;k我相信这里的问题不在于方法的实现,而在于浮点运算的精度损失。有时人们可能会认为这种不精确性是可以忽略的,但当我们对浮点变量进行密集运算时,如三重嵌套循环,这些不精确性变得非常重要

解决这个问题的一种方法是缩放浮点数,使其“丢失”小数部分。例如,如果您知道矩阵中的数字不会超过两个小数位数,则将它们全部乘以100,得到它们的整数表示形式。然后对整数执行算术运算(精确),最后得到结果的浮点表示形式,并将其除以100


希望这能有所帮助。

我相信您的问题不在于方法的实现,而在于浮点运算的精度损失。有时人们可能会认为这种不精确性是可以忽略的,但当我们对浮点变量进行密集运算时,如三重嵌套循环,这些不精确性就会变成符号重要的

解决这个问题的一种方法是缩放浮点数,使其“丢失”小数部分。例如,如果您知道矩阵中的数字不会超过两个小数位数,则将它们全部乘以100,得到它们的整数表示形式。然后对整数执行算术运算(精确),最后得到结果的浮点表示形式,并将其除以100


希望这有帮助。

我已经编译并仔细调试了您的代码。如果您只想在2^k*2^k的矩阵上使用此函数,这两个修改将有所帮助

第一:

for(i=srC; i< endR; i++) {
    for(j=scC;j< endC;j++) {
        for(k=0; k<newDim; k++) 
            /*c[i][j] += a[i][k]*b[k][j];*/
            c[i][j] += a[i][scA+k] * b[srB+k][j];
    }
}

我已经编译并仔细调试了您的代码。如果您只打算在2^k*2^k
矩阵上使用此函数,这两个修改将有所帮助

第一:

for(i=srC; i< endR; i++) {
    for(j=scC;j< endC;j++) {
        for(k=0; k<newDim; k++) 
            /*c[i][j] += a[i][k]*b[k][j];*/
            c[i][j] += a[i][scA+k] * b[srB+k][j];
    }
}

请添加您的函数声明添加声明。请添加您的函数声明添加声明。虽然我的脑海中出现了true和想法,但我不认为我会像这样改变答案,无论您选择通过3 for循环迭代相乘还是通过将矩阵向上分割递归相乘。缩放浮点值是一个简单的问题尤其是当你考虑矩阵乘法是集合Q中的闭运算(假设矩阵成分也是Q)时,这样做的愚蠢方式。。最好是使用带有分子/分母的对象,并通过缩放分母来执行除法。最终结果是没有精度损失,这甚至比使用浮点值造成的损失要好。虽然我想到了这一点,但我不认为无论您选择乘法,我都会这样改变答案矩阵迭代3通过循环或递归地将它们分开。缩放浮点数是一种愚蠢的方式,尤其是当考虑矩阵乘法是集合Q中的闭运算(假设矩阵成分也是Q)的情况下。。最好使用带有分子/分母的对象,并通过缩放分母进行除法。最终结果是没有精度损失,甚至比使用浮点值造成的损失更好。使用mods进行测试,第一部分是yay,第二部分是nay。我对第二部分进行了必要的修改。在rega中rds到第一个,看起来我需要a的行和b的列的偏移量,因此数字不能相加。在第二部分,当我将矩阵的另一个幂增加到2,8X8时,因为它的工作方式与4X4所示的一样,它只正确地处理了角点,中间部分由于缺少注释掉的部分而关闭s、 无论如何,谢谢你的帮助。嗯……我用一些较大的矩阵(8x816x16,随机生成的值)再次尝试了修改后的代码,用在线矩阵计算器检查结果,对我来说效果很好。我猜行/列定义可能有问题。k循环条件不应该是k