Matrix multiplication __ Matrix multiplication

Source: Internet
Author: User
Tags mul

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&gt::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 &LT;&LT

	"\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:


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.