Skip to content

Commit c417215

Browse files
committed
is.inCH() now times out lpSolve() if it takes too long and retries with invariantly perturbed inputs. References statnet/ergm-private#230.
1 parent 043344a commit c417215

File tree

2 files changed

+42
-14
lines changed

2 files changed

+42
-14
lines changed

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: ergm
2-
Version: 3.10.0-4669
3-
Date: 2018-10-25
2+
Version: 3.10.0-4674
3+
Date: 2018-10-26
44
Title: Fit, Simulate and Diagnose Exponential-Family Models for Networks
55
Authors@R: c(
66
person("Mark S.", "Handcock", role=c("aut"), email="handcock@stat.ucla.edu"),

R/is.inCH.R

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,19 +115,47 @@ is.inCH <- function(p, M, verbose=FALSE, ...) { # Pass extra arguments directly
115115
## NOTE: PCA code has been moved to .Hummel.steplength().
116116
##
117117

118-
L = cbind(1, M)
119-
118+
timeout <- 1
120119
for(i in seq_len(nrow(p))){
121-
q = c(1, p[i,])
122-
############################################
123-
# USE lp FUNCTION FROM lpSolve PACKAGE:
124-
#' @importFrom lpSolve lp
125-
ans <- lp(objective.in = c(-q, q),
126-
const.mat = rbind( c(q, -q), cbind(L, -L)),
127-
const.dir = "<=",
128-
const.rhs = c(1, rep(0, NROW(L))),
129-
...
130-
)
120+
############################################
121+
# USE lp FUNCTION FROM lpSolve PACKAGE:
122+
#' @importFrom lpSolve lp
123+
124+
## This works around what appears to be a bug in lpsolve library
125+
## that causes the process the process to reproducibly hang on
126+
## some inputs. After a time limit, the call is terminated and
127+
## re-attempted after randomly shifting p and M (preserving
128+
## whether one is in the convex hull of the other).
129+
130+
## TODO: Parametrize the timeout settings and/or figure out what's
131+
## wrong with lpSolve().
132+
133+
repeat{
134+
ans <- forkTimeout({
135+
L <- cbind(1, M)
136+
q <- c(1, p[i,])
137+
lp(objective.in = c(-q, q),
138+
const.mat = rbind( c(q, -q), cbind(L, -L)),
139+
const.dir = "<=",
140+
const.rhs = c(1, rep(0, NROW(L))),
141+
...
142+
)
143+
}, timeout=timeout, unsupported="silent", onTimeout=list(objval=NA))
144+
145+
if(is.na(ans$objval)){
146+
# Perturb p and M.
147+
shift <- rnorm(1)
148+
M <- M + shift
149+
p <- p + shift
150+
# Increase timeout, in case it's actually a difficult problem.
151+
timeout <- timeout*2
152+
}else{
153+
# Reduce the timeout by a little bit.
154+
timeout <- max(timeout/2^(1/5),1)
155+
break
156+
}
157+
}
158+
131159
if(ans$objval!=0){
132160
if(verbose>1) message(sprintf("is.inCH: iter= %d, outside hull.",i))
133161
return(FALSE) #if the min is not zero, the point p[i,] is not in the CH of the points M

0 commit comments

Comments
 (0)