5.6 函数的零点
5.6.2 一元函数的零点
5.6.2.2 任意一元函数零点的精确解
【 * 例 5.6.2 .2-1 】通过求 的零点,综合叙述相关指令的用法。
(1)构造一个内联函数对象
被解函数 以 为自变量, 和 为数。假如在 fzero 中直接采用字符串表示被解函数,容易出错。因此先构造内联函数如下:
y=inline('sin(t)^2*exp(-a*t)-b*abs(t)','t','a','b'); %<1>
(2)作图法观察函数零点分布
a=0.1;b=0.5;t=-10:0.01:10; % 对自变量采样,采样步不宜太大。
y_char=vectorize(y); % 为避免循环,把 y 改写成适合数组运算形式。 <4>
Y=feval(y_char,t,a,b); % 在采样点上计算函数值。
clf,plot(t,Y,'r');hold on,plot(t,zeros(size(t)),'k'); % 画坐标横轴
xlabel('t');ylabel('y(t)'),hold off
图 5.6.2 .2-1 函数零点分布观察图
(3)利用 zoom 和 ginput 指令获得零点的初始近似值(在 MATLAB 指令窗中进行)
zoom on % 在 MATLAB 指令窗中运行,获局部放大图
[tt,yy]=ginput(5);zoom off % 在 MATLAB 指令窗中运行,用鼠标获 5 个零点猜测值。
图 5.6.2 .2-2 局部放大和利用鼠标取值图
tt % 显示所得零点初始猜测值(该指令可在 Notebook 中运行)。
tt =
-2.0032
-0.5415
-0.0072
0.5876
1.6561
(4)求靠近 tt(4) 的精确零点
[t4,y4,exitflag]=fzero(y,tt(4),[],a,b) %<11>
Zero found in the interval: [0.57094, 0.60418].
t4 =
0 。 5993
y4 =
0
exitflag =
1
(5)求在 tt(3)附近的精确零点
从理论分析可知, 函数的一个零点。但即便是以十分靠近该零点的 为搜索的初始值,也找不到 ,而却找到了另一个零点。原因是曲线没有穿越横轴。请看下面指令的运行结果。
[t3,y3,exitflag]=fzero(y,tt(3),[],a,b)
Zero found in the interval: [0.58266, -0.59706].
t3 =
-0.5198
y3 =
0
exitflag =
1
(6)观察 fzero 所采用的 options 缺省设置,并更改控制计算精度的相对误差设置。
op=optimset('fzero') % 提取 fzero 所采用的 options 缺省设置
op =
ActiveConstrTol: []
......
Display: 'final'
......
TolX: 2.2204e-016
TypicalX: []
op=optimset('tolx',0.01); % 把终止计算的相对误差阈值设置得较大
op.TolX % 观察新设置值。注意 TolX 字母的大小写。
ans =
0.0100
(7)利用新设置的选项参数重新求 tt(4)附近的零点,以便比较。
[t4n,y4n,exitflag]=fzero(y,tt(4),op,a,b) % 采用新的 op 设置参数。
Zero found in the interval: [0.57094, 0.60418].
t4n =
0 。 6042
y4n =
0 。 0017
exitflag =
1
〖说明〗
1、本例是采用内联函数形式求取函数零点的。
2、 若采用如下 M 函数文件(该文件必须放在搜索路径上)
[y_M.m]
function y=y_M(t,a,b)
y=sin(t).^2.*exp(-a*t)-b*abs(t);
则相应的求零点指令是 [t 4m ,y 4m ,exitflag]=fzero('y_M',tt(4),[],a,b)• 若直接用字符串表达函数,则应把被解函数自变量 t 改成 x ,参数 a 、 b 改成 P1 、 P2 。相应的具体指令如下
P1=0.1;P2=0.5;
y_C='sin(x).^2.*exp(-P1*x)-P2*abs(x)';
[t 4c ,y 4c ,exitflag]=fzero(y_C,tt(4),[],P1,P2)
5.6.3 多元函数的零点
【例 5.6.3 -1 】求解二元函数方程组 的零点。
(1)从三维坐标初步观察两函数图形相交情况
x=-2:0.05:2;y=x;[X,Y]=meshgrid(x,y); % 产生 x-y 平面上网点坐标
F1=sin(X-Y);F2=cos(X+Y);
F0=zeros(size(X));
surf(X,Y,F1),
xlabel('x'),ylabel('y'),
view([-31,62]),hold on,
surf(X,Y,F2),surf(X,Y,F0),
shading interp,
hold off
图 5.6.3 -0 两函数的三维相交图
(2)在某区域观察两函数 0 等位线的交点情况
clear;
x=-2:0.5:2;y=x;[X,Y]=meshgrid(x,y); % 产生 x-y 平面上网点坐标
F1=sin(X-Y);F2=cos(X+Y);
v=[-0.2, 0, 0.2]; % 指定三个等位值,是为了更可靠地判断 0 等位线的存在。
contour(X,Y,F1,v) % 画 F1 的三条等位线。
hold on,contour(X,Y,F2,v),hold off % 画 F2 的三条等位线。
图 5.6.3 -1 两个二元函数 0 等位线的交点图
(3)从图形获取零点的初始近似值
在图 5.6.3 -1 中,用 ginput 获取两个函数 0 等位线(即三线组中间那条线)交点的坐标。
[x0,y0]=ginput(2); % 在图上取两个点的坐标
disp([x0,y0])
-0.7926 -0.7843
0.7926 0.7843
(4)利用 fsolve 求精确解。以求( 0.7926,7843 )附近的解为例。
本例直接用字符串表达被解函数。注意:在此,自变量必须写成 x(1), x(2) 。假如写成 xy(1), xy(2) ,指令运行将出错。
fun='[sin(x(1)-x(2)),cos(x(1)+x(2))]'; %<12>
xy=fsolve(fun,[x0(2),y0(2)]) %<13>
xy =
0.7854 0.7854
(5)检验
fxy1=sin(xy(1)-xy(2));fxy2=cos(xy(1)+xy(2));disp([fxy1,fxy2])
1.0e-006 *
-0.0994 0.2019
〖说明〗指令 <12><13> 可用以下任何一组指令取代。
(A)内联函数形式指令
fun=inline('[sin(x(1)-x(2)), cos(x(1)+x(2))]', 'x'); % 项 'x' 必须有。
xy=fsolve(fun,[x0(2), y0(2)]);
(B) M 函数文件形式及指令
先用如下 fun.m 表示被解函数(并在搜索路径上)
[fun.m]
function ff=fun(x)
ff(1)=sin(x(1)-x(2));
ff(2)=cos(x(1)+x(2));
然后运行指令 xy=fsolve('fun',[x0(2),y0(2)]) 。
第四步检验中的结果表明:所找零点处的函数值小于 ,是一个十分接近零的小数。该精度由 options.TolFun 控制。 options.TolFun 的缺省值是 1.0000e-006 。它可以用下列指令看到
options=optimset('fsolve');
options.TolFun
ans =
1.0000e-006