当前位置: 首页 > news >正文

MATLAB 解线性方程组的迭代法

MATLAB 中解线性方程组 \(Ax = b\) 的迭代法有多种实现方式。下面我将详细介绍常用的迭代方法、MATLAB 内置函数和自定义实现。

1. 迭代法简介

方法 特点 收敛条件
雅可比迭代 简单,并行性好 严格对角占优
高斯-赛德尔 收敛通常比雅可比快 严格对角占优
逐次超松弛 引入松弛因子加速 0 < ω < 2

2. MATLAB 内置函数

2.1 直接使用反斜杠(推荐优先尝试)

% 对于一般线性方程组
A = [4, -1, 0; -1, 4, -1; 0, -1, 4];
b = [1; 2; 3];
x = A \ b;  % 直接法,通常最有效

2.2 迭代法求解器

% 使用 bicgstab(双共轭梯度稳定法)
x = bicgstab(A, b);% 使用 gmres(广义最小残差法)
x = gmres(A, b);% 使用 pcg(预处理共轭梯度法,对称正定矩阵)
x = pcg(A, b);

3. 自定义迭代法实现

3.1 雅可比迭代法 (Jacobi)

function [x, iter, rel_err] = jacobi(A, b, x0, max_iter, tol)% 雅可比迭代法求解 Ax = b% 输入:%   A: 系数矩阵 (n×n)%   b: 右端向量 (n×1)%   x0: 初始猜测 (n×1)%   max_iter: 最大迭代次数%   tol: 容许误差% 输出:%   x: 解向量%   iter: 实际迭代次数%   rel_err: 相对误差历史n = length(b);x = x0;x_new = zeros(n, 1);rel_err = zeros(max_iter, 1);D = diag(diag(A));       % 对角线部分R = A - D;              % 非对角线部分for iter = 1:max_iter% 雅可比迭代公式: x_new = D^{-1}(b - R*x)x_new = (b - R * x) ./ diag(D);% 计算相对误差rel_err(iter) = norm(x_new - x, 2) / norm(x_new, 2);% 检查收敛if rel_err(iter) < tolx = x_new;rel_err = rel_err(1:iter);fprintf('Jacobi 迭代在 %d 次后收敛\n', iter);return;endx = x_new;endwarning('Jacobi: 达到最大迭代次数 %d 但未收敛\n', max_iter);rel_err = rel_err(1:iter);
end

3.2 高斯-赛德尔迭代法 (Gauss-Seidel)

function [x, iter, rel_err] = gauss_seidel(A, b, x0, max_iter, tol)% 高斯-赛德尔迭代法求解 Ax = b% 输入输出同雅可比法n = length(b);x = x0;rel_err = zeros(max_iter, 1);L = tril(A, -1);  % 严格下三角D = diag(diag(A)); % 对角线U = triu(A, 1);    % 严格上三角for iter = 1:max_iterx_old = x;% 高斯-赛德尔迭代: (L+D)x_new = b - U*xfor i = 1:nsum1 = 0;for j = 1:i-1sum1 = sum1 + A(i, j) * x(j);endsum2 = 0;for j = i+1:nsum2 = sum2 + A(i, j) * x_old(j);endx(i) = (b(i) - sum1 - sum2) / A(i, i);end% 计算相对误差rel_err(iter) = norm(x - x_old, 2) / norm(x, 2);% 检查收敛if rel_err(iter) < tolrel_err = rel_err(1:iter);fprintf('Gauss-Seidel 迭代在 %d 次后收敛\n', iter);return;endendwarning('Gauss-Seidel: 达到最大迭代次数 %d 但未收敛\n', max_iter);rel_err = rel_err(1:iter);
end

3.3 逐次超松弛迭代法 (SOR)

function [x, iter, rel_err] = sor(A, b, x0, omega, max_iter, tol)% 逐次超松弛迭代法 (SOR) 求解 Ax = b% 输入:%   omega: 松弛因子 (0 < omega < 2)% 其他参数同前n = length(b);x = x0;rel_err = zeros(max_iter, 1);if omega <= 0 || omega >= 2error('松弛因子必须在 (0, 2) 范围内');endfor iter = 1:max_iterx_old = x;for i = 1:nsigma = 0;for j = 1:nif j ~= isigma = sigma + A(i, j) * x(j);endend% SOR 迭代公式x(i) = (1 - omega) * x(i) + omega * (b(i) - sigma) / A(i, i);end% 计算相对误差rel_err(iter) = norm(x - x_old, 2) / norm(x, 2);% 检查收敛if rel_err(iter) < tolrel_err = rel_err(1:iter);fprintf('SOR (ω=%.2f) 在 %d 次后收敛\n', omega, iter);return;endendwarning('SOR: 达到最大迭代次数 %d 但未收敛\n', max_iter);rel_err = rel_err(1:iter);
end

