def strassen_multiply(self, other):
# Implementation for 2^n × 2^n matrices
if self.rows <= 64: # Use standard multiplication for small matrices
return self.multiply(other)
n = self.rows
mid = n // 2
# Divide matrices into quadrants
a11 = self.submatrix(0, mid, 0, mid)
a12 = self.submatrix(0, mid, mid, n)
a21 = self.submatrix(mid, n, 0, mid)
a22 = self.submatrix(mid, n, mid, n)
b11 = other.submatrix(0, mid, 0, mid)
b12 = other.submatrix(0, mid, mid, n)
b21 = other.submatrix(mid, n, 0, mid)
b22 = other.submatrix(mid, n, mid, n)
# Compute the 7 products
p1 = (a11 + a22).strassen_multiply(b11 + b22)
p2 = (a21 + a22).strassen_multiply(b11)
p3 = a11.strassen_multiply(b12 - b22)
p4 = a22.strassen_multiply(b21 - b11)
p5 = (a11 + a12).strassen_multiply(b22)
p6 = (a21 - a11).strassen_multiply(b11 + b12)
p7 = (a12 - a22).strassen_multiply(b21 + b22)
# Compute quadrants of result
c11 = p1 + p4 - p5 + p7
c12 = p3 + p5
c21 = p2 + p4
c22 = p1 - p2 + p3 + p6
return Matrix.combine(c11, c12, c21, c22)