Python 查找函数的根/零
我试图通过使用二分法找到函数的根,说明:Python 查找函数的根/零,python,function,root,Python,Function,Root,我试图通过使用二分法找到函数的根,说明: if f(a)*f(b) < 0 then a root exists, then you repeat with f(a)*f(c)<0 where c = (a+b)/2 但我不知道如何修复代码,使其正常工作。 这是我的代码,但它不能正常工作 from scipy import * from numpy import * def rootmethod(f, a, b, tol): x = a fa
if f(a)*f(b) < 0 then a root exists,
then you repeat with f(a)*f(c)<0 where c = (a+b)/2
但我不知道如何修复代码,使其正常工作。
这是我的代码,但它不能正常工作
from scipy import *
from numpy import *
def rootmethod(f, a, b, tol):
x = a
fa = sign(eval(f))
x = b
fb = sign(eval(f))
c = a + b
iterations = 0
if fa == 0:
return a
if fb == 0:
return b
calls = 0
fx = 1
while fx != 0:
iterations = iterations + 1
c *= 0.5
x = a + c
fc = sign(eval(f))
calls = calls + 1
if fc*fa >= 0:
x = a
fx = sign(eval(f))
if fc == 0 or abs(sign(fc)) < eps:
fx = sign(eval(f))
return x, iterations, calls
print rootmethod("(x-1)**3 - 1", 1, 3, 10*e-15)
新编辑。。但仍然不起作用
if fa*fb < 0:
while fx != 0:
iterations = iterations + 1
c = (a + b)/2.0
x = c
fc = sign(eval(f))
calls = calls + 1
if fc*fa >= 0:
x = c
fx = sign(eval(f))
if fc == 0 or abs(sign(fc)) < tol:
fx = sign(eval(f))
return x, iterations, calls
编辑:将方法描述中的c=a+b*2更改为c=a+b/2。我认为您的一个问题是:
x = a + c
由于c=a+b*.5,您不需要在此处添加a
更新
您似乎没有检查fa*fb是否开始小于0,而且我也看不到您在哪里缩小了界限:您应该在循环中将a或b重新分配给c,然后重新计算c
代码自从我上次玩python已经有一段时间了,所以请对此持保留态度^_^
x = a
fa = sign(eval(f))
x = b
fb = sign(eval(f))
iterations = 0
if fa == 0:
return a
if fb == 0:
return b
calls = 0
fx = 1
while fa != fb:
iterations += 1
c = (a + b)/2.0
x = c
fc = eval(f)
calls += 1
if fc == 0 or abs(fc) < tol:
#fx = fc not needed since we return and don't use fx
return x, iterations, calls
fc = sign(fc)
if fc != fa:
b = c
fb = fc
else
a = c
fa = fc
#error because no zero is expected to be found
我相信您的循环在伪代码中应该是这样的,并且省略一些检查:
before loop:
a is lower bound
b is upper bound
Establish that f(a) * f(b) is < 0
while True:
c = (a+b)/2
if f(c) is close enough to 0:
return c
if f(a) * f(c) > 0:
a = c
else
b = c
换句话说,如果中点不是答案,那么根据其符号将其作为新端点之一。坦白地说,您的代码有点乱。这里有一些有效的方法。阅读循环中的注释。 顺便说一句,给定函数的解是2,而不是3.75
from scipy import *
from numpy import *
def rootmethod(f, a, b, tol):
x = a
fa = sign(eval(f))
x = b
fb = sign(eval(f))
c = a + b
iterations = 0
if fa == 0:
return a
if fb == 0:
return b
calls = 0
fx = 1
while 1:
x = (a + b)/2
fx = eval(f)
if abs(fx) < tol:
return x
# Switch to new points.
# We have to replace either a or b, whichever one will
# provide us with a negative
old = b # backup variable
b = (a + b)/2.0
x = a
fa = eval(f)
x = b
fb = eval(f)
# If we replace a when we should have replaced b, replace a instead
if fa*fb > 0:
b = old
a = (a + b)/2.0
print rootmethod("(x-1)**3 - 1", 1, 3, 0.01)
请注意,该代码有一个由舍入错误引起的简单缺陷
a=0.015707963267948963
b=0.015707963267948967
c=(a+b)*.5
c又变成b了,快看!。
你可以在无限循环中结束
如果公差非常小,如1e-16
def FindRoot( fun, a, b, tol = 1e-16 ):
a = float(a)
b = float(b)
assert(sign(fun(a)) != sign(fun(b)))
c = (a+b)/2
while math.fabs(fun( c )) > tol:
if a == c or b == c:
break
if sign(fun(c)) == sign(fun(b)):
b = c
else:
a = c
c = (a+b)/2
return c
现在,一遍又一遍地调用eval不是很有效。
这是你可以做的
expr = "(x-1.0)**3.0 - 1.0"
fn = eval( "lambda x: " + expr )
print FindRoot( fn, 1, 3 )
或者您可以将eval和lambda定义放在FindRoot中
有帮助吗
Reson
你能具体说明出了什么问题吗?i、 e.解释器错误消息,不正确的输出(如果是),例如输入/输出。。这个输入..x3-4*x2+2*x-4,2,5,10*e-15给出了2,1,1,其中2是根,但正确答案是3.75。。它没有到达那里,也没有超过1absignfc