4. 测试示例

4.1 定义测试问题

% 创建严格对角占优矩阵(保证迭代法收敛)
n = 100;
A = diag(4 * ones(n, 1)) + diag(-1 * ones(n-1, 1), 1) + diag(-1 * ones(n-1, 1), -1);% 生成精确解
x_exact = ones(n, 1);% 计算右端项
b = A * x_exact;% 设置初始猜测和参数
x0 = zeros(n, 1);
max_iter = 1000;
tol = 1e-6;
omega = 1.2;  % SOR 松弛因子

4.2 运行不同迭代法

% 雅可比迭代
tic;
[x_jacobi, iter_j, err_j] = jacobi(A, b, x0, max_iter, tol);
time_j = toc;% 高斯-赛德尔迭代
tic;
[x_gs, iter_gs, err_gs] = gauss_seidel(A, b, x0, max_iter, tol);
time_gs = toc;% SOR 迭代
tic;
[x_sor, iter_sor, err_sor] = sor(A, b, x0, omega, max_iter, tol);
time_sor = toc;% 直接法对比
tic;
x_direct = A \ b;
time_direct = toc;

4.3 比较结果

% 计算误差
err_jacobi = norm(x_jacobi - x_exact, 2);
err_gs = norm(x_gs - x_exact, 2);
err_sor = norm(x_sor - x_exact, 2);
err_direct = norm(x_direct - x_exact, 2);% 显示结果
fprintf('\n=========== 迭代法性能比较 ===========\n');
fprintf('方法\t\t迭代次数\t时间(s)\t\t相对误差\n');
fprintf('--------------------------------------------\n');
fprintf('Jacobi\t\t%d\t\t%.4f\t\t%.2e\n', iter_j, time_j, err_jacobi);
fprintf('Gauss-Seidel\t%d\t\t%.4f\t\t%.2e\n', iter_gs, time_gs, err_gs);
fprintf('SOR (ω=%.1f)\t%d\t\t%.4f\t\t%.2e\n', omega, iter_sor, time_sor, err_sor);
fprintf('直接法\\\t\t-\t\t%.4f\t\t%.2e\n', time_direct, err_direct);% 绘制收敛历史
figure;
semilogy(1:length(err_j), err_j, 'b-', 'LineWidth', 2, 'DisplayName', 'Jacobi');
hold on;
semilogy(1:length(err_gs), err_gs, 'r-', 'LineWidth', 2, 'DisplayName', 'Gauss-Seidel');
semilogy(1:length(err_sor), err_sor, 'g-', 'LineWidth', 2, 'DisplayName', sprintf('SOR (ω=%.1f)', omega));
grid on;
xlabel('迭代次数');
ylabel('相对误差 (log scale)');
title('迭代法收敛历史比较');
legend('Location', 'best');

5. 实用技巧

5.1 预处理技术

% 对角预处理(简单但有效)
D = diag(diag(A));
A_precond = D^(-1/2) * A * D^(-1/2);
b_precond = D^(-1/2) * b;% 使用预处理
x = jacobi(A_precond, b_precond, x0, max_iter, tol);

5.2 收敛性检查函数

function is_convergent = check_convergence(A, method)% 检查迭代法收敛性% method: 'jacobi' 或 'gauss_seidel'n = size(A, 1);if strcmp(method, 'jacobi')D = diag(diag(A));R = A - D;T = -D \ R;  % 迭代矩阵elseif strcmp(method, 'gauss_seidel')L = tril(A, -1);D = diag(diag(A));U = triu(A, 1);T = -(D + L) \ U;  % 迭代矩阵elseerror('未知方法');endrho = max(abs(eig(T)));  % 谱半径is_convergent = (rho < 1);fprintf('谱半径 ρ = %.4f, 收敛: %s\n', rho, string(is_convergent));
end

5.3 自适应 SOR

function [x, omega_opt] = adaptive_sor(A, b, x0, max_iter, tol)% 自适应选择最优松弛因子n = length(b);omegas = 1.0:0.1:1.9;  % 测试不同的 ωbest_iter = inf;omega_opt = 1.0;% 测试不同 ωfor omega = omegas[~, iter, ~] = sor(A, b, x0, omega, max_iter, tol);if iter < best_iterbest_iter = iter;omega_opt = omega;endendfprintf('最优松弛因子: ω = %.2f\n', omega_opt);[x, ~, ~] = sor(A, b, x0, omega_opt, max_iter, tol);
end

参考代码 matlab解线性方程组的迭代法 www.youwenfan.com/contentcnt/122244.html

6. 性能优化建议

  1. 向量化计算:避免内层循环
  2. 稀疏矩阵:使用 sparse 存储
  3. 预处理:使用 icholilu 预处理
  4. 并行计算:使用 parfor 加速
