Hello INLA people!
I have been using the experimental mode for a little while now based on suggestions here and my own experience where it seemed more stable and faster. I had however a lot of difficulties fitting LGCP models and it turns out the experimental mode does not seem to be working so well compared to the classic mode. Basically, point patterns with spiky distributions and large areas of low intensities seem very difficult to fit for the experimental mode. This is partly expected since such distributions are wildly variable, but the classic mode does a much better job compared to the experimental mode which seems to run into numerical issues. Here are different scenarios with varying levels of clustering with on top, predictions from the classic mode and on the bottom, predictions from the experimental mode. Predictions are logged to facilitate visualization. The tolerance to clustering seems much lower for the experimental mode. Predictions seem to make sense just around the observations, but they quickly explode for areas without observations. The mesh size is obviously too coarse to describe the most clustered patterns, but I would expect both mode to behave the same way. One thing I noticed is that if I add a small number of random points in the whole domain, it is much easier to obtain reasonable resuts. My interpretation is that low intensities are very difficult to fit since you can always get closer to 0 which drives higher sd. Hence, even a small number of observations can help anchoring predictions. Below is the code for reproducing the figure. I am using inlabru to make the code simpler, but I am facing the same issue with my own INLA implementation for the LGCP model. Any idea what might be going on and how to solve this problem?
Thanks for your input!
François

library(sp)
library(terra)
library(INLA)
library(inlabru)
set.seed(12345)
ncenters <- 10
npoints <- 100
mult <- c(20, 40, 60, 80, 100, 150)
edge <- 100
mesh <-
inla.mesh.2d(
loc.domain = cbind(c(-300, 1300, -300, 1300), c(-300, -300, 1300, 1300)),
max.edge = c(edge, edge * 2),
cutoff = edge,
offset = c(edge, edge * 2)
)
matern <- inla.spde2.pcmatern(mesh,
prior.range = c(10, 0.1),
prior.sigma = c(3, 0.1))
cmp <- coordinates ~ mySmooth(coordinates, model = matern) + Intercept(1)
layout(matrix(1:(length(mult) * 2), nrow = 2, byrow = FALSE))
l <- lapply(mult, function(i) {
cx <- runif(ncenters, 0, 1000)
cy <- runif(ncenters, 0, 1000)
x <- i * rnorm(ncenters * npoints)
y <- i * rnorm(ncenters * npoints)
p <- SpatialPoints(cbind(cx + x, cy + y))
### Sprinkle uniform observations
#add<-SpatialPoints(matrix(runif(2*50,-500,1500),ncol=2))
#p<-rbind(p,add)
lapply(c("classic", "experimental"), function(j) {
bru_options_set(inla.mode = j, verbose = FALSE)
fit <- lgcp(cmp, p, domain = list(coordinates = mesh))
preds <- predict(
fit,
pixels(
mesh,
nx = 100,
ny = 100,
mask = TRUE
),
~ data.frame(lambda = exp(mySmooth + Intercept),
field = mySmooth),
n.samples = 50
)
ras <- rast(preds$lambda[, "mean"])
plot(log(ras), mar = c(1, 1, 1, 5), axes = FALSE)
plot(
p,
pch = 16,
cex = 0.5,
col = gray(0, 0.5),
axes = FALSE,
add = TRUE
)
mtext(
side = 3,
adj = 0.5,
line = -2,
text = j
)
})
})