第7章:矩阵的逆与行列式基础

Haiyue
14min

第7章:矩阵的逆与行列式基础

学习目标
  • 理解可逆矩阵的定义和条件
  • 掌握求逆矩阵的方法
  • 理解行列式的定义和几何意义
  • 掌握行列式的计算方法
  • 理解行列式与线性变换的关系

可逆矩阵的基本概念

矩阵的逆的定义

对于 n×nn \times n 方阵 AA,如果存在矩阵 BB 使得: AB=BA=InAB = BA = I_n

则称 AA可逆矩阵(或非奇异矩阵),BBAA逆矩阵,记作 A1A^{-1}

重要性质:

  1. 逆矩阵唯一
  2. (A1)1=A(A^{-1})^{-1} = A
  3. (AB)1=B1A1(AB)^{-1} = B^{-1}A^{-1}
  4. (AT)1=(A1)T(A^T)^{-1} = (A^{-1})^T
import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import inv, det

# 可逆矩阵示例
A = np.array([[2, 1],
              [1, 1]])

print("矩阵 A:")
print(A)

# 计算逆矩阵
A_inv = inv(A)
print("\nA 的逆矩阵:")
print(A_inv)

# 验证 AA^(-1) = I
identity_check = A @ A_inv
print("\nAA^(-1) =")
print(identity_check)

# 验证 A^(-1)A = I
identity_check2 = A_inv @ A
print("\nA^(-1)A =")
print(identity_check2)

可逆性的判定条件

方阵 AA 可逆当且仅当以下条件等价:

  1. AA 的行列式 det(A)0\det(A) \neq 0
  2. AA 的秩等于 nn(满秩)
  3. AA 的列向量线性无关
  4. AA 的行向量线性无关
  5. 齐次方程组 Ax=0A\mathbf{x} = \mathbf{0} 只有零解
  6. 对任意 b\mathbf{b},方程组 Ax=bA\mathbf{x} = \mathbf{b} 有唯一解
def check_invertibility(A):
    """
    检查矩阵是否可逆
    """
    print(f"矩阵 A:")
    print(A)

    # 计算行列式
    det_A = det(A)
    print(f"\ndet(A) = {det_A:.6f}")

    # 计算秩
    rank_A = np.linalg.matrix_rank(A)
    n = A.shape[0]
    print(f"rank(A) = {rank_A}, 矩阵大小 = {n}×{n}")

    # 判断可逆性
    if abs(det_A) > 1e-10:
        print("矩阵可逆")
        try:
            A_inv = inv(A)
            print("逆矩阵:")
            print(A_inv)
        except:
            print("数值计算出现问题")
    else:
        print("矩阵不可逆(奇异矩阵)")

# 测试可逆矩阵
print("测试1:可逆矩阵")
A1 = np.array([[1, 2], [3, 4]])
check_invertibility(A1)

print("\n" + "="*50 + "\n")

# 测试不可逆矩阵
print("测试2:不可逆矩阵")
A2 = np.array([[1, 2], [2, 4]])
check_invertibility(A2)

求逆矩阵的方法

方法1:高斯-约旦消元法

通过行变换将增广矩阵 [AI][A|I] 化为 [IA1][I|A^{-1}]

