newton_1dim#

rateslib.dual.newton_1dim(f, g0, max_iter=50, func_tol=1e-14, conv_tol=1e-09, args=(), pre_args=(), final_args=(), raise_on_fail=True)#

Use the Newton-Raphson algorithm to determine the root of a function searching one variable.

Parameters:
  • f (callable) – The function, f, to find the root of. Of the signature: f(g, *args). Must return a tuple where the second value is the derivative of f with respect to g.

  • g0 (DualTypes) – Initial guess of the root. Should be reasonable to avoid failure.

  • max_iter (int) – The maximum number of iterations to try before exiting.

  • func_tol (float, optional) – The absolute function tolerance to reach before exiting.

  • conv_tol (float, optional) – The convergence tolerance for subsequent iterations of g.

  • args (tuple of float, Dual, Dual2 or str) – Additional arguments passed to f.

  • pre_args (tuple of float, Dual, Dual2 or str) – Additional arguments passed to f used only in the float solve section of the algorithm. Functions are called with the signature f(g, *(*args[as float], *pre_args)).

  • final_args (tuple of float, Dual, Dual2 or str) – Additional arguments passed to f in the final iteration of the algorithm to capture AD sensitivities. Functions are called with the signature f(g, *(*args, *final_args)).

  • raise_on_fail (bool, optional) – If False will return a solver result dict with state and message indicating failure.

Return type:

dict

Notes

Solves the root equation \(f(g; s_i)=0\) for g. This method is AD-safe, meaning the iteratively determined solution will preserve AD sensitivities, if the functions are suitable. Functions which are not AD suitable, such as discontinuous functions or functions with no derivative at given points, may yield spurious derivative results.

This method works by first solving in the domain of floats (which is typically faster for most complex functions), and then performing final iterations in higher AD modes to capture derivative sensitivities.

For special cases arguments can be passed separately to each of these modes using the pre_args and final_args arguments, rather than generically supplying it to args.

Examples

Iteratively solve the equation: \(f(g, s) = g^2 - s = 0\). This has solution \(g=\pm \sqrt{s}\) and \(\frac{dg}{ds} = \frac{1}{2 \sqrt{s}}\). Thus for \(s=2\) we expect the solution g=Dual(1.41.., ["s"], [0.35..]).

In [1]: from rateslib.dual import newton_1dim

In [2]: def f(g, s):
   ...:     f0 = g**2 - s   # Function value
   ...:     f1 = 2*g        # Analytical derivative is required
   ...:     return f0, f1
   ...: 

In [3]: s = Dual(2.0, ["s"], [])

In [4]: newton_1dim(f, g0=1.0, args=(s,))
Out[4]: 
{'status': 'SUCCESS',
 'state': 1,
 'g': <Dual: 1.414214, (s), [0.4]>,
 'iterations': 6,
 'time': 6.103515625e-05}