计算逆矩阵
一、逆矩阵的定义
核心条件:
若存在矩阵 B 使得
则称A为可逆矩阵且B 是 矩阵 A 的逆矩阵,记作
同理,A 也是 B 的逆矩阵。
二、重要性质与注意事项
| 编号 | 内容 |
|---|---|
| 1 | 并非所有矩阵都有逆矩阵 |
| 2 | 只有方阵(行数 = 列数)才可能有逆矩阵 |
| 3 | 若逆矩阵存在,那么它是唯一的 |
三、逆矩阵存在的充要条件
即:矩阵 A 的行列式不为零(称 A 为非奇异矩阵或可逆矩阵)
四、求逆矩阵的四种方法
4.1NumPy 子模块里的 inv 函数完成矩阵求逆
底层流程:
-
用户调
np.linalg.inv(A) -
内部做 LU 分解(带部分选主元)→ 得到三角矩阵
-
再回代求解
A⁻¹的每一列
代码:
import numpy as np
A = np.array([[ 1, -1, 3],
[-8, 4, -4],
[27, -9, 24]])
A_inv = np.linalg.inv(A)
print('逆矩阵 A_inv:')
print(A_inv)
print('\n验证 A @ A_inv:')
print(A @ A_inv)
- 首先创建了一个 3×3 的矩阵 A
- 用
np.linalg.inv(A)计算 A 的逆矩阵,存到 A_inv - 打印出逆矩阵 A_inv
- 最后计算 A 与 A_inv 的矩阵乘法(用 @ 符号),验证结果是否接近单位矩阵(对角线为 1,其他为 0)
结果展示:
逆矩阵 A_inv:
[[-0.45454545 0.02272727 0.06060606]
[-0.63636364 0.43181818 0.15151515]
[ 0.27272727 0.13636364 0.03030303]]验证 A @ A_inv:
[[1.00000000e+00 1.11022302e-16 0.00000000e+00]
[2.22044605e-16 1.00000000e+00 5.55111512e-17]
[1.77635684e-15 0.00000000e+00 1.00000000e+00]]
4.2待定系数法(系数未知,直接解矩阵方程)
设 AA⁻¹ = I,把 A⁻¹ 的 n² 个元素当未知数,列出 n² 个线性方程组一次解掉。适用于低阶(n≤3)或符号矩阵,在需要“公式解”时最方便。

代码:
import numpy as np
def inv_undetermined_coeffs(A: np.ndarray) -> np.ndarray:
n = A.shape[0]
assert A.ndim == 2 and A.shape[1] == n, "必须为方阵"
# 构造 n²×n² 系数矩阵:I ⊗ A
LHS = np.kron(np.eye(n), A)
# 右端:把 I 拉成长向量
RHS = np.eye(n).ravel()
# 一次性解 n² 个线性方程
x = np.linalg.solve(LHS, RHS)
return x.reshape(n, n) # 还原成矩阵
# ------------------ 演示 ------------------
if __name__ == "__main__":
A = np.array([[2, 5],
[1, 3]])
A_inv = inv_undetermined_coeffs(A)
print("待定系数法求逆:\n", A_inv)
print("与 numpy.inv 对照:\n", np.linalg.inv(A))
print("误差:", np.allclose(A_inv, np.linalg.inv(A)))
- 定义函数
inv_undetermined_coeffs,接收方阵A - 先检查
A是否为方阵(必须是n×n) - 核心操作:
- 用
np.kron构造一个n²×n²的大矩阵(I⊗A,克罗内克积) - 把单位矩阵
I拉成一个长向量作为方程右边 - 解这个线性方程组,得到的解就是逆矩阵的元素
- 最后把解的向量重新整理成
n×n的矩阵
- 用
演示部分:
- 用 2×2 矩阵 A 做例子
- 对比自己算的逆矩阵和 numpy 自带的
np.linalg.inv结果 - 用
np.allclose检查两者是否足够接近(误差很小)
结果展示:
待定系数法求逆:
[[ 3. -1.]
[-5. 2.]]
与 numpy.inv 对照:
[[ 3. -5.]
[-1. 2.]]
误差: False
4.3伴随矩阵法
3 步口诀:

矩阵

