NumPy科学计算库学习_012_NumPy数组中的线性代数

一、点积np.dot(A,B)

1、数字与数字之间的点积
  • 即数字A与数字B的乘积。
num_dot = np.dot(2,10)
print("【数与数的点积】\n",num_dot)
【数与数的点积】
 20
2、数字与任意形状数组的点积
  • 即该数字与数组每个元素相乘,只改变每个元素的值,数组形状不变。
arr1d_num_dot = np.dot(2,np.array([5,6,7]))
arr2d_num_dot = np.dot(2,np.array([[5,6,7],[5,6,7]]))
arr3d_num_dot = np.dot(2,np.array([[[5,6,7],[5,6,7]],[[5,6,7],[5,6,7]]]))

print("【数字与一维数组的点积】\n",arr1d_num_dot)
print("【数字与二维数组的点积】\n",arr2d_num_dot)
print("【数字与三维数组的点积】\n",arr3d_num_dot)
【数字与一维数组的点积】
 [10 12 14]
【数字与二维数组的点积】
 [[10 12 14]
 [10 12 14]]
【数字与三维数组的点积】
 [[[10 12 14]
  [10 12 14]]

 [[10 12 14]
  [10 12 14]]]
3、一维数组之间的点积
  • 返回的值就是向量的内积
  • 两个一维数组的列必须相同
arr1d_dot = np.dot(np.array([2,3,4]),np.array([5,6,7]))
print("【一维数组之间的点积】\n","2x5+3x6+4x7 =","10+18+28 =",arr1d_dot)
【一维数组之间的点积】
 2x5+3x6+4x7 = 10+18+28 = 56
4、二维数组之间的点积
  • 矩阵A最后一维 = 矩阵B第一维
  • 合法运算条件 => 矩阵A列数 = 矩阵B行数
  • 结果满足形状 => (A的行数,B的列数)

\[{\begin{bmatrix} \color{red}{4}&\color{red}{2}&\color{red}{3}\\ {1}&{3}&{1}\\ \end{bmatrix}_{(2,3)}} {\cdot} {\begin{bmatrix} \color{red}{2}&{7}\\ \color{red}{-5}&{-7}\\ \color{red}{9}&{3}\\ \end{bmatrix}_{(3,2)}} = {\begin{bmatrix} \color{red}{8-10+27=25}&\color{lightgrey}{?}\\ \color{lightgrey}{?}&\color{lightgrey}{?}\\ \end{bmatrix}_{(2,2)}} \]

\[{\begin{bmatrix} \color{red}{4}&\color{red}{2}&\color{red}{3}\\ {1}&{3}&{1}\\ \end{bmatrix}_{(2,3)}} {\cdot} {\begin{bmatrix} {2}&\color{red}{7}\\ {-5}&\color{red}{-7}\\ {9}&\color{red}{3}\\ \end{bmatrix}_{(3,2)}} = {\begin{bmatrix} \color{lightgrey}{?}&\color{red}{28-14+9=23}\\ \color{lightgrey}{?}&\color{lightgrey}{?}\\ \end{bmatrix}_{(2,2)}} \]

\[{\begin{bmatrix} {4}&{2}&{3}\\ \color{red}{1}&\color{red}{3}&\color{red}{1}\\ \end{bmatrix}_{(2,3)}} {\cdot} {\begin{bmatrix} \color{red}{2}&{7}\\ \color{red}{-5}&{-7}\\ \color{red}{9}&{3}\\ \end{bmatrix}_{(3,2)}} = {\begin{bmatrix} \color{lightgrey}{?}&\color{lightgrey}{?}\\ \color{red}{2-15+9=-4}&\color{lightgrey}{?}\\ \end{bmatrix}_{(2,2)}} \]

\[{\begin{bmatrix} {4}&{2}&{3}\\ \color{red}{1}&\color{red}{3}&\color{red}{1}\\ \end{bmatrix}_{(2,3)}} {\cdot} {\begin{bmatrix} {2}&\color{red}{7}\\ {-5}&\color{red}{-7}\\ {9}&\color{red}{3}\\ \end{bmatrix}_{(3,2)}} = {\begin{bmatrix} \color{lightgrey}{?}&\color{lightgrey}{?}\\ \color{lightgrey}{?}&\color{red}{7-21+3=-11}\\ \end{bmatrix}_{(2,2)}} \]

\[\color{darkorange}{最终结果=>} \color{darkorange}{\begin{bmatrix} {25}&{23}\\ {-4}&{-11}\\ \end{bmatrix}_{({2},{2})}} \]

5、多维数组之间的点积
  • 矩阵A最后一维 = 矩阵B倒数第二维
A = np.random.random((2,3,4,3))
B = np.random.random((5,2,2,2,3,1))
print("【矩阵A形状】\n",A.shape)
print("【矩阵B形状】\n",B.shape)
C = np.dot(A,B)
print("【矩阵C形状】\n",C.shape)
print("---------------------------------")

