NumPy解线性代数问题

矩阵运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import numpy.linalg as la
import numpy as np
a = np.array([[1, 2, 3]])
b = np.array([[4], [5], [6]])
print(la.norm(a)) # a的二范数,即模长
print(b@a) # 即a.dot(b),可表示点乘(一维数组)和矩阵乘法(二维数组)
a = np.reshape(a, -1)
b = np.reshape(b, -1)
print(np.inner(a, b)) # a,b的内积,两参数的shape必须为(n,)(1维)
print(np.cross(a, b)) # a,b的叉乘

A = np.arange(1, 17).reshape(4, 4)
B = np.eye(4) # 4阶单位矩阵
print(la.det(A)) # 行列式
print(la.matrix_rank(A)) # 秩
print(A.T) # 转置阵
print(la.inv(A+10*B)) # (A+10*B)的逆矩阵
print(A@B)
print(np.c_[A, B]) # 横向分块矩阵
print(np.r_[A, B]) # 纵向分块矩阵
print(A[0:2, 0:2]) # 矩阵切片,左上角2*2的子矩阵
print(np.delete(A, 3, axis=0)) # 删除某(些)行(0)或列(1)
print(np.delete(A, [0, 2], axis=1))
print(np.delete(A, [0, 2])) # 默认按一维顺序删除单点

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
3.7416573867739413
[[ 4 8 12]
[ 5 10 15]
[ 6 12 18]]
32
[-3 6 -3]
4.7331654313261276e-30
2
[[ 1 5 9 13]
[ 2 6 10 14]
[ 3 7 11 15]
[ 4 8 12 16]]
[[ 0.11277778 0.00333333 -0.00611111 -0.01555556]
[-0.005 0.09 -0.015 -0.02 ]
[-0.02277778 -0.02333333 0.07611111 -0.02444444]
[-0.04055556 -0.03666667 -0.03277778 0.07111111]]
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]
[ 9. 10. 11. 12.]
[13. 14. 15. 16.]]
[[ 1. 2. 3. 4. 1. 0. 0. 0.]
[ 5. 6. 7. 8. 0. 1. 0. 0.]
[ 9. 10. 11. 12. 0. 0. 1. 0.]
[13. 14. 15. 16. 0. 0. 0. 1.]]
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]
[ 9. 10. 11. 12.]
[13. 14. 15. 16.]
[ 1. 0. 0. 0.]
[ 0. 1. 0. 0.]
[ 0. 0. 1. 0.]
[ 0. 0. 0. 1.]]
[[1 2]
[5 6]]
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[ 2 4]
[ 6 8]
[10 12]
[14 16]]
[ 2 4 5 6 7 8 9 10 11 12 13 14 15 16]

解线性方程组

齐次线性方程组的基础解系

scipy.linalg.null_space()可以获得基础解系 \[ \begin{cases} x_1 -5x_2 +2x_3 -3x_4=0 \\ 5x_1 +3x_2 +6x_3 -x_4=0 \\ 2_1 +4x_2 +2x_3 +x_4=0 \\ \end{cases} \] 的基础解系:

1
2
3
4
import numpy as np
from scipy.linalg import null_space
A = np.array([[1, -5, 2, -3], [5, 3, 6, -1], [2, 4, 2, 1]])
print(null_space(A)) # 零空间,即基础解系

输出:

1
2
3
4
[[ 0.79428706 -0.07832183]
[-0.19204896 -0.36561063]
[-0.52695834 0.38844091]
[ 0.23353839 0.84220438]]

两个列向量即为基础解系

非齐次线性方程组解

numpy.linalg.pinv()可以求矩阵的伪逆矩阵,这样对于形如\(Ax=b\)的线性方程组,pinv(A)@b就可以得到一组解

一般地,当方程组有:

  • 无穷多组解,得到的是最小范数解
  • 唯一解,得到的是唯一的那组解
  • 无解,得到的是最小二乘解\(x^*\),即满足\(|Ax^*-b|^2\)最小的解

特征值与特征向量

numpy.linalg.eig()可以得到矩阵的特征值和特征向量

返回二元组分别是特征值和特征向量的list,特征向量表示为列向量

例如: $$ A=,

P=,

=$$ 验证\(P^{-1}AP=\Lambda\)

1
2
3
4
5
6
7
import numpy as np
from numpy.linalg import eig
A = np.array([[0, -2, 2], [-2, -3, 4], [2, 4, -3]])
values, vectors = eig(A)
print(values)
print(vectors)
print(np.linalg.inv(vectors)@A@vectors)

输出:

1
2
3
4
5
6
7
[ 1. -8.  1.]
[[ 0.94280904 -0.33333333 -0.2981424 ]
[-0.23570226 -0.66666667 0.74535599]
[ 0.23570226 0.66666667 0.59628479]]
[[ 1.00000000e+00 -6.10622664e-16 -1.11022302e-16]
[ 0.00000000e+00 -8.00000000e+00 -4.44089210e-16]
[-5.55111512e-17 4.44089210e-16 1.00000000e+00]]