def matrix_inverse_gauss_jordan(A):
    """
    使用高斯-约旦消元法求逆矩阵
    """
    n = A.shape[0]
    if A.shape[0] != A.shape[1]:
        raise ValueError("矩阵必须是方阵")

    # 构造增广矩阵 [A|I]
    augmented = np.column_stack([A.astype(float), np.eye(n)])
    print("增广矩阵 [A|I]:")
    print(augmented)
    print()

    # 高斯-约旦消元
    for i in range(n):
        # 寻找主元
        max_row = i
        for k in range(i+1, n):
            if abs(augmented[k, i]) > abs(augmented[max_row, i]):
                max_row = k

        # 交换行
        if max_row != i:
            augmented[i], augmented[max_row] = augmented[max_row].copy(), augmented[i].copy()
            print(f"交换第 {i+1} 行和第 {max_row+1} 行")

        # 检查主元是否为零
        if abs(augmented[i, i]) < 1e-10:
            raise ValueError("矩阵不可逆")

        # 将主元化为1
        pivot = augmented[i, i]
        augmented[i] = augmented[i] / pivot
        print(f"第 {i+1} 行除以 {pivot:.3f}")
        print(augmented)
        print()

        # 消除该列的其他元素
        for j in range(n):
            if j != i and abs(augmented[j, i]) > 1e-10:
                factor = augmented[j, i]
                augmented[j] = augmented[j] - factor * augmented[i]
                print(f"第 {j+1} 行 <- 第 {j+1} 行 - {factor:.3f} * 第 {i+1} 行")

    print("最终结果 [I|A^(-1)]:")
    print(augmented)

    # 提取逆矩阵
    A_inv = augmented[:, n:]
    return A_inv

# 示例
A_example = np.array([[1, 2], [3, 4]])
print("求矩阵的逆:")
print(A_example)
print()

A_inv_manual = matrix_inverse_gauss_jordan(A_example)
print("\n计算得到的逆矩阵:")
print(A_inv_manual)

# 验证
print("\n验证 AA^(-1):")
print(A_example @ A_inv_manual)

方法2:伴随矩阵法

对于 2×22 \times 2 矩阵: A=[abcd]A = \begin{bmatrix} a & b \\ c & d \end{bmatrix}

逆矩阵为: A1=1det(A)[dbca]A^{-1} = \frac{1}{\det(A)} \begin{bmatrix} d & -b \\ -c & a \end{bmatrix}

def inverse_2x2(A):
    """
    2×2矩阵的逆矩阵公式
    """
    if A.shape != (2, 2):
        raise ValueError("只适用于2×2矩阵")

    a, b = A[0, 0], A[0, 1]
    c, d = A[1, 0], A[1, 1]

    det_A = a*d - b*c
    if abs(det_A) < 1e-10:
        raise ValueError("矩阵不可逆")

    A_inv = np.array([[d, -b], [-c, a]]) / det_A
    return A_inv

# 测试2×2矩阵逆矩阵公式
A_2x2 = np.array([[3, 1], [2, 1]])
print("2×2矩阵:")
print(A_2x2)

A_inv_formula = inverse_2x2(A_2x2)
print("\n使用公式计算的逆矩阵:")
print(A_inv_formula)

A_inv_numpy = inv(A_2x2)
print("\nNumPy计算的逆矩阵:")
print(A_inv_numpy)

print("\n差异:")
print(np.abs(A_inv_formula - A_inv_numpy))

行列式的定义与性质

行列式的定义

2×2矩阵的行列式: det[abcd]=adbc\det\begin{bmatrix} a & b \\ c & d \end{bmatrix} = ad - bc

3×3矩阵的行列式(萨吕斯法则): det[abcdefghi]=aei+bfg+cdhcegafhbdi\det\begin{bmatrix} a & b & c \\ d & e & f \\ g & h & i \end{bmatrix} = aei + bfg + cdh - ceg - afh - bdi

def det_2x2(A):
    """计算2×2矩阵的行列式"""
    return A[0,0]*A[1,1] - A[0,1]*A[1,0]

def det_3x3(A):
    """计算3×3矩阵的行列式(萨吕斯法则)"""
    a, b, c = A[0, :]
    d, e, f = A[1, :]
    g, h, i = A[2, :]

    positive = a*e*i + b*f*g + c*d*h
    negative = c*e*g + a*f*h + b*d*i

    return positive - negative

# 测试行列式计算
print("2×2矩阵行列式计算:")
A_2 = np.array([[3, 1], [2, 4]])
print(f"矩阵: \n{A_2}")
print(f"手工计算: {det_2x2(A_2)}")
print(f"NumPy计算: {det(A_2)}")

print("\n3×3矩阵行列式计算:")
A_3 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 10]])
print(f"矩阵: \n{A_3}")
print(f"萨吕斯法则: {det_3x3(A_3)}")
print(f"NumPy计算: {det(A_3)}")

