ift_1dim#
- rateslib.dual.ift_1dim(s, s_tgt, h, ini_h_args=(), max_iter=50, func_tol=1e-14, conv_tol=1e-09, raise_on_fail=True)#
Use the inverse function theorem to determine a function value of one variable.
- Parameters:
s (Callable[DualTypes, DualTypes]) – The known inverse function of g such that g(s(x))=x. Of the signature: s(x).
s_tgt (DualTypes) – The value of s for which g is to be found.
h (Callable, string) – The iterative function to use to determine the solution g. See notes.
ini_h_args – Initial arguments passed to the iterative function,
h
.max_iter (int > 1) – Number of maximum iterations to perform.
func_tol (float, optional) – The absolute function tolerance to reach before exiting.
conv_tol (float, optional) – The convergence tolerance for subsequent iterations of g, passed to
h
to implement.raise_on_fail (bool, optional) – If False will return a solver result dict with state and message indicating failure.
Notes
Available iterative methods
‘bisection’: requires
ini_h_args
to be a tuple of two floats defining the interval. The interval will be halved in each iteration and the relevant interval side kept.‘modified_dekker’: Requires
ini_h_args
to be a tuple of two floats defining the interval. For info seeHalving Interval for Dekker
.‘modified_brent’: Requires
ini_h_args
to be a tuple of two floats defining the interval. For info seeHalving Interval for Brent
.‘ytm_quadratic’: Requires
ini_h_args
to be a tuple of three floats defining the interval and interior point. This algorithm utilises sequential quadratic approximation and is specifically tuned for solving bond yield-to-maturity.
Mathematical background
This method is used to find the value of g from s in the one-dimensional equation:
\[g(s) \qquad \text{where,} \qquad s(g) \; \text{is a known analytical inverse of} \; g.\]\(g(s)\) is not analytical and hence requires iterations to determine.
What is ``h``
h() is a function that is used to perform iterations to determine g from s. If a custom function is provided, it must conform to the following signature:
h(s, s_target, conv_tol, *h_args) -> (g_i, f_i, state, *h_args_i)
The input parameters provide:
s: The inverse function of g such that g(s(x))=x.
s_target: The target value of s for which g is to be found.
conv_tol: The convergence tolerance which is measured internally by h.
h_args: Additional arguments passed to h which facilitate its internal operation.
The output parameters provide:
g_i: The value of g at the current iteration, representative of \(g(s_i)\).
f_i: A measure of error in the iteration
state: A state flag return from the iteration as indicator to the controlling process.
h_args_i: Arguments passed to the next iteration of h.
state
flag returns are:-2: The algorithm failed for an internal reason.
1: conv_tol has been satisfied and the solution is considered to have converged.
None: The algorithm has not yet converged and will continue.
AD Implementation
The AD order of the solution is determined by the AD order of the
s_tgt
input.Examples
The most prevalent use of this technique in rateslib is to solve bond yield-to-maturity from a given price. Suppose we develop a formula, s(g) which determines the price (s) of a 2y bond with 3% annual coupon given its ytm (g):
\[s(g) = \frac{3}{1+g/100} + \frac{103}{(1+g/100)^2}\]Then we use the bisection method to discover the ytm given a price of 101:
In [1]: from rateslib.dual import ift_1dim, Dual In [2]: def s(g): ...: return 3 / (1 + g / 100) + 103 / (1 + g / 100) ** 2 ...: # solve for a bond price of 101 with lower and upper ytm bounds of 2.0 and 3.0. In [3]: result = ift_1dim(s, Dual(101.0, ["price"], []), "bisection", (2.0, 3.0)) In [4]: print(result) {'status': 'SUCCESS', 'state': 1, 'g': <Dual: 2.481314, (price), [-0.5]>, 'iterations': 30, 'time': 0.00014901161193847656}