Strassen matrix multiplication

Strassen matrix multiplication is achieved by recursively, the second order matrix multiplication will generally (can be extended to n-th order, but in claim Strassen matrix multiplication is a power of 2 n ) multiplications are needed to reduce 8 to 7, the calculated time O (nE3) is reduced from O (nE2.81).

Matrix C = A * B, can be written as
C11 = A11B11 + A12B21
a C12 A11B12 + A12B22 =
C21 = A21B11 + A22B21
to C22 A21B12 + = A22B22
If A, B, C is a matrix of second order, the common need to 4 multiplications and 8 additions. If the order is greater than 2, block matrix can be calculated. The amount of time O (nElg8) that is O (nE3).

To improve computation time complexity of the algorithm, necessary to reduce the number of multiplications. By ideological divide and conquer method, Strassen propose a new method to complete the second-order matrix multiplication multiplication by seven, the algorithm is as follows:

S1= B12 - B12
S2= A11 + A12
S3= A21 + A22
S4= B21 - B11
S5= A11 + A22
S6= B11 + B22
S7= A12 - A22
S8= B21 + B22
S9= A11 - A21
S10= B11 + B12

Ml = A11 (B12 - B12)
M2 = (A11 + A12) B22
M3 = (A21 + the A22) B11
M4 = the A22 (B21 of - B11)
M5 = (A11 + the A22) (B11 + B22)
M6 = (A12 - the A22 ) (B22 + B21 of)
M7 = (A11 - A21) (B11 + B12)
completed seven multiplications do the following addition:
C11 = M5 + M4 - M6 M2 +
a C12 Ml = M2 +
C21 + M3 = M4
to C22 = M5 + M1 - M3 - M7
all calculated using the 7 and 18 times of multiplication and subtraction, to reduce the computation time is O (nElg7) is about O (nE2.81). Computational complexity is greatly improved ..

 

  1 #include<stdio.h>
  2 #include<math.h>
  3 #define N 4
  4 
  5 void main(){
  6     void print(int A[][N],int n);
  7     void common(int A[][N],int B[][N],int C[][N],int n);
  8     void ADD(int A[][N],int B[][N],int C[][N],int n);
  9     void SUB(int A[][N],int B[][N],int C[][N],int n);
 10     void STRASSEN(int n,int A[][N],int B[][N],int C[][N]);
 11     int A[N][N];
 12     int    B[N][N];
 13     int C[N][N];
 14     int i,j,n;
 15     n=N;
 16     for(i=0;i<n;i++)                        //构造数组
 17         for(j=0;j<n;j++){
 18             A [I] [J] = RAND ()% 10 ;
 . 19              B [I] [J] = RAND ()% 10 ;
 20 is          }
 21 is      the printf ( " Array A: \ n- " );
 22 is      Print (A, n-) ;    
 23 is      the printf ( " array B: \ n- " );
 24      Print (B, n-);
 25      the printf ( " \ nC = A * B; array C: \ n- " );
 26 is      Common (A, B, C, n- );
 27      Print (C, n-);
 28      the printf ( " \ n-transducer method Strssen algorithm: \ n- " );
 29     STRASSEN (n-, A, B, C);
 30      Print (C, n-);
 31 is } //     main function 
