Skip to content

Commit df885b6

Browse files
authored
Merge pull request #49 from vermashresth/master
Stressens Multiplication and Matrix Chain Multiplication
2 parents 6c12190 + cf2bdae commit df885b6

File tree

2 files changed

+305
-0
lines changed

2 files changed

+305
-0
lines changed

divide_and_conquer/strassen.cpp

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
#include<iostream>
2+
#include<cstdlib>
3+
#include<ctime>
4+
using namespace std;
5+
6+
7+
void createMatrix(int **A4,int size);
8+
void output(int **A, int size);
9+
void standardMult(int **A, int **B, int **C, int size);
10+
void strassens(int **A, int **B, int **C, int size);
11+
void Add(int **A, int **B, int **T, int n);
12+
void Sub(int **A, int **B, int **T, int n);
13+
14+
15+
16+
17+
int main() {
18+
int size = 8;
19+
20+
21+
int **A, **B, **C;
22+
23+
for(int size=16;size<2048;size*=2){
24+
25+
A = new int *[size];
26+
B = new int *[size];
27+
C = new int *[size];
28+
29+
30+
for(int i=0; i<size; i++) {
31+
A[i] = new int[size];
32+
B[i] = new int[size];
33+
C[i] = new int[size];
34+
}
35+
36+
//Matrices for i,j as i*j%1000
37+
createMatrix(A,size);
38+
createMatrix(B,size);
39+
40+
41+
42+
cout<<"Size of the matrix : "<<size<<"*"<<size<<endl<<endl;
43+
//Multiplying Matrices using Standard Method
44+
45+
int time = clock();
46+
standardMult(A,B,C,size);
47+
int now=clock();
48+
//output(C,size);
49+
cout<<"Standard Multiplication: "<<(now-time)/1000000.0<<" Seconds"<<endl;
50+
51+
//Multiplying Matrices using Strassen's Algorithm
52+
//cout<<endl<<endl<<"Strassen's way" <<endl;
53+
time = clock();
54+
strassens(A,B,C,size);
55+
now=clock();
56+
//output(C,size);
57+
cout<<"Stressen's multiplication : "<<(now-time)/1000000.0<<" Seconds"<<endl<<endl;
58+
59+
}}
60+
61+
62+
63+
//Add matrices
64+
void Add(int **A, int **B, int **T, int n) {
65+
for(int i=0; i<n; i++) {
66+
for(int j=0; j<n; j++) {
67+
T[i][j] = A[i][j] + B[i][j];
68+
}
69+
}
70+
}
71+
72+
//Subtract matricess
73+
void Sub(int **A, int **B, int **T, int n) {
74+
for(int i=0; i<n; i++) {
75+
for(int j=0; j<n; j++) {
76+
T[i][j] = A[i][j] - B[i][j];
77+
}
78+
}
79+
}
80+
81+
82+
//method for matrix generation
83+
void createMatrix(int **A,int size) {
84+
for(int i=0; i<size; i++) {
85+
for(int j=0; j<size; j++) {
86+
A[i][j] = (i+1)*(j+1) % 1000;
87+
}
88+
}
89+
}
90+
91+
//method to print a matrix
92+
void output(int **A, int size) {
93+
cout<<endl;
94+
for(int i=0; i<size; i++) {
95+
for(int j=0; j<size; j++) {
96+
cout<<A[i][j]<<" ";
97+
}
98+
cout<<endl;
99+
}
100+
}
101+
102+
//traditional method of multiplying two square matrices
103+
void standardMult(int **A, int **B, int **C, int size) {
104+
for(int i=0; i<size; i++) {
105+
for(int j=0; j<size; j++) {
106+
C[i][j] = 0;
107+
for(int k=0; k<size; k++) {
108+
C[i][j] += A[i][k] * B [k][j];
109+
}
110+
}
111+
}
112+
}
113+
114+
//strassen's product
115+
void strassens(int **A, int **B, int **C, int size) {
116+
if ( size <= 100)
117+
{
118+
standardMult(A,B,C,size);
119+
}
120+
else
121+
{
122+
//Divide and conquer step
123+
int n = size/2;
124+
int N = size/2;
125+
int newsize = size/2;
126+
127+
//Smaller matrices
128+
int **A11, **A12, **A21, **A22, **B11, **B12, **B21, **B22, **C11, **C12, **C21, **C22;
129+
130+
//Matrices for Strassens
131+
int **M1, **M2, **M3, **M4, **M5, **M6, **M7;
132+
133+
134+
int **P, **Q;
135+
136+
//memory allocation for columns
137+
A11 = new int *[n];A12 = new int *[n];A21 = new int *[n];A22 = new int *[n];
138+
B11 = new int *[n];B12 = new int *[n];B21 = new int *[n];B22 = new int *[n];
139+
C11 = new int *[n];C12 = new int *[n];C21 = new int *[n];C22 = new int *[n];
140+
141+
//stressens matrices
142+
M1 = new int *[n];
143+
M2 = new int *[n];
144+
M3 = new int *[n];
145+
M4 = new int *[n];
146+
M5 = new int *[n];
147+
M6 = new int *[n];
148+
M7 = new int *[n];
149+
150+
P = new int *[n];
151+
Q = new int *[n];
152+
153+
//memory allocation for columns
154+
for(int i=0; i<N; i++) {
155+
A11[i] = new int[N];A12[i] = new int[N];A21[i] = new int[N];A22[i] = new int[N];
156+
B11[i] = new int[N];B12[i] = new int[N];B21[i] = new int[N];B22[i] = new int[N];
157+
C11[i] = new int[N];C12[i] = new int[N];C21[i] = new int[N];C22[i] = new int[N];
158+
159+
M1[i] = new int[N];
160+
M2[i] = new int[N];
161+
M3[i] = new int[N];
162+
M4[i] = new int[N];
163+
M5[i] = new int[N];
164+
M6[i] = new int[N];
165+
M7[i] = new int[N];
166+
167+
P[i] = new int[N];
168+
Q[i] = new int[N];
169+
170+
}
171+
172+
//Dividing input matrices A and B into 4 submatrices each.
173+
for (int i = 0; i < newsize; i++) {
174+
for (int j = 0; j < newsize; j++) {
175+
A11[i][j] = A[i][j];
176+
A12[i][j] = A[i][j + newsize];
177+
A21[i][j] = A[i + newsize][j];
178+
A22[i][j] = A[i + newsize][j + newsize];
179+
180+
B11[i][j] = B[i][j];
181+
B12[i][j] = B[i][j + newsize];
182+
B21[i][j] = B[i + newsize][j];
183+
B22[i][j] = B[i + newsize][j + newsize];
184+
}
185+
}
186+
187+
//M1
188+
Sub(B12,B22,P,n);strassens(A11,P,M1,n);
189+
190+
//M2
191+
Add(A11,A12,P,n);strassens(P,B22,M2,n);
192+
193+
//M3
194+
Add(A21,A22,P,n);strassens(P,B11,M3,n);
195+
196+
//M4
197+
Sub(B21,B11,P,n);strassens(A22,P,M4,n);
198+
199+
//M5
200+
Add(A11,A22,P,n);Add(B11,B22,Q,n);strassens(P,Q,M5,n);
201+
202+
//M6
203+
Sub(A12,A22,P,n);Add(B21,B22,Q,n);strassens(P,Q,M6,n);
204+
205+
//M7
206+
Sub(A11,A21,P,n);Add(B11,B12,Q,n);strassens(P,Q,M7,n);
207+
208+
//C11
209+
Add(M4,M5,P,n);Sub(M6,M2,Q,n);Add(P,Q,C11,n);
210+
211+
//C12
212+
Add(M1,M2,C12,n);
213+
214+
//C21
215+
Add(M3,M4,C21,n);
216+
217+
//C22
218+
Add(M1,M5,P,n); Add(M3,M7,Q,n); Sub(P,Q,C22,n);
219+
220+
//algorithm part
221+
for (int i = 0; i < n ; i++) {
222+
for (int j = 0 ; j < n ; j++) {
223+
C[i][j] = C11[i][j];
224+
C[i][j + n] = C12[i][j];
225+
C[i + n][j] = C21[i][j];
226+
C[i + n][j + n] = C22[i][j];
227+
}
228+
}
229+
}
230+
}
231+
232+
233+
234+
235+
236+

