The matrix multiplication is realized by programming, and the optimization method is considered when the matrix scale is large:
(1) The general solution:
Matrix multiplication, 3 for loops to fix
void Mul (int** Matrixa, int** matrixb, int** Matrixc)
{for
(int i = 0; i < n; ++i)
{
for (int j = 0; J < N; ++j)
{
matrixc[i][j] = 0;
for (int k = 0; k < n; ++k)
{
Matrixc[i][j] + = matrixa[i][k] * matrixb[k][j];}
}
(2) Strassen algorithm (block + divide-and-conquer idea):
Algorithm idea:
Strassen Algorithm Flow:
The universal matrix multiplication algorithm is of time complexity, and the complexity of Strassen algorithm is only. But as N gets bigger, like when n >> 100, the Strassen algorithm becomes more efficient than the universal matrix multiplication algorithm.
The specific code implementation is as follows:
#include <iostream> #include <ctime> #include <Windows.h> using namespace std; Template<typename t> class strassen_class{public:void ADD (t** Matrixa, t** matrixb, t** matrixresult, int MatrixS ize); Matrix add void SUB (t** Matrixa, t** matrixb, t** matrixresult, int matrixsize); Matrix subtraction void MUL (t** Matrixa, t** matrixb, t** matrixresult, int matrixsize);//naive algorithm to implement void Fillmatrix (t** Matrixa, t** Ma TRIXB, int length);//a,b matrix assignment void Printmatrix (t **matrixa, int matrixsize);//print matrix void Strassen (int N, T **matrixa, t * *
MATRIXB, T **MATRIXC);//strassen algorithm Implementation}; The addition of matrices template<typename t> void Strassen_class<t>::add (t** Matrixa, t** matrixb, t** MatrixResult, int Matr Ixsize) {for (int i = 0; i < matrixsize. i++) {for (int j = 0; J < Matrixsize; J +) {Matrixresult[i][j]
= Matrixa[i][j] + matrixb[i][j]; The subtraction of the}}//Matrix template<typename t> void Strassen_class<t>::sub (t** Matrixa, t** matrixb, t** MatrixResult, int MatRixsize) {for (int i = 0; i < matrixsize. i++) {for (int j = 0; J < Matrixsize; J +) {Matrixresult[i][j]
= Matrixa[i][j]-matrixb[i][j]; Multiply template<typename t> void Strassen_class<t>::mul (t** Matrixa, t** matrixb, t** MatrixResult, I NT Matrixsize) {for (int i = 0; i < matrixsize i++) {for (int j = 0; J < Matrixsize; J +) {Matrixresult I
[j] = 0;
for (int k = 0; k < matrixsize; k++) {matrixresult[i][j] = Matrixresult[i][j] + matrixa[i][k] * Matrixb[k][j];
Use a two-dimensional array for the dynamic memory method request int **a;
A = new int *[desired_array_row];
for (int i = 0; i < Desired_array_row i++) a[i] = new int [desired_column_size];
Release for (int i = 0; i < Your_array_row; i++) Delete [] a[i];
Delete[] A; * * Template<typename t> void Strassen_class<t>::strassen (int N, T **matrixa, T **MATRIXB, t **MatrixC) {int
Halfsize = N/2;
int newsize = N/2; if (N <= 64)//Divide the threshold, is less than this value is no longer recursive calculation, but the use of regular matrixComputational methods {MUL (Matrixa, MATRIXB, MATRIXC, N);
else {t** A11;
t** A12;
t** A21;
t** A22;
t** B11;
t** B12;
t** B21;
t** B22;
t** C11;
t** C12;
t** C21;
t** C22;
t** M1;
t** M2;
t** M3;
t** M4;
t** M5;
t** M6;
t** M7;
t** Aresult;
t** Bresult;
Making a 1 diminsional pointer based array.
A11 = new T *[newsize];
A12 = new T *[newsize];
A21 = new T *[newsize];
A22 = new T *[newsize];
B11 = new T *[newsize];
B12 = new T *[newsize];
B21 = new T *[newsize];
B22 = new T *[newsize];
C11 = new T *[newsize];
C12 = new T *[newsize];
C21 = new T *[newsize];
C22 = new T *[newsize];
M1 = new T *[newsize];
M2 = new T *[newsize];
M3 = new T *[newsize];
M4 = new T *[newsize];
M5 = new T *[newsize];
M6 = new T *[newsize];
M7 = new T *[newsize];
Aresult = new T *[newsize];
Bresult = new T *[newsize];
int newlength = newsize;
Making that 1 diminsional pointer based array, a 2D pointer based arrayfor (int i = 0; i < newsize i++) {A11[i] = new T[newlength];
A12[i] = new T[newlength];
A21[i] = new T[newlength];
A22[i] = new T[newlength];
B11[i] = new T[newlength];
B12[i] = new T[newlength];
B21[i] = new T[newlength];
B22[i] = new T[newlength];
C11[i] = new T[newlength];
C12[i] = new T[newlength];
C21[i] = new T[newlength];
C22[i] = new T[newlength];
M1[i] = new T[newlength];
M2[i] = new T[newlength];
M3[i] = new T[newlength];
M4[i] = new T[newlength];
M5[i] = new T[newlength];
M6[i] = new T[newlength];
M7[i] = new T[newlength];
Aresult[i] = new T[newlength];
Bresult[i] = new T[newlength];
//splitting input matrixes to 4 submatrices each.
for (int i = 0; i < N/2. i++) {for (int j = 0; J < N/2; J +) {A11[i][j] = matrixa[i][j];
A12[I][J] = matrixa[i][j + N/2];
A21[I][J] = matrixa[i + n/2][j];
A22[I][J] = matrixa[i + n/2][j + N/2]; B11[I][J] = MatrixB[I][J];
B12[I][J] = matrixb[i][j + N/2];
B21[I][J] = matrixb[i + n/2][j];
B22[I][J] = matrixb[i + n/2][j + N/2]; }//here we calculate M1.
M7 matrices.
M1[][] ADD (A11, A22, Aresult, halfsize); ADD (B11, B22, Bresult, halfsize); p5= (a+d) * (e+h) Strassen (halfsize, Aresult, Bresult, M1);
Now so we need to multiply this and we use the Strassen itself. M2[][] ADD (A21, A22, Aresult, halfsize); M2= (A21+A22) B11 p3= (c+d) *e Strassen (halfsize, Aresult, B11, M2);
Mul (ARESULT,B11,M2); M3[][] SUB (B12, B22, Bresult, halfsize); M3=A11 (b12-b22) p1=a* (f-h) Strassen (halfsize, A11, Bresult, M3);
Mul (A11,BRESULT,M3); M4[][] SUB (B21, B11, Bresult, halfsize); M4=a22 (B21-B11) p4=d* (G-E) Strassen (halfsize, A22, Bresult, M4);
Mul (A22,BRESULT,M4); M5[][] ADD (A11, A12, Aresult, halfsize); m5= (A11+A12) B22 p2= (a+b) *h Strassen (halfsizE, Aresult, B22, M5);
Mul (ARESULT,B22,M5);
M6[][] SUB (A21, A11, Aresult, halfsize); ADD (B11, B12, Bresult, halfsize); M6= (A21-A11) (B11+B12) p7= (c-a) (e+f) Strassen (halfsize, Aresult, Bresult, M6);
Mul (ARESULT,BRESULT,M6);
M7[][] SUB (A12, A22, Aresult, halfsize); ADD (B21, B22, Bresult, halfsize); M7= (A12-A22) (b21+b22) p6= (b-d) * (g+h) Strassen (halfsize, Aresult, Bresult, M7);
Mul (ARESULT,BRESULT,M7);
C11 = M1 + M4-M5 + M7;
ADD (M1, M4, Aresult, halfsize);
SUB (M7, M5, Bresult, halfsize);
ADD (Aresult, Bresult, C11, halfsize);
C12 = M3 + M5;
ADD (M3, M5, C12, halfsize);
C21 = M2 + M4;
ADD (M2, M4, C21, halfsize);
C22 = M1 + m3-m2 + M6;
ADD (M1, M3, Aresult, halfsize);
SUB (M6, M2, Bresult, halfsize);
ADD (Aresult, Bresult, C22, halfsize); At this point, we have calculated the C11. C22 matrices, and now we are going to//put them together and make a unit matrix which would descrIbe our resulting Matrix. Combining small matrices to a large matrix for (int i = 0; i < N/2 i++) {for (int j = 0; J < N/2; J +) {Matrixc[i][j] = c11[
I][J];
Matrixc[i][j + N/2] = C12[i][j];
Matrixc[i + n/2][j] = C21[i][j];
Matrixc[i + n/2][j + N/2] = C22[i][j];
}//Free matrix memory space for (int i = 0; i < newlength i++) {delete[] a11[i]; delete[] a12[i]; delete[] a21[i];
Delete[] a22[i]; Delete[] b11[i]; Delete[] b12[i];
Delete[] b21[i];
Delete[] b22[i]; Delete[] c11[i]; Delete[] c12[i];
Delete[] c21[i];
Delete[] c22[i]; Delete[] m1[i]; Delete[] m2[i]; Delete[] m3[i];
Delete[] m4[i]; Delete[] m5[i]; Delete[] m6[i];
Delete[] m7[i]; Delete[] aresult[i];
Delete[] bresult[i]; } delete[] A11; Delete[] A12; Delete[] A21;
Delete[] A22; Delete[] B11; Delete[] B12; Delete[] B21;
Delete[] B22; Delete[] C11; Delete[] C12; Delete[] C21;
Delete[] C22; Delete[] M1; Delete[] M2; Delete[] M3; Delete[] M4;
Delete[] M5; Delete[] M6; DelEte[] M7;
Delete[] Aresult;
Delete[] Bresult; }//end of Else}//fill matrix template<typename t> void Strassen_class<t>::fillmatrix (t** Matrixa, T** MatrixB, in T length) {for (int row = 0; row < length; row++) {for (int column = 0; column < length; column++) {Mat
Rixb[row][column] = (Matrixa[row][column] = rand ()% 5); }}//print matrix template<typename t> void Strassen_class<t>::P rintmatrix (T **matrixa, int matrixsize) {cout
<< Endl; for (int row = 0; row < matrixsize. row++) {for (int column = 0; column < matrixsize; column++) {cout &L
t;< Matrixa[row][column] << "T";
if ((column + 1)% ((matrixsize)) = = 0) cout << Endl;
}} cout << Endl;
the int main () {strassen_class<int> stra;//defines the Strassen_class class object int matrixsize = 0; int** Matrixa; Storing matrix a int** matrixb; Storing matrix B int** matrixc;
Depositing the result matrix clock_t starttime_for_normal_multipilication; clock_t Endtime_for_noRmal_multipilication;
clock_t Starttime_for_strassen;
clock_t Endtime_for_strassen;
Srand (Time (0));
cout << "\ n Please enter a matrix size (must be a power exponent value of 2 (for example: 32,64,512,..):";
Cin >> Matrixsize;
int N = Matrixsize;//for readiblity.
Application memory Matrixa = new int *[matrixsize];
MATRIXB = new int *[matrixsize];
MATRIXC = new int *[matrixsize];
for (int i = 0; i < matrixsize i++) {Matrixa[i] = new Int[matrixsize];
Matrixb[i] = new Int[matrixsize];
Matrixc[i] = new Int[matrixsize]; } stra. Fillmatrix (Matrixa, MATRIXB, matrixsize); Matrix Assignment//*******************conventional multiplication test cout << "naive matrix algorithm start clock:" << (Starttime_for_norm
Al_multipilication = Clock ()); Stra. MUL (Matrixa, MATRIXB, MATRIXC, matrixsize);/naive matrix multiplication algorithm T (n) = O (n^3) cout << "\ na naïve matrix algorithm end clock:" << (endtime_for
_normal_multipilication = Clock ());
cout << "\ n matrix operation results ... \ n"; Stra.
Printmatrix (MATRIXC, matrixsize); Strassen multiplication Test cout <<
"\nstrassen algorithm start Clock:" << (Starttime_for_strassen = Clock ()); Stra. Strassen (N, Matrixa, MATRIXB, MATRIXC);
Strassen matrix multiplication algorithm cout << "\nstrassen algorithm End Clock:" << (Endtime_for_strassen = Clock ());
cout << "\ n matrix operation results ... \ n"; Stra.
Printmatrix (MATRIXC, matrixsize);
cout << "Matrix size" << matrixsize; cout << "\ na naïve matrix algorithm:" << (Endtime_for_normal_multipilication-starttime_for_normal_multipilication) < < "Clocks ..." << (endtime_for_normal_multipilication-starttime_for_normal_multipilication)/CLOCKS_PER_SEC
<< "Sec"; cout << "\nstrassen algorithm:" << (Endtime_for_strassen-starttime_for_strassen) << "Clocks." << (end
Time_for_strassen-starttime_for_strassen)/clocks_per_sec << "sec\n";
System ("Pause");
return 0; }
The results of the operation are as follows: