Skip to content

Commit fb8c3a8

Browse files
committed
add optimConstr tests + constrOptim convergence code consistency fix
1 parent d3aa819 commit fb8c3a8

File tree

2 files changed

+66
-5
lines changed

2 files changed

+66
-5
lines changed

src/library/stats/R/constrOptim.R

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,19 @@ constrOptim <-
8282
if (s.mu * obj > s.mu * obj.old) break
8383
}
8484
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)
85+
a$convergence <- 21L # 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)
8787
}
8888
if (i == outer.iterations) {
89-
a$convergence <- 7
89+
a$convergence <- 7L
9090
a$message <- gettext("Barrier algorithm ran out of iterations and did not converge")
9191
}
9292
if (mu > 0 && obj > obj.old) {
93-
a$convergence <- 11
93+
a$convergence <- 11L
9494
a$message <- gettextf("Objective function increased at outer iteration %d", i)
9595
}
9696
if (mu < 0 && obj < obj.old) {
97-
a$convergence <- 11
97+
a$convergence <- 11L
9898
a$message <- gettextf("Objective function decreased at outer iteration %d", i)
9999
}
100100
a$outer.iterations <- i
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
objective <- function(p){
2+
out <- -log(p[1] + p[2]) + log(p[2]) + log(1 - p[1] - p[2])
3+
out
4+
}
5+
6+
gradfun <- function(p){
7+
out <- c(
8+
-1/(p[1] + p[2]) - 1/(1 - p[1] - p[2]),
9+
-1/(p[1] + p[2]) + 1/p[2] - 1/(1 - p[1] - p[2])
10+
)
11+
out
12+
}
13+
startp <- c(1/3, 1/3)
14+
small <- 1e-6
15+
CI <- c(small, small, small - 1)
16+
UI <- rbind(
17+
c(1, 0), # p1>small
18+
c(0, 1), # p2>small
19+
c(-1, -1) # p1+p2 < 1-small
20+
)
21+
22+
out <- constrOptim(
23+
theta = startp,
24+
f = objective,
25+
grad = gradfun,
26+
ui = UI,
27+
ci = CI,
28+
outer.iterations = 100,
29+
method = "BFGS"
30+
)
31+
32+
# Convergence code 0 (set by optim)
33+
stopifnot(identical(out$convergence, 0L))
34+
35+
set.seed(0)
36+
startp <- c(1/3, 1/3) + rnorm(2) * 1e-6
37+
38+
out <- constrOptim(
39+
theta = startp,
40+
f = objective,
41+
grad = gradfun,
42+
ui = UI,
43+
ci = CI,
44+
outer.iterations = 100,
45+
method = "BFGS"
46+
)
47+
# Convergence code 21 (set by constrOptim)
48+
stopifnot(identical(out$convergence, 21L))
49+
50+
out <- constrOptim(
51+
theta = startp,
52+
f = objective,
53+
grad = gradfun,
54+
ui = UI,
55+
ci = CI,
56+
outer.iterations = 100,
57+
method = "Nelder-Mead"
58+
)
59+
60+
# Convergence code 0 (set by optim)
61+
stopifnot(identical(out$convergence, 0L))

0 commit comments

Comments
 (0)