MATLAB 中使用 inv() 函数求解线性方程组

5 阅读3分钟

inv() 函数是 MATLAB 中用于计算矩阵逆的核心函数,仅适用于求解适定线性方程组(即系数矩阵为 n 阶非奇异方阵、方程数等于未知数个数且有唯一解)。

一、inv() 求解的核心原理与使用前提

1. 核心原理

对于线性方程组 AX=BA \cdot X = BAA 为 n 阶系数矩阵,XX 为未知数列向量,BB 为常数项列向量):

  • AA 是非奇异矩阵(行列式≠0、满秩),则存在唯一逆矩阵 A1A^{-1}
  • 两边同时左乘 A1A^{-1},可得解:X=A1BX = A^{-1} \cdot B
  • inv(A) 函数的作用就是计算 A1A^{-1},再与 BB 相乘得到解。

2. 严格使用前提(缺一不可)

  • AA 必须是方阵(行数=列数,即方程数=未知数个数);
  • AA 必须非奇异(满秩、行列式≠0),否则 inv(A) 会报错“Matrix is singular to working precision”。

二、完整实操步骤(以三阶方程组为例)

示例方程组

求解以下适定线性方程组: {x1+2x2+3x3=142x1+5x2+2x3=183x1+x2+5x3=20\begin{cases} x_1 + 2x_2 + 3x_3 = 14 \\ 2x_1 + 5x_2 + 2x_3 = 18 \\ 3x_1 + x_2 + 5x_3 = 20 \end{cases} 对应矩阵形式: A=[123252315],B=[141820]A = \begin{bmatrix}1 & 2 & 3 \\ 2 & 5 & 2 \\ 3 & 1 & 5\end{bmatrix}, \quad B = \begin{bmatrix}14 \\ 18 \\ 20\end{bmatrix}

步骤1:定义系数矩阵 A 和常数向量 B

首先在 MATLAB 中准确定义矩阵和向量,注意 B 必须是列向量(用分号分隔):

% 定义3阶系数矩阵A(方阵)
A = [1 2 3; 2 5 2; 3 1 5];
% 定义常数项列向量B(3×1)
B = [14; 18; 20];

步骤2:验证 A 是否为非奇异矩阵(可选但推荐)

在调用 inv() 前,先验证 A 的非奇异性,避免报错:

% 方法1:计算行列式(行列式≠0则非奇异)
det_A = det(A);
disp(['矩阵A的行列式:', num2str(det_A)]);

% 方法2:计算秩(秩=阶数则满秩/非奇异)
rank_A = rank(A);
disp(['矩阵A的秩:', num2str(rank_A), ',矩阵阶数:', num2str(size(A,1))]);

输出结果

矩阵A的行列式:-18
矩阵A的秩:3,矩阵阶数:3

行列式=-18≠0、秩=3=阶数,说明 A 非奇异,可使用 inv() 求解。

步骤3:用 inv() 计算逆矩阵并求解方程组

核心代码仅两行,先求逆矩阵,再与 B 相乘:

% 计算A的逆矩阵
A_inv = inv(A);

% 求解方程组 X = A^-1 * B(注意是矩阵乘法*,而非点乘.*)
X = A_inv * B;

% 输出解
disp('方程组的解:');
disp(X);

输出结果

方程组的解:
   1.0000
   2.0000
   3.0000

x1=1x_1=1x2=2x_2=2x3=3x_3=3,与理论解完全一致。

步骤4:验证解的正确性(必做)

通过计算“残差”验证解是否正确,残差接近 0 则解有效:

% 计算残差:A*X - B(理论上应全为0,浮点误差导致接近0)
residual = A * X - B;
disp('残差(理论值为0):');
disp(residual);

输出结果

残差(理论值为0):
   1.0e-14 *
   -0.0888
    0.1776
         0

残差量级为 101410^{-14},可认为近似为 0,解正确。

三、完整可运行代码

% 1. 定义系数矩阵和常数向量
A = [1 2 3; 2 5 2; 3 1 5];
B = [14; 18; 20];

% 2. 验证A的非奇异性
det_A = det(A);
rank_A = rank(A);
disp(['矩阵A的行列式:', num2str(det_A)]);
disp(['矩阵A的秩:', num2str(rank_A), ',矩阵阶数:', num2str(size(A,1))]);

% 3. 求解方程组
if det_A ~= 0 && rank_A == size(A,1)
    A_inv = inv(A);
    X = A_inv * B;
    disp('=== 方程组的解 ===');
    disp(X);
    
    % 4. 验证解
    residual = A * X - B;
    disp('=== 残差(接近0则解正确) ===');
    disp(residual);
else
    disp('矩阵A为奇异矩阵,无法使用inv()求解!');
end

四、常见问题与避坑指南

1. 报错“Matrix is singular to working precision”

  • 原因:A 是奇异矩阵(行列式=0、秩<阶数),不存在逆矩阵;
  • 解决
    • 检查方程组是否存在唯一解(适定);
    • 改用 pinv()(伪逆)或 \ 运算符求解(推荐 \ 运算符)。

2. 解的精度低(残差大)

  • 原因:A 是“病态矩阵”(条件数大,行列式接近0但不为0),inv() 对病态矩阵精度差;
  • 解决
    • cond(A) 计算条件数(值越大越病态);
    • 优先改用 \ 运算符(MATLAB 自动优化算法);
    • 对数据做归一化预处理。

3. 维度不匹配报错“Inner matrix dimensions must agree”

  • 原因
    • B 是行向量(如 B = [14 18 20]),而非列向量;
    • 误将矩阵乘法 * 写成点乘 .*
  • 解决
    • 将 B 改为列向量(B = [14; 18; 20]);
    • 确保用 A_inv * B(矩阵乘法)。

4. 非方阵使用 inv() 报错

  • 原因:A 不是方阵(如超定/欠定方程组),inv() 仅支持方阵;
  • 解决:放弃 inv(),改用 \ 运算符(适配所有类型方程组)。

五、inv() 与 \ 运算符的对比(选型建议)

特性inv() 函数\ 运算符(左除)
适用场景仅非奇异方阵(适定方程组)所有类型方程组(适定/超定/欠定)
计算效率低(先求逆再乘法)高(直接求解,自动选最优算法)
精度对病态矩阵差对病态矩阵更鲁棒
代码复杂度两步(求逆+乘法)一步(A\B)

核心选型原则

  • 仅在需要手动获取逆矩阵时用 inv()(如矩阵分析、理论验证);
  • 求解方程组优先用 \ 运算符X = A \ B,效率和精度均优于 inv(),且适配场景更广。