碼農眼中的數學之~矩陣專欄(附Numpy講解)

 

2.矩陣專欄

吐槽一下:矩陣自己不難,可是矩陣的寫做太蛋疼了 (⊙﹏⊙)汗 還好有Numpy,否則真的崩潰了...html

LaTex有沒有一個集成了不少經常使用公式以及推導或者含題庫的在線編輯器?python

代碼褲子:https://github.com/lotapp/BaseCodegit

在線編程系:https://mybinder.org/v2/gh/lotapp/BaseCode/master程序員

數學基礎:http://www.javashuo.com/article/p-vgbqvoti-hk.htmlgithub

Numpy基礎:http://www.javashuo.com/article/p-wbewjuba-ha.html面試

在線預覽http://github.lesschina.com/python/ai/math/矩陣專欄.html編程

2.1.矩陣的定義

矩陣:是一個按照長方陣列排列的複數或實數集合。數組

通俗講就是:把數排成m行n列後,而後用中括號把它們括住,這種形式的組合就是矩陣了~ eg:app

$\begin{bmatrix} &a_{11}&a_{12}&a_{13}&...&a_{1n} \\ &a_{21}&a_{22}&a_{23}&...&a_{2n} \\ &a_{31}&a_{32}&a_{33}&...&a_{3n} \\ &\vdots&\vdots&\vdots&\ddots&\vdots\\ &a_{m1}&a_{m2}&a_{m3}&...&a_{mn} \\ \end{bmatrix}$less

好比上面這個示例就是一個m × n的矩陣(m行n列的矩陣),若是m=n那麼就叫作n階方陣,eg:

$\begin{bmatrix} 1&2&3 \\ 4&5&6 \\ 7&8&9 \end{bmatrix}$

這個就是3階方陣


若是回到中學,老師確定都是經過一次方程組來引入矩陣(逆天的老師是這麼講的):

$\begin{cases}x_1+x_2=-1\\2x_1-x_2=4\\3x_1+5x_2=-7\\\end{cases}$ ==> $\begin{bmatrix}1&1\\2&-1\\3&5\end{bmatrix}\begin{bmatrix}x_1\\x_2\end{bmatrix}=\begin{bmatrix}-1\\4\\-7\end{bmatrix}$

若是你方程組都忘記怎麼解的話...好吧仍是說下吧:「好比這題,能夠先把x2移到右邊,這樣x1就等於一個表達式了(x1=-x2-1),而後帶入第二個表達式就能夠解出x1和x2了,一次的其實兩個表達式就能夠解出了,剩下的你能夠把值帶進去驗證一下」

2.2.矩陣的運算(含冪運算)

2.2.1.加、減

加減比較簡單,就是對應元素相加減 (只有行列都相同的矩陣才能夠進行)

就不用麻煩的LaTex一行行打了,我們用更方便的 NumPy 來演示一下矩陣加法(不懂代碼的直接看結果,不影響閱讀的)

Numpy有專門的矩陣函數(np.mat),用法和ndarray差很少,咱們這邊使用常用ndarray類型,基礎忘記了能夠去查看一下:Numpy基礎

擴展:矩陣的加法運算知足交換律:A + B = B + A (乘法不行)

In [1]:
import numpy as np
In [2]:
# 建立兩個集合
A = np.arange(1,10).reshape((3,3))
B = np.arange(9).reshape((3,3))

print(A)
print("-"*5)
print(B)
 
[[1 2 3]
 [4 5 6]
 [7 8 9]]
-----
[[0 1 2]
 [3 4 5]
 [6 7 8]]
In [3]:
# 加法
A + B
Out[3]:
array([[ 1,  3,  5],
       [ 7,  9, 11],
       [13, 15, 17]])
In [4]:
# 和A+B相等
B + A
Out[4]:
array([[ 1,  3,  5],
       [ 7,  9, 11],
       [13, 15, 17]])
In [5]:
# 減法
A - B
Out[5]:
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])
In [6]:
################ 變化來了 ################
In [7]:
# 以前說過 」只有行列都相同的矩陣才能夠進行「 來驗證一下
# 建立一個2行3列的矩陣
C = np.arange(6).reshape((2,3))
D = np.arange(6).reshape((3,2))

