根据给定函数 F(x) 的中间值定理,我应该写一个函数,它得到一个数学函数,两个数字a和b,以及一个误差范围,它给出数字x作为输出,其函数的值接近0到epsilon。例子:
>>> find_root(lambda x : x - 1 , -10, 10)
1.0009765625
>>> find_root(lambda x : x**2 , -10, 10)
>>> #returned None
这是我到目前为止编写的代码,我认为我走在正确的道路上,但是我不知道要循环什么,我没有得到这段代码的正确答案。那么我应该解决什么问题呢?
def find_root(f, a, b, EPS=0.001):
if (f(a)*f(b))<0:
for i in range(a,b):
if f(i)<EPS:
return (i)
else:
return (None)
使用二分法:
def find_root(f, a, b, EPS=0.0001):
if f(a)==0 : return a
if f(b)==0 : return b
if f(a)*f(b)>0 : return None
c=(a+b)/2
while(abs(f(c))>EPS) :
if f(a)*f(c)<0 : b=c
else : a=c
c=(a+b)/2
return c
最简单的解决方案是这样的:
def find_root(f, a, b, EPS=0.001):
#assuming a < b
x = a
while x <= b:
if abs(f(x)) < EPS:
return x
else:
x += EPS
结果:
>>>find_root(lambda x: x-1, -10, 10)
0.9999999999998982
>>>find_root(lambda x: x-1, -10, -2)
None
如您所知,如果初始值均为正值或均为负值,则过程无法找到根。
以下是有关如何使用二进制搜索实现它的建议,以加快该过程:
def find_root(f, a, b, EPS=0.001):
fa = f(a)
fb = f(b)
if fa*fb > 0: # both positive or both negative
return None
while abs(fa) > EPS and abs(fb) > EPS:
c = (a+b)/2.0
fc = f(c)
if fa*fc >= 0:
a = c
fa = fc
else:
b = c
fb = fc
if abs(fa) <= EPS:
return a
else:
return b
find_root(lambda x : x-1, -10, 10)
的返回值为 1.0009765625。