A = np.random.random((2,3,2))
B = np.random.random((4,2,2))
print("【矩阵A形状】\n",A.shape)
print("【矩阵B形状】\n",B.shape)
C = np.dot(A,B)
print("【矩阵C形状】\n",C.shape)
print("---------------------------------")
【矩阵A】
 (2, 3, 4, 3)
【矩阵B】
 (5, 2, 2, 2, 3, 1)
【矩阵C】
 (2, 3, 4, 5, 2, 2, 2, 1)
---------------------------------
【矩阵A】
 (2, 3, 2)
【矩阵B】
 (4, 2, 2)
【矩阵C】
 (2, 3, 4, 2)
---------------------------------

二、内积np.inner(A,B)

  • 即数字A与数字B的乘积。
1、数字与数字之间的内积
num_inner = np.inner(2,3)
print("【数字与数字间的内积】\n",num_inner)
【数字与数字间的内积】
 6
2、数字与任意形状数组的内积
  • 即该数字与数组每个元素相乘,只改变每个元素的值,数组形状不变。
arr1d_num_inner = np.dot(2,np.array([5,6,7]))
arr2d_num_inner = np.dot(2,np.array([[5,6,7],[5,6,7]]))
arr3d_num_inner = np.dot(2,np.array([[[5,6,7],[5,6,7]],[[5,6,7],[5,6,7]]]))

print("【数字与一维数组的内积】\n",arr1d_num_inner)
print("【数字与二维数组的内积】\n",arr2d_num_inner)
print("【数字与三维数组的内积】\n",arr3d_num_inner)
【数字与一维数组的内积】
 [10 12 14]
【数字与二维数组的内积】
 [[10 12 14]
 [10 12 14]]
【数字与三维数组的内积】
 [[[10 12 14]
  [10 12 14]]

 [[10 12 14]
  [10 12 14]]]
3、一维数组之间的内积
  • 两个一维数组的列必须相同
arr1d_inner = np.inner(np.array([2,3,4]),np.array([5,6,7]))
print("【一维数组之间的内积】\n","2x5+3x6+4x7 =","10+18+28 =",arr1d_inner)
【一维数组之间的内积】
 2x5+3x6+4x7 = 10+18+28 = 56
4、二维数组之间的内积
  • A的最后一维 = B的最后一维

\[{\begin{bmatrix} \color{red}{1}&\color{red}{2}&\color{red}{3}\\ {1}&{2}&{3}\\ \end{bmatrix}_{(2,3)}} {\cdot} {\begin{bmatrix} \color{red}{0}&\color{red}{1}&\color{red}{2}\\ {0}&{1}&{2}\\ {0}&{1}&{2}\\ \end{bmatrix}_{(3,3)}} = {\begin{bmatrix} \color{red}{0+2+6=8}&\color{lightgrey}{?}&\color{lightgrey}{?}\\ \color{lightgrey}{?}&\color{lightgrey}{?}&\color{lightgrey}{?}\\ \end{bmatrix}_{(2,3)}} \]

\[{\begin{bmatrix} \color{red}{1}&\color{red}{2}&\color{red}{3}\\ {1}&{2}&{3}\\ \end{bmatrix}_{(2,3)}} {\cdot} {\begin{bmatrix} {0}&{1}&{2}\\ \color{red}{0}&\color{red}{1}&\color{red}{2}\\ {0}&{1}&{2}\\ \end{bmatrix}_{(3,3)}} = {\begin{bmatrix} \color{lightgrey}{?}&\color{red}{0+2+6=8}&\color{lightgrey}{?}\\ \color{lightgrey}{?}&\color{lightgrey}{?}&\color{lightgrey}{?}\\ \end{bmatrix}_{(2,3)}} \]

\[{\begin{bmatrix} \color{red}{1}&\color{red}{2}&\color{red}{3}\\ {1}&{2}&{3}\\ \end{bmatrix}_{(2,3)}} {\cdot} {\begin{bmatrix} {0}&{1}&{2}\\ {0}&{1}&{2}\\ \color{red}{0}&\color{red}{1}&\color{red}{2}\\ \end{bmatrix}_{(3,3)}} = {\begin{bmatrix} \color{lightgrey}{?}&\color{lightgrey}{?}&\color{red}{0+2+6=8}\\ \color{lightgrey}{?}&\color{lightgrey}{?}&\color{lightgrey}{?}\\ \end{bmatrix}_{(2,3)}} \]

\[{\begin{bmatrix} {1}&{2}&{3}\\ \color{red}{1}&\color{red}{2}&\color{red}{3}\\ \end{bmatrix}_{(2,3)}} {\cdot} {\begin{bmatrix} \color{red}{0}&\color{red}{1}&\color{red}{2}\\ {0}&{1}&{2}\\ {0}&{1}&{2}\\ \end{bmatrix}_{(3,3)}} = {\begin{bmatrix} \color{lightgrey}{?}&\color{lightgrey}{?}&\color{lightgrey}{?}\\ \color{red}{0+2+6=8}&\color{lightgrey}{?}&\color{lightgrey}{?}\\ \end{bmatrix}_{(2,3)}} \]

