パイソンで線形代数

  • numpy.linalgがそれ。でも、こちらの方がより実践的かも。
  • その構成は:
    • Matrix and vector products
    • Decompositions
    • Matrix eigenvalues
    • Norms and other numbers
    • Solving equations and inverting matrices
    • Exceptions
    • Linear algebra on several matrices at once
  • Matrix and vector products
    • dot product スカラーの普通の積(複素数も)、ベクトルの内積、行列の通常の積、アレイの場合は、左側アレイの最終軸と右側アレイの後ろから2番目の軸とを対応付けた積(使わなそう…)
np.dot(3,4)
3 + 2j # 複素数
(3+2j) * (2+4j)
np.dot(3+2j,2+4j)
a = np.arange(6).reshape((2,3))
b = np.arange(6)[::-1].reshape((3,2))
np.dot(a,b)
np.dot(b,a)
np.dot(3,4)
Out[65]: 12
np.dot(3+2j,2+4j) # 複素ベクトルの場合、ノルム計算には共役複素数を使うがそうならないことに注意
Out[67]: (-2+16j)
np.dot(a,b) # 行列の積
Out[101]: 
array([[ 5,  2],
       [32, 20]])
np.dot(b,a)
Out[104]: 
array([[12, 21, 30],
       [ 6, 11, 16],
       [ 0,  1,  2]])
    • vdot product。ベクトル用の内積複素数の場合は、第一要素の共役複素数と第二要素そのものとで内積を取るのでノルムに対応。二次元以上にしてもベクトル化したうえでのベクトル内積になることに注意
np.vdot(3,4)
np.vdot(1+2j,1+3j)
np.vdot(1+3j,1+2j)
np.vdot(1+2j,1+3j)
Out[121]: (7+1j)
np.vdot(1+3j,1+2j)
Out[122]: (7-1j)

conj(1+2j) * (1+3j)
Out[119]: (7+1j)

(1+2j) * conj(1+3j)
Out[120]: (7-1j)
    • 1乗ノルム計算は、np.linalg.norm()
a = [1,1]
np.linalg.norm(a)**2
np.vdot(a,a)
np.linalg.norm(a)**2
Out[144]: 2.0000000000000004

np.vdot(a,a)
Out[145]: 2
a =[1+2j,3+1j]
np.linalg.norm(a)**2
Out[147]: 15.000000000000002

np.vdot(a,a)
Out[148]: (15+0j)
    • 後は(たぶん)普通に線形代数的分解や連立方程式解法
    • テンソル方程式が解けたり、高次元アレイの逆があるのは、いいかも(numpy.linalg.tensorsolve、numpy.linalg.tensorinv)
>>> a = np.eye(2*3*4)
>>> a.shape = (2*3, 4, 2, 3, 4)
>>> b = np.random.randn(2*3, 4)
>>> x = np.linalg.tensorsolve(a, b)
>>> x.shape
(2, 3, 4)
>>> np.allclose(np.tensordot(a, x, axes=3), b)
True