二分法求一元函数的根--北太天元学习12
二分法求一元函数的根--北太天元学习12
我们看到很多函数具有这样的性质: 如果存在f(a) 和 f(b) 异号,那么在
a 和 b 之间存在 x , 使得 f(x) = 0 .

我们可以用下面的被称为二分法的方法求得 x 的近似值。
在第一步中,我们选择a和b的中点,称之为c。
如果 f(a) 和 f(c) 异号,那么我们用点a和c重复这个过程,
, 如果 f(c)和f(b) 异号,那么用点c和b 重复这个过程。
可以想象,在重复充分多的次数后,f的根就被确定在了一个足够小的区间内,
取这个区间的中点就是f(x)的一个足够好的近似根了。
我们还使用北太天元学习11中的例子, 求 f(x) = x^3-5x-2 的一个近似根.
clf
close all
clear all
a= -0.6;
b = -0.2;
tol=1e-4;%设定忍量
n=1;%设置索引
x(1) = (a+b)/2;
while abs(a-b)> 1e-4;%应用二分法, 等到区间长度小于或者等于给定忍量跳出循环
if sign( f(x(n)) ) * sign( b ) < 0
a = x(n);
else
b = x(n);
end
n = n + 1; ;%更新索引
x(n) = (a+b)/2;
end
x(end) %输出迭代的最后一个x点
%画出迭代过程
hold on
plot(0:length(x)-1,x, 'r-', 'LineWidth', 3);
sh = scatter(0:length(x)-1, x, 'filled');
set(sh, 'SizeData', 500)
title(['二分法迭代 x(end) = ', num2str(x(end))]);
hold off
%定义一个子函数
function y = f(x)
y = x.^3 -5*x -2;
end

我们如果想重用二分法的代码,最好还是把上面的二分法的脚本写成一个函数。
今天,我们介绍使用函数句柄作为m函数的输入参数
% 二分法求 fh(x) =0 的解 ,
% 在实数范围内求解,
% fh: 实值函数的句柄
% x0, x1: 求解的范围[x0,x1]
% ep: 误差
% Nm: 最大的二分次数
function sol = bisectionEx1(fh, x0, x1, ep, Nm)
while (sign( fh(x1) ) * sign( fh(x0) ) > 0)
fprintf('猜的初始范围不对\n');
x0 = input ('请输入x0:') ;
x1 = input ('请输入x1:\n');
end
xlist = zeros(Nm,1);
xlist (1) = x0;
for i = 2 : Nm
barx = (x1 + x0) / 2;
if sign( fh(barx) ) * sign( fh(x1) ) < 0
x0 = barx;
else
x1 = barx;
end
xlist (i) = barx;
if (abs(xlist(i) - xlist (i-1)) < ep)
break
end
end
outStr = ['二分法求得根是', num2str(barx), '']
subplot(1,2,1)
sh = scatter(xlist(1:i),log( abs( fh(xlist(1:i)) ) ) ,'filled');
set(sh, 'SizeData', 500);
for k= 1:i/2
text(xlist(k), log(abs(fh(xlist(k)))), num2str(k),'FontSize',24);
end
xlabel('x'); ylabel('log( abs( f(x) ) )')
subplot(1,2,2)
plot(1:i, xlist(1:i),'r-*','LineWidth', 3);
xlabel('迭代次数:i'); ylabel('第i次迭代后得到的x')
title(['经过', num2str(i), '次二分得到的根是', num2str(xlist(i))])
end

知识点小结:
text: 把字符串写在图中的某个位置
sign: 符号函数
子函数 function 放在脚本代码的后面
函数句柄 fh = @(t) t.^2 - 1 ; gh = @sin ; gh = @test_bi_f; % best_bi_f 是一个m函数
函数句柄作为m函数的输入参数
subplot(m,n,k) mxn子图, k