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