constrOptim 问题

Issue with constrOptim

使用constrOptim函数进行约束优化时,有时会出现以下错误信息:

Error in optim(theta.old, fun, gradient, control = control, method = method,  : 
  initial value in 'vmmin' is not finite

例子

x <- c(-0.2496881061155757641767394261478330008685588836669921875, 
        0.0824038146359631351600683046854101121425628662109375, 
        0.25000000111421105675191256523248739540576934814453125)

nw <- length(x)
ui <- diag(1, nrow = nw)
ui <- rbind(ui, rep(0, nw))
ui[cbind(2:(nw + 1), 1:nw)] <- -1
ci <- rep(-0.8 / (nw + 1), nw + 1)

constrOptim(theta = rep(0, nw), f = function(theta) mean((theta - x)^2),
            grad = function(theta) 2 * (theta - x), ui = ui, ci = ci, 
            method = "BFGS")

我所知道的

问题发生在constrOptim内部的迭代过程中,当结果非常接近边界时,BFGS优化器评估的几乎所有点都是NaNs(不包括初始点)。在这种情况下,BFGS 有时会 return 一个 NaN 的最优值和一个相应的约束集外的最小化参数。

constrOptim中,提供给BFGS的objective函数由

给出
R <- function(theta, theta.old, ...) {
  ui.theta <- ui %*% theta
  gi <- ui.theta - ci
  if (any(gi < 0))  {
    return(NaN) 
  }
  gi.old <- ui %*% theta.old - ci
  bar <- sum(gi.old * log(gi) - ui.theta)
  if (!is.finite(bar)) 
    bar <- -Inf
  f(theta, ...) - mu * bar
}

我的问题

在我看来,问题的明显解决方案是简单地 return sign(mu) * Inf 而不是 NaN 如果有任何 gi < 0,但是这个可以解决吗会导致其他问题吗?

正确归一化梯度后

constrOptim(theta = rep(0, nw), f = function(theta) mean((theta - x)^2),
            grad = function(theta) 2 / nw * (theta - x), ui = ui, ci = ci, 
            method = "BFGS")

我无法再重现该问题。看来这个问题是由于 objective 函数的梯度和内部梯度中对数障碍项的梯度的错误加权引起的。

但是,我仍然认为在边界外返回 Inf 会比返回 NaN 更稳健。