数值分析算法 MATLAB 实践 线性方程组 SOR迭代法
A1 = [8 -3 2; 4 11 -1; 6 3 12]; b1 = [20; 33; 36];
w=1.2;
it_max = 1000;eps=1e-6;
[x6,t6,k6_cnt,w] = SORFunc(A1,b1,it_max,eps,w);
disp('迭代次数:k6_cnt=');
disp(k6_cnt)
disp(['方程组的解:x6 = ']);
disp(x6)
A2 = [8 -3 2; 4 11 -1; 6 3 12]; b2 = [20; 33; 36];
W=1.2;
it_max = 1000;eps=1e-6;
[x7,k7_cnt,flag]=SOR(A2,b2,eps,W,it_max);
disp('迭代次数:k7_cnt=');
disp(k7_cnt)
disp(['方程组的解:x7 = ']);
disp(x7)
x0 = [0;0;0];
A3 = [8 -3 2; 4 11 -1; 6 3 12]; b3 = [20; 33; 36];
it_max = 1000; eps=1e-6;
w0 = 0.6;
w1 = 1.1;
w2 = 1.9;
[x8_0, k8_cnt0] = SORFunmethod(A3, b3, x0, it_max, eps, w0);
[x8_1, k8_cnt1] = SORFunmethod(A3, b3, x0, it_max, eps, w1);
[x8_2, k8_cnt2] = SORFunmethod(A3, b3, x0, it_max, eps, w2);
disp('迭代次数:k8_cnt0=');
disp(k8_cnt0)
disp(['方程组的解:x8_0 = ']);
disp(x8_0)
disp('迭代次数:k8_cnt1=');
disp(k8_cnt1)
disp(['方程组的解:x8_1 = ']);
disp(x8_1)
disp('迭代次数:k8_cnt2=');
disp(k8_cnt2)
disp(['方程组的解:x8_2 = ']);
disp(x8_2)
function [x,n,flag]=SOR(A,b,eps,W,it_max)
if nargin<5
it_max=10000;
end
if nargin<4
W=1;
end
if nargin<3
eps=1e-11;
end
k=length(A);
n=0;
x=zeros(k,1);
y=zeros(k,1);
flag='OK!';
while (1)
y=x;
for i=1:k
z=b(i);
for j=1:k
if j~=i
z=z-A(i,j)*x(j);
end
end
if abs(A(i,i))<1e-10 | n==it_max
flag='fail!';
return;
end
z=z/A(i,i);
x(i)=(1-W)*x(i)+W*z;
end
if norm(y-x,inf)<eps
break;
end
n=n+1;
end
end
function [x,t,it,w] = SORFunc(A,b,I,eps,w)
tic
[n,~] = size(A);
x = zeros(n,1);
D = diag(diag(A));
L = -tril(A,-1);
U = -triu(A,1);
w_opt = 2/(1+sqrt(1-(vrho(D\(L+U)))^2));
if nargin < 4
eps = 1e-6;
w = w_opt;
end
if nargin < 5
w = w_opt;
end
Lw = (D-w*L)\((1-w)*D+w*U);
f = w*((D-w*L)\b);
x_exact = A\b;
it = 1;
for k = 1:I-1
x = Lw*x+f;
if norm(x-x_exact)>eps
it = it+1;
end
end
t = toc;
end
function [x, k] = SORFunmethod(A, b, x0, MaxIters, err, w)
n = length(x0);
x1 = x0;
x2 = zeros(n, 1);
x3 = zeros(n, 1);
r = max(abs(b - A*x1));
k = 0;
while r > err
for i = 1:n
sum = 0;
for j = 1:n
if j > i
sum = sum + A(i, j) * x1(j);
elseif j < i
sum = sum + A(i, j) * x2(j);
end
end
x2(i) = (1 - w)*x1(i) + w*(b(i) - sum) / (A(i, i) + eps);
end
for i = n:-1:1
sum = 0;
for j = 1:n
if j > i
sum = sum + A(i, j) * x3(j);
elseif j < i
sum = sum + A(i, j) * x2(j);
end
end
x3(i) = (1 - w) * x2(i) + w * (b(i) - sum) / A(i, i);
end
r = max(abs(x3 - x1));
x1 = x3;
k = k + 1;
if k > MaxIters
x = [];
return;
end
end
x = x1;
end