I'm looking for comments on the use of decorators for the following problem (validating initial guesses for bracketing rootfinding methods), as well as any other comments you might have on the design below.
def bracketing(rootfinder):
def wrapper(func, x0, x1, *args, **kwargs):
func_x0, func_x1 = func(x0), func(x1)
if func_x0 * func_x1 > 0.0:
return None
return rootfinder(func, x0, x1, *args, **kwargs)
return wrapper
@bracketing
def bisection(func, x0, x1, max_iterations, tolerance):
if x1 < x0:
x0, x1 = x1, x0
func_x0 = func(x0)
for _ in range(max_iterations):
x_mid = 0.5 * (x0 + x1)
func_x_mid = func(x_mid)
if func_x0 * func_x_mid > 0.0:
x0 = x_mid
func_x0 = func_x_mid
else:
x1 = x_mid
if x1 - x0 < tolerance:
return x_mid
return None
@bracketing
def false_position(func, x0, x1, max_iterations, tolerance):
func_x0, func_x1 = func(x0), func(x1)
for _ in range(max_iterations):
x2 = (x0 * func_x1 - x1 * func_x0) / (func_x1 - func_x0)
func_x2 = func(x2)
if func_x0 * func_x2 > 0.0:
x0, func_x0 = x2, func_x2
else:
x1, func_x1 = x2, func_x2
if abs(func_x2) < tolerance:
return x2
return None