\[{\begin{bmatrix} {1}&{2}&{3}\\ \color{red}{1}&\color{red}{2}&\color{red}{3}\\ \end{bmatrix}_{(2,3)}} {\cdot} {\begin{bmatrix} {0}&{1}&{2}\\ \color{red}{0}&\color{red}{1}&\color{red}{2}\\ {0}&{1}&{2}\\ \end{bmatrix}_{(3,3)}} = {\begin{bmatrix} \color{lightgrey}{?}&\color{lightgrey}{?}&\color{lightgrey}{?}\\ \color{lightgrey}{?}&\color{red}{0+2+6=8}&\color{lightgrey}{?}\\ \end{bmatrix}_{(2,3)}} \]

\[{\begin{bmatrix} {1}&{2}&{3}\\ \color{red}{1}&\color{red}{2}&\color{red}{3}\\ \end{bmatrix}_{(2,3)}} {\cdot} {\begin{bmatrix} {0}&{1}&{2}\\ {0}&{1}&{2}\\ \color{red}{0}&\color{red}{1}&\color{red}{2}\\ \end{bmatrix}_{(3,3)}} = {\begin{bmatrix} \color{lightgrey}{?}&\color{lightgrey}{?}&\color{lightgrey}{?}\\ \color{lightgrey}{?}&\color{lightgrey}{?}&\color{red}{0+2+6=8}\\ \end{bmatrix}_{(2,3)}} \]

\[\color{darkorange}{最终结果=>} \color{darkorange}{\begin{bmatrix} {8}&{8}&{8}\\ {8}&{8}&{8}\\ \end{bmatrix}_{({2},{2})}} \]

5、多维数组之间的内积
  • 矩阵A最后一维 = 矩阵B最后一维
A = np.random.random((1,2,2,3))
B = np.random.random((3,2,3))
print("【矩阵A形状】\n",A.shape)
print("【矩阵B形状】\n",B.shape)
C = np.inner(A,B)
print("【矩阵C形状】\n",C.shape)
print("---------------------------------")

A = np.random.random((2,2))
B = np.random.random((1,2,2))
print("【矩阵A形状】\n",A.shape)
print("【矩阵B形状】\n",B.shape)
C = np.inner(A,B)
print("【矩阵C形状】\n",C.shape)
print("---------------------------------")
【矩阵A形状】
 (1, 2, 2, 3)
【矩阵B形状】
 (3, 2, 3)
【矩阵C形状】
 (1, 2, 2, 3, 2)
---------------------------------
【矩阵A形状】
 (2, 2)
【矩阵B形状】
 (1, 2, 2)
【矩阵C形状】
 (2, 1, 2)
---------------------------------

三、矩阵乘积运算A@B

1、含义
  • Python中,符号@代表2个含义:
    • 代表装饰器
    • 代表numpy.matmul(A,B)
  • 显然这里的A@B代表NumPy数组之间的乘积运算。
2、注意
  • A@B 等价于 numpy.matmul(A,B)
  • 只允许矩阵之间相乘
3、一维数组(向量)之间的运算
  • 规则服从内积np.inner(A,B)
  • 列必须相同。
A = np.array([1,4])
B = np.array([2,2])
print("1 x 2 + 4 x 2 =",A@B)
1 x 2 + 4 x 2 = 10
4、二维数组之间的运算
  • 规则服从点积np.dot(A,B)
  • 合法运算条件 => 矩阵A列数 = 矩阵B行数
  • 结果满足形状 => (A的行数,B的列数)
A =  np.random.random((3,2))
print(A.shape)
B = np.random.random((2,2))
print(B.shape)
C = A@B
print(C)
【A的形状】
 (22, 40)
【B的形状】
 (40, 19)
【A@B形状】
 (22, 19)
【np.dot(A,B)形状】
 (22, 19)
5、一维数组与多维数组的运算
  • 假设:$$ A = [0,6] $$ $$ B = [[1,2],[3,4]] $$
  • 这种情况很有意思,我们先看看api怎么描述的:
  • 解释起来有两种情况
    • 当第一个参数为1-D时,由于A的形状在numpy中表示为(2,)(非矩阵,是向量,表示2个元素),要在2加一个轴,这个轴的值为1。即A被升维成矩阵,形状是(1,2)。此时,A与B执行点积操作。当运算完毕后,A原本被添加的轴会被回收,即A回到形状(2,)的向量模式。

      \[{\begin{bmatrix} \color{red}{0}&\color{red}{6}\\ \end{bmatrix}_{(1,2)}} {\begin{bmatrix} \color{red}{1}&{2}\\ \color{red}{3}&{4}\\ \end{bmatrix}_{(2,2)}} = {\begin{bmatrix} \color{red}{0*1+6*3=18}&\color{lightgrey}{?}\\ \end{bmatrix}_{(1,2)}} \]

      \[{\begin{bmatrix} \color{red}{0}&\color{red}{6}\\ \end{bmatrix}_{(1,2)}} {\begin{bmatrix} {1}&\color{red}{2}\\ {3}&\color{red}{4}\\ \end{bmatrix}_{(2,2)}} = {\begin{bmatrix} \color{lightgrey}{?}&\color{red}{0*2+6*4=24}\\ \end{bmatrix}_{(1,2)}} \]

      \[\color{darkorange}{最终结果=>} \color{darkorange}{\begin{bmatrix} {28}&{24}\\ \end{bmatrix}_{({1},{2})}} \]

