二分法求解非线性方程

  在所有数值方法中,二分法是求解非线性方程最直观、最简单的方法。二分法是以连续函数的介值定理为基础建立的。由介值定理可知,如果函数$f(x)$在区间$[a,b]$上连续,同时$f(a)f(b)<0$,即$f(a)$和$f(b)$符号相反,那么$f(x)$在区间$[a,b]$内一定有实根。

原理

  二分法的基本思想为:用对分区间的思路根据分点处函数$f(x)$的符号逐步将有限区间缩小使在足够小的区间内,分点与理论上的根之间距离足够小,继而用分点的值近似理论上的根。

函数ditomy.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function [x0,fval] = ditomy(fun,a,b,D)
%ditomy.m函数为二分法求解非线性方程
fa = feval(fun,a); %计算a点函数值
fb = feval(fun,b); %计算b点函数值
if fa*fb > 0;
error('此方程无解');
end
if nargin < 3; %检查输入参数个数
error('a与b将被重定义');
elseif nargin == 3;
D = 1e-6; %设置D的缺省值
end
if fa == 0; %检查a点函数值是否为0
m = a;
fm = fa;
elseif fb == 0; %检查b点函数值是否为0
m = b;
fm = fb;
else
while abs(b-a) > D; %控制二分法结束条件
m = [a+b]/2; %二分区间端点
fm = feval(fun,m); %计算中点的函数值
if fa*fm > 0; %条件
a = m; %端点更新
fa = fm; %端点函数更新
elseif fb*fm > 0; %条件
b = m; %端点更新
fb = fm; %端点函数更新
else
break
end
end
end
x0 = m;
if nargout == 2;
fval = fm; %根据输出个数赋值
end

举个栗子

用二分法求方程$f(x)=x^3cos(x)+2x^3-2sinx$在区间$[1,3]$内的根。

1
2
3
4
5
6
7
8
9
10
%非线性方程的m文件fun.m
function f = fun(x)
f = x^3*cos(x)+2*x^2-2sin(x);

%调用编写的二分函数求解非线性方程
[x0,fval] = ditomy('fun',1,3);

%运行结果
%x0 = 2.3978
%fval = -4.1724e-06

  
参考资料
MATLABR2013a求解数学问题