0
点赞
收藏
分享

微信扫一扫

北京科技大学 数值计算方法实验代码

草原小黄河 2022-05-01 阅读 69
其他matlab

前言:

数值计算方法实验可以使用Matlab、C/C++、Python、Java等语言进行编程,考虑到同学期数学实验课程使用Matlab进行,建议提前熟悉Matlab编程(也效率更高)。

本文中各实验使用Matlab编程实现。

据观察,不同学年实验题目会有所变化,故本文将会介绍Matlab使用的一些基础知识,帮助理解。

(本文代码已添加注释)

目录

Matlab使用入门

实验一:非线性方程求根

实验二:线性方程组求解

实验三:数值积分


Matlab使用入门

实验一:非线性方程求根

共含六个脚本(.m)文件,实现二分法、简单迭代法、牛顿迭代法

f.m

%原函数为f=exp(x)+3*x^3-2*x^2+log(x)-1;
function f=fun(x)
f=exp(x)+3*x^3-2*x^2+log(x)-1;
end

g.m

%牛顿迭代法 x1=x-f(x)/f`(x) 公式对应函数
%原函数的导数为f'(x)=exp(x)+9*x^2-4*x+1.0/x
function g = g(x)
g=x-fun(x)/(exp(x)+9*x^2-4*x+1.0/x);
end
%或使用如下公式(可以直接求导数)
%syms a;
%f = a - (fun(a)./diff(fun(a)));
%g = subs(f,x);%牛顿迭代公式

main.m

%采用两种以上不同的算法求解exp(x)+3*x^3-2*x^2+ln(x)-1=0在[0,1]范围内的一个根,要求两次迭代误差小于1.0e-4。
%计算时将main.m中代码贴入命令行窗口
x0=0;
x1=0.5;
x2=1;
eps=1.0e-4;%计算精度
first_fun(x0,x2,eps);%二分法迭代
second_fun(x1,eps);%简单迭代法迭代
third_fun(x2,eps);%牛顿迭代法迭代
%plot:生成函数图像
x=linspace(0,1);
y=exp(x)+3*x.^3-2*x.^2+log(x)-1;
plot(x,y)

first_fun.m

%二分法计算函数的零点
%函数输出根的近似值和迭代次数
function [temp,k]=first_fun(down,up,eps)
k=0;
temp=0;
while abs(up-down)>eps  %循环迭代,未达精度要求继续执行
    if k>20
        break
    end
    temp=(up+down)/2;
    y3=fun(temp);
    if y3==0
        up=temp;
        down=temp;
    elseif fun(down)*y3<0
        up=temp;
    else
        down=temp;
    end
    k=k+1;
    %test
    %disp('二分法迭代次数='),disp(k);
    %disp('近似解=');double(temp)
end
disp('二分法迭代次数='),disp(k);
disp('近似解=');double(temp)

second_fun.m

%简单迭代法计算函数的零点
%函数输出根的近似值和迭代次数
function [k,x1]=second_fun(x0,eps)
k=1;
x1=fun(x0);
%test
%disp('简单迭代法迭代次数='),disp(k);
%disp('近似解=');double(x1)
while(abs(x1-x0)>eps)
    if k>20
        break
    end    
    x0=x1;
	x1=fun(x1);
    k = k +1;
    %test
    %disp('简单迭代法迭代次数='),disp(k);
    %disp('近似解=');double(x1)
end
disp('简单迭代法迭代次数='),disp(k);
disp('近似解=');

third_fun.m

%牛顿迭代法计算函数的零点
%函数输出根的近似值和迭代次数
function [k,x1]=third_fun(x0,eps)
k=1;
x1=g(x0);
%test
%disp('牛顿迭代法迭代次数='),disp(k);
%disp('近似解='),disp(x1);
while abs(x0-x1)>eps %eval(x0-x1)
    x0=x1;
    if k>20
        break
    end
    x1 =g(x0);
    k = k+1;
    %test
    %disp('牛顿迭代法迭代次数='),disp(k);
    %disp('近似解='),disp(x1);
end
disp('牛顿迭代法迭代次数='),disp(k);
disp('近似解='),disp(x1);

实验二:线性方程组求解

共含五个脚本(.m)文件,实现高斯消元法、列主元消元法、雅可比迭代法、高斯-赛德尔迭代法

main.m

%已知如下四元一次线性方程组,请选择至少两种算法编程求解它,并分析所得到结果的合理性。
a=[14,2,1,5;8,17,2,10;4,18,3,6;12,26,11,20];%原系数矩阵
b=[1;2;3;4];%常数列向量
x0=[0;0;0;0];
eps=1.0e-6;%精度
%disp('高斯消元法')
c=gauss(a,b);
%disp('列主元消元法')
d=lzy(a,b);
%disp('Jacobi迭代法')
[e,n1]=Jacobi(a,b,x0,eps);
%disp('高斯赛德尔迭代法')
[f,n2]=gauss_seidel(a,b,x0,eps);

gauss.m

%高斯消元法求解
function x=gauss(a,b)
%参量说明:A为系数矩阵;B为常数列向量;extend为增广矩阵
%将增广矩阵化为上三角,再回带求解x
%此方法较为常规,将extend(k,k)元素乘以-extend(i,k)/extend(k,k)加到第i行
%从1:n-1列,主对角元素的以下行,通过两层循环来遍历
extend=[a,b];
n=length(b);
ra=rank(a);
rz=rank(extend);
temp=rz-ra;
if temp>0
    disp('无解');
    return;
end
if ra==rz
    if ra==n
        x=zeros(n,1);
        for p=1:n-1
            for k=p+1:n
                m=extend(k,p)/extend(p,p);
                extend(k,p:n+1)=extend(k,p:n+1)-m*extend(p,p:n+1);
            end
        end
        b=extend(1:n,n+1);
        a=extend(1:n,1:n);
        x(n)=b(n)/a(n,n);
        for q=n-1:-1:1
            x(q)=(b(q)-sum(a(q,q+1:n)*x(q+1:n)))/a(q,q);
        end
    end
end
disp('高斯消元法解得:'),disp(x);

lzy.m

%列主元消元法求解
function x=lzy(a,b)
matrix=[a,b];
[row,col]=size(matrix);
x=zeros(row,1);

%判定输入矩阵是否符合要求
if row~=col-1
    disp('请输入n*(n+1)维矩阵');
else
    for ii = 1:row-1
        %寻找主元
        max = ii;
        for jj = ii+1:row
            if abs(matrix(jj,ii)) > abs(matrix(max,ii))
                max = jj;
            end
        end
        matrix([ii,max],:) = matrix([max,ii],:);
        if matrix(ii,ii) == 0
            disp(['第',num2str(ii),'个主元素为零']);
            return;
        end
        %开始消元
        for jj = ii+1:row
            matrix(jj,:) = matrix(jj,:)-...
                matrix(jj,ii)/matrix(ii,ii)*matrix(ii,:);
        end
    end
    %消元完毕,开始回代
    if matrix(row,row)==0
        disp(['第',num2str(row),'个主元素为零']);
        return;
    end
    x(row)=matrix(row,col)/matrix(row,col-1);
    for ii=row-1:-1:1
        x(ii)=(matrix(ii,col)...
            -matrix(ii,1:row)*x)/matrix(ii,ii);
    end
end
disp('列主元消元法解得:'),disp(x);
end

Jacobi.m

%Jacobi迭代法
function [y,n]=Jacobi(a,b,x0,eps)

D=diag(diag(a));     %求对角矩阵
L=-tril(a,-1);       %求下三角矩阵
U=-triu(a,1);        %求上三角矩阵
B=D\(L+U);
f=D\b;
y=B*x0+f;
n=1;
while norm(y-x0)>=eps %用2范数去逼近
    x0=y;
    y=B*x0+f;
    n=n+1;
end
disp('Jacobi迭代法解得:'),disp(y);
disp('迭代次数:'),disp(n);

gauss_seidel.m

%高斯赛德尔迭代法
function [y,n]=gauss_seidel(a,b,x0,eps)
D=diag(diag(a));   %求对角矩阵
L=-tril(a,-1);     %求下三角阵
U=-triu(a,1);      %求上三角阵
B=(D-L)\U;
f=(D-L)\b;
y=B*x0+f;
n=1;
while norm(y-x0)>=eps  %用2范数去逼近
    x0=y;
    y=B*x0+f;
    n=n+1;
end
disp('GaussSeidel迭代法解得:'),disp(y);
disp('迭代次数:'),disp(n);

实验三:数值积分

共含四个脚本(.m)文件,实现复合梯形公式、复合Simpson公式

fun.m

%原函数
function f = fun(x)
f=(2*x-x^2+x^3+exp(x/2))^0.5;
end

main.m

%选择一种或多种数值积分方法求解下列函数在区间[0,2]内的积分值,要求精度小于1.0e-5:
%f(x) =(2*x-x^2+x^3+exp(x/2))^0.5
a=0;
b=2;
e=1.0e-5;%精度
n=1;
Simpson(a,b,n,e);
tixing(a,b,n,e) ;
%plot:生成函数图像
%x=linspace(0,2);
%y=(2*x-x.^2+x.^3+exp(x/2)).^0.5;
%plot(x,y)

tixing.m

function [h,n] = tixing(a,b,n,e) %复合梯形公式
%区间为[a,b],n为初始区间切割次数,e为精度
%先求初始步长对应的公式值
h = (b-a)/n; %步长
T1= fun(a)+fun(b);
T1=T1*h/2;
%求变步长对应的公式值
n=n+1;
h = (b-a)/n;
x=a;
T2=fun(x)+fun(b);
for k=1:n-1       
    x = x+h;
    T2 = T2+ 2*fun(x);
end
T2=T2*h/2;
while abs(T2-T1)>e %循环迭代,未达精度要求继续执行
    T1=T2;
    x=a;
    T2=fun(x)+fun(b);
    n=n+1;
    h = (b-a)/n;
    for k=1:n-1
        x = x+h;
        T2 = T2+ 2*fun(x);
    end
    T2=T2*h/2;
end
disp('复合梯形公式迭代积分值:'),disp(T2);
disp('最终步长:'),disp(h);
disp('迭代次数:'),disp(n);

Simpson.m

function [h,n] = Simpson(a,b,n,e) %复合Simpon公式
%区间为[a,b],n为初始区间切割次数,e为精度
%先求初始步长对应的公式值
h = (b-a)/n; %步长
x = a;
S1= fun(x)-fun(b);
for k=1:n        
    x = x+h/2;
    S1 = S1+ 4*fun(x);
    x=x+h/2;
    S1=S1+ 2*fun(x);
end
S1=S1*h/6;
%求变步长对应的公式值
n=n+1;
h = (b-a)/n;
x=a;
S2=fun(x)-fun(b);
for k=1:n       
    x = x+h/2;
    S2 = S2+ 4*fun(x);
    x=x+h/2;
    S2 = S2+ 2*fun(x);
end
S2=S2*h/6;
while abs(S2-S1)>e  %循环迭代,未达精度要求继续执行
    S1=S2;
    x=a;
    S2=fun(x)-fun(b);
    n=n+1;
    h = (b-a)/n;
    for k=1:n
        x = x+h/2;
        S2 = S2+ 4*fun(x);
        x=x+h/2;
        S2 = S2+ 2*fun(x);
    end
    S2=S2*h/6;
end
disp('复合Simpon公式迭代积分值:'),disp(S2);
disp('最终步长:'),disp(h);
disp('迭代次数:'),disp(n);

举报

相关推荐

0 条评论