基于Numpy的矩阵相乘

基于Numpy的矩阵相乘

@author: Heisenberg

主要介绍了矩阵乘法、哈达玛积、克罗内克积的概念及基于numpy的实现。

1. 矩阵乘法

1.1 概念

即线性代数中不满足交换律的矩阵乘法,又称为矩阵内积、点积(dot-product)。 i . e . A B ≠ B A i.e. AB\neq BA i.e.AB=BA。一般记为 A ⋅ B A\cdot B AB

A ( m × n ) ⋅ B ( n × k ) = C ( m × k ) A_{(m\times n)}\cdot B_{(n\times k)}=C_{(m\times k)} A(m×n)B(n×k)=C(m×k)基本算法是 A A A的第一行乘以 B B B的第一列求和作为新矩阵第一个元素 C 11 C_{11} C11 A A A的第一行乘以 B B B的第二列求和作为新矩阵第一个元素 C 12 C_{12} C12,以此类推。

举个栗子:
[ 1 0 2 − 1 3 1 ] ⋅ [ 3 1 2 1 1 0 ] = [ 5 1 4 2 ] \left[\begin{array}{ccc} 1 & 0 & 2 \\ -1 & 3 & 1 \end{array}\right] \cdot\left[\begin{array}{ll} 3 & 1 \\ 2 & 1 \\ 1 & 0 \end{array}\right]=\left[\begin{array}{ll} 5 & 1 \\ 4 & 2 \end{array}\right] [110321]321110=[5412]

1.2 实现方法

1.2.1 @方法
import numpy as np
A = np.array([[1,0,2],[-1,3,1]])
B = np.array([[3,1],[2,1],[1,0]])
A@B
#Out[1]:
#array([[5, 1],
#       [4, 2]])

1.2.2 dot方法
A.dot(B) #or np.dot(A,B)
#Out[2]:
#array([[5, 1],
#       [4, 2]])
1.2.3 matmul方法
np.matmul(A,B)
#Out[3]:
#array([[5, 1],
#       [4, 2]])
1.2.4 dot() vs matmul()

在两个array的维度均为两维的情况下结果相同。

但在3个维度时,结合下例来看:

  • matmul()方法将最后两个维度作为矩阵的两维,相当于有2个 2 × 2 2\times 2 2×2的矩阵,在这个维度上进行对应位置的矩阵乘法,即可以视为
    [ [ 2 × 3 ] [ 2 × 3 ] ] ⋅ [ [ 3 × 2 ] [ 3 × 2 ] ] = [ [ 2 × 3 ] ⋅ [ 3 × 2 ] [ 2 × 3 ] ⋅ [ 3 × 2 ] ] = [ [ 2 × 2 ] [ 2 × 2 ] ] \left[\begin{array}{c}[2\times 3] \\ [2\times 3] \end{array}\right]\cdot\left[\begin{array}{c}[3\times 2] \\ [3\times 2] \end{array}\right] = \left[\begin{array}{c}[2\times 3]\cdot [3\times 2] \\ [2\times 3]\cdot [3\times 2] \end{array}\right]=\left[\begin{array}{c}[2\times 2] \\ [2\times 2] \end{array}\right] [[2×3][2×3]][[3×2][3×2]]=[[2×3][3×2][2×3][3×2]]=[[2×2][2×2]]

    np.matmul中,多维的矩阵,将前n-2维视为后2维的元素后,进行乘法运算;且禁止矩阵与标量的乘法。

  • dot()方法将 A A A的最后一个维度作为向量,并将 B B B的倒数第二维看作另一个向量,因此 A A A可以看成有 2 × 2 2\times2 2×2个向量, B B B中有 2 × 2 2\times2 2×2个向量,dot会将 A A A的向量与 B B B的向量全部组合在一起,因此会有种 ( 2 × 2 ) × ( 2 × 2 ) (2\times2)\times(2\times2) (2×2)×(2×2)个结果,即可以视为

[ [ 1 × 3 ] [ 1 × 3 ] [ 1 × 3 ] [ 1 × 3 ] ] ⋅ [ [ 3 × 1 ] [ 3 × 1 ] [ 3 × 1 ] [ 3 × 1 ] ] = [ 1 × 3 ] ⋅ [ [ 3 × 1 ] [ 3 × 1 ] [ 3 × 1 ] [ 3 × 1 ] ] + [ 1 × 3 ] ⋅ [ [ 3 × 1 ] [ 3 × 1 ] [ 3 × 1 ] [ 3 × 1 ] ] + [ 1 × 3 ] ⋅ [ [ 3 × 1 ] [ 3 × 1 ] [ 3 × 1 ] [ 3 × 1 ] ] + [ 1 × 3 ] ⋅ [ [ 3 × 1 ] [ 3 × 1 ] [ 3 × 1 ] [ 3 × 1 ] ] = [ [ 2 × 2 ] [ 2 × 2 ] [ 2 × 2 ] [ 2 × 2 ] ] \left[\begin{array}{llll}[1\times 3] \\ [1\times 3] \\ [1\times 3] \\ [1\times 3] \end{array}\right]\cdot\left[\begin{array}{cc}[3\times 1]&[3\times 1] \\ [3\times 1]&[3\times 1] \end{array}\right] \\= [1\times 3]\cdot\left[\begin{array}{cc}[3\times 1]&[3\times 1] \\ [3\times 1]&[3\times 1] \end{array}\right]+[1\times 3]\cdot\left[\begin{array}{cc}[3\times 1]&[3\times 1] \\ [3\times 1]&[3\times 1] \end{array}\right]+[1\times 3]\cdot\left[\begin{array}{cc}[3\times 1]&[3\times 1] \\ [3\times 1]&[3\times 1] \end{array}\right]+[1\times 3]\cdot\left[\begin{array}{cc}[3\times 1]&[3\times 1] \\ [3\times 1]&[3\times 1] \end{array}\right]\\ =\left[\begin{array}{c}[2\times 2] \\ [2\times 2]\\ [2\times 2]\\ [2\times 2] \end{array}\right] [1×3][1×3][1×3][1×3][[3×1][3×1][3×1][3×1]]=[1×3][[3×1][3×1][3×1][3×1]]+[1×3][[3×1][3×1][3×1][3×1]]+[1×3][[3×1][3×1][3×1][3×1]]+[1×3][[3×1][3×1][3×1][3×1]]=[2×2][2×2][2×2][2×2]

