我目前正在进行的一个项目是将两种不同的数值方法(直接和迭代)与系统的实际解析解进行比较,其中每种方法针对两个不同的矩阵大小。下面包含的第一个.m文件提供了一个三对角矩阵求解器的实现,其中main
函数绘制了两种不同大小的三对角矩阵的解:2500x2500矩阵和50x50矩阵。
function main
n=50;
for i=1:2
di=2*ones(n,1);
up=-ones(n,1);
lo=-ones(n,1);
b=ones(n,1)/(n*n);
[subl,du,supu]=tridiag_factor(lo,di,up);
usol = tridiag_solve(subl,du,supu,b);
%figure(i)
plot(usol);
hold on;
title(['tridiag ' num2str(n) ''])
n=2500;
end
function [subl,du,supu]=tridiag_factor(subd,d,supd)
n=length(d);
for i=1:n-1
subd(i)=subd(i)/d(i);
d(i+1)=d(i+1)-subd(i)*supd(i);
end
subl=subd; supu=supd; du=d;
function x = tridiag_solve(subl,du,supu,b)
% forward solve
n=length(b); z=b;
z(1)=b(1);
for i=2:n
z(i)=b(i)-subl(i)*z(i-1);
end
% back solve
x(n)=z(n);
for i=n-1:-1:1
x(i)=(z(i)-supu(i)*x(i+1))/du(i);
end
在绘制第一个usol
之后,我包含了一个hold on
语句,这样我就可以在for
循环的第二次迭代期间捕获同一图形上的第二个usol
。下一段代码是Jacobi
方法,它迭代地求解一个三对角矩阵的系统。在我的例子中,我构造了两个不同大小的三对角矩阵,我将在这段代码之后提供它们:
function [xf,r] = jacobi(A,b,x,tol,K)
%
% The function jacobi applies Jacobi's method to solve A*x = b.
% On entry:
% A coefficient matrix of the linear system;
% b right-hand side vector of the linear system;
% x initial approximation;
% eps accuracy requirement: sx=top when norm(dx) < eps;
% K maximal number of steps allowed.
% On return:
% x approximation for the solution of A*x = b;
% r residual vector last used to update x,
% if success, then norm(r) < eps.[
%
n = size(A,1);
fprintf('Running the method of Jacobi...\n');
for k = 1:K
% r = b - A*x;
for i=1:n
sum=0;
for j = 1:n
if j~=i
sum=sum+A(i,j)*x(j);
end
end
x(i)=(b(i)-sum)/(A(i,i));
end;
k=k+1;
r = b - A*x;
% fprintf(' norm(r) = %.4e\n', norm(r));
if (norm(r) < tol)
fprintf('Succeeded in %d steps\n', k);
return;
end;
end
fprintf('Failed to reached accuracy requirement in %d steps.\n', K);
xf=x;
%r(j) = r(j)/A(j,j);
%x(j) = x(j) + r(j);
现在,最后,下面是我希望在两个jacobi
函数调用中使用的两个三对角矩阵的代码(以及与相应矩阵对应的每个系统的其他相关信息):
% First tridiagonal matrix
n=50;
A_50=full(gallery('tridiag', n, -1, 2, -1));
% Second tridiagonal matrix
n=2500;
A_2500=full(gallery('tridiag', n, -1, 2, -1));
K=10000;
tol=1e-6;
b_A50=ones(length(A_50), 1);
for i=1:length(A_50)
b_A50(i,1)=0.0004;
end
x_A50=ones(length(A_50),1);
b_A2500=ones(length(A_2500), 1);
for i=1:length(A_2500)
b_A2500(i,1)= 1.6e-7;
end
x_A25000=ones(length(A_2500),1);
正如问题标题中所述,我需要将jacobi(A_50,b_A50,x_A50,tol,K)
、jacobi(A_2500,b_A2500,x_A25000,tol,K)
和数学函数y=@(x) -0.5*(x-1)*x
生成的向量以及第一段代码中显示的main
函数生成的两个usol
(用于n=50
和n=2500
)绘制在同一图上,但由于向量的长度不同,我没有运气。我知道这可能是一个简单的解决办法,但当然,我的初学者的matlab技能还不够。
注意:我知道x_A50
和x_A2500
对于x来说是微不足道的选择,但我想在请求帮助的同时,最好现在保持简单,不要在我的代码中制造更多的问题。
1条答案
按热度按时间qv7cva1a1#
1.在MatLab中,发送到相同
plot
的轨迹必须具有相同的长度。1.我只为
jacobi
函数的三对角线和结果跟踪分配了一个包含所有跟踪的变量。1.我已将2500缩短到250,原因是2500与50相比,三个记录道和较短的
jacobi
与最后一个记录道相比是如此平坦,以至于必须使用分贝标度才能在您询问的同一图形窗口中找到它们。1.首先生成所有数据,然后绘制所有数据。
因此,下面的脚本在同一个图中绘制所有轨迹:
如上所述,人们必须放大才能找到一些痕迹
组合非常小的道和大的道的一种方法是使用Y对数刻度