print("【A@B】\n",A@B)
【A@B】
[18 24]
  • 相似地,当第二个参数为1-D时,A同样需要升维。【区别在于】要在(2,)中的2后面添加一个值为1的轴,达到升维的效果。然后,B与A执行点积操作。当运算完毕后,A原本被添加在后面的轴会被回收,即A回到形状(2,)的向量模式。

    \[{\begin{bmatrix} \color{red}{1}&\color{red}{2}\\ {3}&{4}\\ \end{bmatrix}_{(2,2)}} {\begin{bmatrix} \color{red}{0}\\ \color{red}{6}\\ \end{bmatrix}_{(2,1)}} = {\begin{bmatrix} \color{red}{1*0+2*6=12}&\color{lightgrey}{?}\\ \end{bmatrix}_{(1,2)}} \]

    \[{\begin{bmatrix} {1}&{2}\\ \color{red}{3}&\color{red}{4}\\ \end{bmatrix}_{(2,2)}} {\begin{bmatrix} \color{red}{0}\\ \color{red}{6}\\ \end{bmatrix}_{(2,1)}} = {\begin{bmatrix} \color{lightgrey}{?}&\color{red}{3*0+4*6=24}\\ \end{bmatrix}_{(1,2)}} \]

    \[\color{darkorange}{最终结果=>} \color{darkorange}{\begin{bmatrix} {12}&{24}\\ \end{bmatrix}_{({1},{2})}} \]

print("【B@A】\n",B@A)
【B@A】
[12 24]
6、多维数组间的运算
  • If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.
  • 解释为:当参数维度>2时,参数被理解为一些矩阵(参数的最后两个维数为矩阵维数)的stack,计算时会相应的广播。
A = np.random.random((2,2,4))
print("【A】\n",A)
B = np.random.random((2,4,2))
print("【B】\n",B)
print("【A@B】\n",A@B,"\n【shape】\n",A.shape)
【A】
 [[[0.0809837  0.29952977 0.12203496 0.04121702]
  [0.16743815 0.07071087 0.71797707 0.36474334]]

 [[0.64873228 0.94993455 0.90620734 0.57375955]
  [0.05383746 0.16905596 0.37846488 0.18973101]]]
【B】
 [[[0.13524156 0.63780383]
  [0.82055257 0.5262344 ]
  [0.65808148 0.86527029]
  [0.77220339 0.88265401]]

 [[0.54261569 0.20017844]
  [0.14652248 0.14892133]
  [0.80195632 0.32822467]
  [0.21656456 0.30341411]]]
【A@B】
 [[[0.36886916 0.35124818]
  [0.83481004 1.08718959]]

 [[1.34219377 0.74285408]
  [0.39858486 0.21774171]]] 
【shape】
 (2, 2, 4)

四、矩阵的逆运算

1、 numpy.linalg.inv(np.array)

A = np.array([[1,2],[-1,-3]])
np.linalg.inv(A)
array([[ 3.,  2.],
       [-1., -1.]])

2、定义矩阵的逆

  • 什么是逆矩阵
    • \(矩阵A为n阶方阵,若存在n阶矩阵B,使得矩阵A、B的乘积为单位阵,则称A为可逆阵,B为A的逆矩阵。若方阵的逆阵存在,则称为可逆矩阵或非奇异矩阵,且其逆矩阵唯一。\\\)
  • 什么是奇异矩阵:
    • \(首先,看这个矩阵是不是方阵(即行数和列数相等的矩阵,若行数和列数不相等,那就谈不上奇异矩阵和非奇异矩阵)。如是方阵,再看此矩阵的\color{red}{行列式}|A|是否等于0,若等于0,称矩阵A为奇异矩阵;若不等于0,称矩阵A为非奇异矩阵。 同时,由|A|≠0可知矩阵A可逆,这样可以得出另外一个重要结论:可逆矩阵就是非奇异矩阵,非奇异矩阵也是可逆矩阵。 如果A为奇异矩阵,则AX=0有无穷解,AX=b有无穷解或者无解。如果A为非奇异矩阵,则AX=0有且只有唯一零解,AX=b有唯一解。\)

3、计算矩阵\(A\)的逆的方式

