使用渐变函数R

时间:2017-02-05 14:16:45

标签: r optimization numeric numerical-methods hessian

我需要使用我的渐变函数计算 Hessian 数字(由公式编程,不是数字)。像numDerivrootSolve这样的包使用不满足我需要的数字渐变来计算粗体。我需要在optim包中执行内部(没有我可以调用的单独方法),但是处理我的优化任务的唯一方法在nlopt包中很好地实现并传递了它为了获得粗麻布,optim的最佳值对于我的程序来说太贵了。

所以我需要一些使用非数值梯度计算Hessian的函数(参见例如这些公式https://neos-guide.org/content/difference-approximations)。我不能做这样的功能,因为我不明白如何选择参数h(增量),我的功能非常敏感。我可以在R中找到这样的函数,还是从optim包以某种方式检索它?或者有人至少可以解释如何为h选择最小化值的错误,那么我会自己发布这个函数吗?

1 个答案:

答案 0 :(得分:3)

如果我理解正确,你应该使用numDeriv::jacobian(),它采用向量值函数并计算矩阵(每个元素相对于每个输入的导数),并将其应用于分析梯度函数。 jacobian()确实使用数值近似(Richardson外推,确切地说),但我没有看到任何其他方法可以从黑盒渐变函数到Hessian?

您需要指定(或使用默认值)数字“delta”函数(默认为1e-4)。另一方面,optim()用于计算Hessian的内部代码也使用有限差异:请参阅herehere ...

下面我定义一个函数,它的渐变函数和它的Hessian;此代码显示jacobian(grad(x))与Hessian相同(对于特定的测试用例)。

library(numDeriv)
x1 <- c(1,1,1)

测试我没有弄乱渐变和Hessian函数:

all.equal(grad(f,x1),g(x1)) ## TRUE
all.equal(h(x1),hessian(f,x1)) ## TRUE

我的Hessian和渐变的雅可比行列式的数值等价:

all.equal(h(x1),jacobian(g,x1)) ## TRUE

测试功能:

f <- function(x) {
  sin(x[1])*exp(x[2])*x[3]^2
}

g <- function(x) {
  c(cos(x[1])*exp(x[2])*x[3]^2,
    sin(x[1])*exp(x[2])*x[3]^2,
    sin(x[1])*exp(x[2])*2*x[3])
}  

h <- function(x) {
    m <- matrix(NA,3,3)
    m[lower.tri(m,diag=TRUE)] <-
        c(-sin(x[1])*exp(x[2])*x[3]^2,
          cos(x[1])*exp(x[2])*x[3]^2,
          cos(x[1])*exp(x[2])*2*x[3],
    # col 2
           sin(x[1])*exp(x[2])*x[3]^2,
           sin(x[1])*exp(x[3])*2*x[3],
    # col 3
           sin(x[1])*exp(x[2])*2)
    m <- Matrix::forceSymmetric(m,"L")
    m <- unname(as.matrix(m))
    return(m)
}