1

内積行列を作成する方法を理解しようとしています。これまでに作成したコードは次のとおりです。

C = [[4,1,9], [6,2,8], [7,3,5]]
D = [[2,9], [5,2], [1,0]]

def prettyPrint(A):
    for i in range(len(A)):
        line = "{0: >7}".format("|"+str(A[i][0]))
        for j in range(1, len(A[i])):
            line = line + "{0: >7}".format(str(A[i][j]))
        line = line + "|"
        print(line)
#for addition of vectors   
def matrixADD(A,B):
    Z = []
    for i in range(len(A)):
        row = []
        for j in range(len(A[0])):
            row.append(A[i][j]+B[i][j])
        Z.append(row)
    return Z
#for subtraction of vectors
def matrixSUB(A,B):
    Z = []
    for i in range(len(A)):
        row = []
        for j in range(len(A[0])):
            row.append(A[i][j]-B[i][j])
        Z.append(row)
    return Z
#for multiplication of vectors
def row(A,i):
    Z = []
    Z.extend(A[i])
    return Z

def col(B,j):
    Z = []
    for row in B:
        Z.append(row[j])
    return Z

def dotProduct(x,y):
    prod = 0
    prod = sum(p*q for p,q in zip(x,y))
    return prod

def matrixMUL(A,B):
    Z = []
    #Need to do.
    return Z

print("\nC * D:")
prettyPrint(matrixMUL(C,D))

matrixMUL(A,B)悩んでいる部分です。プログラムは次のような計算を行うことになっています: 例:

Z = C * D =
row(C,0) • col(D,0)   row(C,0) • col(D,1)
row(C,1) • col(D,0)   row(C,1) • col(D,1)
row(C,2) • col(D,0)   row(C,2) • col(D,1)
Z =
(4*2 + 1*5 + 9*1)   (4*9 + 1*2 + 9*0)
(6*2 + 2*5 + 8*1)   (6*9 + 2*2 + 8*0)
(7*2 + 3*5 + 5*1)   (7*9 + 3*2 + 5*0)
Z =
22    38
30    58
34    69

そして、この印刷ステートメントだけがあります:

C * D:
     |22     38|
     |30     58|
     |34     69| 

他のツリー(または3つ?タイプミスがあるかどうかわからない)関数を使用する必要があります。私はこれを過去 3 日間試してきましたが、考えられることはすべて調べました。これは私が試した中で失敗したコードの一部です (うまくいかなかったものをコメントアウトしただけです):

def matrixMUL(A,B):
    Z = []
    Z.append(int(dotProduct(row(A,B),col(A,B))))
    #if len(col(B,j)) != len(row(A,i)):
        #print("Cannot multiply the two matrices. Incorrect dimensions.")
    #else:
        #for n in range(row(A,i)):
            #for m in range(col(B,j)):
                #Z.append(dotProduct(x,y))
    return Z
    #mult = sum(p*q for p,q in zip(x,y))
    #Z.append(mult)
    #Z = []
    #for i in range(len(A)):
        #row = []
        #for j in range(len(A[0])):
            #row.append(A[i][j]+B[i][j])
        #Z.append(row)
    #return Z    

他に何を試すことができるかわかりません。誰か助けてくれませんか?

4

1 に答える 1

0

You can do it this way:

def matrixMUL(A,B):
    Z = [[0] * len(B[0]) for zz in range(len(A))]
    for i in range(0,len(A)):
        a = row(A,i)
        for j in range(0,len(B[0])):
            b = col(B,j)
            Z[i][j] = sum(p*q for p,q in zip(a,b))
    return Z

A difficulty that I've encountered when writing code like this is initialising the matrix correctly in the first place.

If we use code like Z = [[0] * len(B[0])] * len(A), then we end up creating a list Z that contains len(A) references to the same list of length len(B[0]) zeros. Thus, code like z[0][0] = 1 will appear to "magically" change Z[1][0] and Z[2][0] to equal 1 at the same time, because all of these refer to the same element in the same list.

By initialising the matrix Z with a list comprehension as shown above, we can be sure we have a set of unique lists referred to in Z.

Another approach that avoids the need to initialise all of Z (and thus avoids the list reference problem entirely) is:

def matrixMUL2(A,B):
    Z = []
    for i in range(0,len(A)):
        a = row(A,i)
        r = []
        for j in range(0,len(B[0])):
            b = col(B,j)
            r.append(sum(p*q for p,q in zip(a,b)))
        Z.append(r)
    return Z

Neither function does as much error checking as it should (e.g. checking that the matrices have corresponding dimension sizes, as is required for multiplication), so they are not up to a good production-code standard as yet. Also, as has been suggested in comments, if numpy was available, I'd highly recommend using numpy instead of writing one's own code for this.

于 2013-03-29T00:35:21.720 に答える