Learn R Programming

LambertW (version 0.6.4)

W: Lambert W function, its logarithm and derivative

Description

The Lambert W function \(W(z) = u\) is defined as the inverse of (see xexp)

$$ u \exp(u) = z, $$

i.e., it satisfies \(W(z) \exp(W(z)) = z\).

W evaluates the Lambert W function (W), its first derivative (deriv_W), and its logarithm (log_W). All of them have a principal (branch = 0 (default)) and non-principal branch (branch = -1) solution.

W is a wrapper for lambert_W0C and lambert_Wm1_C in the lamW package.

Usage

W(z, branch = 0)

deriv_W(z, branch = 0, W.z = W(z, branch = branch))

log_deriv_W(z, branch = 0, W.z = W(z, branch = branch))

deriv_log_W(z, branch = 0, W.z = W(z, branch = branch))

log_W(z, branch = 0, W.z = W(z, branch = branch))

Arguments

z

a numeric vector of real values; note that W(Inf, branch = 0) = Inf.

branch

either 0 or -1 for the principal or non-principal branch solution.

W.z

Lambert W function evaluated at z; see Details below for why this is useful.

Value

numeric; same dimensions/size as z.

W returns numeric, Inf (for z = Inf), or NA if \(z < -1/e\).

Note that W handles NaN differently to lambertW0_C and lambertWm1_C in the lamW package; it returns NA.

Details

Depending on the argument \(z\) of \(W(z)\) one can distinguish 3 cases:

\(z \geq 0\)

solution is unique W(z) = W(z, branch = 0)

;
\(-1/e \leq z < 0\)

two solutions: the principal (W(z, branch = 0)) and non-principal (W(z, branch = -1)) branch;

\(z < -1/e\)

no solution exists in the reals.

log_W computes the natural logarithm of \(W(z)\). This can be done efficiently since \(\log W(z) = \log z - W(z)\). Similarly, the derivative can be expressed as a function of \(W(z)\):

$$ W'(z) = \frac{1}{(1 + W(z)) \exp(W(z))} = \frac{W(z)}{z(1 + W(z))}. $$

Note that \(W'(0) = 1\) and \(W'(-1/e) = \infty\).

Moreover, by taking logs on both sides we can even simplify further to $$ \log W'(z) = \log W(z) - \log z - \log (1 + W(z))$$ which, since \(\log W(z) = \log z - W(z)\), simplifies to

$$ \log W'(z) = - W(z) - \log (1 + W(z)).$$

For this reason it is numerically faster to pass the value of \(W(z)\) as an argument to deriv_W since W(z) often has already been evaluated in a previous step.

References

Corless, R. M., G. H. Gonnet, D. E. G. Hare, D. J. Jeffrey and D. E. Knuth (1996). “On the Lambert W function”. Advances in Computational Mathematics, pp. 329-359.

See Also

lambertW0_C and lambertWm1_C in the lamW package; xexp.

Examples

Run this code
# NOT RUN {
 
W(-0.25) # "reasonable" input event
W(-0.25, branch = -1) # "extreme" input event

curve(W(x, branch = -1), -1, 2, type = "l", col = 2, lwd = 2)
curve(W(x), -1, 2, type = "l", add = TRUE, lty = 2)
abline(v = - 1 / exp(1))

# For lower values, the principal branch gives the 'wrong' solution; 
# the non-principal must be used.
xexp(-10)
W(xexp(-10), branch = 0)
W(xexp(-10), branch = -1)
curve(log(x), 0.1, 5, lty = 2, col = 1, ylab = "")
curve(W(x), 0, 5, add = TRUE, col = "red")
curve(log_W(x), 0.1, 5, add = TRUE, col = "blue")
grid()
legend("bottomright", c("log(x)", "W(x)", "log(W(x))"),
       col = c("black", "red", "blue"), lty = c(2, 1, 1))

# }

Run the code above in your browser using DataLab