I am trying to implement Dekker's method for root finding and I can't seem to figure out an issue where the algorithm does not seem to correctly converge to a solution and stops abruptly sometimes.
My implementation is based on the equations on the Wiki for Dekker's method Wiki
I'm quite new to python and programming and would appreciate any insight into where I might be going wrong.
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(func)(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(func)(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(func)(a_k_plus_1)) < abs(eval(func)(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 == max_iterations:
print('Not converged')
Testing method:
def function(x):
return -np.cos(x) + x*x*x + 2*x*x + 1
dekker('function', [-3,1], 1e-6, 100)
You had a number of problems.
First, you were only computing
mk
when you used the bisection method. You need to computemk
on EVERY iteration, because you need to comparesk
andmk
every time.Next, your two lines of code to advance
bk
andbk_plus_1
at the end were not in the right order, so you trashed thebk
value before saving it.Next, you were doing the computation to check whether you needed to move
ak
, but you never used the results of that computation. This seems to work:Output: