使用numDeriv R包进行两次微分失败

时间:2014-07-09 12:39:02

标签: r numerical-methods derivative

您如何解释使用numDeriv包进行数值两次微分的失败?

下面是一个函数Y及其一阶导数dY

Y <- function(x, A=1, B=1, a=1){
  A*cos(a*x) + B*sin(a*x) - x/2/a*cos(a*x)
}
dY <- function(x, A=1, B=1, a=1){
  -a*A*sin(a*x) + a*B*cos(a*x) - cos(a*x)/2/a + x/2/a*sin(a*x)
}

以下是grad包的numDeriv功能的成功说明:

library(numDeriv)
x <- c(0.2,0.4,0.6)
grad(Y, x)
## [1] 0.31123 0.14900 0.01742
dY(x)
## [1] 0.31123 0.14900 0.01742

下面的两次分化工作也很好:

dYnum <- function(x) grad(Y, x)
d2Ynum <- function(x) grad(dYnum, x)
d2Ynum(x)
## [1] -0.8820 -0.7368 -0.5777
grad(dY, x)
## [1] -0.8821 -0.7368 -0.5777

但是当用一个尖锐的近似替换Y时,两次不同的方法会失败:

xx <- seq(0.01, 0.99, by=0.01)
Yapprox <- approxfun(xx, Y(xx))
dYnum <- function(x) grad(Yapprox, x)
dYnum(x) # first-order derivative is OK
## [1] 0.31124 0.14901 0.01743
d2Ynum <- function(x) grad(dYnum, x)
d2Ynum(x) # not the good result
## [1] -2698 -1127  -589
grad(dY, x)  # this is the good result
## [1] -0.8821 -0.7368 -0.5777

但是,当用大概替换dYnum时,它会再次起作用:

xx <- seq(0.1, 0.9, by=0.01)
dYnumapprox <- approxfun(xx, dYnum(xx)) # approxfun(xx, grad(Yapprox, xx))
d2Ynum_ <- function(x) grad(dYnumapprox, x)
d2Ynum_(x) 
## [1] -0.8820 -0.7368 -0.5777

2 个答案:

答案 0 :(得分:1)

你忘记了上一学期的内在衍生物。分母中的a取消内在导数。所以它应该是

  -a*A*sin(a*x) + a*B*cos(a*x) - cos(a*x)/2/a + x/2*sin(a*x)

至于错误,我怀疑罪魁祸首是近似值。取决于近似的类型,函数值中的采样点之间的误差可以是任意大的,这仅在计算导数时放大。使用少得多的采样点可以获得更好的结果,而不是99。


RTFM :每R-manual approxfun只提供分段常数或线性近似值。两者都不可区分。这意味着分段线性逼近的导数在跳跃时是分段常数,而二阶导数是分段零,在采样点处具有Δ峰值。通过分段线性函数重新插值一阶导数,虽然不是最大数学过程,但会导致合理的结果。

使用R-manual splinefun获得实际上是两次可微分的插值函数。

答案 1 :(得分:0)

不确定你的期望:不是没有什么是数字差异称为&#34;误差放大&#34; 。您的dYnum值与非近似值不同的事实应该是一个巨大的红旗,警告您,您为第二次数值微分提供的数据已经产生了噪音。 grad(或任何其他数值微分器)函数然后尽职地区分由数据中的噪声引起的高频分量。