Is there a method to check for convergence when using newon's method?

Viewed 46

I have a function that I want to solve using newton's method. The problem is that the convergence depends on the initial guess. I want to write an if statement. If the function converges then to store the variable, but if didn't converge I want to change the initial statement. The initial statements will be a priori stored in a list.

    for i in range(len(initial_guess)):

        t_end = newton(self.ray_param_eq, initial_guess[i],
                   fprime=self.ray_param_eq_prime,
                   fprime2=self.ray_param_eq_second_prime,
                   args=(self.c, self.k, ray.z_0, ray.y_0, ray.theta, self.A, self.B),
                   maxiter=100, tol=1.48e-5, disp=False)
        if t_end is not None: break
        if t_end is None: continue

initil_guess = the list with the initial guess variables

The code above didn't raise an error, but I do not know if it works or not.

2 Answers

Indeed, scipy.optimize.newton() offers a way to obtain information on element-wise information on convergence (as evaluating the difference of the iterative parameter sequence against the tolerance level tol). Just add

t_end = newton(..., full_output=True)

Take this code snippet as a minimum viable example

def f(x):
    return (x-2.0)**2 

t_end = newton(f, 0.0, maxiter=1000, tol=1.48e-5, disp=False, full_output=True)

t_end
> (1.9999835249000992,
       converged: True
            flag: 'converged'
  function_calls: 25
      iterations: 24
            root: 1.9999835249000992)

In turn, you can leverage convergence information via

if t_end[1].converged:
     break # exit while-loop

for a function f with a scalar parameter x (as seen in the snippet above) or

if t_end.converged.all():
     break # exit while-loop

if the function input x is an iterable (tuple, list, NumPy array, etc.)

Unless your iterates suffer from catastrophic numerical instability or you are close to a multiple root, convergence is "explosive" at some point. So you might check if the iterates stabilize to the very last bits of the floating-point representation (a small number of ULPs).

Related