print(C)
print("-"*5)
print(D)
 
[[0 1 2]
 [3 4 5]]
-----
[[0 1]
 [2 3]
 [4 5]]
In [8]:
# 2行3列的矩陣 + 3行2列的矩陣
C + D # 不一樣形狀的矩陣不能進行加運算
 
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-bc97e29f7e31> in <module>()
      1 # 2行3列的矩陣 + 3行2列的矩陣
----> 2C + D # 不一樣形狀的矩陣不能進行加運算

ValueError: operands could not be broadcast together with shapes (2,3) (3,2) 
In [9]:
C - D # 不一樣形狀的矩陣不能進行減運算
 
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-9-ca5169d0bf6c> in <module>()
----> 1C - D # 不一樣形狀的矩陣不能進行減運算

ValueError: operands could not be broadcast together with shapes (2,3) (3,2) 
 

2.2.2.數乘、數除

這個也比較簡單,就是和每一個元素相乘,eg:2×A,A本來的每個元素都擴大了兩倍

數除其實就是乘以倒數(1/x)

In [10]:
print(A)
 
[[1 2 3]
 [4 5 6]
 [7 8 9]]
In [11]:
# 好比2×A,A本來的每個元素都擴大了兩倍
2 * A
Out[11]:
array([[ 2,  4,  6],
       [ 8, 10, 12],
       [14, 16, 18]])
In [12]:
print(A)
 
[[1 2 3]
 [4 5 6]
 [7 8 9]]
In [13]:
# 友情提醒:Numpy裏面的運算基本上都是針對每個元素
A / 2
Out[13]:
array([[0.5, 1. , 1.5],
       [2. , 2.5, 3. ],
       [3.5, 4. , 4.5]])
 

2.2.3.矩陣乘法

矩陣乘法仍是要用LaTex演示一下的,否則有些朋友可能仍是以爲比較抽象:(你們有什麼好用的LaTex在線編輯器能夠推薦的)

拿上面那個方程組來演示一下:

$\begin{bmatrix}1&1\\2&-1\\3&5\end{bmatrix}\begin{bmatrix}x_1\\x_2\end{bmatrix} ==> \begin{cases}x_1+x_2\\2x_1-x_2\\3x_1+5x_2\end{cases}$

稍微變化一下就更形象了:

$\begin{bmatrix}1&1\\2&-1\\3&5\end{bmatrix}\begin{bmatrix}x_1&y_1\\x_2&y_2\end{bmatrix} ==> \begin{cases}x_1+x_2\\2x_1-x_2\\3x_1+5x_2\end{cases} \begin{cases}y_1+y_2\\2y_1-x_2\\3y_1+5y_2\end{cases}==>\begin{bmatrix}x_1+x_2&y_1+y_2\\2x_1-x_2&2y_1-y_2\\3x_1+5x_2&3y_1+5y_2\end{bmatrix}$

舉個簡單的例子:A×B

$\begin{bmatrix} 1&2 \\3&4 \end{bmatrix}\begin{bmatrix} 4&3 \\2&1 \end{bmatrix}=\begin{bmatrix} 1*4+2*2&1*3+2*1 \\3*4+4*2&3*3+4*1 \end{bmatrix}=\begin{bmatrix} 8&5 \\20&13 \end{bmatrix}$

之後記不得怎麼乘就本身推一下,值得注意的是:

兩個矩陣的乘法僅當第一個矩陣A的列數(column)和另外一個矩陣B的行數(row)相等才能夠進行計算

你這樣想就記得了:$\begin{bmatrix} 1&2 \\3&4 \end{bmatrix}\begin{bmatrix} x_1 \end{bmatrix} 還原成方程組就是這樣\begin{cases}1*x_1+2*?\\3*x_1+4*?\end{cases}\\這是什麼鬼?至少得這樣吧:\begin{bmatrix} 1&2 \\3&4 \end{bmatrix}\begin{bmatrix} x_1 \\x_2 \end{bmatrix}$

In [14]:
# 經過代碼看一看
A = np.array([[1,2],[3,4]])
B = np.array([[4,3],[2,1]])

