Nothing
#
#
# strausshard.S
#
# $Revision: 2.38 $ $Date: 2022/05/23 02:33:06 $
#
# The Strauss/hard core process
#
# StraussHard() create an instance of the Strauss-hardcore process
# [an object of class 'interact']
#
#
# -------------------------------------------------------------------
#
StraussHard <- local({
BlankStraussHard <-
list(
name = "Strauss - hard core process",
creator = "StraussHard",
family = "pairwise.family", # evaluated later
pot = function(d, par) {
v <- (d <= par$r)
v[ d <= par$hc ] <- (-Inf)
v
},
par = list(r = NULL, hc = NULL), # filled in later
parnames = c("interaction distance",
"hard core distance"),
hasInf = TRUE,
selfstart = function(X, self) {
# self starter for StraussHard
nX <- npoints(X)
if(nX < 2) {
# not enough points to make any decisions
return(self)
}
r <- self$par$r
md <- minnndist(X)
if(md == 0) {
warning(paste("Pattern contains duplicated points:",
"hard core must be zero"))
return(StraussHard(r=r, hc=0))
}
if(!is.na(hc <- self$par$hc)) {
# value fixed by user or previous invocation
# check it
if(md < hc)
warning(paste("Hard core distance is too large;",
"some data points will have zero probability"))
return(self)
}
# take hc = minimum interpoint distance * n/(n+1)
hcX <- md * nX/(nX+1)
StraussHard(r=r, hc = hcX)
},
init = function(self) {
r <- self$par$r
hc <- self$par$hc
if(length(hc) != 1)
stop("hard core distance must be a single value")
if(!is.na(hc)) {
if(!is.numeric(hc) || hc <= 0)
stop("hard core distance hc must be a positive number, or NA")
if(!is.numeric(r) || length(r) != 1 || r <= hc)
stop("interaction distance r must be a number greater than hc")
}
},
update = NULL, # default OK
print = NULL, # default OK
interpret = function(coeffs, self) {
loggamma <- as.numeric(coeffs[1])
gamma <- exp(loggamma)
return(list(param=list(gamma=gamma),
inames="interaction parameter gamma",
printable=dround(gamma)))
},
valid = function(coeffs, self) {
loggamma <- as.numeric(coeffs[1])
return(is.finite(loggamma))
},
project = function(coeffs, self) {
loggamma <- as.numeric(coeffs[1])
if(is.finite(loggamma))
return(NULL)
hc <- self$par$hc
if(hc > 0) return(Hardcore(hc)) else return(Poisson())
},
irange = function(self, coeffs=NA, epsilon=0, ...) {
r <- self$par$r
hc <- self$par$hc
if(anyNA(coeffs))
return(r)
loggamma <- coeffs[1]
if(abs(loggamma) <= epsilon)
return(hc)
else
return(r)
},
hardcore = function(self, ...) {
return(self$par$hc)
},
version=NULL, # evaluated later
# fast evaluation is available for the border correction only
can.do.fast=function(X,correction,par) {
return(all(correction %in% c("border", "none")))
},
fasteval=function(X,U,EqualPairs,pairpot,potpars,correction,
splitInf=FALSE, ...) {
#' fast evaluator for StraussHard interaction
if(!all(correction %in% c("border", "none")))
return(NULL)
if(spatstat.options("fasteval") == "test")
message("Using fast eval for StraussHard")
r <- potpars$r
hc <- potpars$hc
hclose <- (strausscounts(U, X, hc, EqualPairs) != 0)
rclose <- strausscounts(U, X, r, EqualPairs)
if(!splitInf) {
answer <- ifelseAX(hclose, -Inf, rclose)
answer <- matrix(answer, ncol=1)
} else {
answer <- ifelseAX(hclose, 0, rclose)
answer <- matrix(answer, ncol=1)
attr(answer, "-Inf") <- hclose
}
return(answer)
},
Mayer=function(coeffs, self) {
# second Mayer cluster integral
gamma <- exp(as.numeric(coeffs[1]))
r <- self$par$r
hc <- self$par$hc
return(pi * (hc^2 + (1-gamma) * (r^2 - hc^2)))
},
delta2 = function(X, inte, correction, ..., sparseOK=FALSE) {
r <- inte$par$r
hc <- inte$par$hc
#' positive part
U <- as.ppp(X)
nU <- npoints(U)
cl <- weightedclosepairs(U, r, correction=correction, what="indices")
if(is.null(cl)) # can't handle edge correction
return(NULL)
v <- sparseMatrix(i=cl$i, j=cl$j, x=cl$weight,
dims=c(nU, nU))
#' hard core part
hcl <- closepairs(U, hc, what="indices")
ihit <- hcl$i
jhit <- hcl$j
vh <- NULL
if(is.ppp(X)) {
#' count conflicts between data points
nhit <- as.integer(table(factor(jhit, levels=seq_len(nU))))
#' for a conflicting pair X[i], X[j],
#' status of X[j] will change when X[i] is deleted
#' iff X[j] is only in conflict with X[i]
changes <- (nhit == 1)
if(any(changes)) {
changesJ <- changes[jhit]
vh <- sparseMatrix(i=ihit[changesJ], j=jhit[changesJ], x=TRUE,
dims=c(nU, nU))
}
} else if(is.quad(X)) {
#' count conflicts with existing data points
izdat <- is.data(X)
hitdata <- izdat[ihit]
nhitdata <- as.integer(table(factor(jhit[hitdata],
levels=seq_len(nU))))
#' for a conflicting pair U[i], U[j],
#' status of U[j] will change when U[i] is added/deleted
#' iff EITHER
#' U[i] = X[i] is a data point and
#' U[j] is only in conflict with X[i],
#' OR
#' U[i] is a dummy point,
#' U[j] has no conflicts with X.
changesJ <- (hitdata & (nhitdata[jhit] == 1)) |
(!hitdata & (nhitdata[jhit] == 0))
if(any(changesJ))
vh <- sparseMatrix(i=ihit[changesJ], j=jhit[changesJ], x=TRUE,
dims=c(nU, nU))
} else stop("X should be a ppp or quad object")
# pack up
if(!sparseOK) {
v <- as.matrix(v)
if(!is.null(vh)) vh <- as.matrix(vh)
}
attr(v, "deltaInf") <- vh
return(v)
}
)
class(BlankStraussHard) <- "interact"
StraussHard <- function(r, hc=NA) {
instantiate.interact(BlankStraussHard, list(r=r, hc=hc))
}
StraussHard <- intermaker(StraussHard, BlankStraussHard)
StraussHard
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.