как я могу оценить производную сплайн-функции в R?

R может сгенерировать сплайн-функцию, используя splinefun() в библиотеке сплайнов. Однако мне нужно оценить эту функцию по ее первой и второй производной. Есть ли способ сделать это?

Например

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

Как я могу оценить f'(x) для вектора x?


person David LeBauer    schedule 02.12.2010    source источник


Ответы (3)


Это очень легко сделать, так как возможность вычислять функцию по ее производной встроена в функцию!

 f_of_x(x, deriv = 1)

Спасибо R-Core!

person David LeBauer    schedule 02.12.2010
comment
Это не оператор ==, а =. - person IRTFM; 02.12.2010

Вас также может заинтересовать функция TkSpline в пакете TeachingDemos, которая отображает сплайн-функцию вместе с ее производными.

person Greg Snow    schedule 02.12.2010

Использование аргумента deriv = для splinefun разумно, и следует добавить, что вторая и третья производные должны быть доступны, но если вы поработаете с примерами, вы поймете, что линейные аппроксимации имеют неровности или разрывы на более высоких степенях. .

В ситуации, когда у вас есть аналитическое выражение, есть некоторые, по общему признанию, ограниченные положения для алгоритмического дифференцирования. См. страницу справки (deriv) для более подробной информации.

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

А затем построить «вручную» вторую функцию с этим результатом. Или вы можете использовать пример DD, представленный на странице help(deriv), чтобы немного автоматизировать процесс:

 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.
person IRTFM    schedule 02.12.2010
comment
+1 спасибо за понимание; однако я использую сплайн для аппроксимации модели с интенсивными вычислениями. - person David LeBauer; 03.12.2010
comment
Я боялся этого. Я бы посоветовал просмотреть примеры на странице splinefun, чтобы получить лучшее представление о том, как они ведут себя с аргументами более высокого порядка (чем 1), чтобы получить =. Это имело смысл после того, как я потратил некоторое время на построение графика, но поначалу результаты казались довольно неприятными. - person IRTFM; 03.12.2010