print(A)
print("-"*5)
print(B)
 
[[1 2]
 [3 4]]
-----
[[4 3]
 [2 1]]
In [15]:
# 注意一下,Numpy裏面的乘法默認是每一個數對應相乘
# 若是是矩陣相乘可使用dot()方法
# 或者你建立矩陣對象,這樣×默認就是矩陣乘法了

A.dot(B) # 矩陣A×矩陣B
Out[15]:
array([[ 8,  5],
       [20, 13]])
 

程序驗證了咱們上面的運算結果,還得注意一下:

A×BB×A是不同的,eg:B×A

$\begin{bmatrix} 4&3 \\2&1 \end{bmatrix}\begin{bmatrix} 1&2 \\3&4 \end{bmatrix}=\begin{bmatrix} 4*1+3*3&4*2+3*4 \\2*1+1*3&2*2+1*4 \end{bmatrix}=\begin{bmatrix} 13&20 \\5&8 \end{bmatrix}$

若是你乘着乘着就忘記到底怎麼乘,就把右邊的矩陣換成x1,x2,而後就會了

In [16]:
print(A)
print("-"*5)
print(B)
 
[[1 2]
 [3 4]]
-----
[[4 3]
 [2 1]]
In [17]:
B.dot(A) # 矩陣B×矩陣A
Out[17]:
array([[13, 20],
       [ 5,  8]])
In [18]:
################ 變化來了 ################
In [19]:
# 來驗證一下」兩個矩陣的乘法僅當第一個矩陣A的列數(column)和另外一個矩陣D的行數(row)相等才能夠進行計算「
print(A)
print("-"*5)
print(D)
 
[[1 2]
 [3 4]]
-----
[[0 1]
 [2 3]
 [4 5]]
In [20]:
# A有2列 D有3行
A.dot(D) # 不能乘
 
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-20-c1a9f22a6f8d> in <module>()
      1 # A有2列 D有3行
----> 2A.dot(D) # 不能乘

ValueError: shapes (2,2) and (3,2) not aligned: 2 (dim 1) != 3 (dim 0)
In [21]:
# 你反過來就符合A的列數=D的行數了
D.dot(A)
Out[21]:
array([[ 3,  4],
       [11, 16],
       [19, 28]])
 

2.2.4.冪乘、冪運算

冪乘比較簡單,就是每一個元素開平方,不必定是方陣

