我正在为Strassen的矩阵乘法编写一个程序,我收到以下错误:
Traceback (most recent call last):
File "StrassensMult_v01.py", line 130, in <module>
cMatrix = matrixMul(aMatrix, bMatrix)
File "StrassensMult_v01.py", line 92, in matrixMul
C11 = matrixAdd(S1, matrixAdd(S4, matrixAdd(S5, S7, add), sub), add)
File "StrassensMult_v01.py", line 73, in matrixAdd
Sum[i].append(obj(A[i][j], B[i][j]))
TypeError: 'int' object has no attribute '__getitem__'
以下是所有相关代码:
#!/usr/bin/env python
from operator import add, sub
def Partition(A):
'''this works. Perfect.'''
'''Divides the given matrix into 4 different matrices'''
order = getOrder(A)
divVal = order/2
a11= []
a12= []
a21= []
a22= []
for i in range(0,divVal):
a11.append([])
for j in range(0,divVal):
a11[i].append(A[i][j])
for i in range(0,divVal):
a12.append([])
for j in range(divVal,order):
a12[i].append(A[i][j])
for i in range(divVal,order):
a21.append([])
for j in range(0,divVal):
a21[i-divVal].append(A[i][j])
for i in range(divVal,order):
a22.append([])
for j in range(divVal,order):
a22[i-divVal].append(A[i][j])
return a11, a12, a21, a22
def Combine(C11, C12, C21, C22):
'''Freaking finished!!!'''
'''Combines 4 matrices into a single matrix'''
divVal = getOrder(C11)
order = len(C11) + len(C12)
C = []
for i in range(0, divVal):
C.append([])
for j in range(0, divVal):
C[i].append(C11[i][j])
for i in range(0, divVal):
for j in range(0, divVal):
C[i].append(C12[i][j])
for i in range(0, divVal):
C.append([])
for j in range(0, divVal):
C[divVal + i].append(C21[i][j])
for i in range(0, divVal):
for j in range(0,divVal):
C[divVal + i].append(C22[i][j])
return C
def matrixAdd(A, B, obj):
'''This works fine, too.'''
'''Adds(or subtracts) two matrices based on obj function object'''
'''Obj is for in case of matrix subtraction. Just pass a add or sub function object to it, and hey presto!'''
order = getOrder(A)
Sum = []
for i in range(order):
Sum.append([])
for j in range(order):
Sum[i].append(obj(A[i][j], B[i][j]))
return Sum
def matrixMul(A, B):
'''Multiplies matrices based on strassen's method'''
n = getOrder(A)
#print n
if n != 1:
A11, A12, A21, A22 = Partition(A)
B11, B12, B21, B22 = Partition(B)
S1 = matrixMul(matrixAdd(A11, A22, add), matrixAdd(B11, B22, add))
S2 = matrixMul(matrixAdd(A21, A22, add), B11)
S3 = matrixMul(matrixAdd(B12, B22, sub), A11)
S4 = matrixMul(matrixAdd(B21, B11, sub), A22)
S5 = matrixMul(matrixAdd(A11, A12, add), B22)
S6 = matrixMul(matrixAdd(A21, A11, sub), matrixAdd(B11, B12, add))
S7 = matrixMul(matrixAdd(A12, A22, sub), matrixAdd(B21, B22, add))
C11 = matrixAdd(S1, matrixAdd(S4, matrixAdd(S5, S7, add), sub), add)
C12 = matrixAdd(S3, S5, add)
C21 = matrixAdd(S2, S4, add)
C22 = matrixAdd(S1, matrixAdd(S3, matrixAdd(S2, S6, add), sub), add)
C = Combine(C11,C12, C21, C22)
else:
C = []
C.append(A[0][0] * B[0][0])
return C
def inputVal():
n = input('Enter the order of the square matrices you wish to multiply: ')
print 'Enter matrix values: '
Amat = []
Bmat = []
print '\n\nFor first matrix...'
for i in range(n):
Amat.append([])
for j in range(n):
Amat[i].append(input('Enter A[%s][%s]: ' %(i,j)))
print '\n\nFor second matrix...'
for i in range(n):
Bmat.append([])
for j in range(n):
Bmat[i].append(input('Enter B[%s][%s]: ' %(i,j)))
return Amat, Bmat
'''Input the matrices'''
getOrder = lambda x: len(x)
'''Get the order of the matrix'''
aMatrix, bMatrix = inputVal()
cMatrix = matrixMul(aMatrix, bMatrix)
print cMatrix
if __name__ == '__main__':
main()
用Strassen的方程式:
假设nXn矩阵,其中n是2的精确幂
S1 = (A11 + A22)(B11 + B22)
S2 = (A21 + A22) * B11
S3 = (B12 - B22) * A11
S4 = (B21 - B11) * A22
S5 = (A11 + A12) * B22
S6 = (A21 - A11) * (B11 + B12)
S7 = (A12 - A22) * (B21 + B22)
C11 = S1 + S4 - S5 + S7
C12 = S3 + S5
C21 = S2 + S4
C22 = S1 + S3 - S2 + S6
为什么会发生TypeError?我意识到所有功能链接都存在一些问题,但如果有人指出我的方向正确,那就太棒了。
答案 0 :(得分:0)
问题在于处理matrixMul
中的角点情况,矩阵A
的顺序,n = 1。
def matrixMul(A, B):
n = getOrder(A)
if n != 1:
# ...
else:
C = []
C.append(A[0][0] * B[0][0])
return C
请注意,在这种情况下返回列表而不是矩阵。
要解决此问题,您可以这样写:
C = []
C.append([A[0][0] * B[0][0]])
或更简单:
C = [[ A[0][0] * B[0][0] ]]