Learn R Programming

Deriv (version 1.0)

Deriv: Symbollic differentiation of an expression or function

Description

Symbollic differentiation of an expression or function

Usage

Deriv(f, x, env = parent.frame())
Deriv.function(f, x = names(formals(f)), env = environment(f))

Arguments

f
An expression or function to be differentiated
x
A character string with variable name with resptect to which f must be differentiated. If f is function x is optional and defaults to names(formals(f))
env
An environment where the symbols and functions are searched for. Defaults to parent.frame() for f expression and to environment(f) if f is a function.

Value

  • An expression (for Deriv) or a function (for Deriv.function) with the derivative of f.

concept

symbollic derivation

Details

R already contains two differentiation functions: D and deriv. D does simple univariate differentiation. "deriv" uses D do to multivariate differentiation. The output of "D" is an expression, whereas the output of "deriv" is an executable function. R's existing functions have several limitations. They can probably be fixed, but since they are written in C, this would probably require a lot of work. Limitations include:
  • The derivatives table can't be modified at runtime, and is only available in C.
  • The output of "deriv" can not be differentiated again.
  • Neither function can substitute function calls. eg: f <- function(x, y) x + y; deriv(f(x, x^2), "x")

So, here are the advantages and disadvantages of this implementation: GOOD POINTS:

  • It is entirely written in R, so would be easier to maintain.
  • Can do multi-variate differentiation.
  • Can differentiate function calls:
  • It's easy to add custom entries to the derivatives table. It could be easier though... it would be nice if something like worked, rather than the clunky function definitions. (This is purely a cosmetic issue, though... everything works as is.)
  • The output is an executable function, which makes it suitable for use in optimization problems.

BAD POINTS:

  • Differentiating vector-valued functions doesn't work properly, since the multiplication code doesn't know when to use scalar vs matrix multiplication. Unfortunately, solving this is a hard problem because we would need to know if an arbitrary expression is a vector or not. We would have to add extra metadata to do this. Bottom line: can compute gradients but not Jacobians or Hessians.
  • Gives useless error messages when it gets stuck. This could be fixed.
Two working environments derivatives and simplifications are created in the package namescape. As their names indicates, they contain tables of derivatives and simplification rules. A priori, user has not to manipulate them directly.

Examples

Run this code
f <- function(x) x^2
Deriv.function(f)
# function (x)
# 2 * x

f <- function(x, y) sin(x) * cos(y)
Deriv.function(f)
# function (x, y)
# sin(x) * (sin(y) * c(0, 1)) + cos(y) * (cos(x) * c(1, 0))

f_ <- Deriv.function(f)
f_(3, 4)
#              x         y
# [1,] 0.6471023 0.1068000
Deriv(expression(f(x, y^2)), "y")
# expression(sin(x) * (neg.sin(y^2) * (2 * y)))

Deriv(expression(f(x, y^2)), c("x", "y"))
# expression(sin(x) * (neg.sin(y^2) * (2 * (y * t(c(0, 1))))) +
#     cos(x) * t(c(1, 0)) * cos(y^2))

Deriv(expression(sin(x^2) * y), "x")
# expression(cos(x^2) * (2 * x) * y)

Run the code above in your browser using DataLab