简体   繁体   English

在C中将矩阵相乘

[英]multiply matrices in loop in C

I am attempting to multiply several matrices using a loop in C . 我试图使用C的循环将几个矩阵相乘。 I obtain the expected answer in R , but cannot obtain the expected answer in C . 我在R获得了预期的答案,但在C却没有获得预期的答案。 I suspect the problem is related to the += function which seems to double the value of the product after the first iteration of the loop. 我怀疑问题与+=函数有关,该函数似乎在循环的第一次迭代后将乘积的值加倍。

I am not very familiar with C and have not been able to replace the += function with one that will return the expected answer. 我对C不太熟悉,还无法用+=函数替换将返回预期答案的函数。

Thank you for any advice. 感谢您的任何建议。

First, here is the R code that returns the expected answer: 首先,这是返回预期答案的R代码:

B0 = -0.40
B1 =  0.20

mycov1 = exp(B0 + -2 * B1) / (1 + exp(B0 + -2 * B1))
mycov2 = exp(B0 + -1 * B1) / (1 + exp(B0 + -1 * B1))
mycov3 = exp(B0 +  0 * B1) / (1 + exp(B0 +  0 * B1))
mycov4 = exp(B0 +  1 * B1) / (1 + exp(B0 +  1 * B1))

trans1 = matrix(c(1 - 0.25 - mycov1,     mycov1,   0.25 * 0.80,              0,
                                  0,   1 - 0.50,             0,    0.50 * 0.75,
                                  0,          0,             1,              0,
                                  0,          0,             0,              1), 
               nrow=4, ncol=4, byrow=TRUE)

trans2 = matrix(c(1 - 0.25 - mycov2,     mycov2,   0.25 * 0.80,              0,
                                  0,   1 - 0.50,             0,    0.50 * 0.75,
                                  0,          0,             1,              0,
                                  0,          0,             0,              1), 
               nrow=4, ncol=4, byrow=TRUE)

trans3 = matrix(c(1 - 0.25 - mycov3,     mycov3,   0.25 * 0.80,              0,
                                  0,   1 - 0.50,             0,    0.50 * 0.75,
                                  0,          0,             1,              0,
                                  0,          0,             0,              1), 
               nrow=4, ncol=4, byrow=TRUE)

trans4 = matrix(c(1 - 0.25 - mycov4,     mycov4,   0.25 * 0.80,              0,
                                  0,   1 - 0.50,             0,    0.50 * 0.75,
                                  0,          0,             1,              0,
                                  0,          0,             0,              1), 
               nrow=4, ncol=4, byrow=TRUE)

trans2b <- trans1  %*% trans2
trans3b <- trans2b %*% trans3
trans4b <- trans3b %*% trans4
trans4b

#
# This is the expected answer
#
#            [,1]      [,2]      [,3]      [,4]
# [1,] 0.01819965 0.1399834 0.3349504 0.3173467
# [2,] 0.00000000 0.0625000 0.0000000 0.7031250
# [3,] 0.00000000 0.0000000 1.0000000 0.0000000
# [4,] 0.00000000 0.0000000 0.0000000 1.0000000
#

Here is my C code. 这是我的C代码。 The C code is fairly long because I do not know C well enough to be efficient: C代码相当长,因为我对C不够了解,无法高效使用:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

char quit;

int main(){

int i, j, k, ii, jj, kk ;

double B0, B1, mycov ;

double trans[4][4]     = {0} ;

double prevtrans[4][4] = {{1,0,0,0},
                          {0,1,0,0},
                          {0,0,1,0},
                          {0,0,0,1}};

B0 = -0.40 ;
B1 =  0.20 ;

for (i=1; i <= 4; i++) {

          mycov = exp(B0 + B1 * (-2+i-1)) / (1 + exp(B0 + B1 * (-2+i-1))) ;

          trans[0][0] =     1 - 0.25 - mycov ;
          trans[0][1] =                mycov ;
          trans[0][2] =          0.25 * 0.80 ;
          trans[0][3] =                    0 ;

          trans[1][0] =                    0 ;
          trans[1][1] =             1 - 0.50 ;
          trans[1][2] =                    0 ;
          trans[1][3] =          0.50 * 0.75 ;

          trans[2][0] =                    0 ;
          trans[2][1] =                    0 ;
          trans[2][2] =                    1 ;
          trans[2][3] =                    0 ;

          trans[3][0] =                    0 ;
          trans[3][1] =                    0 ;
          trans[3][2] =                    0 ;
          trans[3][3] =                    1 ;

          for (ii=0; ii<4; ii++){

               for(jj=0; jj<4; jj++){

                    for(kk=0; kk<4; kk++){

                         trans[ii][jj] += trans[ii][kk] * prevtrans[kk][jj] ;

                    }
               }
          }

          prevtrans[0][0] =     trans[0][0] ;
          prevtrans[0][1] =     trans[0][1] ;
          prevtrans[0][2] =     trans[0][2] ;
          prevtrans[0][3] =     trans[0][3] ;
          prevtrans[1][0] =     trans[1][0] ;
          prevtrans[1][1] =     trans[1][1] ;
          prevtrans[1][2] =     trans[1][2] ;
          prevtrans[1][3] =     trans[1][3] ;
          prevtrans[2][0] =     trans[2][0] ;
          prevtrans[2][1] =     trans[2][1] ;
          prevtrans[2][2] =     trans[2][2] ;
          prevtrans[2][3] =     trans[2][3] ;
          prevtrans[3][0] =     trans[3][0] ;
          prevtrans[3][1] =     trans[3][1] ;
          prevtrans[3][2] =     trans[3][2] ;
          prevtrans[3][3] =     trans[3][3] ;

}

  printf("To close this program type 'quit' and hit the return key\n");
  printf("               \n");
  scanf("%d", &quit);

  return 0;

}

Here is the final matrix returned by the above C code: 这是上面的C代码返回的最终矩阵:

0.4821  3.5870  11.68  381.22
0       1       0      76.875
0       0       5      0
0       0       0      5

This line 这条线

                     trans[ii][jj] += trans[ii][kk] * prevtrans[kk][jj] ;

is not right. 是不正确的。 You're modifying trans in place while you are still using it to compute the resultant matrix. 您仍在使用Trans来计算结果矩阵时,正在修改trans You need another matrix to store the result of the multiplication temporarily. 您需要另一个矩阵来临时存储乘法结果。 And then use: 然后使用:

      // Store the resultant matrix in temp.
      for (ii=0; ii<4; ii++){

           for(jj=0; jj<4; jj++){

                temp[ii][jj] = 0.0;

                for(kk=0; kk<4; kk++){

                     temp[ii][jj] += trans[ii][kk] * prevtrans[kk][jj] ;

                }
           }
      }

      // Transfer the data from temp to trans
      for (ii=0; ii<4; ii++){

           for(jj=0; jj<4; jj++){
                trans[ii][jj] = temp[ii][jj];
           }
      }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM