【问题标题】:Matrix Multiplication Error in CC中的矩阵乘法错误
【发布时间】:2013-12-15 02:16:48
【问题描述】:

我一直在编写一些代码来使用 C 实现离散余弦变换。这是我用于矩阵乘法的代码。

float Yt[8][8][4];
float Y8[8][8][4]={{{0.980785,-0.555570,0.555570 ...}}};
float A[8][8]={{0.707107,0.707107 ... }};

for(k=0;k<4;++k){
        for(i=0;i<8;++i){
            for(j=0;j<8;++j){
            Yt[i][j][k]=0;
            }}}

for(k=0;k<4;++k){
    for(i=0;i<8;++i){
         for(j=0;j<8;++j){
            for(l=0;l<8;++l){
                Yt[i][j][k]+=A[i][l]*Y8[l][j][k];
                }}}}

Y8 是同一个 8x8 矩阵,重复 4 次。 我的代码成功编译并运行。但是,我收到的输出显然是不正确的。 Yt[i][j][k] for k=0,1,2,3 应该都是相同的值,但我最终得到 k=0,1 的正确值和 k=2,3 的不同值。

谁能明白为什么我得到的最后两个矩阵的值不正确?

【问题讨论】:

  • for(l=0;l&lt;8;++l)之前添加Yt[i][j][k] = 0.0
  • 我会添加一些代码来强制执行Y8[][][1:3] == Y8[][][0],然后再试一次。放在Yt的初始化循环里就行了:Y8[i][j][k] = Y8[i][j][0];

标签: c matrix matrix-multiplication


【解决方案1】:

@chux 在使用之前对它们的值进行了很好的初始化Yt。你可以这样做:

for(k=0;k<4;++k){
  for(i=0;i<8;++i){
    for(j=0;j<8;++j){
      double temp = 0.0;
      for(l=0;l<8;++l){
        temp += A[i][l]*Y8[l][j][k];
      }
      Yt[i][j][k] = temp;
    }
  }
}

这将允许编译器使用寄存器进行累加,然后只访问一次Yt(及其三个索引操作)。

【讨论】:

  • 我确实事先初始化了 Yt,只是将它排除在我的 OP 之外。而Y8只有3次是一样的,因为我现在用它来排查问题。 Y8 是来自图像的值矩阵
  • 确定Y8 是相同的四次吗?如果您将代码修改为Yt[i][j][k]+=A[i][l]*Y8[l][j][0]; 怎么办 - 如果您的矩阵乘法错误,它仍然应该是错误的。如果它突然正确,那么Y8 不是你想的那样。
  • 按照您的建议运行它,所有值都按预期出现。我想我需要仔细看看Y8
【解决方案2】:

初始化Yt[i][j][k]

我怀疑这将按如下方式完成

for(j=0;j<8;++j){
  Yt[i][j][k] = 0.0;
  for(l=0;l<8;++l){
    Yt[i][j][k] += A[i][l]*Y8[l][j][k];
  }
}

... 或在其声明中。类似double Yt[8][8][4] = { 0.0 };

【讨论】:

  • 你得到 +1 是因为它首先是你的想法……如果你只使用一次声明就可以了——在循环内部初始化更健壮。我更喜欢使用临时变量(更快,不需要聪明的编译器)
猜你喜欢
  • 2013-12-18
  • 1970-01-01
  • 2021-08-30
  • 2016-05-22
  • 2016-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多