Coverage for /usr/lib/python3/dist-packages/scipy/special/_lambertw.py: 67%
3 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
1from ._ufuncs import _lambertw
4def lambertw(z, k=0, tol=1e-8):
5 r"""
6 lambertw(z, k=0, tol=1e-8)
8 Lambert W function.
10 The Lambert W function `W(z)` is defined as the inverse function
11 of ``w * exp(w)``. In other words, the value of ``W(z)`` is
12 such that ``z = W(z) * exp(W(z))`` for any complex number
13 ``z``.
15 The Lambert W function is a multivalued function with infinitely
16 many branches. Each branch gives a separate solution of the
17 equation ``z = w exp(w)``. Here, the branches are indexed by the
18 integer `k`.
20 Parameters
21 ----------
22 z : array_like
23 Input argument.
24 k : int, optional
25 Branch index.
26 tol : float, optional
27 Evaluation tolerance.
29 Returns
30 -------
31 w : array
32 `w` will have the same shape as `z`.
34 Notes
35 -----
36 All branches are supported by `lambertw`:
38 * ``lambertw(z)`` gives the principal solution (branch 0)
39 * ``lambertw(z, k)`` gives the solution on branch `k`
41 The Lambert W function has two partially real branches: the
42 principal branch (`k = 0`) is real for real ``z > -1/e``, and the
43 ``k = -1`` branch is real for ``-1/e < z < 0``. All branches except
44 ``k = 0`` have a logarithmic singularity at ``z = 0``.
46 **Possible issues**
48 The evaluation can become inaccurate very close to the branch point
49 at ``-1/e``. In some corner cases, `lambertw` might currently
50 fail to converge, or can end up on the wrong branch.
52 **Algorithm**
54 Halley's iteration is used to invert ``w * exp(w)``, using a first-order
55 asymptotic approximation (O(log(w)) or `O(w)`) as the initial estimate.
57 The definition, implementation and choice of branches is based on [2]_.
59 See Also
60 --------
61 wrightomega : the Wright Omega function
63 References
64 ----------
65 .. [1] https://en.wikipedia.org/wiki/Lambert_W_function
66 .. [2] Corless et al, "On the Lambert W function", Adv. Comp. Math. 5
67 (1996) 329-359.
68 https://cs.uwaterloo.ca/research/tr/1993/03/W.pdf
70 Examples
71 --------
72 The Lambert W function is the inverse of ``w exp(w)``:
74 >>> import numpy as np
75 >>> from scipy.special import lambertw
76 >>> w = lambertw(1)
77 >>> w
78 (0.56714329040978384+0j)
79 >>> w * np.exp(w)
80 (1.0+0j)
82 Any branch gives a valid inverse:
84 >>> w = lambertw(1, k=3)
85 >>> w
86 (-2.8535817554090377+17.113535539412148j)
87 >>> w*np.exp(w)
88 (1.0000000000000002+1.609823385706477e-15j)
90 **Applications to equation-solving**
92 The Lambert W function may be used to solve various kinds of
93 equations. We give two examples here.
95 First, the function can be used to solve implicit equations of the
96 form
98 :math:`x = a + b e^{c x}`
100 for :math:`x`. We assume :math:`c` is not zero. After a little
101 algebra, the equation may be written
103 :math:`z e^z = -b c e^{a c}`
105 where :math:`z = c (a - x)`. :math:`z` may then be expressed using
106 the Lambert W function
108 :math:`z = W(-b c e^{a c})`
110 giving
112 :math:`x = a - W(-b c e^{a c})/c`
114 For example,
116 >>> a = 3
117 >>> b = 2
118 >>> c = -0.5
120 The solution to :math:`x = a + b e^{c x}` is:
122 >>> x = a - lambertw(-b*c*np.exp(a*c))/c
123 >>> x
124 (3.3707498368978794+0j)
126 Verify that it solves the equation:
128 >>> a + b*np.exp(c*x)
129 (3.37074983689788+0j)
131 The Lambert W function may also be used find the value of the infinite
132 power tower :math:`z^{z^{z^{\ldots}}}`:
134 >>> def tower(z, n):
135 ... if n == 0:
136 ... return z
137 ... return z ** tower(z, n-1)
138 ...
139 >>> tower(0.5, 100)
140 0.641185744504986
141 >>> -lambertw(-np.log(0.5)) / np.log(0.5)
142 (0.64118574450498589+0j)
143 """
144 return _lambertw(z, k, tol)