#行列UとVを掛け算する
def matrix_multiplication(U,V):
answer=[]
u_colmun_length=len(U[0])
v_row_lengthh=len(V)
v_column_length=len(V[0])
#Uの列数とVの行数が同じじゃないなら計算できない
if u_colmun_length != v_row_lengthh:
print("Could not compute")
return
else:
#Uの行列から1行を取り出す
for u in U:
temp=[]
colmun_index=0
#Vの行列から一列を取り出す
for _ in range(v_column_length):
a = [x[colmun_index] for x in V]
el_index=0
temp_multiple=0
#Uの行とVの列を掛け算し足し合わせる
for _ in range(u_colmun_length):
temp_multiple+=u[el_index]*a[el_index]
el_index+=1
#行列の行を作成
temp.append(temp_multiple)
colmun_index+=1
#行を追加
answer.append(temp)
print(answer)
matrix_multiplication([[2,3],[3,5]],[[2,1]])
matrix_multiplication([[2,3]],[[2],[3]])
matrix_multiplication([[2,3],[2,10]],[[3,5],[3,3]])
matrix_multiplication([[2,3,3],[2,10,3]],[[3,5,2],[3,3,1],[2,4,5]])
"""
Result
Could not compute
[[13]]
[[15, 19], [36, 40]]
[[21, 31, 22], [42, 52, 29]]
"""
1# 行列UとVを掛け算する2defmatrix_multiplication(U, V):3 answer =[]4 u_colmun_length =len(U[0])5 v_row_lengthh =len(V)6 v_column_length =len(V[0])7# Uの列数とVの行数が同じじゃないなら計算できない8if u_colmun_length != v_row_lengthh:9print("Could not compute")10returnNone11else:12# Uの行列から1行を取り出す13for u in U:14 temp =[]15 colmun_index =016# Vの行列から一列を取り出す17for _ inrange(v_column_length):18 a =[x[colmun_index]for x in V]19 el_index =020 temp_multiple =021# Uの行とVの列を掛け算し足し合わせる22for _ inrange(u_colmun_length):23 temp_multiple += u[el_index]* a[el_index]24 el_index +=125# 行列の行を作成26 temp.append(temp_multiple)27 colmun_index +=128# 行を追加29 answer.append(temp)30return answer
31########################################################32# ここまで質問者さんのコード33########################################################3435from pprint import pprint
36import numpy as np
3738# 計算できるパターンで答えがあっているかどうか39np.random.seed(42)40num_tests =1000041num_ok =04243for i inrange(num_tests):44# 行列 A, B の列数、行数をランダムに生成する。45 N, M, L = np.random.randint(1,10,3)46# 行列 A, B の値をランダムに生成する。47 A = np.random.randint(1,10, size=(N, M))48 B = np.random.randint(1,10, size=(M, L))4950# numpy の計算結果51 ret1 = A @ B
5253# 自作した関数の計算結果54 ret2 = matrix_multiplication(A, B)5556ifnot np.array_equal(ret1, ret2):57print("=== incorrect case found ===")58print(f"A {A.shape}\n{A}")59print(f"B {B.shape}\n{B}")60print(f"numpy {ret1.shape}:\n{ret1}")61print(f"matrix_multiplication:\n{ret2}")62else:63 num_ok +=16465print(f"{num_ok} / {num_tests}")# 10000 / 10000
補足
A: (N, M) の行列, B: (M, L) の行列としたとき、
行列積 C は (N, L) の行列でその (i, j) 成分は
C_{ij} = \sum_k^M A_{ik} B_{kj}
なので、定義に従い書くと以下のようになる。
python
1defmatrix_multiplication(A, B):2 A_rows, A_cols =len(A),len(A[0])# A の行数及び列数3 B_rows, B_cols =len(B),len(B[0])# B の行数及び列数45if A_cols != B_rows:6print("Could not compute")7returnNone89# (A_rows, B_cols) の0で初期化した行列を作成する。10 ret =[[0for j inrange(B_cols)]for i inrange(A_rows)]1112for i inrange(A_rows):13for j inrange(B_cols):14for k inrange(A_cols):15 ret[i][j]+= A[i][k]* B[k][j]1617return ret
追記
↓これは[[0]]と出るのですが二次元配列ですか。
ret = [[0 for j in range(B_cols)] for i in range(A_rows)]
ここにインデックスをあらかじめ指定して代入するということですかね?
[[0]]と表示されているのにIndex out of rangeみたいなエラーが出ないので不思議でした
回答ありがとうございます。
やはり確認するにはテストケースを作って確かめるのですね。
コードを拝見いたしましたがこんなにスマートに行列の掛け算ができるのですね。
↓これは[[0]]と出るのですが二次元配列ですか。
ret = [[0 for j in range(B_cols)] for i in range(A_rows)]
ここにインデックスをあらかじめ指定して代入するということですかね?
[[0]]と表示されているのにIndex out of rangeみたいなエラーが出ないので不思議でした
あと↓ですがかけたものを足しているということでいいですか?勉強不足のせいか読み方が分かりません・・・。
C_{ij} = \sum_k^M A_{ik} B_{kj}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。