% 向量化的雅可比迭代
function x = jacobi_vectorized(A, b, x0, max_iter, tol)n = length(b);x = x0;d = diag(A);for iter = 1:max_iterx_new = x + (b - A * x) ./ d;  % 向量化计算if norm(x_new - x) / norm(x_new) < tolx = x_new;break;endx = x_new;end
end

7. 完整使用示例

% 1. 准备问题
n = 500;
A = gallery('poisson', sqrt(n));  % 生成泊松问题矩阵
b = rand(n, 1);
x0 = zeros(n, 1);
max_iter = 1000;
tol = 1e-8;% 2. 检查收敛性
fprintf('检查收敛性:\n');
check_convergence(A, 'jacobi');
check_convergence(A, 'gauss_seidel');% 3. 求解
[x_j, iter_j] = jacobi(A, b, x0, max_iter, tol);
[x_gs, iter_gs] = gauss_seidel(A, b, x0, max_iter, tol);
[x_sor, omega] = adaptive_sor(A, b, x0, max_iter, tol);% 4. 验证结果
residual_j = norm(b - A * x_j) / norm(b);
residual_gs = norm(b - A * x_gs) / norm(b);
residual_sor = norm(b - A * x_sor) / norm(b);fprintf('\n残差:\n');
fprintf('Jacobi: %.2e\n', residual_j);
fprintf('Gauss-Seidel: %.2e\n', residual_gs);
fprintf('SOR: %.2e\n', residual_sor);

总结

情况 推荐方法
小规模稠密矩阵 直接法 A\b
大规模稀疏矩阵 预处理共轭梯度法 pcg
非对称矩阵 GMRES 或 BiCGSTAB
教学/简单问题 雅可比或高斯-赛德尔
需要最佳收敛速度 SOR 或 自适应 SOR

这些 MATLAB 实现可以直接使用,也可以根据具体问题调整参数。

http://www.jsqmd.com/news/660808/

相关文章:

  • FPGA实战:3级CIC滤波器Verilog代码详解(附仿真测试技巧)
  • 终极抖音无水印下载器:3分钟掌握批量下载与直播录制完整指南
  • 2026年康养房机构推荐及选购参考/别墅康养房,医养康养房,洋房康养房避暑房,养老房 - 品牌策略师
  • 5G NR CSI-RS配置避坑指南:从TRS到波束管理,手把手教你避开RRC信令里的那些‘坑’
  • 网易云音乐NCM格式解密:3步解锁加密音乐的完整指南
  • CMS网站模板选型:主流系统、分类对比与使用注意事项
  • 如何评估主流分析仪器公司,细聊产品口碑和售后服务该如何选择 - mypinpai
  • 基于Python的热门网游推荐网站毕设
  • 5分钟掌握APK Installer:如何在Windows上轻松安装安卓应用?
  • 10个Illustrator脚本:彻底改变你的设计工作流,提升300%效率的终极方案
  • 如何评估花纹钢格板、不锈钢钢格板厂家,哪家性价比高 - 工业品网
  • 基于Python的物流信息管理系统毕设
  • 实战指南:Java应用通过JDBC直连华为云GaussDB(for openGauss)
  • B站CC字幕下载终极指南:3分钟学会免费提取B站视频字幕的完整方法
  • 将目标元素移动到数组开头,其余元素保持原顺序的方法
  • 从‘路由聚合’到‘超网’:一次讲透CIDR如何拯救了濒临枯竭的IPv4
  • 从Arduino到PCB:手把手复现TCD132D线性CCD扫描相机(附完整代码与避坑指南)
  • 如何快速获取海量ASMR资源:asmr-downloader下载工具完整指南
  • 基于Python的画师约稿平台毕业设计源码
  • Digital:从零开始掌握开源数字电路设计与模拟的终极教程
  • AI Agent 的“记忆”到底怎么建?从架构到测试,一篇讲透
  • 为什么92%的AI编程工具跳过兼容性校验?深度拆解LLM代码生成器的语义鸿沟与4层静态+动态混合检测架构
  • C++计算直线倾斜角与方位角
  • 艾尔登法环存档复制器:三步安全迁移游戏角色的终极指南
  • 3步解锁音乐自由:这款开源工具让你真正拥有音频文件
  • 别再只盯着AUC了!从点击率到转化率模型,聊聊AUC指标在广告推荐中的那些‘坑’
  • 如何高效使用开源电路板查看器:专业用户的实用指南
  • Cursor AI Pro破解终极指南:如何简单快速绕过试用限制免费使用
  • 【实战】RuoYi-Vue开发环境一站式部署:从零到一启动前后端分离项目
  • 别再死记硬背了!用‘阅览室占座’和‘独木桥过河’两个生活例子,彻底搞懂操作系统的P、V操作