0

nloptr包中,类似的函数lbfgs()似乎需要一个渐变函数。但如果我不提供渐变功能,它们也可以工作。

我的问题是:是nloptr自动计算梯度函数,还是lbfgs()不需要梯度函数?

如果目标函数很复杂,可以nloptr自动计算梯度函数,还是必须由用户提供?

library(nloptr)

## example for auglag()
x0 <- c(1, 1)
fn <- function(x) {
  (x[1] - 2) ^ 2 + (x[2] - 1) ^ 2
}

hin <- function(x) {
  -0.25 * x[1] ^ 2 - x[2] ^ 2 + 1 # hin >= 0
}

heq <- function(x) {
  x[1] - 2 * x[2] + 1 # heq == 0
}
## it works even gr = NULL
auglag(x0, fn, gr = NULL, hin = hin, heq = heq, localsolver = "LBFGS")

gr <- function(x) nl.grad(x, fn)
## it also works, when provide the gradient function.
auglag(x0, fn, gr = gr, hin = hin, heq = heq, localsolver = "LBFGS")
4

1 回答 1

1

?lbfgs中,我们读到如果没有提供这个函数,它确实会自动计算梯度:

gr:函数fn的梯度;如果未指定,将以数字方式计算。

深入研究 的源代码lbfgs,我们看到它使用以下nl.grad函数执行此操作:

if (is.null(gr)) {
    gr <- function(x) nl.grad(x, fn)
}

nl.grad从(或来自)的源代码?nl.grad可以清楚地看出,该函数执行中心差分以数值计算梯度。这种估计梯度的方法仅评估 2k 个附近点的 k 个变量的函数,这对于简单和复杂的函数都应该适用。

于 2017-05-02T02:10:40.563 回答