(1) 待定系数法(\({A}^{-1}\)\({A}\)的逆;\({I}\)为单位矩阵,对角线均为\(1\),其他位置均为\(0\)。)

\[A = {\begin{bmatrix} {1}&{2}\\ {-1}&{-3}\\ \end{bmatrix}_{(2,2)}} , I = {\begin{bmatrix} {1}&{0}\\ {0}&{1}\\ \end{bmatrix}_{(2,2)}} \]

\[假设:{A}^{-1} = {\begin{bmatrix} {a}&{b}\\ {c}&{d}\\ \end{bmatrix}_{(2,2)}} \]

\[\begin{aligned} A{\cdot}{A}^{-1}&= {\begin{bmatrix} {1}&{2}\\ {-1}&{-3}\\ \end{bmatrix}_{(2,2)}} {\begin{bmatrix} {a}&{b}\\ {c}&{d}\\ \end{bmatrix}_{(2,2)}} = {\begin{bmatrix} {1}&{0}\\ {0}&{1}\\ \end{bmatrix}_{(2,2)}}\\ &= {\begin{bmatrix} {a+2c}&{b+2d}\\ {-a-3c}&{-b-3d}\\ \end{bmatrix}_{(2,2)}}\\ \end{aligned} \]

\[\begin{cases} a+2c = 1\\ b+2d = 0\\ -a-3c = 0\\ -b-3d = 1\\ \end{cases} => \begin{cases} a = 3\\ b = 2\\ c = -1\\ d = -1\\ \end{cases} \]

\[故: {A}^{-1}={\begin{bmatrix} {3}&{2}\\ {-1}&{-1}\\ \end{bmatrix}_{(2,2)}}\\ \]

(2) 高斯消元法

\[A = {\begin{bmatrix} {1}&{2}\\ {-1}&{-3}\\ \end{bmatrix}_{(2,2)}} , I = {\begin{bmatrix} {1}&{0}\\ {0}&{1}\\ \end{bmatrix}_{(2,2)}} \]

\[\begin{aligned} {A}{I}& = \left[\begin{array}{lc|rc} 1 & 2 & 1 & 0\\ -1 & -3 & 0 & 1\\ \end{array}\right]\\ &\overset{{r_1}+{r_2}}{\rightarrow} \left[\begin{array}{lc|rc} 1 & 2 & 1 & 0\\ 0 & -1 & 1 & 1\\ \end{array}\right]\\ &\overset{{r_1}+{2r_2}}{\rightarrow} \left[\begin{array}{lc|rc} 1 & 0 & 3 & 2\\ 0 & -1 & 1 & 1\\ \end{array}\right]\\ &\overset{{-r_2}}{\rightarrow} \left[\begin{array}{lc|rc} 1 & 0 & 3 & 2\\ 0 & 1 & -1 & -1\\ \end{array}\right]\\ &\end{aligned} \]

\[故: {A}^{-1}={\begin{bmatrix} {3}&{2}\\ {-1}&{-1}\\ \end{bmatrix}_{(2,2)}}\\ \]

(3) 矩阵LU三角分解法
  • 线性代数的目的是求解线性方程组\(A\vec{x}=\vec{b}\),并非单纯求A的逆。
  • 单就解方程而言,LU分解是最实用的算法,很少会去求逆,求逆可以说是下下策。
