矩陣求逆
1. 矩陣求逆演算法介紹
1.1 利用伴隨矩陣求逆
(1) 代數餘子式
一個 \(n \times n\) 矩陣 \(A\),\(A\) 在 \((i,j)\) 處的代數餘子式為 \(A\) 去掉第 \(i\) 行和第 \(j\) 列後剩下的矩陣的行列式的值再乘上 \((-1)^{i+j}\)
(2) 伴隨矩陣
一個 \(n \times n\) 矩陣 \(A\),\(A\) 的伴隨矩陣 \(C_A\) 為一個 \(n \times n\) 矩陣,\(C_A\) 在 \((i,j)\) 處的值為 \(A\) 在 \((i,j)\) 處的代數餘子式
(3) 轉置矩陣
一個 \(n \times n\)
(4) 逆矩陣
一個 \(n \times n\) 矩陣 \(A\),\(A\) 的逆矩陣 \(A^{-1}\) 為 \(\frac{1}{d} \cdot (C_A)^T\)。其中 d 是矩陣 \(A\) 的行列式,\(C_A\) 是 \(A\) 的伴隨矩陣,\((C_A)^T\) 是 \(C_A\) 的轉置矩陣
1.2 利用高斯行變換
一個 \(n \times n\) 的矩陣 \(A\),構造一個 \(n \times n\)
再通過初等行變換,將上述矩陣轉變為 \([I_{n \times n}|P_{n \times n}]\) 的形式,則有 \(A^{-1} = P\)
2. 矩陣行列式
2.1 使用餘子式
對於 \(n \times n\) 的矩陣 \(A\),其行列式 \(det(A)\) 的值等於 任意一行的元素 依次乘以 對應位置的餘子式 的結果之和
2.2 利用行變換
通過初等行變換將矩陣變成對角矩陣(除了對角線之外其它元素均為 0 的矩陣),對角線元素的乘積即為行列式的值
3. 矩陣求逆程式碼(python)
兩種求逆方法各有優劣,利用伴隨矩陣的方法在對整數矩陣求逆時精度更好,會損失精度的除法運算只在最後一步中使用;利用高斯行變換求解時可能會因為行變換的除法而損失一定的精度
但就時間複雜度來說,伴隨矩陣所消耗的時間複雜度遠大於使用高斯行變換的方式
3.1 利用伴隨矩陣
def _determinant(matrix):
"""遞迴計算矩陣行列式"""
if len(matrix) == 1:
return matrix[0][0]
else:
d = 0
matrix_row, matrix_col = len(matrix), len(matrix[0])
for col in range(matrix_col):
# 刪去第 0 行 col 列
m = [[matrix[i][j] for j in range(matrix_col) if j != col] for i in range(matrix_row) if i != 0]
d = d + (-1) ** (col & 1) * matrix[0][col] * _determinant(m)
return d
def _cofactor(matrix):
"""計算伴隨矩陣"""
matrix_row, matrix_col = len(matrix), len(matrix[0])
res = [[0 for _ in range(matrix_col)] for _ in range(matrix_row)]
for row in range(matrix_row):
for col in range(matrix_col):
# 刪去第 i 行 j 列
m = [[matrix[i][j] for j in range(matrix_col) if j != col] for i in range(matrix_row) if i != row]
# 計算餘子式
res[row][col] = (-1) ** ((row + col) & 1) * _determinant(m)
return res
def _traverse(matrix):
"""矩陣轉置"""
return [[matrix[col][row] for col in range(len(matrix[0]))] for row in range(len(matrix))]
def inverse(matrix):
d = _determinant(matrix) # 行列式
if d == 0: # 行列式等於0,不存在逆矩陣
return None
else:
cofactor = _cofactor(matrix) # 獲取伴隨矩陣
res = _traverse(cofactor) # 伴隨矩陣的轉置
# 將每個元素都除以 d
for row in range(len(res)):
for col in range(len(res[0])):
res[row][col] = res[row][col] / d
return res
3.2 利用高斯行變換
def inverse(matrix):
row, col = len(matrix), len(matrix[0]) # 矩陣的行列
t_matrix = [[matrix[r][c] for c in range(col)] for r in range(row)]
e_matrix = [[0 if c != r else 1 for c in range(col)] for r in range(row)] # 擴充套件矩陣
for i in range(row):
# 尋找第i列不為0的行
for r in range(i, row):
if t_matrix[r][i] != 0:
if i != r:
t_matrix[i], t_matrix[r] = t_matrix[r], t_matrix[i]
e_matrix[i], e_matrix[r] = e_matrix[r], e_matrix[i]
break
else: # 找不到對應的行,沒有逆矩陣
return None
# 對當前行的變換
temp = t_matrix[i][i]
for c in range(col):
t_matrix[i][c] /= temp
e_matrix[i][c] /= temp
# 對其它行的變換
for r in range(row):
if r != i:
temp = t_matrix[r][i]
for c in range(col):
e_matrix[r][c] = e_matrix[r][c] - e_matrix[i][c] * temp
t_matrix[r][c] = t_matrix[r][c] - t_matrix[i][c] * temp
return e_matrix