Проблема с 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, NaNс (исключая начальную точку). В этом случае BFGS иногда будет возвращать оптимальное значение NaN и соответствующий параметр минимизации вне набора ограничений.

В constrOptimЦелевая функция, подаваемая в BFGS, определяется как

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
}

Мой вопрос

Мне кажется, что очевидное решение проблемы - просто вернуть sign(mu) * Inf вместо NaN если есть gi < 0, но может ли это исправить привести к другим проблемам?

1 ответ

Решение

После правильной нормализации градиента

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")

Я больше не могу повторить проблему. Похоже, что проблема была вызвана неправильным взвешиванием градиента целевой функции и градиента члена логарифмического барьера во внутреннем градиенте.

Тем не менее, я все еще думаю, что возврат Inf за границу был бы более надежным, чем возврат NaN.

Другие вопросы по тегам