如何为 nlm 提供梯度(或粗麻布)?

How does one supply a gradient (or hessian) to nlm?

在非线性最小化函数 stats::nlm 的帮助文件中,它指出参数之一 f 是(强调我的):

the function to be minimized, returning a single numeric value. This should be a function with first argument a vector of the length of p followed by any other arguments specified by the ... argument. If the function value has an attribute called gradient or both gradient and hessian attributes, these will be used in the calculation of updated parameter values.

这是否意味着梯度和粗麻布由如下命令提供:

attr(f, 'gradient') <- function(...){...}

这个函数的输入和输出应该是什么?

将此与一般优化器进行对比 stats::optim:

optim(par, fn, gr = NULL, ...,
  method = c("Nelder-Mead", "BFGS", "CG", "L-BFGS-B", "SANN",
             "Brent"), ...)

其中梯度被显式指定为 optim 的参数,示例参见:how to propery specify a gradient function for use in optim() or other optimizer

检查 nlm 的代码内部没有帮助。

这是一个简单的一维示例:

f <- function(x) {
  out <- -exp(-0.5 * x^2)
  attr(out, 'gradient') <- -x * out 
  attr(out, 'hessian') <-  (x^2 - 1) * out
  return(out)
}

nlm(f, 1.3, hessian = TRUE, check.analyticals = TRUE)

给出:

# $minimum
# [1] -1
# 
# $estimate
# [1] 4.23687e-14
# 
# $gradient
# [1] 4.23687e-14
# 
# $hessian
# [,1]
# [1,]    1
# 
# $code
# [1] 1
# 
# $iterations
# [1] 3