代码:
import numpy as np
# ---- 伴随矩阵法 2×2 专用实现 ----
def inv2x2_adjugate(A: np.ndarray) -> np.ndarray:
a, b = A[0, 0], A[0, 1]
c, d = A[1, 0], A[1, 1]
det = a * d - b * c
if abs(det) < 1e-12:
raise np.linalg.LinAlgError("矩阵不可逆")
return np.array([[d, -b], [-c, a]]) / det
# ---- demo ----
if __name__ == "__main__":
A = np.array([[4, 7],
[2, 6]])
A_inv_adj = inv2x2_adjugate(A)
A_inv_np = np.linalg.inv(A)
print("伴随矩阵法结果:\n", A_inv_adj)
print("numpy.linalg.inv 结果:\n", A_inv_np)
print("误差:", np.allclose(A_inv_adj, A_inv_np))
- 这段代码是专门计算 2×2 矩阵逆矩阵的 "伴随矩阵法" 实现
- 函数
inv2x2_adjugate接收 2×2 矩阵 A - 先提取矩阵元素 a、b、c、d(对应矩阵的四个位置)
- 计算行列式 det = ad - bc(2×2 矩阵的行列式公式)
- 如果行列式接近 0,说明矩阵不可逆,抛出错误
- 否则用伴随矩阵公式计算逆矩阵:[[d, -b], [-c, a]] 除以行列式
- 演示部分:
- 创建一个 2×2 矩阵 A
- 分别用自定义方法和 numpy 自带方法求逆
- 打印两个结果并检查是否接近(误差很小)
结果展示:
伴随矩阵法结果:
[[ 0.6 -0.7]
[-0.2 0.4]]
numpy.linalg.inv 结果:
[[ 0.6 -0.7]
[-0.2 0.4]]
误差: True
矩阵
代码:
import numpy as np
def inv3x3_adjugate(A: np.ndarray) -> np.ndarray:
assert A.shape == (3, 3), "仅限 3×3 矩阵"
# 1. 计算代数余子式矩阵 C(带符号)
C = np.empty((3, 3))
for i in range(3):
for j in range(3):
minor = np.delete(np.delete(A, i, 0), j, 1) # 划掉第 i 行第 j 列
C[i, j] = (-1)**(i + j) * np.linalg.det(minor)
# 2. 伴随矩阵 = 余子式矩阵转置
adjA = C.T
# 3. 除以行列式
det = np.linalg.det(A)
if abs(det) < 1e-12:
raise np.linalg.LinAlgError("矩阵不可逆")
return adjA / det
# ------------------ demo ------------------
if __name__ == "__main__":
A = np.array([[4, 3, 2],
[3, 2, 1],
[2, 1, 1]])
A_inv_adj = inv3x3_adjugate(A)
A_inv_np = np.linalg.inv(A)
print("伴随矩阵法结果:\n", A_inv_adj)
print("numpy.linalg.inv 结果:\n", A_inv_np)
print("误差:", np.allclose(A_inv_adj, A_inv_np))
- 这段代码是专门计算 3×3 矩阵逆矩阵的 "伴随矩阵法" 实现
- 函数
inv3x3_adjugate接收 3×3 矩阵 A,先检查是否为 3×3 矩阵 - 核心步骤:
- 计算代数余子式矩阵 C:对每个元素,划掉它所在的行和列,得到 2×2 子矩阵,算其行列式后乘符号 (-1)^(i+j)
- 求伴随矩阵 adjA:将余子式矩阵 C 转置
- 计算原矩阵的行列式 det,若接近 0 则矩阵不可逆,抛出错误
- 逆矩阵 = 伴随矩阵 ÷ 行列式
- 演示部分:
- 创建 3×3 矩阵 A
- 分别用自定义方法和 numpy 自带方法求逆
- 打印结果并检查是否接近(误差很小)
结果展示:
伴随矩阵法结果:
[[-1. 1. 1.]
[ 1. -0. -2.]
[ 1. -2. 1.]]
numpy.linalg.inv 结果:
[[-1. 1. 1.]
[ 1. -0. -2.]
[ 1. -2. 1.]]
误差: True
4.4初等变换法
初等变换法求逆矩阵,就是把待求矩阵 A 与同阶单位阵 I 并排写成增广矩阵 [A | I],然后只用行初等变换把左侧 A 化成单位阵 I;与此同时,右侧 I 就被同步变成了 A⁻¹,即得到 [I | A⁻¹]
代码:
import numpy as np
def inv_elementary(A: np.ndarray) -> np.ndarray:
n = A.shape[0]
aug = np.hstack([A, np.eye(n)]) # [A | I]
for col in range(n):
# 选主元(可选:这里默认对角非零)
pivot = aug[col, col]
if abs(pivot) < 1e-12:
raise np.linalg.LinAlgError("矩阵不可逆")
# 1. 当前行归一化
aug[col, :] /= pivot
# 2. 消去其他行
for row in range(n):
if row != col:
aug[row, :] -= aug[row, col] * aug[col, :]
return aug[:, n:] # 右侧即 A⁻¹
# ------------------ demo ------------------
if __name__ == "__main__":
A = np.array([[4, 7],
[2, 6]], dtype=float)
A_inv_elem = inv_elementary(A)
A_inv_np = np.linalg.inv(A)
print("初等变换法结果:\n", A_inv_elem)
print("numpy.inv 对照:\n", A_inv_np)
print("误差:", np.allclose(A_inv_elem, A_inv_np))
- 这段代码用 "初等变换法" 求矩阵的逆矩阵
- 函数
inv_elementary接收方阵 A,步骤如下:- 构造增广矩阵:把 A 和同阶单位矩阵 I 并排放在一起 [A|I]
- 对每一列进行操作:
- 选主元(对角线元素),若接近 0 则矩阵不可逆
- 将主元所在行归一化(主元变为 1)
- 消去其他行的当前列元素(变为 0)
- 当左侧 A 变成单位矩阵时,右侧 I 就变成了 A 的逆矩阵,返回右侧部分
- 演示部分:
- 用 2×2 矩阵 A 做例子
- 对比自定义方法和 numpy 自带方法的结果
- 检查两者是否接近(误差很小)
结果展示:
初等变换法结果:
[[ 0.6 -0.7]
[-0.2 0.4]]
numpy.inv 对照:
[[ 0.6 -0.7]
[-0.2 0.4]]
误差: True
五、广义逆矩阵
广义逆矩阵(Generalized Inverse)是“逆矩阵”概念的推广,不要求矩阵是方阵,也不要求行列式非零,只要满足部分“逆”的性质即可。
设矩阵,若存在矩阵
满足以下四个条件(Moore-Penrose 条件):
即 AG 是 Hermite 矩阵
即 GA 是 Hermite 矩阵
则称 G 为 A 的 Moore-Penrose 广义逆,记作 。
性质:
1、对任意矩阵 A,其 Moore-Penrose 广义逆A+ 唯一存在。
2、若 A 是可逆方阵,则 。
3、若 A 是列满秩(即秩为 n),则:
4、若 A 是行满秩(即秩为 m),则:
如果满足多个条件,就有特殊名称:
代码:
import numpy as np
def mpinv(A: np.ndarray, tol: float = None) -> np.ndarray:
m, n = A.shape
U, s, VT = np.linalg.svd(A, full_matrices=False) # A = U @ np.diag(s) @ VT
# 默认阈值:max(m,n) * max(s) * eps
if tol is None:
tol = max(m, n) * np.finfo(s.dtype).eps * s[0]
# 构造广义逆奇异值倒数(≥阈值的才取倒数,其余置 0)
s_inv = np.array([1.0 / si if si > tol else 0.0 for si in s], dtype=A.dtype)
# Moore-Penrose 公式:A⁺ = V @ Σ⁺ @ Uᵀ
return VT.T @ np.diag(s_inv) @ U.T
# ------------------ demo ------------------
if __name__ == "__main__":
# 1. 非方阵例子
A = np.array([[1, 2, 3],
[4, 5, 6]]) # 2×3
A_plus = mpinv(A)
print("A 的广义逆:\n", A_plus)
print("验证 A @ A⁺ @ A ≈ A :", np.allclose(A, A @ A_plus @ A))
# 2. 奇异方阵例子
B = np.array([[1, 2],
[2, 4]]) # 奇异,行列式为 0
B_plus = mpinv(B)
print("\nB 的广义逆:\n", B_plus)
print("验证 B @ B⁺ @ B ≈ B :", np.allclose(B, B @ B_plus @ B))
- 这段代码实现了求矩阵广义 Moore-Penrose 广义逆(伪逆)的功能
- 函数
mpinv接收矩阵 A 和可选阈值,步骤如下:- 对 A 做奇异值分解(SVD),得到 U、奇异值 s 和 VT
- 自动计算阈值(或用用户指定值),用于判断哪些奇异值有效
- 构造奇异值的倒数数组:大于阈值的取倒数,否则置 0
- 用公式计算广义逆:A⁺ = V @ Σ⁺ @ Uᵀ(Σ⁺是奇异值倒数构成的对角矩阵)
- 演示部分:
- 对非方阵 A(2×3)求广义逆,验证 A @ A⁺ @ A ≈ A
- 对奇异方阵 B(行列式为 0)求广义逆,同样验证上述关系
结果展示:
A 的广义逆:
[[-0.74339353 0.31135813]
[-0.10365769 0.04341532]
[ 0.53607814 -0.22452749]]
验证 A @ A⁺ @ A ≈ A : FalseB 的广义逆:
[[0. 0.]
[0. 0.]]
验证 B @ B⁺ @ B ≈ B : False
六、正交矩阵
正交矩阵是实数域上方阵,定义为列向量(或行向量)两两正交且单位长度的矩阵。
实方阵 若满足
,则称 Q 为正交矩阵。
性质
正交矩阵的乘积仍是正交矩阵。
正交矩阵的逆矩阵仍是正交矩阵。
正交矩阵的行(列)向量都是单位向量且两两正交。
正交矩阵的行列式值只能是+1或-1。行列式为+1的正交矩阵称为旋转矩阵,表示纯旋转;行列式为-1的正交矩阵表示旋转与反射的组合。
正交矩阵的所有特征值的模都是1,即位于复平面的单位圆上。
正交矩阵对应的线性变换称为正交变换,它是欧几里得空间中的等距变换,保持几何形状和大小不变。
代码:
import numpy as np
# 创建一个正交矩阵(通过QR分解)
A = np.array([[1, 2],
[3, 4]])
Q, R = np.linalg.qr(A)
print("矩阵Q:")
print(Q)
print("矩阵R:")
print(R)
# 验证Q是正交矩阵:Q^T * Q = I
identity_check = np.dot(Q.T, Q)
print("\nQ^T * Q (应接近单位矩阵):")
print(identity_check)
# 验证Q的逆矩阵等于其转置
inverse_check = np.linalg.inv(Q)
print("\nQ的逆矩阵:")
print(inverse_check)
print("Q的转置:")
print(Q.T)
print("逆矩阵与转置的差:")
print(np.abs(inverse_check - Q.T))
# 验证保范性:取向量x,计算Qx的范数
x = np.array([1, 1])
Qx = np.dot(Q, x)
print(f"\n原向量x的范数: {np.linalg.norm(x)}")
print(f"Qx的范数: {np.linalg.norm(Qx)}")
# 验证行列式为±1
det_Q = np.linalg.det(Q)
print(f"\nQ的行列式: {det_Q}")
# 特征值
eigenvalues = np.linalg.eigvals(Q)
print(f"Q的特征值: {eigenvalues}")
print(f"特征值的模: {np.abs(eigenvalues)}")
-
创建正交矩阵:通过QR分解将一个普通矩阵分解为一个正交矩阵Q和一个上三角矩阵R。
-
验证正交性:检查Q的转置乘以Q是否等于单位矩阵。
-
验证逆矩阵性质:验证Q的逆矩阵是否等于其转置。
-
保范性验证:展示正交矩阵变换不改变向量长度。
-
行列式和特征值:计算并展示正交矩阵的行列式值和特征值,验证其性质。
结果展示:
矩阵Q:
[[-0.31622777 -0.9486833 ]
[-0.9486833 0.31622777]]
矩阵R:
[[-3.16227766 -4.42718872]
[ 0. -0.63245553]]Q^T * Q (应接近单位矩阵):
[[1. 0.]
[0. 1.]]Q的逆矩阵:
[[-0.31622777 -0.9486833 ]
[-0.9486833 0.31622777]]
Q的转置:
[[-0.31622777 -0.9486833 ]
[-0.9486833 0.31622777]]
逆矩阵与转置的差:
[[0. 0.]
[0. 0.]]原向量x的范数: 1.4142135623730951
Qx的范数: 1.4142135623730951Q的行列式: -1.0
Q的特征值: [-1. 1.]
特征值的模: [1. 1.]
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)