Source code for numa.RootFinder._bisection

from numa import utils


[docs]def bisection(function, interval_start, interval_end, max_iterations=10000, giveIterations=False): """Approximate one root of a given one-parameter function using the Bisection method; note that the root has to be inside the interval or the bisection method won't yield any results. This method can only return one of the possible roots if multiple exist. Parameters ---------- function: callable Function to analyze. interval_start: int lower limit of the domain interval_end: int upper limit of the domain max_iterations: int Maximum number of iterations until the loop breaks. Default set to 10000 giveIterations: boolean, optional Information whether the value for iterations needed and the error should be returned or not. Lists starts at iteration two since the error is always calculated with respect to the previous guess. Returns ------- tuple (root value, error, convergence) Notes ----- Calculates the midpoint after every iteration as .. math:: m_N = \\frac{a_N + b_N}{2} References ------- [1] https://www.math.ubc.ca/~pwalls/math-python/roots-optimization/bisection/ """ err_accepted = 10e-15 a_n = interval_start b_n = interval_end convergence = list() for n in range(1, max_iterations+1): m_n = (a_n + b_n)/2 # Middlepoint y_n = function(m_n) # Function at middle point if function(a_n)*y_n < 0: # root is on left side of m_n a_n = a_n b_n = m_n # set new interval end err = abs(function(m_n) - 0) convergence.append((n, err)) if err < err_accepted: if not giveIterations: return (a_n + b_n)/2, err if giveIterations: return (a_n + b_n)/2, err, convergence elif function(b_n)*y_n < 0: # root is on right side of m_n a_n = m_n # set new interval start b_n = b_n err = abs(function(m_n) - 0) convergence.append((n, err)) if err < err_accepted: if not giveIterations: return (a_n + b_n)/2, err if giveIterations: return (a_n + b_n)/2, err, convergence elif y_n == 0: # Exact solution if not giveIterations: return m_n, 0 if giveIterations: convergence.append((n, 0)) return m_n, 0, convergence else: utils.MethodStuckError( "Bisection won't converge to root. Please adjust limits." ) raise utils.MaximumIterationError(n)