deriv {stats} | R Documentation |
Symbolic and Algorithmic Derivatives of Simple Expressions
Description
Compute derivatives of simple expressions, symbolically and algorithmically.
Usage
D (expr, name)
deriv(expr, ...)
deriv3(expr, ...)
## Default S3 method:
deriv(expr, namevec, function.arg = NULL, tag = ".expr",
hessian = FALSE, ...)
## S3 method for class 'formula'
deriv(expr, namevec, function.arg = NULL, tag = ".expr",
hessian = FALSE, ...)
## Default S3 method:
deriv3(expr, namevec, function.arg = NULL, tag = ".expr",
hessian = TRUE, ...)
## S3 method for class 'formula'
deriv3(expr, namevec, function.arg = NULL, tag = ".expr",
hessian = TRUE, ...)
Arguments
expr |
a |
name , namevec |
character vector, giving the variable names (only
one for |
function.arg |
if specified and non- |
tag |
character; the prefix to be used for the locally created variables in result. Must be no longer than 60 bytes when translated to the native encoding. |
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. |
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.
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.
References
Bates D. M., Chambers J. M. (1992). “Nonlinear Models.” In Chambers J. M., Hastie T. J. (eds.), Statistical Models in S, chapter 10. Wadsworth & Brooks/Cole.
Griewank A., Corliss G. F. (eds.) (1991). Automatic Differentiation of Algorithms: Theory, Implementation, and Application, series SIAM proceedings series. ISBN 089871284X.
See Also
nlm
and optim
for numeric minimization
which could make use of derivatives,
Examples
## 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
})
## End(Not run)
mode(dx2x)
x <- -1:2
eval(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 <- 1
eval(dxy)
eval(D.sc)
## function returned:
deriv((y ~ sin(cos(x) * y)), c("x","y"), function.arg = 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 derivative
D(expression(x^2), "x")
stopifnot(D(as.name("x"), "x") == 1)
## Higher derivatives
deriv3(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)
## End(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) - 1
stopifnot(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)))))