Strassen 矩阵乘法
矩阵大小限制为2的n次方
import numpy as np
def matrix_minus(Matrix_A, Matrix_B):
rows = len(Matrix_A)
columns = len(Matrix_A[0])
Matrix_C = [list() for i in range(rows)]
for i in range(rows):
for j in range(columns):
Matrix_C[i].append(Matrix_A[i][j] - Matrix_B[i][j])
return Matrix_C
def matrix_add(Matrix_A, Matrix_B):
rows = len(Matrix_A)
columns = len(Matrix_A[0])
Matrix_C = [list() for i in range(rows)]
for i in range(rows):
for j in range(columns):
Matrix_C[i].append(Matrix_A[i][j] + Matrix_B[i][j])
return Matrix_C
def matrix_divide(Matrix_A, row, column):
length = len(Matrix_A) // 2
Matrix_B = [list() for i in range(length)]
k = 0
for i in range((row - 1) * length, row * length):
for j in range((column - 1) * length, column * length):
Matrix_B[k].append(Matrix_A[i][j])
k += 1
return Matrix_B
def matrix_merge(Matrix_11, Matrix_12, Matrix_21, Matrix_22):
length = len(Matrix_11)
Matrix_All = [list() for i in range(length * 2)]
for i in range(length):
Matrix_All[i] = Matrix_11[i] + Matrix_12[i]
for j in range(length):
Matrix_All[j + length] = Matrix_21[j] + Matrix_22[j]
return Matrix_All
def Strassen(Matrix_A, Matrix_B):
if len(Matrix_A) == 1:
matrix_all = [list() for i in range(1)]
matrix_all[0].append(Matrix_A[0][0] * Matrix_B[0][0])
else:
MatLength = len(Matrix_A)
NextMatLength = MatLength / 2
a00 = matrix_divide(Matrix_A, 1, 1)
a01 = matrix_divide(Matrix_A, 1, 2)
a10 = matrix_divide(Matrix_A, 2, 1)
a11 = matrix_divide(Matrix_A, 2, 2)
b00 = matrix_divide(Matrix_B, 1, 1)
b01 = matrix_divide(Matrix_B, 1, 2)
b10 = matrix_divide(Matrix_B, 2, 1)
b11 = matrix_divide(Matrix_B, 2, 2)
m1 = Strassen((matrix_add(a00, a11)), matrix_add(b00, b11))
m2 = Strassen(matrix_add(a10, a11), b00)
m3 = Strassen(a00, matrix_minus(b01, b11))
m4 = Strassen(a11, matrix_minus(b10, b00))
m5 = Strassen(matrix_add(a00, a01), b11)
m6 = Strassen(matrix_minus(a10, a00), matrix_add(b00, b01))
m7 = Strassen(matrix_minus(a01, a11), matrix_add(b10, b11))
matrix_all = matrix_merge(matrix_add(matrix_add(m1, m4), matrix_minus(m7, m5)), matrix_add(m3, m5), matrix_add(m2, m4), matrix_add(matrix_add(m1, m3), matrix_minus(m6, m2)))
return matrix_all
def testnumpy():
arr1 = np.random.randint(0, 10, size=(16, 16))
arr2 = np.random.randint(10, 20, size=(16, 16))
result_arr = np.dot(arr1, arr2)
return arr1, arr2, result_arr
if __name__ == '__main__':
arr1, arr2, result_numpy = testnumpy()
result_Strassen = Strassen(arr1, arr2)
print(result_Strassen)
print(result_numpy)