来源是西电2024年暑期数模集训《数值计算方法概述》的题目
题目:分别用逐步搜索法、二分法、比例求根法、牛顿法、弦截法求下列方程的根,并分别画出几种方法所求根的收敛速度对比图(即画出相对误差随迭代步数的变化趋势图)
1.;
2.
目录
交叉法
交叉法(Bracketing Method)是基于根的存在性定理的方法,基本算法结构是
1.已知根的存在区间(a,b),显然有f(a)f(b)<0
2.在(a,b)中选取一个c,计算f(c)的值。
c起到一个分割区间的作用,最终得到的(a,c)或(c,b)是一个更小的区间
3.我们要得到的更小的区间显然也需要是个有根区间,因此要满足区间两端函数值异号。显然a,b中必然有且仅有一个与c异号,有且仅有一个与c同号;(这里只考虑c≠0,c若为0则直接是所求的解)。
具体实现:①if f(c)==0;若为0,则x=c。
②if f(a)f(c)<0;若异号,则小区间位(a,c),反之为(c,b)。
4.得到的小区间成为新的(a,b),回到第2步循环
1.逐步搜索法
老师在这里讲的逐步搜索法似乎与本人在《数值计算方法》课程上学的有所不同,是把逐步搜索法归于交叉法中。交叉法中c取a+h即可
而在《数值计算方法》中学习的逐步搜索法是一种求解有根区间的方法,是交叉法的前置步骤。
本题所指代的逐步搜索法的代码如下
% 逐步搜索法求根
function c=step_srch(a,b,n,f)
c=a;
for i=0:1:n
if f(c)==0.0
break
elseif f(c)*f(a)<0
b=c;
else
a=c;
end
if(n~=i)
h=(b-a)/(n-i);
c=a+h;
end
end
end
定义了一个求根函数,输入分别为区间边界a,b,迭代次数n,函数句柄f;返回f(x)=0的根。
2.二分法
交叉法中的c取(a+b)/2即可,代码如下。
% 二分法
function c=bisect(a,b,n,f)
c=(a+b)/2;
for i=0:1:n
if f(c)==0.0
break
elseif f(c)*f(a)<0
b=c;
else
a=c;
end
c=(a+b)/2;
end
end
同样定义了一个求根函数,输入分别为区间边界a,b,迭代次数n,函数句柄f;返回f(x)=0的根。
3.比例求根法
交叉法中的c取a-f(a)(a-b)/(f(a)-f(b))即可,代码如下。
% 比例求根法
function c=proportionality(a,b,n,f)
c=a-f(a)*(a-b)/(f(a)-f(b));
for i=0:1:n
if f(c)==0.0
break
elseif f(c)*f(a)<0
b=c;
else
a=c;
end
c=a-f(a)*(a-b)/(f(a)-f(b));
end
end
同样定义了一个求根函数,输入分别为区间边界a,b,迭代次数n,函数句柄f;返回f(x)=0的根。
迭代法
一般而言,迭代法或者函数迭代法,是改写原方程f(x)=0为x=g(x),形式上成为一个x关于x的关系式,也成为了迭代法中的递推公式。
但接下来的两种方法与函数迭代法本身的定义还是有所区别。
4.牛顿迭代法
牛顿法(Newton-Raphson Method)又称切线法,如切线一般的逼近最终的解。
其递推公式为。
若求解的是m重根,应当使用修正的公式
特点:只需要一个初始值x0;需要知道原函数及其导数(导数可以是解析的也可以是数值的)。
% 牛顿迭代法
% 求解的根的重数为m
function x=Newton_Raphson(x0,n,f,fl,m)
x=x0;
for i=0:1:n
x=x-m*f(x)/(fl(x));
end
end
定义了一个求根函数,输入分别为初始值x0,迭代次数n,函数句柄f,fl,重根次数m;返回f(x)=0的根。
5.弦截法
弦截法(Secant Method)又称割线法,用割线斜率替代了牛顿法中的导数。
其递推公式
特点:需要使用两个初始值;不需要知道导数。
% 弦截法
function x2=Secant(x0,x1,n,f)
for i=0:1:n
x2=x1-f(x1)*(x1-x0)/(f(x1)-f(x0));
x0=x1;
x1=x2;
end
end
定义了一个求根函数,输入分别为初始值x0,x1,迭代次数n,函数句柄f;返回f(x)=0的根。
完整代码
代码写的是实时脚本,贴的是另存为的.m脚本,能跑就行。
需要说明的是,在使用牛顿法解第二个方程时,按1重根即m=1计算效果却是最好的,因此代码中代入的是1。
另外就是里面使用了eval函数,以减少代码长度和可读性。
%% 数值计算方法概述作业
%% 题目
% 分别用逐步搜索法、二分法、比例求根法、牛顿法、弦截法求下列方程的根,并分别画出几种方法所求根的收敛速度对比图(即画出相对误差随迭代步数的变化趋势图)
%
% 1.$f(x)=\cos x-x$
%
% 2.$f(x)=x^{12}-1$
%% 解答
clear,clc,close
% 一、定义部分
% 定义函数
% $$f_1(x)=\cos x-x$$
%
% $$f_2(x)=x^{12}-1$$
f1=@(x) cos(x)-x;
f2=@(x) x^12-1;
% 定义函数的导数
% 牛顿迭代法需要使用
%
% $$f'_1(x)=-\sin x-1$$
%
% $$f'_2(x)=12x^{11}$$
fl1=@(x) -sin(x)-1;
fl2=@(x) 12*x^11;
% 精确值
x_1=0.739085;
x_2=1;
%%
% 预分配求出根的空间
for i=1:5
eval(['x',num2str(i),'_1','=zeros(1,20);'])
eval(['x',num2str(i),'_2','=zeros(1,20);'])
end
% 二、求解与绘图
for n=1:1:100%迭代次数从1~20
% 求解不同迭代次数n下的方程一的解
x1_1(n)=step_srch(0.5,1,n,f1);
x2_1(n)=bisect(0.5,1,n,f1);
x3_1(n)=proportionality(0.5,1,n,f1);
x4_1(n)=Newton_Raphson(0.7,n,f1,fl1,1);
x5_1(n)=Secant(0.5,1,n,f1);
% 求解不同迭代次数n下的方程二的解
x1_2(n)=step_srch(0.8,1.2,n,f2);
x2_2(n)=bisect(0.8,1.2,n,f2);
x3_2(n)=proportionality(0.8,1.2,n,f2);
x4_2(n)=Newton_Raphson(1.1,n,f2,fl2,1);%令m=1效果最佳
x5_2(n)=Secant(0.8,1.2,n,f2);
end
% 在y轴为对数的半对数坐标系中绘图
N=1:1:n;
for i=1:5
figure(1)
eval(['er',num2str(i),'_1','=abs((x',num2str(i),'_1-x_1)/x_1);'...
'semilogy(N,er',num2str(i),'_1)'])
hold on
figure(2)
eval(['er',num2str(i),'_2','=abs((x',num2str(i),'_2-x_2)/x_2);'...
'semilogy(N,er',num2str(i),'_2)'])
hold on
end
figure(1)
title("cos(x)=x")
legend("逐步搜索法","二分法","比例求根法","牛顿迭代法","弦截法")
hold off
figure(2)
title("x^{12}=1")
legend("逐步搜索法","二分法","比例求根法","牛顿迭代法","弦截法")
hold off
% 三、求根函数的定义
% 1.逐步搜索法求根
function c=step_srch(a,b,n,f)
c=a;
for i=0:1:n
if f(c)==0.0
break
elseif f(c)*f(a)<0
b=c;
else
a=c;
end
if(n~=i)
h=(b-a)/(n-i);
c=a+h;
end
end
end
% 2.二分法
function c=bisect(a,b,n,f)
c=(a+b)/2;
for i=0:1:n
if f(c)==0.0
break
elseif f(c)*f(a)<0
b=c;
else
a=c;
end
c=(a+b)/2;
end
end
% 3.比例求根法
function c=proportionality(a,b,n,f)
c=a-f(a)*(a-b)/(f(a)-f(b));
for i=0:1:n
if f(c)==0.0
break
elseif f(c)*f(a)<0
b=c;
else
a=c;
end
c=a-f(a)*(a-b)/(f(a)-f(b));
end
end
% 4.牛顿迭代法
% m为求解的根的重数
function x=Newton_Raphson(x0,n,f,fl,m)
x=x0;
for i=0:1:n
x=x-m*f(x)/(fl(x));
end
end
% 5.弦截法
function x2=Secant(x0,x1,n,f)
for i=0:1:n
x2=x1-f(x1)*(x1-x0)/(f(x1)-f(x0));
x0=x1;
x1=x2;
end
end