R: Symbolic and Algorithmic Derivatives of Simple Expressions

deriv {stats} | R Documentation

## Symbolic and Algorithmic Derivatives of Simple Expressions

### Description

Compute derivatives of simple expressions, symbolically.

### 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 `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 tbe 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.)

### 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

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

    ## 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"), 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)

    ## 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)

[Package stats version 2.8.1 Index]