3. MATLAB矩阵运算求解线性方程组

问题设定与三种求解路径

本节求解一个来自结构静力分析的 4 节点线性方程组 A·x = b,其中 A 为对称正定刚度矩阵,b 为节点载荷向量。三种方法分别对应 MATLAB 中不同的数值路径:矩阵左除(\)、显式 LU 分解(lu)和 Jacobi 迭代。目标是得到同一解向量 x,并比较残差范数、条件数与耗时。

输入 A (4×4 对称正定) b (4×1 载荷) 路径 1:矩阵左除 x = A \ b 自动选主元 + 部分选主元 路径 2:LU 分解 [L,U] = lu(A) 前代 + 回代 路径 3:Jacobi 迭代 x(k+1) = D⁻¹(b − (L+U)x(k)) 需对角占优 / 谱半径 < 1 输出 x 残差 ‖Ax−b‖ 耗时 t 选型比较维度 数值精度 计算效率 内存占用 适用规模 稳定性 可复用性

构造测试矩阵与基准解

为便于验证,先构造一个已知精确解 x_true = [1; 2; 3; 4] 的对称正定矩阵。矩阵 A 由对角占优的刚度形式生成,b = A * x_true,这样三种方法求出的 x 都应与 x_true 对比。

% 参数区
n = 4;
x_true = [1; 2; 3; 4];

% 构造对称正定矩阵(对角占优)
A = [ 10  -1   2   0;
      -1  11  -1   3;
       2  -1  10  -2;
       0   3  -2   9 ];

b = A * x_true;   % 精确右端项

% 检查对称性与正定性
fprintf('对称性误差: %.2e\n', norm(A - A', 'fro'));
fprintf('最小特征值: %.4f\n', min(eig(A)));

运行后应看到对称性误差为 0,最小特征值大于 0,说明矩阵对称正定,三种方法理论上均可收敛。

方法一:矩阵左除

MATLAB 的 \ 运算符对一般方阵自动执行带部分选主元的 LU 分解,是工程上最常用的直接解法。

tic;
x_backslash = A \ b;
t_backslash = toc;

res_backslash = norm(A * x_backslash - b);
err_backslash = norm(x_backslash - x_true);

fprintf('左除解: '); disp(x_backslash');
fprintf('残差: %.2e  误差: %.2e  耗时: %.6f s\n', ...
        res_backslash, err_backslash, t_backslash);

方法二:显式 LU 分解

当需要对同一系数矩阵 A 反复求解不同右端项时,显式 LU 分解可以复用分解结果,避免重复分解开销。

tic;
[L, U, P] = lu(A);          % P*A = L*U
y = L \ (P * b);            % 前代
x_lu = U \ y;               % 回代
t_lu = toc;

res_lu = norm(A * x_lu - b);
err_lu = norm(x_lu - x_true);

fprintf('LU解: '); disp(x_lu');
fprintf('残差: %.2e  误差: %.2e  耗时: %.6f s\n', ...
        res_lu, err_lu, t_lu);

方法三:Jacobi 迭代

Jacobi 迭代将 A 拆分为对角部分 D 和非对角部分 R,迭代格式为 x(k+1) = D⁻¹(b − R·x(k))。收敛条件为迭代矩阵谱半径小于 1,对本例的对角占优矩阵成立。

D = diag(diag(A));
R = A - D;
D_inv = inv(D);

x_jac = zeros(n, 1);
max_iter = 500;
tol = 1e-12;
res_hist = zeros(max_iter, 1);

tic;
for k = 1:max_iter
    x_jac = D_inv * (b - R * x_jac);
    res_hist(k) = norm(A * x_jac - b);
    if res_hist(k) < tol
        break;
    end
end
t_jac = toc;

res_jac = norm(A * x_jac - b);
err_jac = norm(x_jac - x_true);

fprintf('Jacobi解: '); disp(x_jac');
fprintf('迭代次数: %d\n', k);
fprintf('残差: %.2e  误差: %.2e  耗时: %.6f s\n', ...
        res_jac, err_jac, t_jac);

结果对比与选型判断

方法残差 ‖Ax−b‖解误差 ‖x−x_true‖耗时 (s)适用场景
矩阵左除 \~1e-15~1e-16最快通用首选,单次求解
显式 LU~1e-15~1e-16略慢于左除多右端项复用分解
Jacobi 迭代~1e-12~1e-13取决于迭代次数大规模稀疏矩阵
选型建议:对于中小规模稠密矩阵,优先使用 A \ b;若需对同一 A 求解多个 b,先做 lu(A) 再复用;对于大规模稀疏矩阵且对角占优时,Jacobi 或更高效的迭代法(如共轭梯度)在内存和速度上更有优势。
注意:Jacobi 迭代的收敛性依赖矩阵性质。若矩阵非对角占优或谱半径 ≥ 1,迭代可能发散。实际工程中应先检查 max(abs(eig(inv(D)*(D-A)))) 是否小于 1。