rmh.default {spatstat} | R Documentation |
Generates a random point pattern, simulated from a chosen point process model, using the Metropolis-Hastings algorithm.
rmh.default(model,start,control,verbose=TRUE,...)
model |
A named list of objects specifying the point process model
that is to be simulated, having (some of) the following components:
|
start |
List of parameters determining the initial state of
the algorithm:
n.start and x.start are incompatible;
precisely one of them should be specified.
See Details for details.
|
control |
List of parameters controlling the iterative behaviour
and termination of the algorithm:
|
verbose |
A logical scalar; if verbose is TRUE then
warnings are printed out whenever the storage space alloted to
the underlying Fortran code, to hold the generated points, gets
increased. If it is FALSE then this process proceeds silently. |
... |
Further arguments, e.g. to be passed to trend functions. |
This function generates simulated realisations from any of a range of
spatial point processes, using the Metropolis-Hastings algorithm.
It is the default method for the generic function rmh
.
This function executes a Metropolis-Hastings algorithm with birth, death and shift proposals as described in Geyer and Moller (1994).
The argument model
specifies the point process model to be
simulated. It is a list with the following components:
'strauss'
'straush'
'sftcr'
'straussm'
'straushm'
'dgs'
'diggra'
'geyer'
'lookup'
See the section Extensions for the possibility of extending this list of options.
par
should be as follows, for each of the available conditional
intensity functions:
beta,gamma,r
which are respectively the ``base''
intensity, the pair-wise interaction parameter and the
interaction radius. Note that gamma
must be less than
or equal to 1.
beta,gamma,r,hc
where beta
, gamma
,
and r
are as for the Strauss process, and hc
is
the hardcore radius. Of course hc
must be less than
r
.
beta,sigma,kappa
. Again
beta
is a ``base'' intensity. The pairwise
interaction between two points u != v is
-(sigma/||u-v||)^(2/kappa)
Note that it is necessary that 0 < kappa <1.
beta
:
A vector of ``base'' intensities, one for each possible
type.
gamma
:
A symmetric matrix of interaction parameters,
with gamma_ij pertaining to the interaction between
type i and type j.
radii
:
A symmetric matrix of interaction radii, with
entries r_ij pertaining to the interaction between type
i and type j.
beta
and gamma
as for straussm
and
two ``radii'' components:
iradii
: the interaction radii
hradii
: the hardcore radii
which are both symmetric matrices of nonnegative numbers.
The entries of hradii
must be less than the
corresponding entries
of iradii
.
beta
and rho
. This process has pairwise interaction
function equal to
e(t) = sin^2((pi * t)/(2 * rho))
for t < rho, and equal to 1 for t >= rho.
beta
,
kappa
, delta
and rho
. This process has
pairwise interaction function e(t) equal to 0
for t < delta, equal to
((t-delta)/(rho-delta))^kappa
for delta <= t < rho, and equal to 1 for delta >= rho. Note that here we use the symbol kappa where Diggle, Gates, and Stibbard use beta since we reserve the symbol beta for an intensity parameter.
beta
, gamma
, r
, and sat
.
The components beta
, gamma
, r
are as for
the Strauss model, and sat
is the ``saturation''
parameter. The model is Geyer's ``saturation'' point process
model, a modification of the Strauss process in which
we effectively impose an upper limit (sat
) on the number of
neighbours which will be counted as close to a given point.
Explicitly, a saturation point process with interaction radius r, saturation threshold s, and parameters beta and gamma, is the point process in which each point x[i] in the pattern X contributes a factor
beta gamma^min(s,t(x[i],X))
to the probability density of the point pattern, where t(x[i],X) denotes the number of ``r-close neighbours'' of x[i] in the pattern X.
beta
, r
, and h
, or just with components
beta
and h
.
This model is the pairwise interaction process with an isotropic interaction given by any chosen function H. Each pair of points x[i], x[j] in the point pattern contributes a factor H(d(x[i],x[j])) to the probability density, where d denotes distance and H is the pair interaction function.
The component beta
is a
(positive) scalar which determines the ``base'' intensity
of the process.
In this implementation, H must be a step function. It is specified by the user in one of two ways.
r
is present, then r
is assumed to
give the locations of jumps in the function H,
while the vector h
gives the corresponding
values of the function.
Specifically, the interaction function
H(t) takes the value h[1]
for distances t in the interval
[0, r[1])
; takes the value h[i]
for distances t in the interval
[r[i-1], r[i])
where
i = 2, ..., n;
and takes the value 1 for t >= r[n].
Here n denotes the length of r
.
The components r
and h
must be numeric vectors of equal length.
The r
values must be strictly positive, and
sorted in increasing order.
The entries of h
must be non-negative.
If any entry of h
is greater than 1,
then the entry h[1]
must be 0 (otherwise the specified
process is non-existent).
Greatest efficiency is achieved if the values of
r
are equally spaced.
[Note: The usage of r
and h
has changed from the previous usage in spatstat
versions 1.4-7 to 1.5-1, in which ascending order was not required,
and in which the first entry of r
had to be 0.]
r
is absent, then h
must be
an object of class "stepfun"
specifying
a step function. Such objects are created by
stepfun
.
The stepfun object h
must be right-continuous
(which is the default using stepfun
.)
The values of the step function must all be nonnegative.
The values must all be less than 1
unless the function is identically zero on some initial
interval [0,r). The rightmost value (the value of
h(t)
for large t
) must be equal to 1.
Greatest efficiency is achieved if the jumps (the ``knots'' of the step function) are equally spaced.
x
and y
arguments. Put another way,
it must be capable of calculating the trend value at a
number of points, simultaneously, and should return the
vector of corresponding trend values. An image (see
im()
) provides the trend values at a grid of
points in the observation window and determines the trend
value at other points as the value at the nearest grid point.
Note that the trend or trends must be non-negative; no checking is done for this.
owin
by as.owin()
.
The argument start
determines the initial state of the
Metropolis-Hastings algorithm. Possible components are
w
. For a
multitype point process, n.start
may be a vector
(of length equal to the number of types) giving the number
of points of each type to be generated. Incompatible with
x.start
.
The component n.start
may be a scalar (integer)
or, for a multitype process, a vector of integers of
length equal to the number of types.
A vector-valued n.start
is meaningful only
if p
(the probability of a shift as opposed to a birth or
death) is equal to 1 (so that we are conditioning on the number
of points). When p < 1, if n.start
is vector valued
then it is effectively replaced by its sum.
The resulting set of uniformly generated points gives
the Metropolis-Hastings algorithm an initial state from
which to start. (Actually, when p < 1, the number
n.start
gets multiplied by the ratio of the area of
the expanded window to that of the original window.
Then that many points are uniformly generated in the expanded
window; see below for a discussion of the expanded window.)
The value of n.start
should be roughly equal to
(an educated guess at) the expected number of points which
will be generated inside the window.
"ppp"
, or data which can be coerced
to this class by as.ppp
). Incompatible with
n.start
.
The component x.start
is a point pattern (an object
of class ppp
, or an object which can be coerced
to this class by as.ppp()
). This object provides
an alternative means of specifying the initial ``state''
or configuration for the Metropolis-Hastings algorithm.
If x.start
is specified, but x.start$window
is NULL
, then this gap is filled in by the component
w
of start
. If x.start$window
is present, and if w
is specified as well, the
latter is used as a window to which to clip the final
simulated pattern. Thus in such circumstances it is only
sensible to specify a value of w
which is contained
in x.start$window
. However no checking
is done for this.
The simulated pattern is constructed in x.start$window
.
No expansion takes place. (The argument expand
is
forced to equal 1.) As indicated above, at the end of the
simulation, the resulting pattern is clipped to the window
w
if this is given.
sample()
.
The parameters n.start
and x.start
are incompatible.
The third argument control
controls the simulation
procedure, iterative behaviour, and termination of the
Metropolis-Hastings algorithm. It is a list with components:
fixall
(see
below) to equal TRUE
. In this case, n.start
must be a vector whose entries are these numbers.
We can only condition on the number of points if the simulation
takes place in the original window (as opposed to taking place in
a larger window and then being clipped to the original). Hence,
if p = 1 then expand
defaults to 1 and it is an
error to specify a value of expand
which is greater than 1.
p
is equal to 1.
w
is to be expanded in order to better approximate
the simulation of a process existing in the whole plane,
rather than just in the window. If expand
equals 1,
then we are simulating the latter, unless periodic
(see below) is TRUE
. The larger expand
is,
the better we approximate the former. Note that any value
of expand
smaller than 1 is treated as if it were 1.
The area of the expanded window is equal to expand
times the area of the enclosing box; width and height are
stretched proportionately. Points are generated by the
Metropolis-Hastings algorithm in the expanded window, and
then ``clipped'' down to the original window when algorithm
has finished. The argument expand
defaults to 2
if periodic
is FALSE
and p < 1 and
to 1 if periodic
is TRUE
or if p <
1, or if the starting configuration is specified via
x.start
. Trying to set expand
greater
than 1 when periodic
is TRUE
or p = 1
generates an error. A specified value of expand
is simply ignored if x.start
is given.
periodic
is TRUE
we simulate a process on the torus formed by
identifying opposite edges of the (rectangular) window.
If periodic
is TRUE
and the window is not
rectangular, an error is given.
ptypes
is close to the
relative frequencies of the types which will result from the
simulation.
fixall
is set equal to TRUE
when it is
not meaningful.
A point pattern (an object of class "ppp"
, see
ppp.object
).
The returned value has an attribute info
consisting of
arguments supplied to the function (or default values of arguments
which were not explicitly supplied). These are given so that it
is possible to reconstruct exactly the manner in which the pattern
was generated. The components of info
are model
,
start
, and control
which in turn are lists:
model=list(cif, par, trend)
start=list(n.start,x.start,iseed)
control=list(p=p,q=q,nrep=nrep,expand,periodic,
ptypes=ptypes,fixall=fixall)
Note that only one of x.start
and x.start
appear in
in the start
list.
It is possible to simulate conditionally upon the number of
points, or in the case of multitype processes, upon the number of
points of each type. To condition upon the total number of points,
set p
(the probability of a shift) equal to 1, and specify
n.start
to be a scalar (as usual). To condition upon the
number of points of each type, set p
equal to 1, fixall
equal to TRUE
, and specify n.start
to be a vector of
length nt where nt is the number of types.
In these circumstances
expand
must be equal to 1; it
defaults to 1, and it is an error to specify a value larger
than 1.
n.start
.
The syntax of rmh.default
in respect of the lookup
cif
has changed from the previous release of spatstat
(versions 1.4-7 to 1.5-1).
Read the Details carefully. In particular it is now required
that the first entry of the r
component of par
be strictly positive. (This is the opposite of what was
required in the previous release, which was that this first entry
had to be 0.)
It is also now required that the entries of r
be
sorted into ascending order. (In the previous release it
was assumed that the entries of r
and h
were
in corresponding order and the two vectors were sorted
commensurately. It was decided that this is dangerous sand
unnecessary.)
Note that if you specify the lookup
pairwise interaction
function via stepfun()
the arguments x
and y
which are passed to stepfun()
are slightly
different from r
and h
: length(y)
is equal
to 1+length(x)
; the final entry of y
must be equal
to 1 — i.e. this value is explicitly supplied by the user rather
than getting tacked on internally.
The step function returned by stepfun()
must be right
continuous (this is the default behaviour of stepfun()
)
otherwise an error is given.
There is never a guarantee that the Metropolis-Hastings algorithm has converged to the steady state.
If x.start
is specified then expand
is set equal to 1
and simulation takes place in x.start$window
. Any specified
value for expand
is simply ignored.
The presence of both a component w
of model
and a
non-null value for x.start$window
makes sense ONLY if w
is contained in x.start$window
. However no checking
is done for this.
For multitype processes make sure that, even if there is to be no trend corresponding to a particular type, there is still a component (a NULL component) for that type, in the list.
No checking is done to verify non-negativity of any specified trend or trends.
The argument model$cif
matches the name of a Fortran
subroutine which calculates the conditional intensity function
for the model. It is intended that more options will be
added in the future. The very brave user could try
to add her own. Note that in addition to writing Fortran
code for the new conditional intensity function, the user
would have to modify the code in the files cif.f
and
rmh.default.R
appropriately. (And of course re-install
the spatstat
package so as to update the dynamically
loadable shared object spatstat.so
.)
Note that the lookup
conditional intensity function
permits the simulation (in theory, to any desired degree
of approximation) of any pairwise interaction process for
which the interaction depends only on the distance between
the pair of points.
Adrian Baddeley adrian@maths.uwa.edu.au http://www.maths.uwa.edu.au/~adrian/ and Rolf Turner rolf@math.unb.ca http://www.math.unb.ca/~rolf
Baddeley, A. and Turner, R. (2000) Practical maximum pseudolikelihood for spatial point patterns. Australian and New Zealand Journal of Statistics 42, 283 – 322.
Diggle, P. J. (2003) Statistical Analysis of Spatial Point Patterns (2nd ed.) Arnold, London.
Diggle, P.J. and Gratton, R.J. (1984) Monte Carlo methods of inference for implicit statistical models. Journal of the Royal Statistical Society, series B 46, 193 – 212.
Diggle, P.J., Gates, D.J., and Stibbard, A. (1987) A nonparametric estimator for pairwise-interaction point processes. Biometrika 74, 763 – 770.
Geyer, C.J. and M{o}ller, J. (1994) Simulation procedures and likelihood inference for spatial point processes. Scandinavian Journal of Statistics 21, 359–373.
Geyer, C.J. (1999) Likelihood Inference for Spatial Point Processes. Chapter 3 in O.E. Barndorff-Nielsen, W.S. Kendall and M.N.M. Van Lieshout (eds) Stochastic Geometry: Likelihood and Computation, Chapman and Hall / CRC, Monographs on Statistics and Applied Probability, number 80. Pages 79–140.
rmh
,
rmh.ppm
,
ppp
,
ppm
,
Strauss
,
Softcore
,
StraussHard
,
MultiStrauss
,
MultiStraussHard
,
DiggleGratton
## Not run: require(spatstat) nr <- 1e5 nv <- 5000 ## End(Not run) set.seed(961018) # Strauss process. mod01 <- list(cif="strauss",par=c(beta=2,gamma=0.2,r=0.7), w=c(0,10,0,10)) X1.strauss <- rmh(model=mod01,start=list(n.start=80), control=list(nrep=nr,nverb=nv)) # Strauss process, conditioning on n = 80: X2.strauss <- rmh(model=mod01,start=list(n.start=80), control=list(p=1,nrep=nr,nverb=nv)) # Strauss process equal to pure hardcore: mod02 <- list(cif="strauss",par=c(beta=2,gamma=0,r=0.7),w=c(0,10,0,10)) X3.strauss <- rmh(model=mod02,start=list(n.start=60), control=list(nrep=nr,nverb=nv,iseed=c(42,17,69))) # Strauss process in a polygonal window. x <- c(0.55,0.68,0.75,0.58,0.39,0.37,0.19,0.26,0.42) y <- c(0.20,0.27,0.68,0.99,0.80,0.61,0.45,0.28,0.33) mod03 <- list(cif="strauss",par=c(beta=2000,gamma=0.6,r=0.07), w=owin(poly=list(x=x,y=y))) X4.strauss <- rmh(model=mod03,start=list(n.start=90), control=list(nrep=nr,nverb=nv)) # Strauss process in a polygonal window, conditioning on n = 80. X5.strauss <- rmh(model=mod03,start=list(n.start=90), control=list(p=1,nrep=nr,nverb=nv)) # Strauss process, starting off from X4.strauss, but with the # polygonal window replace by a rectangular one. At the end, # the generated pattern is clipped to the original polygonal window. xxx <- X4.strauss xxx$window <- as.owin(c(0,1,0,1)) X6.strauss <- rmh(model=mod03,start=list(x.start=xxx), control=list(nrep=nr,nverb=nv)) # Strauss with hardcore: mod04 <- list(cif="straush",par=c(beta=2,gamma=0.2,r=0.7,hc=0.3), w=c(0,10,0,10)) X1.straush <- rmh(model=mod04,start=list(n.start=70), control=list(nrep=nr,nverb=nv)) # Another Strauss with hardcore (with a perhaps surprising result): mod05 <- list(cif="straush",par=c(beta=80,gamma=0.36,r=45,hc=2.5), w=c(0,250,0,250)) X2.straush <- rmh(model=mod05,start=list(n.start=250), control=list(nrep=nr,nverb=nv)) # Pure hardcore (identical to X3.strauss). mod06 <- list(cif="straush",par=c(beta=2,gamma=1,r=1,hc=0.7), w=c(0,10,0,10)) X3.straush <- rmh(model=mod06,start=list(n.start=60), control=list(nrep=nr,nverb=nv,iseed=c(42,17,69))) # Soft core: par3 <- c(0.8,0.1,0.5) w <- c(0,10,0,10) mod07 <- list(cif="sftcr",par=c(beta=0.8,sigma=0.1,kappa=0.5), w=c(0,10,0,10)) X.sftcr <- rmh(model=mod07,start=list(n.start=70), control=list(nrep=nr,nverb=nv)) # Multitype Strauss: beta <- c(0.027,0.008) gmma <- matrix(c(0.43,0.98,0.98,0.36),2,2) r <- matrix(c(45,45,45,45),2,2) mod08 <- list(cif="straussm",par=list(beta=beta,gamma=gmma,radii=r), w=c(0,250,0,250)) X1.straussm <- rmh(model=mod08,start=list(n.start=80), control=list(ptypes=c(0.75,0.25),nrep=nr,nverb=nv)) # Multitype Strauss conditioning upon the total number # of points being 80: X2.straussm <- rmh(model=mod08,start=list(n.start=80), control=list(p=1,ptypes=c(0.75,0.25),nrep=nr, nverb=nv)) # Conditioning upon the number of points of type 1 being 60 # and the number of points of type 2 being 20: X3.straussm <- rmh(model=mod08,start=list(n.start=c(60,20)), control=list(fixall=TRUE,p=1,ptypes=c(0.75,0.25), nrep=nr,nverb=nv)) # Multitype Strauss hardcore: rhc <- matrix(c(9.1,5.0,5.0,2.5),2,2) mod09 <- list(cif="straushm",par=list(beta=beta,gamma=gmma, iradii=r,hradii=rhc),w=c(0,250,0,250)) X.straushm <- rmh(model=mod09,start=list(n.start=80), control=list(ptypes=c(0.75,0.25),nrep=nr,nverb=nv)) # Multitype Strauss hardcore with trends for each type: beta <- c(0.27,0.08) tr3 <- function(x,y){x <- x/250; y <- y/250; exp((6*x + 5*y - 18*x^2 + 12*x*y - 9*y^2)/6) } # log quadratic trend tr4 <- function(x,y){x <- x/250; y <- y/250; exp(-0.6*x+0.5*y)} # log linear trend mod10 <- list(cif="straushm",par=list(beta=beta,gamma=gmma, iradii=r,hradii=rhc),w=c(0,250,0,250), trend=list(tr3,tr4),tmax=list(1.5,1.65)) X1.straushm.trend <- rmh(model=mod10,start=list(n.start=350), control=list(ptypes=c(0.75,0.25), nrep=nr,nverb=nv)) # Multitype Strauss hardcore with trends for each type, given as images: x <- seq(0,250,length=51) xy <- expand.grid(x=x,y=x) i1 <- im(matrix(tr3(xy$x,xy$y),nrow=51),x,x) i2 <- im(matrix(tr4(xy$x,xy$y),nrow=51),x,x) mod11 <- list(cif="straushm",par=list(beta=beta,gamma=gmma, iradii=r,hradii=rhc),w=c(0,250,0,250), trend=list(i1,i2)) X2.straushm.trend <- rmh(model=mod11,start=list(n.start=350), control=list(ptypes=c(0.75,0.25),expand=1, nrep=nr,nverb=nv)) # Diggle, Gates, and Stibbard: mod12 <- list(cif="dgs",par=c(beta=3600,rho=0.08),w=c(0,1,0,1)) X.dgs <- rmh(model=mod12,start=list(n.start=300), control=list(nrep=nr,nverb=nv)) # Diggle-Gratton: mod13 <- list(cif="diggra", par=c(beta=1800,kappa=3,delta=0.02,rho=0.04), w=square(1)) X.diggra <- rmh(model=mod13,start=list(n.start=300), control=list(nrep=nr,nverb=nv)) # Geyer: mod14 <- list(cif="geyer",par=c(beta=1.25,gamma=1.6,r=0.2,sat=4.5), w=c(0,10,0,10)) X1.geyer <- rmh(model=mod14,start=list(n.start=200), control=list(nrep=nr,nverb=nv)) # Geyer; same as a Strauss process with parameters # (beta=2.25,gamma=0.16,r=0.7): mod15 <- list(cif="geyer",par=c(beta=2.25,gamma=0.4,r=0.7,sat=10000), w=c(0,10,0,10)) X2.geyer <- rmh(model=mod15,start=list(n.start=200), control=list(nrep=nr,nverb=nv)) mod16 <- list(cif="geyer",par=c(beta=8.1,gamma=2.2,r=0.08,sat=3)) data(redwood) X3.geyer <- rmh(model=mod16,start=list(x.start=redwood), control=list(periodic=TRUE,nrep=nr,nverb=nv)) # Geyer, starting from the redwood data set, simulating # on a torus, and conditioning on n: X4.geyer <- rmh(model=mod16,start=list(x.start=redwood), control=list(p=1,periodic=TRUE,nrep=nr,nverb=nv)) # Lookup (interaction function h_2 from page 76, Diggle (2003)): r <- seq(from=0,to=0.2,length=101)[-1] # Drop 0. h <- 20*(r-0.05) h[r<0.05] <- 0 h[r>0.10] <- 1 mod17 <- list(cif="lookup",par=list(beta=4000,h=h,r=r),w=c(0,1,0,1)) X.lookup <- rmh(model=mod17,start=list(n.start=100), control=list(nrep=nr,nverb=nv)) # Strauss with trend tr <- function(x,y){x <- x/250; y <- y/250; exp((6*x + 5*y - 18*x^2 + 12*x*y - 9*y^2)/6) } beta <- 0.3 gmma <- 0.5 r <- 45 mod17 <- list(cif="strauss",par=c(beta=beta,gamma=gmma,r=r),w=c(0,250,0,250), trend=tr3,tmax=1.5) X1.strauss.trend <- rmh(model=mod17,start=list(n.start=90), control=list(nrep=nr,nverb=nv))