32  
33 is  void Print ( int A [] [N], int n-) {                         // output array 
34 is      int I, J;
 35      for (I = 0 ; I <n-; I ++ ) {
 36          for (J = 0 ; J <n-; J ++ )
 37 [              the printf ( " % 5D " , A [I] [J]);
 38 is          the printf ( " \ n- " );
 39      }
 40 }
 41 
 42 void common(int A[][N],int B[][N],int C[][N],int n){                //普通求解数组C.       T(n)= O(n^3)
 43     int i,j,k;
 44     for(i=0;i<n;i++)                        
 45         for(j=0;j<n;j++){
 46             C[i][j]=0;
 47             for(k=0;k<n;k++)
 48                 C[i][j]+=A[i][k]*B[k][j];
 49         }
 50 }
 51 
 52 void ADD(int A[][N],int B[][N],int C[][N],int n){
 53     int i,j;
 54     for(i=0;i<n;i++)                        
 55         for(j=0;j<n;j++)
 56             C[i][j]=A[i][j]+B[i][j];
 57 }
 58 
 59 void SUB(int A[][N],int B[][N],int C[][N],int n){
 60     int i,j;
 61     for(i=0;i<n;i++)                        
 62         for(j=0;j<n;j++)
 63             C[i][j]=A[i][j]-B[i][j];
 64 }
 65 
 66 void STRASSEN(int n,int A[][N],int B[][N],int C[][N])  //STRASSEN函数(递归)
 67 {
 68     int A11[N][N],A12[N][N],A21[N][N],A22[N][N];
 69     int B11[N][N],B12[N][N],B21[N][N],B22[N][N];
 70     int C11[N][N],C12[N][N],C21[N][N],C22[N][N];
 71     int S1[N][N],S2[N][N],S3[N][N],S4[N][N],S5[N][N],S6[N][N],S7[N][N],S8[N][N],S9[N][N],S10[N][N];
 72     int M1[N][N],M2[N][N],M3[N][N],M4[N][N],M5[N][N],M6[N][N],M7[N][N];
 73     int MM1[N][N],MM2[N][N];
 74     int i,j;
 75 
 76 
 77     if (n==1)
 78         C[0][0]=A[0][0]*B[0][0];
 79     else
 80     {
 81         for(i=0;i<n/2;i++)              
 82             for(j=0;j<n/2;j++)
 83 
 84                 {
 85                     A11[i][j]=A[i][j];
 86                     A12[i][j]=A[i][j+n/2];
 87                     A21[i][j]=A[i+n/2][j];
 88                     A22[i][j]=A[i+n/2][j+n/2];
 89                     B11[i][j]=B[i][j];
 90                     B12[i][j]=B[i][j+n/2];
 91                     B21 of [I] [J] = B [n-I + / 2 ] [J];
 92                      B22 [I] [J] = B [n-I + / 2 ] [n-J + / 2 ];
 93                  }        // will formula matrices A and B is divided into four 
94  
95      the SUB (B12, B22, Sl, n-/ 2 );
 96      the ADD (A11, A12, S2, n-/ 2 );
 97      the ADD (A21, the A22, S3, n-/ 2 );
 98      the SUB (B21 of, B11, S4, n-/ 2 );
 99      the ADD (A11, the A22, S5, n-/ 2 );
 100      the ADD (B11, B22, S6, n-/ 2 );
 101      the SUB (A12, the A22 , S7, n /2);
102     ADD(B21,B22,S8,n/2);
103     SUB(A11,A21,S9,n/2);
104     ADD(B11,B12,S10,n/2);
105     
106 
107     STRASSEN(n/2,A11,S1,M1);//M1=A11(B12-B22)
108     STRASSEN(n/2,S2,B22,M2);//M2=(A11+A12)B22
109     STRASSEN(n/2,S3,B11,M3);//M3=(A21+A22)B11
110     STRASSEN(n/2,A22,S4,M4);//M4=A22(B21-B11)
111     STRASSEN(n/2 , S5, S6, M5); // M5 = (the A22 + A11) (B11 + B22) 
112      STRASSEN (n-/ 2 , S7, S8, M6); // M6 = (the A22-A12) (B22 + B21 of ) 
113      STRASSEN (n-/ 2 , S9, SlO, M7); // M7 = (A11-A21) (B11 + B12)
 114      // calculate M1, M2, M3, M4, M5, M6, M7 ( recursive part) 
115  
1 16  
117  
1 18      the ADD (M5, M4, MM1, N / 2 );                
 119      the SUB (M2, M6, MM2, N / 2 );
 120      the SUB (MM1, MM2, C11, N / 2 ); // C11 = M5 M2-M4 + M6 + 
121  
122      the ADD (Ml, M2, a C12, N / 2);//C12=M1+M2
123 
124     ADD(M3,M4,C21,N/2);//C21=M3+M4
125 
126     ADD(M5,M1,MM1,N/2);
127     ADD(M3,M7,MM2,N/2);
128     SUB(MM1,MM2,C22,N/2);//C22=M5+M1-M3-M7
129 
130     for(i=0;i<n/2;i++)
131         for(j=0;j<n/2;j++)
132         {
133             C[i][j]=C11 [I] [J];
 134              C [I] [J + n-/ 2 ] = a C12 [I] [J];
 135              C [I + n-/ 2 ] [J] = C21 [I] [J];
 136              C [n-I + / 2 ] [n-J + / 2 ] = to C22 [I] [J];
 137          }                                             // results returned C [N] [N] 
138      }
 139 } 

The result:
 
  

 

Reproduced in: https: //www.cnblogs.com/zzsf/p/3840626.html

Guess you like

Origin blog.csdn.net/weixin_33939380/article/details/93540467