3.8 derive() in R
The function derive() and .D() are basic ones in R to get analytical derivative of a function.
= expression(x^2)
FxExpr1 = deriv(FxExpr1, "x")
FxDeriv1 FxDeriv1
## expression({
## .value <- x^2
## .grad <- array(0, c(length(.value), 1L), list(NULL, c("x")))
## .grad[, "x"] <- 2 * x
## attr(.value, "gradient") <- .grad
## .value
## })
= -5:5
x eval(FxDeriv1)
## [1] 25 16 9 4 1 0 1 4 9 16 25
## attr(,"gradient")
## x
## [1,] -10
## [2,] -8
## [3,] -6
## [4,] -4
## [5,] -2
## [6,] 0
## [7,] 2
## [8,] 4
## [9,] 6
## [10,] 8
## [11,] 10
attr(eval(FxDeriv1), "gradient")
## x
## [1,] -10
## [2,] -8
## [3,] -6
## [4,] -4
## [5,] -2
## [6,] 0
## [7,] 2
## [8,] 4
## [9,] 6
## [10,] 8
## [11,] 10
= expression(x1^3 + 2*x2^3 + x1*x2 + sin(x1) + cos(x2))
FxExpr2 = deriv(FxExpr2, c("x1", "x2"), function.arg=c("x1", "x2"), func=TRUE, hessian=TRUE)
FxDeriv2 FxDeriv2
## function (x1, x2)
## {
## .expr7 <- sin(x1)
## .expr9 <- cos(x2)
## .value <- x1^3 + 2 * x2^3 + x1 * x2 + .expr7 + .expr9
## .grad <- array(0, c(length(.value), 2L), list(NULL, c("x1",
## "x2")))
## .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL,
## c("x1", "x2"), c("x1", "x2")))
## .grad[, "x1"] <- 3 * x1^2 + x2 + cos(x1)
## .hessian[, "x1", "x1"] <- 3 * (2 * x1) - .expr7
## .hessian[, "x1", "x2"] <- .hessian[, "x2", "x1"] <- 1
## .grad[, "x2"] <- 2 * (3 * x2^2) + x1 - sin(x2)
## .hessian[, "x2", "x2"] <- 2 * (3 * (2 * x2)) - .expr9
## attr(.value, "gradient") <- .grad
## attr(.value, "hessian") <- .hessian
## .value
## }
FxDeriv2(2, 3)
## [1] 67.92
## attr(,"gradient")
## x1 x2
## [1,] 14.58 55.86
## attr(,"hessian")
## , , x1
##
## x1 x2
## [1,] 11.09 1
##
## , , x2
##
## x1 x2
## [1,] 1 36.99
attr(FxDeriv2(2, 3), "gradient")
## x1 x2
## [1,] 14.58 55.86
attr(FxDeriv2(2, 3), "hessian")[1,,]
## x1 x2
## x1 11.09 1.00
## x2 1.00 36.99
= -5:5
x1 = -5:5
x2 FxDeriv2(x1,x2)
## [1] -348.757 -175.897 -73.131 -21.325 -2.301 1.000 5.382 28.493 89.151
## [10] 206.590 399.325
## attr(,"gradient")
## x1 x2
## [1,] 70.284 144.041
## [2,] 43.346 91.243
## [3,] 23.010 51.141
## [4,] 9.584 22.909
## [5,] 2.540 5.841
## [6,] 1.000 0.000
## [7,] 4.540 6.159
## [8,] 13.584 25.091
## [9,] 29.010 56.859
## [10,] 51.346 100.757
## [11,] 80.284 155.959
## attr(,"hessian")
## , , x1
##
## x1 x2
## [1,] -30.959 1
## [2,] -24.757 1
## [3,] -17.859 1
## [4,] -11.091 1
## [5,] -5.159 1
## [6,] 0.000 1
## [7,] 5.159 1
## [8,] 11.091 1
## [9,] 17.859 1
## [10,] 24.757 1
## [11,] 30.959 1
##
## , , x2
##
## x1 x2
## [1,] 1 -60.28
## [2,] 1 -47.35
## [3,] 1 -35.01
## [4,] 1 -23.58
## [5,] 1 -12.54
## [6,] 1 -1.00
## [7,] 1 11.46
## [8,] 1 24.42
## [9,] 1 36.99
## [10,] 1 48.65
## [11,] 1 59.72
attr(FxDeriv2(x1,x2), "gradient")
## x1 x2
## [1,] 70.284 144.041
## [2,] 43.346 91.243
## [3,] 23.010 51.141
## [4,] 9.584 22.909
## [5,] 2.540 5.841
## [6,] 1.000 0.000
## [7,] 4.540 6.159
## [8,] 13.584 25.091
## [9,] 29.010 56.859
## [10,] 51.346 100.757
## [11,] 80.284 155.959
= attr(FxDeriv2(x1,x2), "hessian")
Hess
for (i in 1:length(x1)) {
cat("\n")
print(paste("i =",i,"; x1 =",x1[i],"; x2 =",x2[i]))
print(Hess[i,,])
}
##
## [1] "i = 1 ; x1 = -5 ; x2 = -5"
## x1 x2
## x1 -30.96 1.00
## x2 1.00 -60.28
##
## [1] "i = 2 ; x1 = -4 ; x2 = -4"
## x1 x2
## x1 -24.76 1.00
## x2 1.00 -47.35
##
## [1] "i = 3 ; x1 = -3 ; x2 = -3"
## x1 x2
## x1 -17.86 1.00
## x2 1.00 -35.01
##
## [1] "i = 4 ; x1 = -2 ; x2 = -2"
## x1 x2
## x1 -11.09 1.00
## x2 1.00 -23.58
##
## [1] "i = 5 ; x1 = -1 ; x2 = -1"
## x1 x2
## x1 -5.159 1.00
## x2 1.000 -12.54
##
## [1] "i = 6 ; x1 = 0 ; x2 = 0"
## x1 x2
## x1 0 1
## x2 1 -1
##
## [1] "i = 7 ; x1 = 1 ; x2 = 1"
## x1 x2
## x1 5.159 1.00
## x2 1.000 11.46
##
## [1] "i = 8 ; x1 = 2 ; x2 = 2"
## x1 x2
## x1 11.09 1.00
## x2 1.00 24.42
##
## [1] "i = 9 ; x1 = 3 ; x2 = 3"
## x1 x2
## x1 17.86 1.00
## x2 1.00 36.99
##
## [1] "i = 10 ; x1 = 4 ; x2 = 4"
## x1 x2
## x1 24.76 1.00
## x2 1.00 48.65
##
## [1] "i = 11 ; x1 = 5 ; x2 = 5"
## x1 x2
## x1 30.96 1.00
## x2 1.00 59.72
There are also some packages for symbolic differentiation to get analytical derivative function.