dp/mcm.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include<stdio.h>
2+
#include<iostream>
3+
#include<ctime>
4+
#include <fstream>
5+
6+
using namespace std;
7+
//random matrix sizes
8+
int mat[]={10,5,2,8,16,10,5,3,8,9,18,15,3,6,11,5,3,2,8,3,9,7,4,9,3};
9+
//5 15 and 25 as number of matrices
10+
int nn[]={5,10,25};
11+
12+
//funtion for matrix chain multiplication using div and cnquer
13+
int mcmdnc(int a,int b)
14+
{
15+
int cost;
16+
//base Case
17+
if(a==b)
18+
cost=0;
19+
else
20+
{
21+
for(int i=a;i<b;i++)
22+
{
23+
if(i==a)
24+
cost=mcmdnc(a,i)+mcmdnc(i+1,b)+mat[a-1]*mat[i]*mat[b];
25+
else
26+
cost=min(cost,(mcmdnc(a,i)+mcmdnc(i+1,b)+mat[a-1]*mat[i]*mat[b]));
27+
}
28+
}
29+
return cost;
30+
}
31+
32+
33+
//function for matrix chain multiplication using dp
34+
int mcmdp(int p[], int n){
35+
int m[n][n];
36+
int i, j, k, L, q;
37+
for (i = 1; i < n; i++)
38+
m[i][i] = 0;
39+
for (L=2; L<n; L++) {
40+
for (i=1; i<=n-L+1; i++){
41+
j = i+L-1;
42+
m[i][j] = 100000;
43+
for (k=i; k<=j-1; k++){
44+
q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
45+
if (q < m[i][j])
46+
m[i][j] = q;
47+
}
48+
}
49+
}
50+
return m[1][n-1];
51+
}
52+
int main(){
53+
int val;
54+
55+
for (int i=0;i<3; i++){
56+
57+
int t=clock();
58+
val= mcmdp(mat,nn[i]);
59+
cout<<"Optimised cost for "<<nn[i]<<" matrices is "<<val<<"(DP)"<<endl<<" time taken :"<< ((float)(clock()-t))/CLOCKS_PER_SEC<<endl;
60+
61+
t=clock();
62+
63+
64+
val=mcmdnc(1,nn[i]-1);
65+
cout<<"Optimised cost for "<<nn[i]<<" matrices is "<<val<<"(DivAndConq)"<<endl<<" time taken :"<< ((float)(clock()-t))/CLOCKS_PER_SEC<<endl;
66+
67+
}
68+
return 0;
69+
}

0 commit comments

Comments
 (0)