TOMS748/findEnclosingBracket.py

51 lines
1.8 KiB
Python
Raw Normal View History

# method to find a bracket that encloses a root of f
from math import *
def findEnclosingBracket(f, x, factor):
""" Finds a bracket [a b] that encloses a root of f : f(a)*f(b) < 0.
A typical value for the factor is 2.
The initial guess must be on the correct side of the real line : the algorithm will never cross the zero during the search.
The factor is increased every 10 iterations in order to speed up convergence for when the root is orders of magnitude away from the initial guess.
If the bracket returned by the function is too wide, try reducing the factor (while always keeping it > 1).
"""
a = x
b = x*factor # try higher
fa = f(a)
fb = f(b)
i = 0
while i in range(100) and fa*fb > 0:
if fabs(fa) < fabs(fb): # fa is closer to 0 than fb, extend the interval in the a direction (reducing it)
a = a / factor
fa = f(a)
else: # fb is closer to 0 than fa, extend the interval in the b direction (augmenting it)
b = b * factor
fb = f(b)
i = i+1
if i % 10 == 0: # every 10 iterations, bump up the factor to speed up convergence
factor = factor * 5
return (a, b, fa, fb)
f = lambda x : exp(sin(x))-2
a, b, fa, fb = findEnclosingBracket(f, 0.005, 2)
print((a,b)); print((fa, fb))
f = lambda x : exp(-x)-1e-200
a, b, fa, fb = findEnclosingBracket(f, 0.001, 2)
print((a,b)); print((fa, fb))
a, b, fa, fb = findEnclosingBracket(f, 0.001, 5)
print((a,b)); print((fa, fb))
f = lambda x : x**(1/3)-1000
a, b, fa, fb = findEnclosingBracket(f, 1e-10, 2)
print((a,b)); print((fa, fb))
# from toms748 import TOMS748_solve1
# def f(x):
# print(x)
# return x**(1/3)-1000
# TOMS748_solve1(f,a,b)