行列式的几何意义

行列式的绝对值表示由矩阵的列向量(或行向量)构成的平行多面体的体积:

  • 2×2矩阵:平行四边形的面积
  • 3×3矩阵:平行六面体的体积
def visualize_determinant_2d():
    """可视化2D行列式的几何意义"""
    fig, axes = plt.subplots(1, 2, figsize=(12, 5))

    # 示例1:正行列式
    v1 = np.array([3, 1])
    v2 = np.array([1, 2])
    A1 = np.column_stack([v1, v2])
    det1 = det(A1)

    # 绘制向量和平行四边形
    axes[0].arrow(0, 0, v1[0], v1[1], head_width=0.1, head_length=0.1,
                  fc='red', ec='red', linewidth=2, label=f'v1 = {v1}')
    axes[0].arrow(0, 0, v2[0], v2[1], head_width=0.1, head_length=0.1,
                  fc='blue', ec='blue', linewidth=2, label=f'v2 = {v2}')

    # 平行四边形的顶点
    parallelogram1 = np.array([[0, 0], [v1[0], v1[1]],
                              [v1[0]+v2[0], v1[1]+v2[1]], [v2[0], v2[1]], [0, 0]])
    axes[0].plot(parallelogram1[:, 0], parallelogram1[:, 1], 'g--', alpha=0.7)
    axes[0].fill(parallelogram1[:-1, 0], parallelogram1[:-1, 1], alpha=0.3, color='green')

    axes[0].set_title(f'det = {det1:.2f} (面积)')
    axes[0].grid(True, alpha=0.3)
    axes[0].legend()
    axes[0].set_aspect('equal')
    axes[0].set_xlim(-1, 5)
    axes[0].set_ylim(-1, 4)

    # 示例2:负行列式(向量顺序相反)
    v3 = np.array([1, 2])
    v4 = np.array([3, 1])
    A2 = np.column_stack([v3, v4])
    det2 = det(A2)

    axes[1].arrow(0, 0, v3[0], v3[1], head_width=0.1, head_length=0.1,
                  fc='red', ec='red', linewidth=2, label=f'v1 = {v3}')
    axes[1].arrow(0, 0, v4[0], v4[1], head_width=0.1, head_length=0.1,
                  fc='blue', ec='blue', linewidth=2, label=f'v2 = {v4}')

    parallelogram2 = np.array([[0, 0], [v3[0], v3[1]],
                              [v3[0]+v4[0], v3[1]+v4[1]], [v4[0], v4[1]], [0, 0]])
    axes[1].plot(parallelogram2[:, 0], parallelogram2[:, 1], 'g--', alpha=0.7)
    axes[1].fill(parallelogram2[:-1, 0], parallelogram2[:-1, 1], alpha=0.3, color='orange')

    axes[1].set_title(f'det = {det2:.2f} (面积,方向相反)')
    axes[1].grid(True, alpha=0.3)
    axes[1].legend()
    axes[1].set_aspect('equal')
    axes[1].set_xlim(-1, 5)
    axes[1].set_ylim(-1, 4)

    plt.tight_layout()
    plt.show()

visualize_determinant_2d()

行列式的重要性质

  1. 转置不变性det(AT)=det(A)\det(A^T) = \det(A)
  2. 多重线性:关于每一行(列)都是线性的
  3. 反对称性:交换两行(列),行列式变号
  4. 乘积性质det(AB)=det(A)det(B)\det(AB) = \det(A)\det(B)