<1> 手撸LU求逆步骤有些长,读者请耐心看...
  • \(\color{red}{目标矩阵A和公式关系:}\)

    \[A = {\begin{bmatrix} {2}&{2}&{3}\\ {4}&{7}&{7}\\ {-2}&{4}&{5}\\ \end{bmatrix}} ; \begin{cases} L\vec{y} = \vec{b}\\ U\vec{x} = \vec{y}\\ \end{cases} ; AA^{-1}=I\\ \]

  • \(\color{red}{分解成U:}\)

    \[{\begin{bmatrix} \color{darkorange}{2}&{2}&{3}\\ \color{red}{4}&{7}&{7}\\ \color{blue}{-2}&{4}&{5}\\ \end{bmatrix}} _{r2-2r1、r1+r2} => {\begin{bmatrix} {2}&{2}&{3}\\ {0}&\color{green}{3}&{1}\\ {0}&\color{pink}{6}&{8}\\ \end{bmatrix}} _{r3-2r2} => {\begin{bmatrix} \color{green}{2}&\color{green}{2}&\color{green}{3}\\ {0}&\color{green}{3}&\color{green}{1}\\ {0}&{0}&\color{green}{6}\\ \end{bmatrix}} _{上三角完成}= U \]

  • \(\color{red}{通过U的过程求出L:}\)

    • \(L的对角线值均为1,对角线上方的值均为0,只需要通过U求对角线下方的值。\)

    \[L = {\begin{bmatrix} {1}&{0}&{0}\\ {a_{21}}&{1}&{0}\\ {a_{31}}&{a_{32}}&{1}\\ \end{bmatrix}} = {\begin{bmatrix} {1}&{0}&{0}\\ {\color{red}{4}/\color{darkorange}{2}}&{1}&{0}\\ {\color{blue}{-2}/\color{darkorange}{2}}&{\color{pink}{6}/\color{green}{3}}&1\\ \end{bmatrix}} = {\begin{bmatrix} {1}&{0}&{0}\\ {2}&{1}&{0}\\ {-1}&{2}&{1}\\ \end{bmatrix}}_{下三角完成} \]

  • \(\color{red}{验证A=LU:}\)

    \[LU = {\begin{bmatrix} {1}&{0}&{0}\\ {2}&{1}&{0}\\ {-1}&{2}&{1}\\ \end{bmatrix}} {\begin{bmatrix} {2}&{2}&{3}\\ {0}&{3}&{1}\\ {0}&{0}&{6}\\ \end{bmatrix}} = {\begin{bmatrix} {2}&{2}&{3}\\ {4}&{7}&{7}\\ {-2}&{4}&{5}\\ \end{bmatrix}} = A {\color{red}{(成立)}} \]

  • \(\color{red}{矩阵的转换:}\)

    • \(\hat{a}代表A^{-1}中的每个元素\)

      \[ AA^{-1} = I <=> {\begin{bmatrix} {a_{11}}&{a_{12}}&{a_{13}}\\ {a_{21}}&{a_{22}}&{a_{23}}\\ {a_{31}}&{a_{32}}&{a_{33}}\\ \end{bmatrix}} {\begin{bmatrix} {\hat{a}_{11}}&{\hat{a}_{12}}&{\hat{a}_{13}}\\ {\hat{a}_{21}}&{\hat{a}_{22}}&{\hat{a}_{23}}\\ {\hat{a}_{31}}&{\hat{a}_{32}}&{\hat{a}_{33}}\\ \end{bmatrix}} = {\begin{bmatrix} {1}&{0}&{0}\\ {0}&{1}&{0}\\ {0}&{0}&{1}\\ \end{bmatrix}} \]

    • \(根据矩阵相乘规则,将以上等式分解为3份\)

    \[ A {\begin{bmatrix} {\hat{a}_{11}}\\ {\hat{a}_{21}}\\ {\hat{a}_{31}}\\ \end{bmatrix}}= {\begin{bmatrix} {1}\\ {0}\\ {0}\\ \end{bmatrix}} ; A {\begin{bmatrix} {\hat{a}_{12}}\\ {\hat{a}_{22}}\\ {\hat{a}_{32}}\\ \end{bmatrix}}= {\begin{bmatrix} {0}\\ {1}\\ {0}\\ \end{bmatrix}} ; A {\begin{bmatrix} {\hat{a}_{13}}\\ {\hat{a}_{23}}\\ {\hat{a}_{33}}\\ \end{bmatrix}}= {\begin{bmatrix} {0}\\ {0}\\ {1}\\ \end{bmatrix}} \]

  • \(\color{red}{带入求逆:}\)

\[ {\begin{bmatrix} {2}&{2}&{3}\\ {4}&{7}&{7}\\ {-2}&{4}&{5}\\ \end{bmatrix}} {\begin{bmatrix} {\hat{a}_{11}}\\ {\hat{a}_{21}}\\ {\hat{a}_{31}}\\ \end{bmatrix}}= {\begin{bmatrix} {1}\\ {0}\\ {0}\\ \end{bmatrix}} => {\begin{bmatrix} {\hat{a}_{11}}\\ {\hat{a}_{21}}\\ {\hat{a}_{31}}\\ \end{bmatrix}} = {\begin{bmatrix} 0.19{\dot4}\\ -0.9\dot{4}\\ 0.8\dot{3}\\ \end{bmatrix}} \]

\[ {\begin{bmatrix} {2}&{2}&{3}\\ {4}&{7}&{7}\\ {-2}&{4}&{5}\\ \end{bmatrix}} {\begin{bmatrix} {\hat{a}_{12}}\\ {\hat{a}_{22}}\\ {\hat{a}_{32}}\\ \end{bmatrix}}= {\begin{bmatrix} {0}\\ {1}\\ {0}\\ \end{bmatrix}} => {\begin{bmatrix} {\hat{a}_{12}}\\ {\hat{a}_{22}}\\ {\hat{a}_{32}}\\ \end{bmatrix}}= {\begin{bmatrix} {0.0\dot{5}}\\ {0.\dot{4}}\\ {-0.\dot{3}}\\ \end{bmatrix}} \]

\[ {\begin{bmatrix} {2}&{2}&{3}\\ {4}&{7}&{7}\\ {-2}&{4}&{5}\\ \end{bmatrix}} {\begin{bmatrix} {\hat{a}_{13}}\\ {\hat{a}_{23}}\\ {\hat{a}_{33}}\\ \end{bmatrix}} {\begin{bmatrix} {0}\\ {0}\\ {1}\\ \end{bmatrix}} => {\begin{bmatrix} {\hat{a}_{13}}\\ {\hat{a}_{23}}\\ {\hat{a}_{33}}\\ \end{bmatrix}}= {\begin{bmatrix} {-0.19\dot{4}}\\ {-0.0\dot{5}}\\ {0.1\dot{6}}\\ \end{bmatrix}} \]

