Source code for numa.RootFinder._NewtonRhapson
from numa import utils
[docs]def NewtonRhapson(function, x0, Dfunction=None, max_iterations=10000, giveIterations=False):
"""Approximate one root of a given one-parameter function using the Newton-Rhapson method;
note that this method can converge very rapidly with a very good initial value for x0. Though a bad value for x0
can make it impossible to find due to endless cycling between the same points or due to an escape to infinity.
Parameters
----------
function: callable
Function to analyze.
x0: float
Initial guess of root value
Dfunction: callable, optional
Derivative function of the given one-parameter-function
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 next x-intercept of the tangent line recursively
.. math::
x_{n+1} = x_n - \\frac{f(x_n)}{f'(x_n)}
References
-------
[1] https://www.math.ubc.ca/~pwalls/math-python/roots-optimization/newton/
"""
err_accepted = 10e-15
convergence = list()
if Dfunction == None:
raise Exception(
"This method currently doesn't support the approximation of derivatives. Please give the derivative function as an input.")
x_n = x0
for n in range(1, max_iterations+1):
y_n = function(x_n)
if y_n == 0:
if not giveIterations:
return x_n, 0
if giveIterations:
convergence.append((n, 0))
return x_n, 0, convergence
if isinstance(Dfunction, float) or isinstance(Dfunction, int):
Dy_n = Dfunction
else:
Dy_n = Dfunction(x_n)
if Dy_n == 0:
raise utils.MethodStuckError("Derivative is zero.")
err = abs(function(x_n) - 0)
convergence.append((n, err))
if err < err_accepted:
if not giveIterations:
return x_n - y_n/Dy_n, err
if giveIterations:
return x_n - y_n/Dy_n, err, convergence
x_n = x_n - y_n/Dy_n
raise utils.MaximumIterationError(n)