下面的函数bisection
应该找到给定三个输入的根:函数f
和使用两个参数a
和b
定义的间隔。目的是在函数中更改a
和b
的值,以使其接近一个公共点,只要它们的符号不同即可。
当我这样调用函数时:
bisection( @(x)x-1 ,-2,3)
不返回任何输出。我在做什么错了?
function X = bisection(f,a,b)
if ge((f(a)*f(b)),0)
disp('Wrong')
return;
end
X = (a+b)/2;
while abs(X)>0.01
if f(X)*f(a)>0
X=a;
else
X=b;
end
end
答案 0 :(得分:1)
输入无限!
干得好!您已经编写了第一个(而不是最后一个,相信我)无限循环。问题是三重的。首先,您的停止条件为abs(X)
,应该为abs(f(X))
-您不必担心X
为零,而希望f(X)
为零。其次,您没有正确更新X
,因此决不会遇到中断条件(除非您很幸运地为该函数在函数零附近提供对称的a,b
边界)。您可以通过在while循环中的某处添加类似disp(f(X)); pause(0.5);
的行来轻松地看到这一点。
通常,请尝试避免使用某些明确的停止条件的无限循环。在下面的代码中,我设置了交互限制,算法将停止运行,超过该限制(捕获该条件并警告用户达到迭代限制会更加优雅...)。
function x0 = bisection(f,a,b)
assert(f(a)*f(b)<0,'Invalid f(x) range. f(a)*f(b) >= 0');
tol = 0.00001; % Tolerance
iter_limit = 10000; % Limit of number of iterations
iter = 0;
x0 = (a+b)/2; % Midpoint
while abs(f(x0)) > tol && iter < iter_limit
if f(x0)*f(a) > 0
a = x0; % Zero to the right of the midpoint
else
b = x0; % Zero to the left
end
x0 = (a+b)/2; % Recalculate midpoint
iter = iter + 1;
end
end
这应该对
没问题f = @(x)x-1;
bisection(f,-2,3);
我得到类似0.999992370 ...的结果,它在实际答案(1)的指定公差内。