バックナンバーはこちら。
https://www.simulationroom999.com/blog/compare-matlabpythonscilabjulia-backnumber/
はじめに
前回から、具体的に各ツール、各言語での行列演算についての話に突入。
四則演算に加えて、アダマール積、べき乗、転置、反転。
まずは手馴れたMATLABから実施したところ。
今回はPythonについて
登場人物
博識フクロウのフクさん
イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん
イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
Pythonの場合
太郎くん
Pythonもてなれたところだからさっとやってしまおう。
フクさん
こんな感じになるな。
#足し算
>>> A+B
array([[ 6, 8],
[10, 12]])
#引き算
>>> A-B
array([[-4, -4],
[-4, -4]])
#掛け算(内積)
>>> A@B
array([[19, 22],
[43, 50]])
>>> A.dot(B)
array([[19, 22],
[43, 50]])
>>> np.matmul(A,B)
array([[19, 22],
[43, 50]])
#アダマール積
>>> A*B
array([[ 5, 12],
[21, 32]])
#左除算
#Pythonでは直接、左除算はできない。
#よって、逆行列との積で除算とする。
>>> np.linalg.inv(A)@B
array([[-3., -4.],
[ 4., 5.]])
>>> np.linalg.inv(A).dot(B)
array([[-3., -4.],
[ 4., 5.]])
>>> np.matmul( np.linalg.inv(A), B )
array([[-3., -4.],
[ 4., 5.]])
#右除算
#Pythonでは直接、右除算はできない。
#よって、逆行列との積で除算とする。
>>> A@np.linalg.inv(B)
array([[ 3., -2.],
[ 2., -1.]])
>>> A.dot(np.linalg.inv(B))
array([[ 3., -2.],
[ 2., -1.]])
>>> np.matmul( A, np.linalg.inv(B) )
array([[ 3., -2.],
[ 2., -1.]])
#べき乗
>>> A**2
array([[ 7, 10],
[15, 22]])
>>> np.linalg.matrix_power(A, 2)
array([[ 7, 10],
[15, 22]])
#転置
>>> A.T
array([[1, 3],
[2, 4]])
>>> A.transpose()
array([[1, 3],
[2, 4]])
#反転
#一次元目(縦方向)に対して反転。
>>> np.flipud(A)
array([[3, 4],
[1, 2]])
>>> A[::-1]
array([[3, 4],
[1, 2]])
#ニ次元目(横方向)に対して反転。
>>> np.fliplr(A)
array([[2, 1],
[4, 3]])
>>> A[:,::-1]
array([[2, 1],
[4, 3]])
パッと見た感じ
太郎くん
Python(Numpy)は内積の演算子は「@」なんだね。
フクさん
そうだね。
一般的に積は「*」なことは多いが、
Python(Numpy)の場合はアダマール積になるから注意が必要だ。
他のツール、言語と比べるとPythonが一番性質が異なる感じだから、この先もちょいちょい苦しめられるかもね。
太郎くん
あと、左除算、右除算もないのかー。
フクさん
右除算はA/Bという書き方はできるのだけど、
演算結果としては、AとBの逆行列のアダマール積なんで、
内積としての除算とは異なるようだ。
太郎くん
確かに、いろいろ苦しめられそうだ・・・。
まとめ
フクさん
まとめだよ。
- Python(Numpy)での基本的な行列演算を確認。
- 内積は「@」
- 「*」だとアダマール積になるので注意
- それ以外にも0オリジンだったり、終端指定が-1だったりとクセが違う。
- 右除算もできるように見せかけて、実は逆行列とのアダマール積なので目的としたものとは異なる。
バックナンバーはこちら。
コメント