qnm.contfrac

Infinite continued fractions via Lentz’s method.

TODO More documentation.

Functions

lentz(a, b[, tol, N_min, N_max, tiny, args]) Compute a continued fraction via modified Lentz’s method.
lentz_gen(a, b[, tol, N_min, N_max, tiny]) Compute a continued fraction via modified Lentz’s method, using generators rather than functions.
qnm.contfrac.lentz(a, b, tol=1e-10, N_min=0, N_max=inf, tiny=1e-30, args=None)[source]

Compute a continued fraction via modified Lentz’s method.

This implementation is by the book [1]. The value to compute is:
b_0 + a_1/( b_1 + a_2/( b_2 + a_3/( b_3 + …)))

where a_n = a(n, *args) and b_n = b(n, *args).

Parameters:
a: callable returning numeric.
b: callable returning numeric.
tol: float [default: 1.e-10]

Tolerance for termination of evaluation.

N_min: int [default: 0]

Minimum number of iterations to evaluate.

N_max: int or comparable [default: np.Inf]

Maximum number of iterations to evaluate.

tiny: float [default: 1.e-30]

Very small number to control convergence of Lentz’s method when there is cancellation in a denominator.

args: tuple [default: None]

Additional arguments to pass to the user-defined functions a, b. If given, the additional arguments are passed to all user-defined functions. So if, for example, a has the signature a(n, x, y), then b must have the same signature, and args must be a tuple of length 2, args=(x,y).

Returns:
(float, float, int)

The first element of the tuple is the value of the continued fraction. The second element is the estimated error. The third element is the number of iterations.

References

[1]WH Press, SA Teukolsky, WT Vetterling, BP Flannery, “Numerical Recipes,” 3rd Ed., Cambridge University Press 2007, ISBN 0521880688, 9780521880688 .

Examples

Compute the square root of two using continued fractions:

>>> from qnm.contfrac import lentz
>>> def rt2b(n):
...     if (n==0):
...         return 1
...     return 2
...
>>> def rt2a(n): return 1
>>> lentz(rt2a, rt2b)
(1.4142135623638004, 4.488287519421874e-11, 14)

Compute phi:

>>> phia = rt2a
>>> phib = rt2a
>>> lentz(phia, phib)
(1.6180339887802424, 6.785971784495359e-11, 25)

Compute pi:

>>> def pia(n):
...     if (n==1):
...         return 4.
...     return (n-1.)*(n-1.)
...
>>> def pib(n):
...     if (n==0):
...         return 0.
...     return 2*n-1.
...
>>> lentz(pia, pib, tol=1.e-15)
(3.1415926535897922, 8.881784197001252e-16, 21)

Compute e:

>>> def e_a(n):
...     if (n==1):
...         return 1.
...     return (n-1.)
...
>>> def e_b(n):
...     if (n==0):
...         return 2.
...     return n
...
>>> lentz(e_a, e_b, tol=1.e-15)
(2.7182818284590464, 3.3306690738754696e-16, 16)

Compute cotan(1):

>>> def cot1_a(n):
...     return -1.
...
>>> def cot1_b(n):
...     return 2.*n+1.
...
>>> lentz(cot1_a, cot1_b, tol=1.e-15)
(0.6420926159343306, 1.1102230246251565e-16, 9)

Compute tan(x):

>>> def tanx_a(n, x):
...     if (n==1):
...         return x
...     else:
...         return -x*x
...
>>> def tanx_b(n, x):
...     if (n==0):
...         return 0.
...     else:
...         return 2*n-1
...
>>> lentz(tanx_a, tanx_b, args=(1.,), tol=1.e-15)
(1.5574077246549018, 2.220446049250313e-16, 10)
qnm.contfrac.lentz_gen(a, b, tol=1e-10, N_min=0, N_max=inf, tiny=1e-30)[source]

Compute a continued fraction via modified Lentz’s method, using generators rather than functions.

This implementation is by the book [1].

Parameters:
a: generator yielding numeric.
b: generator yielding numeric.
tol: float [default: 1.e-10]

Tolerance for termination of evaluation.

N_min: int [default: 0]

Minimum number of iterations to evaluate.

N_max: int or comparable [default: np.Inf]

Maximum number of iterations to evaluate.

tiny: float [default: 1.e-30]

Very small number to control convergence of Lentz’s method when there is cancellation in a denominator.

Returns:
(float, float, int)

The first element of the tuple is the value of the continued fraction. The second element is the estimated error. The third element is the number of iterations.

References

[1]WH Press, SA Teukolsky, WT Vetterling, BP Flannery, “Numerical Recipes,” 3rd Ed., Cambridge University Press 2007, ISBN 0521880688, 9780521880688 .

Examples

Use generators to compute the square root of 2:

>>> from qnm.contfrac import lentz_gen
>>> import itertools
>>> def rt2b_g():
...     yield 1
...     for x in itertools.repeat(2):
...         yield x
...
>>> def rt2a_g():
...     for x in itertools.repeat(1):
...         yield x
...
>>> lentz_gen(rt2a_g(), rt2b_g())
(1.4142135623638004, 4.488287519421874e-11, 14)

See the documentation for lentz() for more examples.