我正在尝试实现 Dekker 的求根方法,但我似乎无法找出算法似乎无法正确收敛到解决方案并且有时会突然停止的问题。
我的实现基于 Wiki 上 Dekker 方法的方程 Wiki
我对 python 和编程还很陌生,如果您能深入了解我可能出错的地方,我将不胜感激。
def dekker(func, x_bounds, tolerance, max_iterations):
# Initial bounds
a0, b0 = x_bounds
bk = b0
b_minus_1 = a0 # previous bk but start with a
k = 0
print(' k xk f(xk)')
while k < max_iterations:
fk = eval(fnon)(bk)
f_minus_1 = eval(fnon)(b_minus_1)
# check for division by zero when attemping secant method
if fk - f_minus_1 == 0:
# implement bisection method when division by zero
bk_plus_1 = (a0 + bk) / 2
else:
sk = bk - (bk - b_minus_1) / (fk - f_minus_1) * fk #secant
mk = (a0 + bk) / 2 # bisection
if sk >= mk and sk <= bk:
bk_plus_1 = sk
else:
bk_plus_1 = mk
fk_plus_1 = eval(fnon)(bk_plus_1)
if fk * fk_plus_1 < 0:
a_k_plus_1 = bk
b_k_plus_1 = bk_plus_1
else:
a_k_plus_1 = a0
b_k_plus_1 = bk_plus_1
if abs(eval(fnon)(a_k_plus_1)) < abs(eval(fnon)(b_k_plus_1)):
best_solution = a_k_plus_1
else:
best_solution = b_k_plus_1
k += 1
print('{0:2.0f} {1:2.8f} {2:2.2e}'.format(k, bk_plus_1, abs(fk_plus_1)))
if(abs(bk - b_minus_1) < tolerance):
print('Converged')
break
bk = bk_plus_1
b_minus_1 = bk
if k == maxk:
print('Not converged')
测试方法:
def function(x):
return -np.cos(x) + x*x*x + 2*x*x + 1
dekker('function', [-3,1], 1e-6, 100)
一些可能有帮助的更改:
fnon
更改为 func
。abs(bk - b_minus_1)
更改为 abs(bk_plus_1 - bk)
来纠正收敛检查中的条件。