关键词:线性代数 / 矩阵 / 基本定义
矩阵对于算法就如同人对于食物般的关系,已经到了密不可分的状态了,在神经网络里,矩阵代表了每层神经元之间的链接,在集成算法里,矩阵记录了每次分类器更新的残差,在马可夫链里,矩阵表示了不同状态下的条件转移概率,矩阵的重要性已经是不言自明了。除了上集说到的方阵,子矩阵,对角矩阵,与单位矩阵之外,接着要进一步介绍一些常用且方便的矩阵,包含了以下几种矩阵类型:纯量矩阵
三角矩阵
共轭矩阵
对称矩阵
正交矩阵
当然矩阵的类型远不止如此,而这几种矩阵在了解的时候不需要太多先验知识,因此才能在一开始率先登场!
矩阵基本定义
这篇文章里的范例也都将沿用上篇文章中的定义,下面就来回顾一下标记符号的各种含义。
中的
称为矩阵的元素,可以是数字,函数,实数,复数。在 python 代码中的numpy模块几乎可以说是数值计算的唯一选择。
import numpy as np
A = np.random.randint(0, 10, 72)
A = A.reshape(9, 8)
print(A)
输出:
[[5 4 5 8 5 7 0 7]
[5 6 4 0 9 8 6 5]
[1 2 9 6 7 7 3 5]
[3 4 7 8 4 6 9 2]
[4 8 1 3 5 4 8 4]
[5 1 5 7 3 9 9 8]
[0 8 4 1 6 9 3 2]
[4 3 0 3 6 4 5 9]
[2 8 6 3 5 5 3 4]]
如果还没安装过numpy,可以使用下面指令在终端快速安装。
pip install numpy
11. 纯量矩阵 – Scalar matrix
在对角矩阵中,主对角线上的元素皆为某一常数 C 时,则称之为纯量矩阵。
c = 5
print(np.diag([c, c, c]))
输出:
[[5, 0, 0],
[0, 5, 0],
[0, 0, 5]]
12. 上三角矩阵 – Upper triangular matrix
在方阵的前提下,主对角线以下元素皆为 0 时,则称之为上三角矩阵。
print(np.triu(A))
输出:
[[5, 4, 5, 8, 5, 7, 0, 7],
[0, 6, 4, 0, 9, 8, 6, 5],
[0, 0, 9, 6, 7, 7, 3, 5],
[0, 0, 0, 8, 4, 6, 9, 2],
[0, 0, 0, 0, 5, 4, 8, 4],
[0, 0, 0, 0, 0, 9, 9, 8],
[0, 0, 0, 0, 0, 0, 3, 2],
[0, 0, 0, 0, 0, 0, 0, 9],
[0, 0, 0, 0, 0, 0, 0, 0]]
p.s. 即便一个矩阵不是方阵,同样可以取上下三角矩阵。
13. 下三角矩阵 – Lower triangular matrix
在方阵的前提下,主对角线以上元素皆为 0 时,则称之为下三角矩阵。
print(np.tril(A))
输出:
[[5, 0, 0, 0, 0, 0, 0, 0],
[5, 6, 0, 0, 0, 0, 0, 0],
[1, 2, 9, 0, 0, 0, 0, 0],
[3, 4, 7, 8, 0, 0, 0, 0],
[4, 8, 1, 3, 5, 0, 0, 0],
[5, 1, 5, 7, 3, 9, 0, 0],
[0, 8, 4, 1, 6, 9, 3, 0],
[4, 3, 0, 3, 6, 4, 5, 9],
[2, 8, 6, 3, 5, 5, 3, 4]]
14. 共轭矩阵 – Conjugate matrix
把 A 矩阵的元素皆取共轭复数后,该新的矩阵为 A 矩阵的共轭矩阵,以
表示。
B = np.array([[1+1.j, 2-1.j],
[3-2.j, 4+5.j]])
print(np.conj(B))
输出:
[[1.-1.j, 2.+1.j],
[3.+2.j, 4.-5.j]]
15. 转置矩阵 – Transpose matrix
把 A 矩阵中的行列编号互换,元素不变,只变位置后的结果称为 A 矩阵的转置矩阵,以
表示。
print(A.T)
输出:
[[5, 5, 1, 3, 4, 5, 0, 4, 2],
[4, 6, 2, 4, 8, 1, 8, 3, 8],
[5, 4, 9, 7, 1, 5, 4, 0, 6],
[8, 0, 6, 8, 3, 7, 1, 3, 3],
[5, 9, 7, 4, 5, 3, 6, 6, 5],
[7, 8, 7, 6, 4, 9, 9, 4, 5],
[0, 6, 3, 9, 8, 9, 3, 5, 3],
[7, 5, 5, 2, 4, 8, 2, 9, 4]]
16. 共轭转置矩阵 – Conjugate transpose matrix
把 A 矩阵的元素皆取共轭复数后,再取转置;或将 A 矩阵的元素先取转置后,再取共轭复数,所得到的新矩阵即为共轭转置矩阵,以
表示。
print(np.matrix(B).H)
输出:
matrix([[1.-1.j, 3.+2.j],
[2.+1.j, 4.-5.j]])
print(np.conj(B).T)
输出:
[[1.-1.j, 3.+2.j],
[2.+1.j, 4.-5.j]]
17. 对称矩阵 – Symmetrix matrix
在方阵的前提下,如果矩阵 A 的转置等于 A 本身,称之为对称矩阵。
def symmetrixIO(mat):
return np.sum(mat != mat.T) == 0
print(symmetrixIO(C))
输出:
False
18. 反对称矩阵 – Skew symmetrix matrix
在方阵的前提下,如果矩阵 A 的转置矩阵恰为 A 的相反矩阵 -A,则称之为反对称矩阵。
def skew_symmetrixIO(mat):
return np.sum(-mat != mat.T) == 0
print(skew_symmetrixIO(
np.array([[ 0, 2, 5],
[-2, 0, -7],
[-5, 7, 0]])
))
输出:
True
19. 厄米特矩阵 – Hermitian matrix
在方阵的前提下,矩阵 A 的共轭转置矩阵恰好等于原矩阵 A,则称之为厄米特矩阵。
def hermitianIO(mat):
return np.sum(mat != np.conj(mat).T) == 0
print(hermitianIO(
np.array([[ 1, 1+1.j, 5],
[1-1.j, 2, 1.j],
[ 5, -1.j, 7]])
))
输出:
True
20. 正交矩阵 – Orthogonal matrix
正交的意思就是指两个向量彼此互相垂直,而正交矩阵则进一步把垂直的概念拓展到矩阵中,矩阵里的每一个行和列向量必须彼此互相垂直,而且向量长度是1的情况下,才称之为正交矩阵。总结矩阵的规则后,我们得到在方阵的前提下,满足以下条件则称之为正交矩阵:
因此很明显的,一个正交矩阵必定是个方阵,而这一系列的条件判断同样可以被写成一个函数用来检测矩阵是否正交。
from Code.linalg import *
def orthogonalIO(mat, decimal=4):
# A^T = A^(-1)
cond1 = np.sum(np.round(mat.T, decimal) !=
np.round(inverse(mat), decimal)) == 0
# A^T . A = A . A^T
cond2 = np.sum(np.round(np.dot(mat.T, mat), decimal) !=
np.round(np.dot(mat, mat.T), decimal)) == 0
# |A| = +-1
cond3 = np.round(np.abs(determinant(mat)), decimal) == 1
return np.sum([cond1, cond2, cond3]) == 3
B = np.array([[-0.23939017, 0.58743526, -0.77305379],
[ 0.81921268, -0.30515101, -0.48556508],
[-0.52113619, -0.74953498, -0.40818426]])
print(orthogonalIO(B, decimal=4))
输出:
True
为了更深入了解矩阵的底层运算,行列式值和逆矩阵都用的是我们自定义的函数,如果想看具体实现方法,欢迎持续关注发布的文章!在这个函数中我们首先就遇到了一个很简单的理论与实际代码之间的差异,那就是小数点近似问题。由于任意行列向量必须是单位向量,常常在实际情况是一个近似的结果,因此在检测正交与否的时候也必须采用近似的方式操作。Github源代码github.com
转发、分享!微信公众号每周更新,同时每周腾讯会议在线免费分享! 关注公众号,点击按钮“AI大会”即可加入微信群(公布腾讯会议房间号),和清华师兄一起面对面讨论Ai。微信公众号