def demonstrate_determinant_properties():
    """演示行列式的性质"""
    A = np.array([[1, 2], [3, 4]])
    B = np.array([[2, 1], [1, 3]])

    print("矩阵 A:")
    print(A)
    print("矩阵 B:")
    print(B)
    print()

    # 性质1:转置不变性
    print("性质1:转置不变性")
    print(f"det(A) = {det(A):.6f}")
    print(f"det(A^T) = {det(A.T):.6f}")
    print(f"相等? {np.isclose(det(A), det(A.T))}")
    print()

    # 性质2:乘积性质
    print("性质2:乘积性质")
    AB = A @ B
    print(f"det(A) = {det(A):.6f}")
    print(f"det(B) = {det(B):.6f}")
    print(f"det(AB) = {det(AB):.6f}")
    print(f"det(A) * det(B) = {det(A) * det(B):.6f}")
    print(f"相等? {np.isclose(det(AB), det(A) * det(B))}")
    print()

    # 性质3:反对称性(交换行)
    print("性质3:反对称性")
    A_swapped = A[[1, 0], :]  # 交换第1行和第2行
    print("交换行后的矩阵:")
    print(A_swapped)
    print(f"原行列式: {det(A):.6f}")
    print(f"交换行后: {det(A_swapped):.6f}")
    print(f"是否变号? {np.isclose(det(A), -det(A_swapped))}")

demonstrate_determinant_properties()

行列式与线性变换

行列式作为变换的度量

行列式描述了线性变换对面积/体积的缩放效果:

def visualize_linear_transformation():
    """可视化线性变换与行列式"""
    fig, axes = plt.subplots(2, 2, figsize=(12, 10))

    # 原始单位正方形
    unit_square = np.array([[0, 1, 1, 0, 0],
                           [0, 0, 1, 1, 0]])

    # 变换矩阵
    transformations = [
        np.array([[2, 0], [0, 1]]),      # 水平拉伸
        np.array([[1, 0.5], [0, 1]]),    # 剪切变换
        np.array([[1, 0], [0, 2]]),      # 垂直拉伸
        np.array([[0, 1], [1, 0]])       # 反射
    ]

    titles = ['水平拉伸 (det=2)', '剪切变换 (det=1)',
              '垂直拉伸 (det=2)', '反射 (det=-1)']

    for i, (T, title) in enumerate(zip(transformations, titles)):
        row, col = i // 2, i % 2
        ax = axes[row, col]

        # 变换后的形状
        transformed_square = T @ unit_square

        # 绘制原始和变换后的形状
        ax.plot(unit_square[0], unit_square[1], 'b-', linewidth=2,
                label='原始', alpha=0.7)
        ax.fill(unit_square[0], unit_square[1], alpha=0.3, color='blue')

        ax.plot(transformed_square[0], transformed_square[1], 'r-',
                linewidth=2, label='变换后')
        ax.fill(transformed_square[0], transformed_square[1],
                alpha=0.3, color='red')

        # 计算行列式
        det_T = det(T)
        ax.set_title(f'{title}\ndet = {det_T}')
        ax.grid(True, alpha=0.3)
        ax.legend()
        ax.set_aspect('equal')
        ax.set_xlim(-0.5, 2.5)
        ax.set_ylim(-0.5, 2.5)

    plt.tight_layout()
    plt.show()

visualize_linear_transformation()

行列式的计算方法

余子式和代数余子式

对于 n×nn \times n 矩阵 AA

  • 余子式 MijM_{ij}:删除第 ii 行第 jj 列后得到的 (n1)×(n1)(n-1) \times (n-1) 矩阵的行列式
  • 代数余子式 Cij=(1)i+jMijC_{ij} = (-1)^{i+j}M_{ij}

按行展开公式: det(A)=j=1naijCij\det(A) = \sum_{j=1}^n a_{ij}C_{ij}

def cofactor_expansion(A, row=0):
    """
    按指定行展开计算行列式
    """
    n = A.shape[0]
    if n == 1:
        return A[0, 0]
    elif n == 2:
        return A[0, 0] * A[1, 1] - A[0, 1] * A[1, 0]

    det_A = 0
    for j in range(n):
        # 构造余子式矩阵
        minor_matrix = np.delete(np.delete(A, row, axis=0), j, axis=1)

        # 计算代数余子式
        cofactor = (-1)**(row + j) * cofactor_expansion(minor_matrix)

        # 累加
        det_A += A[row, j] * cofactor

        print(f"a_{row+1}{j+1} = {A[row, j]}, 代数余子式 = {cofactor:.3f}")

    return det_A

