Skip to content

Commit ab37359

Browse files
committed
fixed layout of code in readme
1 parent 09848a7 commit ab37359

File tree

1 file changed

+75
-67
lines changed

1 file changed

+75
-67
lines changed

Strassen Matrix Multiplication/README.markdown

Lines changed: 75 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,16 @@ Before we begin, you may ask what is matrix multiplication? Great question! It i
1111

1212
### Example: Matrix Multiplication
1313

14-
matrix A = |1 2|
15-
|3 4|
16-
17-
matrix B = |5 6|
18-
|7 8|
19-
20-
A * B = C
14+
```
15+
matrix A = |1 2|, matrix B = |5 6|
16+
|3 4| |7 8|
2117
22-
|1 2| * |5 6| = |1*5+2*7 1*6+2*8| = |19 22|
23-
|3 4| |7 8| |3*5+4*7 3*6+4*8| |43 48|
18+
A * B = C
2419
20+
|1 2| * |5 6| = |1*5+2*7 1*6+2*8| = |19 22|
21+
|3 4| |7 8| |3*5+4*7 3*6+4*8| |43 48|
22+
```
23+
2524
What's going on here? To start, we're multiplying matricies A & B. Our new matrix, C's, elements `[i, j]` are determined by the dot product of the first matrix's ith row and the second matrix's jth column. See [here](https://www.khanacademy.org/math/linear-algebra/vectors-and-spaces/dot-cross-products/v/vector-dot-product-and-vector-length) for a refresher on the dot product.
2625

2726
So the upper left element `[i=1, j=1]` of our new matrix is a combination of A's 1st row and B's 1st column.
@@ -66,14 +65,14 @@ Next, we loop over A's columns and B's rows. Because we know both A's columns &
6665

6766
```swift
6867
for i in 0..<n {
69-
for j in 0..<n {
68+
for j in 0..<n {
7069
```
7170

7271
Then, for each row in A and column in B, we take the dot product of the ith row in A with the jth column in B and set that result equal to the `[i, j]` element in C. Or `C[i, j]`.
7372

7473
```swift
7574
for k in 0..<n {
76-
C[i, j] = A[i, k] * B[k, j]
75+
C[i, j] = A[i, k] * B[k, j]
7776
}
7877
```
7978

@@ -83,20 +82,20 @@ Here's the full implementation:
8382

8483
```swift
8584
public func matrixMultiply(by B: Matrix<T>) -> Matrix<T> {
86-
let A = self
87-
assert(A.columns == B.rows, "Two matricies can only be matrix mulitiplied if one has dimensions mxn & the other has dimensions nxp where m, n, p are in R")
88-
let n = A.columns
89-
var C = Matrix<T>(rows: A.rows, columns: B.columns)
85+
let A = self
86+
assert(A.columns == B.rows, "Two matricies can only be matrix mulitiplied if one has dimensions mxn & the other has dimensions nxp where m, n, p are in R")
87+
let n = A.columns
88+
var C = Matrix<T>(rows: A.rows, columns: B.columns)
9089

91-
for i in 0..<n {
92-
for j in 0..<n {
93-
for k in 0..<n {
94-
C[i, j] = A[i, k] * B[k, j]
95-
}
96-
}
97-
}
90+
for i in 0..<n {
91+
for j in 0..<n {
92+
for k in 0..<n {
93+
C[i, j] = A[i, k] * B[k, j]
94+
}
95+
}
96+
}
9897

99-
return C
98+
return C
10099
}
101100
```
102101

@@ -110,10 +109,10 @@ Volker Strassen first published his algorithm in 1969. It was the first algorith
110109

111110
The basic idea behind Strassen's algorithm is to split A & B into 8 submatricies and then recursively compute the submatricies of C. This strategy is called *Divide and Conquer*.
112111

113-
matrix A = |a b|
114-
|c d|
115-
matrix B = |e f|
116-
|g h|
112+
```
113+
matrix A = |a b|, matrix B = |e f|
114+
|c d| |g h|
115+
```
117116

118117
*There will be 8 recursive calls:*
119118

@@ -149,41 +148,50 @@ Strassen's **7** calls are as follows:
149148

150149
Now we can compute our new matrix C's new quardents!
151150

152-
matrix C = |p5+p4-p2+p6 p1+p2 |
153-
| p3+p4 p1+p5-p3-p7|
154-
151+
```
152+
matrix C = |p5+p4-p2+p6 p1+p2 |
153+
| p3+p4 p1+p5-p3-p7|
154+
```
155155

156156
A great reaction right now would be !!??!?!?!!?! How does this even work??
157157

158158
Let's prove it!
159159

160160
**First** Submatrix:
161161