>>>A = np.array([i for i in range(12)]).reshape([2,2,3])
>>>B = np.array([i for i in range(12)]).reshape([2,3,2])
"""
A
[[[ 0  1  2]
  [ 3  4  5]]

 [[ 6  7  8]
  [ 9 10 11]]]
B
[[[ 0  1]
  [ 2  3]
  [ 4  5]]

 [[ 6  7]
  [ 8  9]
  [10 11]]]
"""
>>>np.matmul(A,B)
"""
array([[[ 10,  13],
        [ 28,  40]],

       [[172, 193],
        [244, 274]]])
"""
>>>np.dot(A,B)
'''
array([[[[ 10,  13],
         [ 28,  31]],

        [[ 28,  40],
         [100, 112]]],


       [[[ 46,  67],
         [172, 193]],

        [[ 64,  94],
         [244, 274]]]])

'''

2. 哈达玛积(按位相乘)

2.1 概念

哈达马积,将矩阵中相同位置的元素相乘,又称element-wise product。一般记为 A ∗ B A*B AB

举个栗子:
( 1 3 2 1 0 0 1 2 2 ) ∗ ( 0 0 2 7 5 0 2 1 1 ) = ( 1 ⋅ 0 3 ⋅ 0 2 ⋅ 2 1 ⋅ 7 0 ⋅ 5 0 ⋅ 0 1 ⋅ 2 2 ⋅ 1 2 ⋅ 1 ) = ( 0 0 4 7 0 0 2 2 2 ) \left(\begin{array}{lll} 1 & 3 & 2 \\ 1 & 0 & 0 \\ 1 & 2 & 2 \end{array}\right) *\left(\begin{array}{lll} 0 & 0 & 2 \\ 7 & 5 & 0 \\ 2 & 1 & 1 \end{array}\right)=\left(\begin{array}{lll} 1 \cdot 0 & 3 \cdot 0 & 2 \cdot 2 \\ 1 \cdot 7 & 0 \cdot 5 & 0 \cdot 0 \\ 1 \cdot 2 & 2 \cdot 1 & 2 \cdot 1 \end{array}\right)=\left(\begin{array}{lll} 0 & 0 & 4 \\ 7 & 0 & 0 \\ 2 & 2 & 2 \end{array}\right) 111302202072051201=101712300521220021=072002402

2.2 实现方法

2.2.1 *方法
A = np.array([[1,2],[3,4]])
B = np.array([[5,6],[7,8]])
A*B
#array([[ 5, 12],
#       [21, 32]])
2.2.2 multiply()方法
np.multiply(A,B)
#array([[ 5, 12],
#       [21, 32]])

3. 克罗内克积

3.1 概念

克罗内克积也被称为直积或张量积,适用于任意矩阵大小,一般记作 A ⊗ B A\otimes B AB

举个栗子:
( 1 2 3 1 ) ⊗ ( 0 3 2 1 ) = ( 1 ⋅ 0 1 ⋅ 3 2 ⋅ 0 2 ⋅ 3 1 ⋅ 2 1 ⋅ 1 2 ⋅ 2 2 ⋅ 1 3 ⋅ 0 3 ⋅ 3 1 ⋅ 0 1 ⋅ 3 3 ⋅ 2 3 ⋅ 1 1 ⋅ 2 1 ⋅ 1 ) = ( 0 3 0 6 2 1 4 2 0 9 0 3 6 3 2 1 ) \left(\begin{array}{ll} 1 & 2 \\ 3 & 1 \end{array}\right) \otimes\left(\begin{array}{ll} 0 & 3 \\ 2 & 1 \end{array}\right)=\left(\begin{array}{llll} 1 \cdot 0 & 1 \cdot 3 & 2 \cdot 0 & 2 \cdot 3 \\ 1 \cdot 2 & 1 \cdot 1 & 2 \cdot 2 & 2 \cdot 1 \\ 3 \cdot 0 & 3 \cdot 3 & 1 \cdot 0 & 1 \cdot 3 \\ 3 \cdot 2 & 3 \cdot 1 & 1 \cdot 2 & 1 \cdot 1 \end{array}\right)=\left(\begin{array}{llll} 0 & 3 & 0 & 6 \\ 2 & 1 & 4 & 2 \\ 0 & 9 & 0 & 3 \\ 6 & 3 & 2 & 1 \end{array}\right) (1321)(0231)=10123032131133312022101223211311=0206319304026231

3.2 np.kron()方法

A = np.array([[1,2],[3,4]])
B = np.array([[5,6],[7,8]])
np.kron(A,B)
#array([[ 5,  6, 10, 12],
#       [ 7,  8, 14, 16],
#       [15, 18, 20, 24],
#       [21, 24, 28, 32]])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值