逆矩阵的计算与应用
计算逆矩阵
文章目录
前言
逆矩阵是我们线性代数所学习的,在Python中我们可以通过numpy.linalg一个包含线性代数的函数模块。使用这个模块,我们可以实现计算逆矩阵。
一、矩阵
矩阵与数组的概念有着本质的区别:①数组是计算机专业的概念,矩阵是数学专业的概念;②数组可以是一维、二维、三维或其他任意维度的,矩阵只能且必须是二维的;③数组中可以包含任意类型的数据,矩阵中元素必须是数值;④数组乘法与矩阵乘法的规则不同。
定义矩阵的两种方式,代码如下:
import numpy as np
A = np.matri`x([[1, 2], [3, 4]]) # 列表
B = np.mat('5 6; 7 8') # 字符串
print(A)
print(B)
二、逆矩阵
1.逆矩阵的定义
A、B为同阶矩阵,如果存在AB = BA = E,即称B为A的逆矩阵,同理,A也是B的逆矩阵,记作
.
- 注意
1)不是所有的矩阵都存在逆矩阵
2)只有方阵才存在逆矩阵
3)如果逆矩阵存在,逆矩阵唯一
4)逆矩阵存在的条件|A| != 0,即可逆矩阵的行列式不为0
2.计算逆矩阵
拓展库Numpy 的线性代数子模块linalg中提供了用来计算逆矩阵的函数inv()。
计算方阵的逆矩阵
代码如下:
(1)方阵求逆
A = np.array([[4, 7],
[2, 6]])
det_A = np.linalg.det(A) #计算行列式
print('A =\n', A)
print('det(A) = {:.2f}'.format(det_A))
A_inv = np.linalg.inv(A) # 求逆
I_check = A @ A_inv # 原矩阵 × 逆矩阵
print('A_inv =\n', A_inv)
print('A · A_inv =\n', I_check)
print('是否单位矩阵?', np.allclose(I_check, np.eye(2)))
运行结果:

(2)非方阵求逆(报错):
B = np.array([[1, 2, 3],
[4, 5, 6]])
print('B =\n', B)
try:
np.linalg.inv(B)
except np.linalg.LinAlgError as e:
print('非方阵求逆报错:', e)
运行结果:

(3)奇异矩阵求逆(报错):
C = np.array([[1, 2],
[2, 4]]) # 第 2 行是第一行的 2 倍 => 行列式 = 0
print('C =\n', C)
print('det(C) = {:.2f}'.format(np.linalg.det(C)))
try:
np.linalg.inv(C)
except np.linalg.LinAlgError as e:
print('奇异矩阵求逆报错:', e)
运行结果:

3.广义逆矩阵
对于任意矩阵A,存在一个唯一的的矩阵M使得下面三个条件同时成立:
(1)AMA=A
(2)MAM=M
(3)AM与MA均为对称矩阵
这样的矩阵M称为矩阵A的Moore-Penrose广义逆矩阵,奇异矩阵也可以计算广义逆矩阵。
在Python中,可以使用numpy库中的numpy.linalg.pinv函数来计算矩阵的Moore-Penrose逆矩阵:
代码如下:
A = np.random.RandomState(42).rand(4, 3)
print('A (4×3):\n', A)
# 计算 Moore-Penrose 广义逆
B = np.linalg.pinv(A)
print('B (3×4)——A 的广义逆:\n', B)
# 验证三个 Moore-Penrose 条件
print('验证 A B A = A:', np.allclose(A, A @ B @ A))
print('验证 B A B = B:', np.allclose(B, B @ A @ B))
print('验证 (A B)^T = A B:', np.allclose(A @ B, (A @ B).T))
print('验证 (B A)^T = B A:', np.allclose(B @ A, (B @ A).T))

计算奇异矩阵的广义逆矩阵:
import numpy as np
C = np.array([[1, 2, 3],
[2, 4, 6],
[3, 6, 9]], dtype=float)
print('C (3×3 奇异矩阵):\n', C)
print('det(C) =', np.linalg.det(C))
# 广义逆
D = np.linalg.pinv(C)
print('D (3×3)——C 的广义逆:\n', D)
# 验证三个 Moore-Penrose 条件
print('验证 C D C = C:', np.allclose(C, C @ D @ C))
print('验证 D C D = D:', np.allclose(D, D @ C @ D))
print('验证 (C D)^T = C D:', np.allclose(C @ D, (C @ D).T))
print('验证 (D C)^T = D C:', np.allclose(D @ C, (D @ C).T))
运行结果:

4.判断是否为正交矩阵
(1)正交矩阵的定义
如果AAT=E(E为单位矩阵,AT表示“矩阵A的转置矩阵”)或ATA=E,则n阶实矩阵A称为正交矩阵。
(2)正交矩阵的性质
- 正交矩阵的行向量和列向量都是单位向量(即长度为1)。
- 行向量与列向量两两正交,任意两行(或两列)的点积为0。
- 逆矩阵等于转置矩阵:A−1=AT。
- 行列式的绝对值为1,即|det(A)|=1。
# 1. 单位矩阵
mat = np.matrix([[1,0,0],[0,1,0],[0,0,1]])
print('inv(mat) == mat.T:\n', np.linalg.inv(mat) == mat.T)
print('det(mat) =', np.linalg.det(mat))
# 2. 对角反射矩阵
mat = np.matrix([[1,0], [0,-1]])
print('inv(mat) == mat.T:\n', np.linalg.inv(mat) == mat.T)
print('det(mat) =', np.linalg.det(mat))
# 3. 正交矩阵的逆矩阵仍是正交矩阵
mat_inv = np.linalg.inv(mat)
print('mat_inv @ mat_inv.T =\n', np.dot(mat_inv, mat_inv.T))
运行结果:

①单位矩阵逆等于转置且行列式为1,是最基本的纯旋转正交矩阵;
②二阶对角反射矩阵同样逆等于转置但行列式为–1,表明它也是正交矩阵,仅做一次镜像翻转;
③最后计算该矩阵的逆再乘其转置得到单位矩阵,证实正交矩阵的逆依旧是正交矩阵。
三、拓展内容
1.特征值、特征向量与逆矩阵的关系
对于矩阵 A A A,如果存在非零向量 v \mathbf{v} v 和标量 λ \lambda λ,使得 A v = λ v A\mathbf{v}=\lambda\mathbf{v} Av=λv,则 λ \lambda λ 是 A A A 的特征值, v \mathbf{v} v 是对应的特征向量;若 A A A 可逆,则 A − 1 A^{-1} A−1 的特征值为 λ − 1 \lambda^{-1} λ−1,且特征向量与 A A A 相同。
import numpy as np
# 定义矩阵 A
A = np.array([[4, 7], [2, 6]])
# 计算特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(A)
# 计算矩阵的逆
A_inv = np.linalg.inv(A)
# 验证逆矩阵的特征值是原矩阵特征值的倒数
inv_eigenvalues = 1 / eigenvalues
# 验证逆矩阵的特征向量与原矩阵相同
inv_eigenvectors = eigenvectors
print("矩阵 A 的特征值:", eigenvalues)
print("矩阵 A 的特征向量:\n", eigenvectors)
print("矩阵 A 的逆矩阵的特征值:", inv_eigenvalues)
print("矩阵 A 的逆矩阵的特征向量:\n", inv_eigenvectors)

2.稀疏矩阵的逆矩阵
稀疏矩阵是指矩阵中大部分元素为零的矩阵称为稀疏矩阵。计算稀疏矩阵的逆矩阵时,可以使用稀疏矩阵库(如 SciPy 的 scipy.sparse)来提高效率。
import numpy as np
from scipy.sparse import csc_matrix, spdiags
from scipy.sparse.linalg import inv
import matplotlib.pyplot as plt
# 8×8 对角稀疏矩阵:对角线 8 个非零元,其余全是 0
n = 8
vals = np.array([5, 8, 2, 7, 4, 9, 1, 6], dtype=float) # 对角元
A = spdiags(vals, 0, n, n).tocsc() # 快速生成对角稀疏矩阵
A_inv = inv(A) # 现在可逆
print("稀疏矩阵 A (8×8):")
print(A.toarray())
print("\nA 的逆矩阵:")
print(A_inv.toarray())


3.逆矩阵实现图像变换
将图片中的每个像素坐标
(
x
,
y
)
(x,y)
(x,y)写成齐次坐标列向量
p
=
[
x
,
y
,
1
]
T
\mathbf{p}=[x,y,1]^T
p=[x,y,1]T,图像变换就是左乘一个
3
×
3
3\times3
3×3矩阵
M
M
M 计算目标坐标:
p
′
=
M
p
\mathbf{p}'=M\mathbf{p}
p′=Mp。若是要实现逆向变换图片则需要计算
M
−
1
M^{-1}
M−1,将目标坐标
p
′
\mathbf{p}'
p′再映射回原始坐标
p
\mathbf{p}
p
参数解释:
M = cv2.getRotationMatrix2D(center, angle=45, scale=1.0) :
(1) center=(cx,cy) —— 旋转中心 像素坐标(非矩阵下标);
(2)angle=45 —— 逆时针角度(单位 °),负值即顺时针;
(3) scale=1.0 —— 旋转后缩放比例,1.0 原大,0.5 半倍,2.0 两倍。
齐次矩阵 M = [cosθ -sinθ tx;sinθ cosθ ty; 0 0 1]
import cv2
import numpy as np
img = cv2.imread(r'C:\Users\wangyuyan\Pictures\Screenshots\houzi.png', cv2.IMREAD_COLOR)
if img is None:
raise FileNotFoundError("图片路径不对或文件不存在")
h, w = img.shape[:2] # 只取高、宽
center = (w // 2, h // 2)
# 正向旋转 45°
M = cv2.getRotationMatrix2D(center, 45, 1.0)
rot = cv2.warpAffine(img, M, (w, h))
# 反向旋转 45°
M_inv = cv2.getRotationMatrix2D(center, -45, 1.0)
restored = cv2.warpAffine(rot, M_inv, (w, h))
cv2.imshow("Original", img)
cv2.imshow("Transformed", rot)
cv2.imshow("Restored", restored)
cv2.waitKey(0)
cv2.destroyAllWindows()



总结
本文围绕Python中逆矩阵的计算与应用展开,先明确矩阵与数组的本质区别,介绍逆矩阵“仅非奇异方阵存在、且唯一”的核心特性;接着讲解用numpy.linalg.inv()计算常规逆矩阵的方法,以及非方阵、奇异矩阵求逆的报错情况;随后引入广义逆矩阵(通过np.linalg.pinv()实现,适用于任意矩阵,需满足4个验证条件),并阐述正交矩阵“逆等于转置、行列式绝对值为1”的特殊性质;最后拓展了逆矩阵在特征值关系(逆矩阵特征值为原矩阵倒数)、稀疏矩阵(用scipy.sparse库高效计算)、图像变换(通过旋转矩阵及其逆实现正向变换与逆向恢复)中的应用,形成从基础概念到实践操作的完整知识体系。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)