矩阵——系统
矩阵看做是一个系统,使用矩阵可以表示一个线性系统。如使用矩阵表示一个方程组,
⎩⎪⎪⎪⎨⎪⎪⎪⎧xi+0.2xj+0.1xk+0.5xl=100−0.5xi+xj+0.2xk+0.1xl=50−0.4xj−xk+0.3xl=20−0.2xi+xl=666
可以表示为,
⎝⎜⎜⎛1−0.50−0.2−0.2−1−0.400.10.2−100.50.10.31⎠⎟⎟⎞⎝⎜⎜⎛1005020666⎠⎟⎟⎞
矩阵乘法
矩阵和向量的乘法
上一节中的线型方程组可以使用矩阵和向量表示,
⎝⎜⎜⎛1−0.50−0.2−0.2−1−0.400.10.2−100.50.10.31⎠⎟⎟⎞⎝⎜⎜⎛xixjxkxl⎠⎟⎟⎞=⎝⎜⎜⎛1005020666⎠⎟⎟⎞
矩阵和向量相乘最终得到的是一个向量,
A⋅x=b
*每次从矩阵中取出一个行向量与列向量进行点乘,可以简单表示为,
⎝⎜⎜⎛a11a21...am1a12a22...am2............a1na2n...amn⎠⎟⎟⎞⋅⎝⎜⎜⎛u1u2...un⎠⎟⎟⎞=⎝⎜⎜⎛a11u1+a12u2+...+a1nuna21u1+a22u2+...+a2nun...am1u1+am2u2+...+amnun⎠⎟⎟⎞
前提是矩阵的列数与向量的元素个数相同。
对于矩阵的行数没有要求。矩阵与向量的点乘可以看做是矩阵将一个向量转换为另一个向量的过程,所以矩阵实际上可以看做是向量的函数(这一视角非常重要)。
矩阵和矩阵的乘法
矩阵A和矩阵B的乘法可以将第二个矩阵B拆成多个列向量,进行矩阵A和多个列向量的乘法。要求矩阵A的列数与矩阵B的行数一致。
A⋅B=A⋅⎝⎛∣c1∣∣c2∣...∣cn∣⎠⎞=⎝⎛∣A⋅c1∣∣A⋅c2∣...∣A⋅cn∣⎠⎞
等同于,
A⋅B=⎝⎜⎜⎛−−−r1r2...rm−−−⎠⎟⎟⎞⋅⎝⎛∣c1∣∣c2∣...∣cn∣⎠⎞=⎝⎜⎜⎛r1⋅c1r2⋅c1...rm⋅c1r1⋅c2r2⋅c2...rm⋅c2.........r1⋅cnr2⋅cn...rm⋅cn⎠⎟⎟⎞
但是矩阵乘法不满足乘法交换律,即使是方阵,交换律得到的结果也是不相等的。这一点很重要。
矩阵乘法实现
接之前Matrix类代码,
def dot(self, another):
"""
返回矩阵乘法结果
:param another: Vector类或Matrix类对象
"""
if isinstance(another, Vector):
assert self.col_num() == len(another)
return Vector([self.row_vector(i)*another] for i in range(self.row_num()))
if isinstance(another, Matrix):
assert self.col_num() == another.row_num()
return Matrix([[self.row_vector(i).dot(another.col_vector(j)) for j in range(another.col_num())] for i in range(self.row_num())])
矩阵乘法的性质与矩阵的幂
- 矩阵乘法不遵守乘法交换律
A⋅B̸=B⋅A
- 矩阵乘法遵守结合律
(A⋅B)⋅C=A⋅(B⋅C)
- 矩阵乘法遵守分配律
A⋅(B+C)=A⋅B+A⋅C
(B+C)⋅A=B⋅A+C⋅A
注意,这两条不等价
- 对任意r⋅c的矩阵A,必存在c⋅x的矩阵O(零矩阵),满足
A⋅Ocx=Orx
- 对任意r⋅c的矩阵A,必存在x⋅r的矩阵O(零矩阵),满足
Oxr⋅A=Oxc
引入矩阵的幂,对于一个实数而言,其k次幂是k个该数相乘的结果。这对于矩阵也是同理的,
Ak=k个AA⋅A⋅...A
前提是A是方阵,否则无法计算矩阵的幂。
矩阵的转置
矩阵的转置实际上就是将矩阵沿着主对角线旋转,将之前的矩阵的列变成新矩阵的行,之前矩阵的行变为新矩阵的列。矩阵转置满足如下性质,
(AT)T=A
(A+B)T=AT+BT
(k⋅A)T=k⋅AT
(A⋅B)T=BT⋅AT
最后一条性质的形式与其他三条不同,给出如下证明,
A是m⋅k的矩阵,B是k⋅n的矩阵
A⋅B是m⋅n的矩阵,AT⋅BT是n⋅m的矩阵,BT⋅AT是m⋅n的矩阵
转置的实现,
def T(self):
"""
返回矩阵的转置矩阵
"""
return Matrix([[e for e in self.col_vector(i)] for i in range(self.col_num())])
Numpy中的矩阵运算
import numpy as np
if __name__ == "__main__":
A = np.array([[1, 2], [3, 4]])
print(A.shape)
print(A.T)
print(A[1, 1])
print(A[0])
print(A[:, 0])
B = np.array([[5, 6], [7, 8]])
print(A + B)
print(10 * B)
p = np.array([10, 100])
print(A * B)
print(A.dot(B))
numpy中矩阵和矩阵、矩阵和向量之间的运算使用的都应使用 np.dot 方法。