Skip to content

Commit e3600f4

Browse files
committed
Proposed fix for bug 17703.
1 parent dc6777a commit e3600f4

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

src/library/stats/R/constrOptim.R

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,37 @@ constrOptim <-
5454
} else function(theta, ...) dR(theta, theta.old, ...)
5555
totCounts <- 0
5656
s.mu <- sign(mu)
57+
a <- NULL
58+
optim_failure <- FALSE
5759

5860
for(i in seq_len(outer.iterations)) {
5961
obj.old <- obj
6062
r.old <- r
6163
theta.old <- theta
64+
a.old <- a
6265

6366
a <- optim(theta.old, fun, gradient, control = control,
6467
method = method, hessian = hessian, ...)
6568
r <- a$value
6669
if (is.finite(r) && is.finite(r.old) &&
6770
abs(r - r.old) < (1e-3 + abs(r)) * outer.eps) break
6871
theta <- a$par
69-
totCounts <- totCounts + a$counts
72+
73+
if (any(ui%*%theta-ci<0) || !is.finite(r) || any(!is.finite(theta))) {
74+
i <- i - 1
75+
a <- a.old
76+
optim_failure <- TRUE
77+
break
78+
}
79+
80+
totCounts <- totCounts + a$counts
7081
obj <- f(theta, ...)
7182
if (s.mu * obj > s.mu * obj.old) break
7283
}
84+
if (optim_failure) {
85+
a$convergence <- 21 # See https://github.com/nashjc/optimx/blob/main/man/optimx.Rd
86+
a$message <- gettextf("Returning solution from outer iteration %d, either because the solution is not in the feasible region or `optim()` provided non-finite outputs. Consider either checking the gradient implementation or using a derivative-free opimizer or reducing `outer.eps`.", i)
87+
}
7388
if (i == outer.iterations) {
7489
a$convergence <- 7
7590
a$message <- gettext("Barrier algorithm ran out of iterations and did not converge")

src/library/stats/man/constrOptim.Rd

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ constrOptim(theta, f, grad, ui, ci, mu = 1e-04, control = list(),
6666
\code{method = "Nelder-Mead"}. It should take arguments matching
6767
those of \code{f} and return a vector containing the gradient.
6868

69+
In some rare cornercases, the call to \code{optim} inside the outer
70+
loop might lead to non-finite function value or parameter values or
71+
parameters outside the feasible region. In these cases, the outer
72+
loop is stopped early and the last useful result is returned. The
73+
\code{message} item in the output list warns the user of this
74+
behaviour.
75+
6976
}
7077
\value{
7178
As for \code{\link{optim}}, but with two extra components:

0 commit comments

Comments
 (0)