\[ A^{-1} = {\begin{bmatrix} {\hat{a}_{11}}&{\hat{a}_{12}}&{\hat{a}_{13}}\\ {\hat{a}_{21}}&{\hat{a}_{22}}&{\hat{a}_{23}}\\ {\hat{a}_{31}}&{\hat{a}_{32}}&{\hat{a}_{33}}\\ \end{bmatrix}} = {\begin{bmatrix} {0.19\dot{4}}&0.0\dot{5}&-0.19\dot{4}\\ {-0.9\dot{4}}&0.\dot{4}&-0.0\dot{5}\\ 0.8\dot{3}&-0.\dot{3}&0.1\dot{6}\\ \end{bmatrix}} \]

  • \(\color{red}{Python代码求逆,对比手算结果:}\)

\[AA^{-1} = {\begin{bmatrix} {2}&{2}&{3}\\ {4}&{7}&{7}\\ {-2}&{4}&{5}\\ \end{bmatrix}} {\begin{bmatrix} {0.19\dot{4}}&0.0\dot{5}&-0.19\dot{4}\\ {-0.9\dot{4}}&0.\dot{4}&-0.0\dot{5}\\ 0.8\dot{3}&-0.\dot{3}&0.1\dot{6}\\ \end{bmatrix}} = {\begin{bmatrix} {1}&{0}&{0}\\ {0}&{1}&{0}\\ {0}&{0}&{1}\\ \end{bmatrix}} = I \]

# 手算的思维验证逆运算
A = np.array([[2,2,3],[4,7,7],[-2,4,5]])
b1 = np.array([1,0,0])
b2 = np.array([0,1,0])
b3 = np.array([0,0,1])
a_hat1 = np.linalg.solve(A,b1)
a_hat2 = np.linalg.solve(A,b2)
a_hat3 = np.linalg.solve(A,b3)
a = np.vstack((a_hat1,a_hat2,a_hat3))
inv_A = np.transpose(a)
print("【A的逆】\n",inv_A)
np.set_printoptions(suppress=True) # 不输出科学计算格式
print("【验证】AA^(-1)=I\n",np.dot(A,inv_A))
【A的逆】
 [[ 0.19444444  0.05555556 -0.19444444]
 [-0.94444444  0.44444444 -0.05555556]
 [ 0.83333333 -0.33333333  0.16666667]]
【验证】AA^(-1)=I
 [[ 1. -0.  0.]
 [-0.  1.  0.]
 [-0. -0.  1.]]
# 最简单的验证方式
A = np.array([[2,2,3],[4,7,7],[-2,4,5]])
np.linalg.inv(A)
array([[ 0.19444444,  0.05555556, -0.19444444],
       [-0.94444444,  0.44444444, -0.05555556],
       [ 0.83333333, -0.33333333,  0.16666667]])
