先放源码,后续文字即公式解释稍后发布。
1.此为函数文件,之后主文件调用此文件。
function sol = jacobi_iterative(A,b,x0,eps,maxiter)
%%
% 输入矩阵判断
[m,n] = size(A); %matrix rows = m, matrix column = n
if m ~= n
error('系数矩阵A必须是方阵,否则不能用雅可比迭代求解!')
elseif m ~= length(b) % 行数不等于b矩阵的长度
error('系数矩阵的维度与右端向量的维度不一致')
end
%%
%判断迭代矩阵是否收敛
if det(A) ~= 0 % 判断矩阵行列式不等于0,即矩阵invertible,non-singular
%获得系数矩阵的对角线向量
D = diag(A); % 此为向量
if all(D) ~= 0 % 系数矩阵对角线元素都不为零
% 核心代码,判断雅可比矩阵
J = inv(diag(D)) * (A - diag(D)); %迭代矩阵,我觉得有问题,
lamda = max(abs(eig(J))); % 求lamda,即为谱半径,特征值的绝对值最大的一个
if lamda >= 1
disp(['谱半径=',num2str(lamda)]);
error('雅可比矩阵收敛')
end
else
fprintf('无效')
end
else
error = ('系数矩阵行列式奇异,不能用雅可比矩阵')
end
%%
%输入参数控制
if nargin == 4
maxiter = 100; %如果输入参数为3,给出默认迭代次数为100
elseif nargin == 3
maxiter = 100;
eps = 1e-12; % 如果输入参数为2,给出默认精度1e-12,迭代次数100
else if nargin == 2
maxiter = 100;
eps = 1e-12;
x0 = zeros(m,1); %矩阵初始化,[m,1]的全零矩阵
else if nargin < 2 || nargin >5
error('输入参数不足或者too many');
end
end
%%
%变量初始化
iter = 0;
x_n = x0;
x_b = x0;
%%
%最核心部分
%按照雅可比迭代公式进行求解,数值逼近
for iter = 1:maxiter
x_b = x_n; %迭代序列,一次迭代完成后,所得的x_n给x_b
for i = 1:n % 雅可矩阵求x_n
S = sum(A(i,:) * x_b) - A(i,i) * x_b(i); % 求和公式,A的第i行*x_b减去i=j的情况
x_n(i) = (b(i) - S) / A(i,i); % 迭代公式
end
err = norm(b - A*x_n); %计算精度
if err <= eps %满足精度跳出循环
break;
end
end
%%
% 输出控制问题
if nargout == 1
sol.info = '迭代终止,满足精度';
sol.convergence = strcat('谱半径',num2str(lamda),'收敛到近似解');
sol.iter = iter;
sol.X = x_n;
sol.norm_error = err;
sol.success = '成功';
elseif nargout < 1
disp(x_n)
end
end
2.主函数文件,调用上述文件。
clc;clear;close all;
A = [8 -3 2;
4 11 -1;
6 3 12;];
b = [20;33;36];
%调用函数
sol = jacobi_iterative(A,b)
jacobi_iterative(A,b)
%雅可比迭代法对于下面两种矩阵不试用,原因是下面两种矩阵的迭代矩阵不收敛
% B = randn(5,1);
% C = maigc(5)