############################################################################
## Lambert W-function defined by W(y*exp(y))=y
W <- function(x) {
logx <- log(x)
y <- pmax(logx, 0)
while (any(abs(logx - log(y) - y) > 1e-9, na.rm = TRUE)) {
y <- y - (y - exp(logx - y)) / (1 + y)
}
y
}
## Derivatives
dW <- function(x, y, dy) {
dy / (exp(y) * (1. + y))
}
## Define new derivative symbol
LamW <- ADjoint(W, dW)
## Test derivatives
(F <- MakeTape(function(x)sum(LamW(x)), numeric(3)))
F(1:3)
F$print() ## Note the 'name'
F$jacobian(1:3) ## gradient
F$jacfun()$jacobian(1:3) ## hessian
############################################################################
## Log determinant
logdet <- ADjoint(
function(x) determinant(x, log=TRUE)$modulus,
function(x, y, dy) t(solve(x)) * dy,
name = "logdet")
(F <- MakeTape(logdet, diag(2)))
## Test derivatives
## Compare with numDeriv::hessian(F, matrix(1:4,2))
F$jacfun()$jacobian(matrix(1:4,2)) ## Hessian
############################################################################
## Holomorphic extension of 'solve'
matinv <- ADjoint(
solve,
function(x,y,dy) -t(y) %*% dy %*% t(y),
complex=TRUE)
(F <- MakeTape(function(x) Im(matinv(x+AD(1i))), diag(2)))
## Test derivatives
## Compare with numDeriv::jacobian(F, matrix(1:4,2))
F$jacobian(matrix(1:4,2))
Run the code above in your browser using DataLab