Strassen 的乘法--> TypeError: 'int' object has no attribute '__getitem__'

Posted

技术标签:

【中文标题】Strassen 的乘法--> TypeError: \'int\' object has no attribute \'__getitem__\'【英文标题】:Strassen's multiplication--> TypeError: 'int' object has no attribute '__getitem__'Strassen 的乘法--> TypeError: 'int' object has no attribute '__getitem__' 【发布时间】:2017-09-18 17:35:11 【问题描述】:

我正在为 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?我意识到所有函数链接都存在一些问题,但如果有人指出我正确的方向,那就太好了。

【问题讨论】:

【参考方案1】:

问题在于处理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] ]]

【讨论】:

以上是关于Strassen 的乘法--> TypeError: 'int' object has no attribute '__getitem__'的主要内容,如果未能解决你的问题,请参考以下文章

实施 Strassen 矩阵乘法算法的问题

矩阵乘法的Strassen算法及时间复杂度

Algorithms - Strassen's algorithm for matrix multiplication 矩阵乘法 Strassen 算法

Algorithms - Strassen's algorithm for matrix multiplication 矩阵乘法 Strassen 算法

矩阵乘法 strassen

Strassen矩阵乘法之思考