(4) PLU三角分解法
  • \(个人认为,PLU解法其实是LU解法的一种优化。\\\)

  • \(P\)的含义:

    • 置换矩阵(Permutation Matrix),作用就是用来置换目标矩阵的行或列的
      • \(PA用来置换行\)
        • 第一行填写A的最后一行
        • 第二行填写A的第一行
        • 第三行填写A的第二行

        \[PA= {\begin{bmatrix} {0}&{0}&{1}\\ {1}&{0}&{0}\\ {0}&{1}&{0}\\ \end{bmatrix}} {\begin{bmatrix} {1}&{2}&{3}\\ {4}&{5}&{6}\\ {7}&{8}&{9}\\ \end{bmatrix}} = {\begin{bmatrix} {7}&{8}&{9}\\ {1}&{2}&{3}\\ {4}&{5}&{6}\\ \end{bmatrix}} \]

      • \(AP用来置换列\)
        • 第一列填写A的第二列
        • 第二列填写A的最后一列
        • 第三列填写A的第一列

        \[AP= {\begin{bmatrix} {1}&{2}&{3}\\ {4}&{5}&{6}\\ {7}&{8}&{9}\\ \end{bmatrix}} {\begin{bmatrix} {0}&{0}&{1}\\ {1}&{0}&{0}\\ {0}&{1}&{0}\\ \end{bmatrix}} = {\begin{bmatrix} {2}&{3}&{1}\\ {5}&{6}&{4}\\ {8}&{9}&{7}\\ \end{bmatrix}} \]

  • \(引入P的原因:\)

    • 规避大数,防止类似memory_out_of_bound的极端错误发生,让运算更加稳定,提高运算效率。
    • 我们拿一个例子说明:

    \[\color{red}{---------A=L_{0}U_{0}出现大数---------}\\ A = {\begin{bmatrix} {10}^{-20}&{1}\\ {1}&{1}\\ \end{bmatrix}} = {\begin{bmatrix} {1}&{0}\\ {10}^{20}&{1}\\ \end{bmatrix}} {\begin{bmatrix} {10^{-20}}&{1}\\ {0}&{1-10^{20}}\\ \end{bmatrix}} =L_{0}U_{0}\\ \color{red}{---------PA=L_{1}U_{1}规避大数---------}\\ PA = {\begin{bmatrix} {0}&{1}\\ {1}&{0}\\ \end{bmatrix}} {\begin{bmatrix} {10}^{-20}&{1}\\ {1}&{1}\\ \end{bmatrix}} = {\begin{bmatrix} {1}&{1}\\ {10}^{-20}&{1}\\ \end{bmatrix}} = {\begin{bmatrix} {1}&{0}\\ {10^{-20}}&{1}\\ \end{bmatrix}} {\begin{bmatrix} {1}&{1}\\ {0}&{1-10^{-20}}\\ \end{bmatrix}} =L_{1}U_{1} \]

    • 选择置换矩阵P的策略:
      \(\color{blue}{沿着对角线从左上角到右下角遍历A,并检测当前列的最大元素在下方的哪一行(当前行上方的行保持不变),找到后就将当前行和目标行交换,并记录下一个。最后按顺序算的乘积就得到了P。}\\\)
    • \(Python中P的求法\)
    A = np.array([[2,2,3],[4,7,7],[-2,4,5]])
    p, l, u = lu(A)
    print("【p】\n",p)
    print("【l】\n",l)
    print("【u】\n",u)
    
    【p】
     [[0. 0. 1.]
     [1. 0. 0.]
     [0. 1. 0.]]
    【l】
     [[ 1.   0.   0. ]
     [-0.5  1.   0. ]
     [ 0.5 -0.2  1. ]]
    【u】
     [[4.  7.  7. ]
     [0.  7.5 8.5]
     [0.  0.  1.2]]
    

五、矩阵的行列式

from scipy.linalg import det
A = np.array([[2,2,3],[4,7,7],[-2,4,5]])
determinant = det(A)
print("【矩阵A的行列式】\n",determinant)
【矩阵A的行列式】
 36.0

六、矩阵的特征值和特征向量

1.函数

scipy.linalg.eig(a, b=None, left=False, right=True, overwrite_a=False, overwrite_b=False, check_finite=True, homogeneous_eigvals=False)

2.代码
from scipy.linalg import eig
A = np.array([[2,2,3],[4,7,7],[-2,4,5]])
eig_val = eig(A)
eig_val
(array([ 1.09944991+1.35711935j,  1.09944991-1.35711935j,
        11.80110019+0.j        ]),
 array([[ 0.09875023+0.32757253j,  0.09875023-0.32757253j,
          0.30227012+0.j        ],
        [ 0.68871688+0.j        ,  0.68871688-0.j        ,
          0.85783339+0.j        ],
        [-0.63697277-0.05365987j, -0.63697277+0.05365987j,
          0.41563765+0.j        ]]))

七、qr分解值

1、函数
  • scipy.linalg.qr(a, overwrite_a=False, lwork=None, mode='full', pivoting=False, check_finite=True)[source]
  • Calculate the decomposition A = Q R where Q is unitary/orthogonal and R upper triangular.
2、代码
from scipy.linalg import qr
A = np.array([[2,2,3],[4,7,7],[-2,4,5]])
qr(A)
(array([[-0.40824829,  0.        ,  0.91287093],
        [-0.81649658, -0.4472136 , -0.36514837],
        [ 0.40824829, -0.89442719,  0.18257419]]),
 array([[-4.89897949, -4.89897949, -4.89897949],
        [ 0.        , -6.70820393, -7.60263112],
        [ 0.        ,  0.        ,  1.09544512]]))

八、svd分解值

1、函数
  • scipy.linalg.svd(a, full_matrices=True, compute_uv=True, overwrite_a=False, check_finite=True, lapack_driver='gesdd')
  • Factorizes the matrix a into two unitary matrices U and Vh, and a 1-D array s of singular values (real, non-negative) such that a == U @ S @ Vh, where S is a suitably shaped matrix of zeros with main diagonal s.
2、代码
from scipy.linalg import svd
A = np.array([[2,2,3],[4,7,7],[-2,4,5]])
svd(A)
(array([[-0.31181575,  0.25631867,  0.91491621],
        [-0.83572711,  0.38412266, -0.39244105],
        [-0.45203002, -0.88698958,  0.09443697]]),
 array([12.64089135,  3.9611834 ,  0.71895193]),
 array([[-0.24226772, -0.65516277, -0.71558934],
        [ 0.96514267, -0.08746437, -0.24667712],
        [ 0.0990251 , -0.75040771,  0.65351534]]))
posted @ 2023-01-03 07:47  顺心无忧  阅读(18)  评论(0编辑  收藏  举报