-
Notifications
You must be signed in to change notification settings - Fork 0
/
myConstrOptim.R
74 lines (74 loc) · 2.3 KB
/
myConstrOptim.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
myConstrOptim = function (theta, f, grad, ui, ci, mu = 1e-04, control = list(),
method = if (is.null(grad)) "Nelder-Mead" else "BFGS", outer.iterations = 100,
outer.eps = 1e-05, ..., hessian = FALSE)
{
if (!is.null(control$fnscale) && control$fnscale < 0)
mu <- -mu
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
}
dR <- function(theta, theta.old, ...) {
ui.theta <- ui %*% theta
gi <- drop(ui.theta - ci)
gi.old <- drop(ui %*% theta.old - ci)
dbar <- colSums(ui * gi.old/gi - ui)
grad(theta, ...) - mu * dbar
}
if (any(ui %*% theta - ci <= 0))
stop("initial value is not in the interior of the feasible region")
obj <- f(theta, ...)
r <- R(theta, theta, ...)
fun <- function(theta, ...) R(theta, theta.old, ...)
gradient <- if (method == "SANN") {
if (missing(grad))
NULL
else grad
}
else function(theta, ...) dR(theta, theta.old, ...)
totCounts <- 0
s.mu <- sign(mu)
for (i in seq_len(outer.iterations)) {
obj.old <- obj
r.old <- r
theta.old <- theta
a <- optim(theta.old, fun, gradient, control = control,
method = method, hessian = hessian, ...)
r <- a$value
if (is.finite(r) && is.finite(r.old) && abs(r - r.old) <
(0.001 + abs(r)) * outer.eps)
break
theta <- a$par
totCounts <- totCounts + a$counts
obj <- f(theta, ...)
if (s.mu * obj > s.mu * obj.old)
break
}
if (i == outer.iterations) {
a$convergence <- 7
a$message <- gettext("Barrier algorithm ran out of iterations and did not converge")
}
if (mu > 0 && obj > obj.old) {
a$convergence <- 11
a$message <- gettextf("Objective function increased at outer iteration %d",
i)
}
if (mu < 0 && obj < obj.old) {
a$convergence <- 11
a$message <- gettextf("Objective function decreased at outer iteration %d",
i)
}
a$outer.iterations <- i
a$counts <- totCounts
a$barrier.value <- a$value
a$value <- f(a$par, ...)
a$barrier.value <- a$barrier.value - a$value
a
}