# 示例:3×3矩阵
A_3x3 = np.array([[1, 2, 3],
                  [4, 5, 6],
                  [7, 8, 9]])

print("3×3矩阵:")
print(A_3x3)
print("\n按第一行展开:")
det_manual = cofactor_expansion(A_3x3, row=0)
print(f"\n手工计算的行列式: {det_manual}")
print(f"NumPy计算的行列式: {det(A_3x3)}")

三角矩阵的行列式

上三角矩阵或下三角矩阵的行列式等于主对角线元素的乘积:

def triangular_determinant():
    """演示三角矩阵行列式的计算"""

    # 上三角矩阵
    upper_triangular = np.array([[2, 3, 1],
                                [0, 4, 2],
                                [0, 0, 5]])

    # 下三角矩阵
    lower_triangular = np.array([[3, 0, 0],
                                [2, 4, 0],
                                [1, 5, 6]])

    print("上三角矩阵:")
    print(upper_triangular)
    det_upper = np.prod(np.diag(upper_triangular))
    print(f"主对角线元素乘积: {det_upper}")
    print(f"NumPy计算的行列式: {det(upper_triangular)}")

    print("\n下三角矩阵:")
    print(lower_triangular)
    det_lower = np.prod(np.diag(lower_triangular))
    print(f"主对角线元素乘积: {det_lower}")
    print(f"NumPy计算的行列式: {det(lower_triangular)}")

triangular_determinant()

应用实例

克拉默法则

对于 nn 元线性方程组 Ax=bA\mathbf{x} = \mathbf{b},如果 det(A)0\det(A) \neq 0,则: xi=det(Ai)det(A)x_i = \frac{\det(A_i)}{\det(A)}

其中 AiA_i 是将 AA 的第 ii 列替换为 b\mathbf{b} 得到的矩阵。

def cramers_rule(A, b):
    """
    使用克拉默法则求解线性方程组
    """
    n = A.shape[0]
    det_A = det(A)

    if abs(det_A) < 1e-10:
        raise ValueError("系数矩阵奇异,无法使用克拉默法则")

    print("使用克拉默法则求解线性方程组")
    print(f"系数矩阵的行列式: {det_A}")
    print()

    x = np.zeros(n)
    for i in range(n):
        # 构造 A_i
        A_i = A.copy()
        A_i[:, i] = b

        det_A_i = det(A_i)
        x[i] = det_A_i / det_A

        print(f"x_{i+1} = det(A_{i+1}) / det(A) = {det_A_i} / {det_A} = {x[i]:.6f}")

    return x

# 示例
A_cramer = np.array([[2, 1, -1],
                     [1, 3, 2],
                     [3, 1, 1]])
b_cramer = np.array([8, 13, 10])

print("方程组:")
print("2x₁ + x₂ - x₃ = 8")
print("x₁ + 3x₂ + 2x₃ = 13")
print("3x₁ + x₂ + x₃ = 10")
print()

x_cramer = cramers_rule(A_cramer, b_cramer)
print(f"\n解向量: {x_cramer}")

# 验证
verification = A_cramer @ x_cramer
print(f"验证: A @ x = {verification}")
print(f"原右端项: {b_cramer}")

本章小结

🔄 正在渲染 Mermaid 图表...
概念定义重要性质应用
逆矩阵AA1=IAA^{-1} = I唯一性、乘积规则求解线性方程组
行列式标量函数几何意义、乘积性判断可逆性、体积计算
可逆性多个等价条件det≠0 ⟺ 满秩线性变换分析
克拉默法则xi=det(Ai)det(A)x_i = \frac{\det(A_i)}{\det(A)}显式解公式小规模方程组
注意事项
  • 逆矩阵只对方阵定义,且必须满足可逆条件
  • 行列式为零的矩阵称为奇异矩阵,不可逆
  • 克拉默法则仅适用于系数矩阵可逆的情况
  • 数值计算中要注意舍入误差对行列式计算的影响

矩阵的逆和行列式是线性代数的核心工具,它们不仅有深刻的理论意义,还在实际应用中发挥重要作用。