CS Core & Software Engineering · Data Structures & Algorithms
Strassen Matrix Multiplication
Divide-and-conquer matrix multiply: why eight half-size products still cost n^3, Strassen's seven products, the \Theta(n^{\log_2 7}) recurrence, and when the extra additions…
Five concepts on Strassen's matrix multiply — why eight half-size products still cost n^3, the seven products, assembling C, the \Theta(n^{\log_2 7}) recurrence, and why a 3-by-3 on paper still uses the triple loop. Running example: A=[[1,3],[5,7]], B=[[2,4],[6,8]], product [[20,28],[52,76]]. Convex hull is a separate topic: same divide-and-conquer family, different object.
- CS Core & Software Engineering
- Hard level
- 5 concepts
1Eight half-size products still cost n cubed
The product C = AB of two n \times n matrices has entries C_{ij} = \sum_k A_{ik} B_{kj}. The triple loop does n^3 scalar multiplies. Divide-and-conquer splits each matrix into four n/2 blocks and writes the same product as four block formulae, each a sum of two half-size products: C_{11} = A_{11}B_{11} + A_{12}B_{21}, and three siblings. That is eight recursive multiplies plus O(n^2) block additions.
The recurrence is T(n) = 8T(n/2) + \Theta(n^2). Master theorem (or unrolling) gives T(n) = \Theta(n^3) — the same class as the triple loop. Splitting the matrix is not enough. You have to multiply fewer than eight blocks.
Figure. A split into four n/2 blocks. Each C block is two products, so eight recursive multiplies — still Θ(n³).
Naive block product
- SplitEach of A, B, C becomes four n/2 blocks.
- Eight productsEach of the four C blocks is a sum of two products, so eight recursive multiplies.
- Same exponentT(n)=8T(n/2)+\Theta(n^2)=\Theta(n^3).
Count on n = 4
A 4-by-4 multiply, split once, uses how many 2-by-2 multiplies and how many scalar multiplies if each 2-by-2 is the ordinary eight-multiply expansion?
- half-size products at the first split8
- scalar multiplies per 2-by-2 (ordinary)8
- total scalar multiplies8 \times 8 = 64 = 4^3
Pro tip. The n^3 count survived the split. Strassen is the move that changes the 8.
Naive divide-and-conquer matrix multiply is \Theta(n^3) because
- It still makes eight half-size products, and 8T(n/2)+\Theta(n^2) solves to \Theta(n^3)
- Block addition is already \Theta(n^3)
- You cannot split a matrix into blocks
Additions of n/2 blocks are \Theta(n^2). The eight recursive multiplies are what keep the exponent at 3.
2Seven products, not eight
Strassen keeps the same four-block split and computes seven carefully chosen products P_1,\ldots,P_7 instead of the eight block multiplies. Each P_k is one product of two linear combinations of blocks of A and of B. The combinations look arbitrary until you expand them: they are the unique (up to scaling) set that lets every needed A_{ik}B_{kj} appear in the right C block and cancel elsewhere.
You do not derive the seven formulae in an exam. You store them, expand one C block once to see the cancellations, and then treat the list as the algorithm.
The same four-block split as the eight-product figure; what changes is the list of seven products in the table, not a new geometry.
The seven products
- Sums firstForm A_{11}+A_{22}, A_{21}+A_{22}, A_{11}+A_{12}, A_{21}-A_{11}, A_{12}-A_{22} and the matching B combinations.
- Seven multipliesP_1 through P_7 — each is one product of two n/2 matrices.
- No eighthThere is no A_{12}B_{21} as a standalone product. It is recovered from the P_k mix.
| Product | Left factor | Right factor |
|---|---|---|
| P_1 | A_{11}+A_{22} | B_{11}+B_{22} |
| P_2 | A_{21}+A_{22} | B_{11} |
| P_3 | A_{11} | B_{12}-B_{22} |
| P_4 | A_{22} | B_{21}-B_{11} |
| P_5 | A_{11}+A_{12} | B_{22} |
| P_6 | A_{21}-A_{11} | B_{11}+B_{12} |
| P_7 | A_{12}-A_{22} | B_{21}+B_{22} |
Seven products (n = 2 scalars)
def strassen_products(A, B):
A11, A12, A21, A22 = A[0][0], A[0][1], A[1][0], A[1][1]
B11, B12, B21, B22 = B[0][0], B[0][1], B[1][0], B[1][1]
P1 = (A11 + A22) * (B11 + B22)
P2 = (A21 + A22) * B11
P3 = A11 * (B12 - B22)
P4 = A22 * (B21 - B11)
P5 = (A11 + A12) * B22
P6 = (A21 - A11) * (B11 + B12)
P7 = (A12 - A22) * (B21 + B22)
return P1, P2, P3, P4, P5, P6, P7P1 through P7 on the 2-by-2 pair
A = [[1, 3], [5, 7]], B = [[2, 4], [6, 8]]. Compute the seven scalar products.
- P_1 = (1+7)(2+8)80
- P_2 = (5+7)\cdot 2, P_3 = 1\cdot(4-8)24, -4
- P_4 = 7\cdot(6-2), P_5 = (1+3)\cdot 828, 32
- P_6 = (5-1)(2+4), P_7 = (3-7)(6+8)24, -56
Pro tip. Seven multiplies, not eight. The additions that built the factors are the \Theta(n^2) work, not extra multiplies.
Strassen's P_3 is
- A_{11}(B_{12}-B_{22}) — one product, the right factor a difference of B blocks
- A_{11}B_{12} + A_{12}B_{22} — two products, the naive C_{12}
- A block addition with no multiply
Each P_k is exactly one multiply. The naive C_{12} is two multiplies; Strassen rebuilds it from P_3+P_5.
3Assemble C from the seven products
Once the seven products exist, each block of C is a sum and difference of a few of them: C_{11} = P_1+P_4-P_5+P_7, C_{12} = P_3+P_5, C_{21} = P_2+P_4, C_{22} = P_1+P_3-P_2+P_6. No further multiply is required. That is why the recurrence counts seven multiplies and \Theta(n^2) additions.
On the running 2-by-2 pair the four assemblies recover 20, 28, 52, 76 — the same C the eight-multiply expansion produced.
Same 2-by-2 block frame; each C block is now a sum of P_k values from the ledger, not a new drawing.
Four assemblies
- C_{11}P_1 + P_4 - P_5 + P_7.
- C_{12} and C_{21}P_3+P_5 and P_2+P_4.
- C_{22}P_1 + P_3 - P_2 + P_6.
Assemble C
def strassen_combine(P1, P2, P3, P4, P5, P6, P7):
C11 = P1 + P4 - P5 + P7
C12 = P3 + P5
C21 = P2 + P4
C22 = P1 + P3 - P2 + P6
return [[C11, C12], [C21, C22]]Assemble the running pair
Using P1=80, P2=24, P3=-4, P4=28, P5=32, P6=24, P7=-56, form the four blocks of C.
- C_{11} = 80+28-32-5620
- C_{12} = -4+3228
- C_{21} = 24+2852
- C_{22} = 80-4-24+2476
Pro tip. Match these four numbers against 1\cdot 2+3\cdot 6=20 and its three siblings. The assemblies are the proof that seven products suffice.
Coding lab. Strassen on the 2-by-2 pair runs in the app, with checks on your output.
C_{12} in Strassen is
- P_3 + P_5
- P_1 + P_4 - P_5 + P_7
- A_{11}B_{12} alone
C_{12}=P_3+P_5. The long four-term sum is C_{11}. A single A_{11}B_{12} is one of the eight naive products, not a Strassen assembly.
4T(n) = 7 T(n/2) + Θ(n²)
Each Strassen step does seven multiplies of n/2 matrices and a constant number of n/2 additions (18 additions and subtractions of blocks). So T(n) = 7T(n/2) + \Theta(n^2), with T(1) = \Theta(1).
Master theorem: a=7, b=2, f(n)=n^2, and \log_2 7 \approx 2.807 > 2, so f is polynomially smaller than n^{\log_2 7} and T(n) = \Theta(n^{\log_2 7}). The exponent dropped below 3 because the 8 became a 7. That is the whole point of the algorithm.
Figure. Exponents only, not runtimes: 2 for the additions, about 2.81 for Strassen, 3 for the eight-product recurrence. Not to scale as values of n^k.
Apply the Master theorem
- Read a,b,fa=7 subproblems, size n/2, combine f(n)=\Theta(n^2).
- Compare exponents\log_b a = \log_2 7 \approx 2.807 > 2.
- Case 1T(n)=\Theta(n^{\log_2 7}).
Unroll one power of two
Ignore the \Theta constants and write T(n) = 7T(n/2) + n^2 for n=4, with T(1)=1. How many leaf multiplies, and what is 4^{\log_2 7}?
- leaf multiplies = 7^{\log_2 4}7^2 = 49
- 4^{\log_2 7} = (2^2)^{\log_2 7}2^{2\log_2 7} = 7^2 = 49
- ordinary 4^364
- leaf saving64-49=15 scalar multiplies
Pro tip. Additions along the recursion tree are lower order. The 49 versus 64 is the multiply count the exponent change predicts.
Strassen's time is \Theta(n^{\log_2 7}) rather than \Theta(n^3) because
- Seven, not eight, half-size multiplies change \log_2 a from 3 to \log_2 7
- Block addition became O(n)
- The Master theorem does not apply to matrix multiply
\log_2 8 = 3 is the naive D&C exponent. Replacing 8 by 7 is the only change that moves the exponent. Additions stay \Theta(n^2). The Master theorem applies directly.
5When seven products lose to the triple loop
The \Theta(n^{2.81}) bound is asymptotic. Each level pays 18 block additions, the recursion wants n a power of two (odd n is padded), and the extra additions are less stable in floating point than the ordinary dot product. On the 2-by-2 running example Strassen used seven multiplies and many more additions than the eight-multiply expansion.
Libraries switch to a tuned triple loop (or a later, still-faster, even-more-addition-heavy algorithm) below a crossover n measured in the hundreds. The syllabus outcome is the seven-product idea and the exponent, not a claim that you should hand-code Strassen for a 4-by-4.
No new geometry — the three-row method table is the figure.
Reasons the crossover is large
- Addition overhead18 block additions per level, each \Theta(n^2).
- PaddingOdd n grows to the next power of two before the recurrence applies cleanly.
- StabilityDifferences such as B_{12}-B_{22} cancel leading digits; the ordinary product does not.
| Method | Multiply count | Use |
|---|---|---|
| Triple loop | n^3 | Default; small n; libraries |
| Eight-product D&C | n^3 | Teaching split; not faster |
| Strassen | \Theta(n^{\log_2 7}) | Large n, after a measured crossover |
For two 3-by-3 matrices on paper, the honest method is
- The triple loop (or nine 3-term dots) — padding to 4-by-4 for Strassen costs more than it saves
- Strassen, because \log_2 7 < 3 for every n
- Eight-product D&C, because it is already \Theta(n^{2.81})
The exponent is asymptotic. Eight-product D&C is still \Theta(n^3). A 3-by-3 is below any crossover.
Notes
- Naive divide-and-conquer multiplies two n \times n matrices by eight products of n/2 blocks plus O(n^2) additions, so T(n)=8T(n/2)+\Theta(n^2)=\Theta(n^3) — the same class as the triple loop.
- Strassen computes the same C=AB with seven half-size products and a constant number of block additions (18 at each level).
- The seven products P_1,\ldots,P_7 are linear combinations of the blocks of A and of B; the four blocks of C are linear combinations of those P_k.
- The recurrence is T(n)=7T(n/2)+\Theta(n^2)=\Theta(n^{\log_2 7}) with \log_2 7 \approx 2.807.
- The crossover is large: extra additions, odd n padding, and worse numerical stability mean the triple loop (or a tuned library) wins on the sizes you multiply by hand.
Formulas
- Naive D&C: T(n)=8T(n/2)+\Theta(n^2)=\Theta(n^3).
- Strassen: T(n)=7T(n/2)+\Theta(n^2)=\Theta(n^{\log_2 7}), \log_2 7 \approx 2.807.
- P_1=(A_{11}+A_{22})(B_{11}+B_{22}), P_2=(A_{21}+A_{22})B_{11}, P_3=A_{11}(B_{12}-B_{22}), P_4=A_{22}(B_{21}-B_{11}), P_5=(A_{11}+A_{12})B_{22}, P_6=(A_{21}-A_{11})(B_{11}+B_{12}), P_7=(A_{12}-A_{22})(B_{21}+B_{22}).
- C_{11}=P_1+P_4-P_5+P_7, C_{12}=P_3+P_5, C_{21}=P_2+P_4, C_{22}=P_1+P_3-P_2+P_6.
- Block additions at one level: 18 of size n/2.
Exam traps & shortcuts
- Eight recursive multiplies do not beat the triple loop — only dropping to seven changes the exponent.
- Count multiplies, not additions, when you name the recurrence. Additions are the \Theta(n^2) work.
- On n=2 the seven products are ordinary scalar multiplies; that is the base case you can check by hand.
- Strassen is not a licence to multiply 3-by-3 matrices this way on an exam — pad to a power of two and the overhead dominates.
Reference tables
The 8 versus 7 is the only change that moves the exponent.
| Algorithm | Recurrence | Solution |
|---|---|---|
| Triple loop | — | \Theta(n^3) |
| Eight-product D&C | T(n)=8T(n/2)+\Theta(n^2) | \Theta(n^3) |
| Strassen | T(n)=7T(n/2)+\Theta(n^2) | \Theta(n^{\log_2 7}) |
Same C from seven products and from four dots.
| Block | Ordinary dots | Strassen assembly |
|---|---|---|
| C_{11} | 1\cdot 2+3\cdot 6=20 | 80+28-32-56=20 |
| C_{12} | 1\cdot 4+3\cdot 8=28 | -4+32=28 |
| C_{21} | 5\cdot 2+7\cdot 6=52 | 24+28=52 |
| C_{22} | 5\cdot 4+7\cdot 8=76 | 80-4-24+24=76 |
Recap
Night-before Strassen pegs.
- Eight
- Naive block multiply: 8 products, still \Theta(n^3).
- Seven
- Strassen: 7 products, 18 block additions, T(n)=7T(n/2)+\Theta(n^2).
- C
- C_{11}=P_1+P_4-P_5+P_7, C_{12}=P_3+P_5, C_{21}=P_2+P_4, C_{22}=P_1+P_3-P_2+P_6.
- Exponent
- \Theta(n^{\log_2 7}), \log_2 7 \approx 2.807.
- Crossover
- Small n and odd n stay with the triple loop.
Practise Strassen Matrix Multiplication
Reading is free and needs no account. Practice, mocks and progress live in the app.
- A 5-question practice set that ends the chapter
- 5 quick checks with worked explanations
- Timed mocks scored with the real marking scheme
- Readiness tracked per topic, kept on your device