必須是方陣才能進行冪運算,好比A²=A×A(矩陣相乘前提:第一個矩陣A的行=第二個矩陣A的列==>方陣

In [22]:
print(A)
print("-"*5)
print(C)
 
[[1 2]
 [3 4]]
-----
[[0 1 2]
 [3 4 5]]
In [23]:
# 冪乘(每一個元素開平方) 
np.power(A,2) # 使用 A**2也同樣
Out[23]:
array([[ 1,  4],
       [ 9, 16]])
In [24]:
# 冪乘(不必定是方陣) 
np.power(C,2)
Out[24]:
array([[ 0,  1,  4],
       [ 9, 16, 25]])
In [25]:
################ 方陣冪運算 ################
In [26]:
# A*A*A
np.linalg.matrix_power(A,3)
Out[26]:
array([[ 37,  54],
       [ 81, 118]])
In [27]:
# 不是方陣就over
np.linalg.matrix_power(C,3)
 
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-27-73f04ef7b54c> in <module>()
      1 # 不是方陣就over
----> 2np.linalg.matrix_power(C,3)

~/anaconda3/lib/python3.6/site-packages/numpy/matrixlib/defmatrix.py in matrix_power(M, n)
    137     M = asanyarray(M)
    138     if M.ndim != 2 or M.shape[0] != M.shape[1]:
--> 139raise ValueError("input must be a square array")
    140     if not issubdtype(type(n), N.integer):
    141         raise TypeError("exponent must be an integer")

ValueError: input must be a square array
 

來個小結 + 擴展

矩陣的加法運算知足交換律:A + B = B + A

矩陣的乘法知足結合律和對矩陣加法的分配律:

結合律:(AB)C = A(BC)

左分配律:(A + B)C = AC + BC

右分配律:C(A + B) = CA + CB

矩陣的乘法與數乘運算之間也知足相似結合律的規律;與轉置之間則知足倒置的

分配律:c(A + B) = cA + cB

結合律:c(AB) = (cA)B = A(cB)

矩陣乘法不知足交換律 通常來講,矩陣A及B的乘積AB存在,但BA不必定存在,即便存在,大多數時候AB ≠ BA


2.3.特殊矩陣

2.3.1.零矩陣

零矩陣就是全部的元素都是0

$ \begin{bmatrix} 0&0&0 \\ 0&0&0 \\ 0&0&0 \end{bmatrix} $

一樣的:全1矩陣就是全部元素都是1

$ \begin{bmatrix} 1&1&1 \\ 1&1&1 \\ 1&1&1 \end{bmatrix} $

In [1]:
import numpy as np
In [2]:
# 一維
# 能夠指定類型 np.zeros(5,dtype=int)
np.zeros(5) # 完整寫法:np.zeros((5,))
Out[2]:
array([0., 0., 0., 0., 0.])
In [3]:
# 二維
np.zeros((2,5))# 建議用元組,官方文檔都是元組
Out[3]:
array([[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]])
In [4]:
# 三維 ==> 能夠這麼理解,2個2*5(2行5列)的矩陣
np.zeros((2,2,5))
Out[4]:
array([[[0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0.]]])
In [5]:
################ 全1矩陣 ################
In [6]:
# `np.ones(tuple)` 用法和`np.zeros(tuple)`差很少
# 能夠指定類型 np.ones(5,dtype=int)
# 一維
np.ones(5) # 完整寫法 np.ones((5,))
Out[6]:
array([1., 1., 1., 1., 1.])
In [7]:
# 二維,傳一個shape元組
np.ones((2,5))
Out[7]:
array([[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]])
In [8]:
# 三維 能夠理解爲兩個二維數組
np.ones((2,2,5))
Out[8]:
array([[[1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.]],

       [[1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.]]])
In [9]:
################ 指定值矩陣 ################
In [10]:
# 建立指定值的矩陣:
np.full((3,5),222)
Out[10]:
array([[222, 222, 222, 222, 222],
       [222, 222, 222, 222, 222],
       [222, 222, 222, 222, 222]])
In [11]:
# 建立指定值的矩陣,浮點類型
np.full((3,5),222.0)
Out[11]:
array([[222., 222., 222., 222., 222.],
       [222., 222., 222., 222., 222.],
       [222., 222., 222., 222., 222.]])
 

2.3.3.轉置矩陣

轉置矩陣 :將矩陣的行列互換獲得的新矩陣(行列式不變)

m行×n列的矩陣行和列交換後就變成了n行×m列的矩陣,eg:3行×2列 ==> 2行×3列

$\begin{bmatrix}1&2 \\3&4 \\5&6\end{bmatrix}^T ==> \begin{bmatrix}1&3&5 \\2&4&6\end{bmatrix}$

矩陣的轉置知足分配律:

$(A + B)^T = A^T + B^T$

$(AB)^T = B^TA^T$

再次提醒:兩個矩陣的乘法僅當第一個矩陣A的列數(column)和另外一個矩陣B的行數(row)相等才能夠進行計算

In [12]:
A = np.arange(6).reshape((2,3))

print(A)
 
[[0 1 2]
 [3 4 5]]
In [13]:
# 轉置矩陣(行列互換)
A.T
Out[13]:
array([[0, 3],
       [1, 4],
       [2, 5]])
In [14]:
B = np.random.randint(10,size=(2,3))

print(B)
 
[[4 4 7]
 [5 3 9]]
In [15]:
################ 驗證系列 ################
In [16]:
# 驗證一下(A+B)^T=A^T+B^T
print(A.T + B.T)
print("-"*5)
print((A+B).T)
 
[[ 4  8]
 [ 5  7]
 [ 9 14]]
-----
[[ 4  8]
 [ 5  7]
 [ 9 14]]
In [17]:
# 驗證一下(A+B)^T=A^T+B^T
# 其實也再一次驗證了,Numpy運算符默認是對每個元素的操做
(A+B).T == A.T + B.T
Out[17]:
array([[ True,  True],
       [ True,  True],
       [ True,  True]])
In [18]:
################ 驗證系列 ################
In [19]:
# 把A變成3*2的矩陣,不夠元素用0補
# reshape:有返回值,不對原始多維數組進行修改
# resize:無返回值,會對原始多維數組進行修改
A.resize(3,2)

print(A)
print(B)
 
[[0 1]
 [2 3]
 [4 5]]
[[4 4 7]
 [5 3 9]]
In [20]:
# 驗證(AB)^T=B^T×A^T
print((A.dot(B)).T)
print("-"*5)
print((B.T).dot(A.T))
 
[[ 5 23 41]
 [ 3 17 31]
 [ 9 41 73]]
-----
[[ 5 23 41]
 [ 3 17 31]
 [ 9 41 73]]
 

2.3.3.上三角矩陣和下三角矩陣

上三角矩陣 :主對角線如下都是零的方陣

$\begin{bmatrix} 2&9&4&7 \\ 0&7&3&3 \\ 0&0&6&1 \\ 0&0&0&1 \end{bmatrix}$

下三角矩陣 :主對角線以上都是零的方陣

$\begin{bmatrix} 2&0&0&0 \\ 3&7&0&0 \\ 5&6&7&0 \\ 1&2&3&4 \end{bmatrix}$

性質(行列式後面會說)

  1. 上(下)三角矩陣的行列式爲對角線元素相乘
  2. 上(下)三角矩陣乘以係數後也是上(下)三角矩陣
  3. 上(下)三角矩陣間的加減法和乘法運算的結果還是上(下)三角矩陣
  4. 上(下)三角矩陣的逆矩陣也仍然是上(下)三角矩陣
In [21]:
# 建立一個5行4列矩陣
A = np.random.randint(10,size=(4,4))

print(A)
 
[[3 5 2 3]
 [7 2 9 6]
 [5 1 7 6]
 [1 2 8 4]]
In [22]:
# 上三角
np.triu(A)
Out[22]:
array([[3, 5, 2, 3],
       [0, 2, 9, 6],
       [0, 0, 7, 6],
       [0, 0, 0, 4]])
In [23]:
# 下三角
np.tril(A)
Out[23]:
array([[3, 0, 0, 0],
       [7, 2, 0, 0],
       [5, 1, 7, 0],
       [1, 2, 8, 4]])
In [24]:
# 驗證一下最後一個性質
# 三角矩陣的逆矩陣也仍然是三角矩陣
print(np.triu(A).T)
print('-'*5)
print(np.tril(A).T)
 
[[3 0 0 0]
 [5 2 0 0]
 [2 9 7 0]
 [3 6 6 4]]
-----
[[3 7 5 1]
 [0 2 1 2]
 [0 0 7 8]
 [0 0 0 4]]
 

2.3.4.對角矩陣

對角矩陣 :主對角線以外的元素皆爲0的方陣 (單位矩陣屬於對角矩陣中的一種)

$\begin{bmatrix}0&0&0 \\0&0&0 \\0&0&0\end{bmatrix} \begin{bmatrix}1&0&0 \\0&1&0 \\0&0&1\end{bmatrix} \begin{bmatrix}2&0&0 \\0&2&0 \\0&0&2\end{bmatrix} \begin{bmatrix}3&0&0 \\0&9&0 \\0&0&6\end{bmatrix}$

擴充:對角矩陣的運算包括和、差運算、數乘運算、同階對角陣的乘積運算,且結果仍爲對角陣

並且有意思的是:對角矩陣的矩陣冪運算等於其對應元素的冪運算

$\begin{bmatrix}3&0&0 \\0&9&0 \\0&0&6\end{bmatrix}^n = \begin{bmatrix}3^n&0&0 \\0&9^n&0 \\0&0&6^n\end{bmatrix}$

In [25]:
# 簡單建立
np.diag([3,9,6])
Out[25]:
array([[3, 0, 0],
       [0, 9, 0],
       [0, 0, 6]])
In [26]:
np.diag([2,2,2])
Out[26]:
array([[2, 0, 0],
       [0, 2, 0],
       [0, 0, 2]])
In [27]:
################ 驗證系列 ################
In [28]:
# np.diag?
print(A)

# 獲取對角元素,而後再生成對角矩陣
B = np.diag(A.diagonal()) #或者 np.diag(np.diag(A))

print(B)
 
[[3 5 2 3]
 [7 2 9 6]
 [5 1 7 6]
 [1 2 8 4]]
[[3 0 0 0]
 [0 2 0 0]
 [0 0 7 0]
 [0 0 0 4]]
In [29]:
B.dot(B).dot(B)
Out[29]:
array([[ 27,   0,   0,   0],
       [  0,   8,   0,   0],
       [  0,   0, 343,   0],
       [  0,   0,   0,  64]])
In [30]:
# 對角矩陣的矩陣冪運算等於其對應元素的冪運算
B**3
Out[30]:
array([[ 27,   0,   0,   0],
       [  0,   8,   0,   0],
       [  0,   0, 343,   0],
       [  0,   0,   0,  64]])
 

2.3.5.單位矩陣

單位矩陣 :單位矩陣是個方陣(行列相等),從左上角到右下角的對角線(稱爲主對角線)上的元素均爲1。其餘全都爲0,eg:

$ \begin{bmatrix} 1&0&0 \\ 0&1&0 \\ 0&0&1 \end{bmatrix} $

任何矩陣 x 單位矩陣 都等於其自己 (反過來也同樣(這個和1×a=a×1一個道理))

In [31]:
# 定義一個2行的單位矩陣(列默認和行一致)
# np.eye(rows,columns=rows)
np.eye(2)
Out[31]:
array([[1., 0.],
       [0., 1.]])
In [32]:
################ 驗證擴展 ################
In [33]:
# 能夠指定類型
B = np.eye(4,dtype=int)

print(B)
 
[[1 0 0 0]
 [0 1 0 0]
 [0 0 1 0]
 [0 0 0 1]]
In [34]:
print(A)
 
[[3 5 2 3]
 [7 2 9 6]
 [5 1 7 6]
 [1 2 8 4]]
In [35]:
# 任何矩陣 x 單位矩陣 都等於其自己
A.dot(B)
Out[35]:
array([[3, 5, 2, 3],
       [7, 2, 9, 6],
       [5, 1, 7, 6],
       [1, 2, 8, 4]])
In [36]:
# 反過來也同樣(這個和1*a=a*1一個道理)
B.dot(A)
Out[36]:
array([[3, 5, 2, 3],
       [7, 2, 9, 6],
       [5, 1, 7, 6],
       [1, 2, 8, 4]])
 

2.3.6.對稱矩陣

對稱矩陣 :元素以主對角線爲對稱軸對應相等的方陣

對稱矩陣的轉置是它自己:$A^T=A$

In [37]:
A = np.random.randint(10,size=(4,4))

print(A)
 
[[0 1 6 9]
 [1 2 4 7]
 [4 8 7 9]
 [3 6 8 0]]
In [38]:
B = np.triu(A)
B += B.T - np.diag(A.diagonal())
print(B)
 
[[0 1 6 9]
 [1 2 4 7]
 [6 4 7 9]
 [9 7 9 0]]
In [39]:
# 驗證一下
B.T == B
Out[39]:
array([[ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True]])
In [40]:
################ 分步解釋 ################
In [41]:
# 建立上三角矩陣
B = np.triu(A)

print(B)
 
[[0 1 6 9]
 [0 2 4 7]
 [0 0 7 9]
 [0 0 0 0]]
In [42]:
# 上三角+它的逆矩陣(發現距離對角矩陣只是多加一次對角線上的元素)
B += B.T

print(B)
 
[[ 0  1  6  9]
 [ 1  4  4  7]
 [ 6  4 14  9]
 [ 9  7  9  0]]
In [43]:
# 因此減去對角線上的元素,獲得對角矩陣
B - np.diag(A.diagonal())
Out[43]:
array([[0, 1, 6, 9],
       [1, 2, 4, 7],
       [6, 4, 7, 9],
       [9, 7, 9, 0]])
 

2.4.逆矩陣

逆矩陣 :設A是數域上的一個n階方陣,若在相同數域上存在另外一個n階矩陣B,使得:AB=BA=E 則咱們稱B是A的逆矩陣(表示爲$A^{-1}$),而A則被稱爲可逆矩陣

通俗話講就是:原矩陣×逆矩陣=逆矩陣×原矩陣=單位矩陣

2.4.1.消元法

可能一看到逆矩陣,你們就想到代數餘子式 ,不過逆天要說的是,代數餘子式就和咱們程序員面試題同樣,有些題目就是又繁瑣實際運用又沒多大意義的題目同樣,不少時候面試官都不看面試題一眼,一樣的那些出題老師本身解題通常都不會使用。我這邊介紹一下方便簡單的方法「消元法

好比求$\begin{bmatrix}3&2 \\1&2\end{bmatrix}^{-1}$,就能夠表示爲:

$\begin{bmatrix}3&2 \\1&2\end{bmatrix}\begin{bmatrix}x_{11}&x_{12} \\x_{21}&x_{22}\end{bmatrix}=\begin{bmatrix}1&0 \\0&1\end{bmatrix}$

轉換成方程組:

$\begin{cases} \begin{bmatrix}3&2 \\1&2\end{bmatrix}\begin{bmatrix}x_{11} \\x_{21}\end{bmatrix}=\begin{bmatrix}1 \\0\end{bmatrix}\\ \begin{bmatrix}3&2 \\1&2\end{bmatrix}\begin{bmatrix}x_{12} \\x_{22}\end{bmatrix}=\begin{bmatrix}0 \\1\end{bmatrix} \end{cases} ==> 求方程組\begin{cases}3x_{11}+2x_{21}=1\\1x_{11}+2x_{21}=0\end{cases}和\begin{cases}3x_{12}+2x_{22}=0\\1x_{12}+2x_{22}=1\end{cases}的解$

這樣很輕鬆就能解出逆矩陣了

$\begin{cases}x_{11}=\frac{1}{2}\\x_{21}=-\frac{1}{4} \end{cases}\\\begin{cases}x_{12}=-\frac{1}{2}\\x_{22}=\frac{3}{4} \end{cases}\\ ==> \begin{bmatrix}\frac{1}{2}&-\frac{1}{2} \\-\frac{1}{4}&\frac{3}{4} \end{bmatrix}$

In [44]:
A = np.array([[3,2],[1,2]])

print(A)
 
[[3 2]
 [1 2]]
In [45]:
# 求A的逆矩陣
np.linalg.inv(A)
Out[45]:
array([[ 0.5 , -0.5 ],
       [-0.25,  0.75]])
 

2.4.2.二階方陣公式

若是隻是2階方陣,有更簡單的公式(只能2階使用,而消元法不受限制)矩陣是否可逆就看分母是否爲0

$\large{\begin{bmatrix}a_{11}&a_{12} \\a_{21}&a_{22}\end{bmatrix}=\frac{1}{a_{11}a_{22}-a_{12}a_{21}}\begin{bmatrix}a_{22}&-a_{12} \\-a_{21}&a_{11}\end{bmatrix}}$

好比求$\begin{bmatrix}3&2 \\1&2\end{bmatrix}^{-1}$:

$\frac{1}{3×2-2×1}\begin{bmatrix}2&-2 \\-1&3\end{bmatrix}=\begin{bmatrix}\frac{1}{2}&-\frac{1}{2} \\-\frac{1}{4}&\frac{3}{4} \end{bmatrix}$

擴展系列:僞逆矩陣

非方陣能夠求 僞逆矩陣 AXA=A,XAX=X

判斷矩陣是否可逆:

$$det\begin{bmatrix}a_{11}&a_{12} \\a_{21}&a_{22}\end{bmatrix}=a_{11}a_{12}-a_{12}a_{21}\\det\begin{bmatrix}a_{11}&a_{12}&a_{13} \\a_{21}&a_{22}&a_{23}\\a_{31}&a_{32}&a_{33}\end{bmatrix}=a_{11}a_{22}a_{33}+a_{12}a_{23}a_{31}+a_{13}a_{21}a_{32}-a_{13}a_{22}a_{31}-a_{12}a_{21}a_{33}-a_{11}a_{23}a_{32}$$

方法不少(好比還能夠經過餘子式),公式其實有規律,你能夠先摸索下(給個提示):

正負
a11a22 +
a12a21 -
正負
a11a22a33 +
a11a23a32 -
a12a21a33 -
a12a23a31 +
a13a21a32 +
a13a22a31 -

程序比較簡單:np.linalg.det(A)

In [46]:
A = np.array([[7, 3, 6],[5, 3, 1]])

print(A)
 
[[7 3 6]
 [5 3 1]]
In [47]:
# 不等於0就是可逆
np.linalg.det(A)
 
---------------------------------------------------------------------------
LinAlgError                               Traceback (most recent call last)
<ipython-input-47-2ce8e7bdf499> in <module>()
      1 # 不等於0就是可逆
----> 2np.linalg.det(A)

~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in det(a)
   1869     a = asarray(a)
   1870     _assertRankAtLeast2(a)
-> 1871_assertNdSquareness(a)
   1872     t, result_t = _commonType(a)
   1873     signature = 'D->D' if isComplexType(t) else 'd->d'

~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in _assertNdSquareness(*arrays)
    209     for a in arrays:
    210         if max(a.shape[-2:]) != min(a.shape[-2:]):
--> 211raise LinAlgError('Last 2 dimensions of the array must be square')
    212 
    213 def _assertFinite(*arrays):

LinAlgError: Last 2 dimensions of the array must be square
In [48]:
# 必須是方陣的驗證
np.linalg.inv(A)
 
---------------------------------------------------------------------------
LinAlgError                               Traceback (most recent call last)
<ipython-input-48-0af3c81a492f> in <module>()
      1 # 必須是方陣的驗證
----> 2np.linalg.inv(A)

~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in inv(a)
    521     a, wrap = _makearray(a)
    522     _assertRankAtLeast2(a)
--> 523_assertNdSquareness(a)
    524     t, result_t = _commonType(a)
    525 

~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in _assertNdSquareness(*arrays)
    209     for a in arrays:
    210         if max(a.shape[-2:]) != min(a.shape[-2:]):
--> 211raise LinAlgError('Last 2 dimensions of the array must be square')
    212 
    213 def _assertFinite(*arrays):

LinAlgError: Last 2 dimensions of the array must be square
In [49]:
# 有時候仍是須要求逆矩陣
# 那就能夠求它的僞逆矩陣
X = np.linalg.pinv(A)

print(X)
 
[[-0.00632911  0.15189873]
 [-0.05696203  0.16708861]
 [ 0.20253165 -0.26075949]]
In [50]:
# A*X*A=A
A.dot(X).dot(A)
Out[50]:
array([[7., 3., 6.],
       [5., 3., 1.]])
In [51]:
# X*A*X=X
X.dot(A).dot(X)
Out[51]:
array([[-0.00632911,  0.15189873],
       [-0.05696203,  0.16708861],
       [ 0.20253165, -0.26075949]])
In [52]:
################ 簡單說下mat ################
In [53]:
# 建立一個矩陣
A = np.mat([[3,2],[1,2]])

print(A)
type(A)
 
[[3 2]
 [1 2]]
Out[53]:
numpy.matrixlib.defmatrix.matrix
In [54]:
# 求它的逆矩陣
A.I
Out[54]:
matrix([[ 0.5 , -0.5 ],
        [-0.25,  0.75]])
In [55]:
# A^T
A.T
Out[55]:
matrix([[3, 1],
        [2, 2]])
In [56]:
# *默認就是矩陣乘法
A * A
Out[56]:
matrix([[11, 10],
        [ 5,  6]])
In [57]:
# 更多本身查看下幫助文檔把,用法和array基本上同樣,
# 我這邊只是簡單提一下,怕大家不去看(全部和矩陣相關的東西,裏面都有封裝,很方便)
np.mat?
相關文章
相關標籤/搜索