您如何解释使用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
答案 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
(或任何其他数值微分器)函数然后尽职地区分由数据中的噪声引起的高频分量。