2010-12-02 15 views
8

R puede generar una función de spline utilizando splinefun() en la biblioteca de splines. Sin embargo, necesito evaluar esta función en sus derivadas primera y segunda. ¿Hay alguna forma de hacer esto?¿cómo puedo evaluar la derivada de una función spline en R?

por ejemplo

library(splines) 
x <- 1:10 
y <- sin(pi/x) #just an example 
f_of_x <- splinefun(x,y) 

¿Cómo puedo evaluar f '(x) para un vector de las x?

Respuesta

14

¡Es muy fácil de hacer ya que la capacidad de evaluar la función en sus derivadas está incorporada en la función!

f_of_x(x, deriv = 1) 

Gracias R-core!

+0

No es un operador "==", pero "=". –

+0

@DWin: corregido, gracias. –

2

Puede que también le interese la función TkSpline en el paquete TeachingDemos que trazará la función spline junto con sus derivadas.

2

El uso del argumento deriv = para splinefun es sensato, y debe agregarse que el segundo y tercer derivado se supone que están disponibles, pero si trabaja con los ejemplos, se dará cuenta de que las aproximaciones lineales son irregulares y discontinuo en grados superiores.

En la situación en la que tiene una expresión analítica, existen algunas disposiciones ciertamente limitadas para la diferenciación algorítmica. Vea la página de ayuda (deriv) para más detalles.

> deriv(~sin(pi/x), "x") 
expression({ 
    .expr1 <- pi/x 
    .value <- sin(.expr1) 
    .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) 
    .grad[, "x"] <- -(cos(.expr1) * (pi/x^2)) 
    attr(.value, "gradient") <- .grad 
    .value 
}) 

Y luego construir "a mano" una segunda función con ese resultado. O puede utilizar el ejemplo DD proporcionada en la página de ayuda (deriv) para automatizar el proceso un poco más:

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(pi/x)), "x", 2) 
-(sin(pi/x) * (pi/x^2) * (pi/x^2) - cos(pi/x) * (pi * (2 * x)/(x^2)^2)) 
DD(expression(sin(pi/x)), "x") 
-(cos(pi/x) * (pi/x^2)) 
funD<- function(x){} 
body(funD) <- DD(expression(sin(pi/x)), "x") 
funD 
    #function (x) 
    #-(cos(pi/x) * (pi/x^2)) 
funD(2) 
# [1] -4.809177e-17 as it should be at a maximum 
funDD <- function(x){} 
body(funDD) <- DD(expression(sin(pi/x)), "x", 2) 
funDD(2) 
# [1] -0.6168503 as it should be at a maximum. 
+0

+1 gracias por la comprensión; sin embargo, estoy usando una spline para aproximarme a un modelo computacionalmente intensivo. –

+0

Tenía miedo de eso. Aconsejaría revisar los ejemplos en la página splinefun para obtener una mejor idea de cómo se comportan con argumentos de orden superior (que 1) para derivar =. Tuvo sentido después de dedicar un tiempo a planear, pero al principio los resultados parecían bastante discordantes. –

Cuestiones relacionadas