💀
[Python]行列の積
行列の積
文字とかと演算できるやつ欲しくて作ったけどSymPyでいいじゃんってなって結局使わなかったコード
R.I.P.
コード
# 添え字付き文字列を格納したXの行列を作成する
def makeCharMat(row, col, char='X'):
res = []
for r in range(row):
res.append([])
for c in range(col):
v = f'{char}{r+1}{c+1}'
res[r].append(v)
return res
# ndarrayではなく通常のリストを受け取る
def matrix_multiply(mat1, mat2):
result = []
row1 = len(mat1)
col1 = len(mat1[0])
row2 = len(mat2)
col2 = len(mat2[0])
if col1 != row2:
raise ValueError("行列のサイズが不適切です")
for i in range(row1):
result.append([])
for j in range(col2):
if type(mat1[i][0]) == str and type(mat2[0][j]) != str: # [文字][数字]
v = ''
for k in range(col1 - 1):
if mat2[k][j] == 0:
continue
elif mat2[k][j] == 1:
v += f'{mat1[i][k]}'
v += '+'
else:
v += f'{mat2[k][j]}{mat1[i][k]}'
v += '+'
# last
if mat2[-1][j] == 0:
v = v.rstrip('+')
elif mat2[-1][j] == 1:
v += f'{mat1[i][-1]}'
else:
v += f'{mat2[-1][j]}{mat1[i][-1]}'
# result
if len(v) == 0:
result[i].append(0)
else:
result[i].append(v)
elif type(mat1[i][0]) != str and type(mat2[0][j]) == str: # [数字][文字]
v = ''
for k in range(col1 - 1):
if mat1[i][k] == 0:
continue
elif mat1[i][k] == 1:
v += f'{mat2[k][j]}'
v += '+'
else:
v += f'{mat1[i][k]}{mat2[k][j]}'
v += '+'
# last
if mat1[i][-1] == 0:
v = v.rstrip('+')
elif mat1[i][-1] == 1:
v += f'{mat2[-1][j]}'
else:
v += f'{mat1[i][-1]}{mat2[-1][j]}'
# result
if len(v) == 0:
result[i].append(0)
else:
result[i].append(v)
elif type(mat1[i][0]) == str and type(mat2[0][j]) == str: # [文字][文字]
v = ''
for k in range(col1 - 1):
v += f'{mat1[i][k]}{mat2[k][j]}'
v += '+'
# last
v += f'{mat1[i][-1]}{mat2[-1][j]}'
result[i].append(v)
else: # [数字][数字]
v = 0
for k in range(col1):
v += mat1[i][k] * mat2[k][j]
result[i].append(v)
return result
def show_mat(mat):
for row in mat:
print("[", end=" ")
for ele in row:
print(f'{ele}\t', end=" ")
print("]")
実行例
X = makeCharMat(2, 2)
Y = makeCharMat(2, 2, char='Y')
N1 = [[1, 2, 3],
[4, 5, 6]]
N2 = [[1, 2],
[3, 4],
[5, 6]]
res1 = matrix_multiply(X, Y) # [文字][文字]
res2 = matrix_multiply(X, N1) # [文字][数字]
res3 = matrix_multiply(N2, X) # [数字][文字]
res4 = matrix_multiply(N1, N2) #[数字][数字]
show_mat(res1)
show_mat(res2)
show_mat(res3)
show_mat(res4)
[ X11Y11+X12Y21 X11Y12+X12Y22 ]
[ X21Y11+X22Y21 X21Y12+X22Y22 ]
[ X11+4X12 2X11+5X12 3X11+6X12 ]
[ X21+4X22 2X21+5X22 3X21+6X22 ]
[ X11+2X21 X12+2X22 ]
[ 3X11+4X21 3X12+4X22 ]
[ 5X11+6X21 5X12+6X22 ]
[ 22 28 ]
[ 49 64 ]
Discussion