Description
Compute derivatives of simple expressions, symbolically and algorithmically.
Usage
D (expr, name) deriv(expr, …)deriv3(expr, …) # S3 method for defaultderiv(expr, namevec, function.arg = NULL, tag = ".expr", hessian = FALSE, …) # S3 method for formuladeriv(expr, namevec, function.arg = NULL, tag = ".expr", hessian = FALSE, …)
# S3 method for defaultderiv3(expr, namevec, function.arg = NULL, tag = ".expr", hessian = TRUE, …)# S3 method for formuladeriv3(expr, namevec, function.arg = NULL, tag = ".expr", hessian = TRUE, …)
Arguments
expr
a expression
or call
or (except D
) a formula with no lhs.
name,namevec
character vector, giving the variable names (only one for D()
) with respect to which derivatives will be computed.
function.arg
if specified and non-NULL
, a character vector of arguments for a function return, or a function (with empty body) or TRUE
, the latter indicating that a function with argument names namevec
should be used.
tag
character; the prefix to be used for the locally created variables in result.
hessian
a logical value indicating whether the second derivatives should be calculated and incorporated in the return value.
…
arguments to be passed to or from methods.
Value
D
returns a call and therefore can easily be iterated for higher derivatives.
deriv
and deriv3
normally return an expression
object whose evaluation returns the function values with a "gradient"
attribute containing the gradient matrix. If hessian
is TRUE
the evaluation also returns a "hessian"
attribute containing the Hessian array.
If function.arg
is not NULL
, deriv
and deriv3
return a function with those arguments rather than an expression.
Details
D
is modelled after its S namesake for taking simple symbolic derivatives.
deriv
is a generic function with a default and a formula
method. It returns a call
for computing the expr
and its (partial) derivatives, simultaneously. It uses so-called algorithmic derivatives. If function.arg
is a function, its arguments can have default values, see the fx
example below.
Currently, deriv.formula
just calls deriv.default
after extracting the expression to the right of ~
.
deriv3
and its methods are equivalent to deriv
and its methods except that hessian
defaults to TRUE
for deriv3
.
The internal code knows about the arithmetic operators +
, -
, *
, /
and ^
, and the single-variable functions exp
, log
, sin
, cos
, tan
, sinh
, cosh
, sqrt
, pnorm
, dnorm
, asin
, acos
, atan
, gamma
, lgamma
, digamma
and trigamma
, as well as psigamma
for one or two arguments (but derivative only with respect to the first). (Note that only the standard normal distribution is considered.)
Since R 3.4.0, the single-variable functions log1p
, expm1
, log2
, log10
, cospi
, sinpi
, tanpi
, factorial
, and lfactorial
are supported as well.
References
Griewank, A. and Corliss, G. F. (1991) Automatic Differentiation of Algorithms: Theory, Implementation, and Application. SIAM proceedings, Philadelphia.
Bates, D. M. and Chambers, J. M. (1992) Nonlinear models. Chapter 10 of Statistical Models in S eds J. M. Chambers and T. J. Hastie, Wadsworth & Brooks/Cole.
See Also
nlm
and optim
for numeric minimization which could make use of derivatives,
Examples
# NOT RUN {## formula argument :dx2x <- deriv(~ x^2, "x") ; dx2x# }# NOT RUN {expression({ .value <- x^2 .grad <- array(0, c(length(.value), 1), list(NULL, c("x"))) .grad[, "x"] <- 2 * x attr(.value, "gradient") <- .grad .value})# }# NOT RUN {mode(dx2x)x <- -1:2eval(dx2x)## Something 'tougher':trig.exp <- expression(sin(cos(x + y^2)))( D.sc <- D(trig.exp, "x") )all.equal(D(trig.exp[[1]], "x"), D.sc)( dxy <- deriv(trig.exp, c("x", "y")) )y <- 1eval(dxy)eval(D.sc)## function returned:deriv((y ~ sin(cos(x) * y)), c("x","y"), func = TRUE)## function with defaulted arguments:(fx <- deriv(y ~ b0 + b1 * 2^(-x/th), c("b0", "b1", "th"), function(b0, b1, th, x = 1:7){} ) )fx(2, 3, 4)## First derivativeD(expression(x^2), "x")stopifnot(D(as.name("x"), "x") == 1)## Higher derivativesderiv3(y ~ b0 + b1 * 2^(-x/th), c("b0", "b1", "th"), c("b0", "b1", "th", "x") )## Higher derivatives:DD <- function(expr, name, order = 1) { if(order < 1) stop("'order' must be >= 1") if(order == 1) D(expr, name) else DD(D(expr, name), name, order - 1)}DD(expression(sin(x^2)), "x", 3)## showing the limits of the internal "simplify()" :# }# NOT RUN {-sin(x^2) * (2 * x) * 2 + ((cos(x^2) * (2 * x) * (2 * x) + sin(x^2) * 2) * (2 * x) + sin(x^2) * (2 * x) * 2)# }# NOT RUN {## New (R 3.4.0, 2017):D(quote(log1p(x^2)), "x") ## log1p(x) = log(1 + x)stopifnot(identical( D(quote(log1p(x^2)), "x"), D(quote(log(1+x^2)), "x")))D(quote(expm1(x^2)), "x") ## expm1(x) = exp(x) - 1stopifnot(identical( D(quote(expm1(x^2)), "x") -> Dex1, D(quote(exp(x^2)-1), "x")), identical(Dex1, quote(exp(x^2) * (2 * x))))D(quote(sinpi(x^2)), "x") ## sinpi(x) = sin(pi*x)D(quote(cospi(x^2)), "x") ## cospi(x) = cos(pi*x)D(quote(tanpi(x^2)), "x") ## tanpi(x) = tan(pi*x)stopifnot(identical(D(quote(log2 (x^2)), "x"), quote(2 * x/(x^2 * log(2)))), identical(D(quote(log10(x^2)), "x"), quote(2 * x/(x^2 * log(10)))))# }
Run the code above in your browser using DataLab