162-
p5+p4-p2+p6 = (a+d)*(e+h) + d*(g-e) - (a+b)*h + (b-d)*(g+h)
163-
= (ae+de+ah+dh) + (dg-de) - (ah+bh) + (bg-dg+bh-dh)
164-
= ae+bg
162+
```
163+
p5+p4-p2+p6 = (a+d)*(e+h) + d*(g-e) - (a+b)*h + (b-d)*(g+h)
164+
= (ae+de+ah+dh) + (dg-de) - (ah+bh) + (bg-dg+bh-dh)
165+
= ae+bg
166+
```
165167

166168
Exactly what we got the first time!
167169

168170
Now let's prove the others.
169171

170172
**Second** submatrix:
171173

172-
p1+p2 = a*(f-h) + (a+b)*h
173-
= (af-ah) + (ah+bh)
174-
= af+bh
174+
```
175+
p1+p2 = a*(f-h) + (a+b)*h
176+
= (af-ah) + (ah+bh)
177+
= af+bh
178+
```
175179

176180
**Third** submatrix:
177181

178-
p3+p4 = (c+d)*e + d*(g-e)
179-
= (ce+de) + (dg-de)
180-
= ce+dg
182+
```
183+
p3+p4 = (c+d)*e + d*(g-e)
184+
= (ce+de) + (dg-de)
185+
= ce+dg
186+
```
181187

182188
**Fourth** submatrix:
183189

184-
p1+p5-p3-p7 = a*(f-h) + (a+d)*(e+h) - (c+d)*e - (a-c)*(e+f)
185-
= (af-ah) + (ae+de+ah+dh) -(ce+de) - (ae-ce+af-cf)
186-
= cf+dh
190+
```
191+
p1+p5-p3-p7 = a*(f-h) + (a+d)*(e+h) - (c+d)*e - (a-c)*(e+f)
192+
= (af-ah) + (ae+de+ah+dh) -(ce+de) - (ae-ce+af-cf)
193+
= cf+dh
194+
```
187195

188196
Great! The math checks out!
189197

@@ -209,15 +217,15 @@ var APrep = Matrix(size: m)
209217
var BPrep = Matrix(size: m)
210218

211219
for i in A.rows {
212-
for j in A.columns {
213-
APrep[i, j] = A[i,j]
214-
}
220+
for j in A.columns {
221+
APrep[i, j] = A[i,j]
222+
}
215223
}
216224

217225
for i in B.rows {
218-
for j in B.columns {
219-
BPrep[i, j] = B[i, j]
220-
}
226+
for j in B.columns {
227+
BPrep[i, j] = B[i, j]
228+
}
221229
}
222230
```
223231

@@ -228,9 +236,9 @@ let CPrep = APrep.strassenR(by: BPrep)
228236
var C = Matrix(rows: A.rows, columns: B.columns)
229237

230238
for i in 0..<A.rows {
231-
for j in 0..<B.columns {
232-
C[i,j] = CPrep[i,j]
233-
}
239+
for j in 0..<B.columns {
240+
C[i,j] = CPrep[i,j]
241+
}
234242
}
235243
```
236244

@@ -251,16 +259,16 @@ var g = Matrix(size: nBy2)
251259
var h = Matrix(size: nBy2)
252260

253261
for i in 0..<nBy2 {
254-
for j in 0..<nBy2 {
255-
a[i,j] = A[i,j]
256-
b[i,j] = A[i, j+nBy2]
257-
c[i,j] = A[i+nBy2, j]
258-
d[i,j] = A[i+nBy2, j+nBy2]
259-
e[i,j] = B[i,j]
260-
f[i,j] = B[i, j+nBy2]
261-
g[i,j] = B[i+nBy2, j]
262-
h[i,j] = B[i+nBy2, j+nBy2]
263-
}
262+
for j in 0..<nBy2 {
263+
a[i,j] = A[i,j]
264+
b[i,j] = A[i, j+nBy2]
265+
c[i,j] = A[i+nBy2, j]
266+
d[i,j] = A[i+nBy2, j+nBy2]
267+
e[i,j] = B[i,j]
268+
f[i,j] = B[i, j+nBy2]
269+
g[i,j] = B[i+nBy2, j]
270+
h[i,j] = B[i+nBy2, j+nBy2]
271+
}
264272
}
265273
```
266274

@@ -290,12 +298,12 @@ And finally, we combine these submatricies into our new matrix C!
290298
```swift
291299
var C = Matrix(size: n)
292300
for i in 0..<nBy2 {
293-
for j in 0..<nBy2 {
294-
C[i, j] = c11[i,j]
295-
C[i, j+nBy2] = c12[i,j]
296-
C[i+nBy2, j] = c21[i,j]
297-
C[i+nBy2, j+nBy2] = c22[i,j]
298-
}
301+
for j in 0..<nBy2 {
302+
C[i, j] = c11[i,j]
303+
C[i, j+nBy2] = c12[i,j]
304+
C[i+nBy2, j] = c21[i,j]
305+
C[i+nBy2, j+nBy2] = c22[i,j]
306+
}
299307
}
300308
```
301309

0 commit comments

Comments
 (0)