Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detection function extension #31

Open
david-borchers opened this issue Mar 31, 2018 · 7 comments
Open

Detection function extension #31

david-borchers opened this issue Mar 31, 2018 · 7 comments
Assignees

Comments

@david-borchers
Copy link
Collaborator

Implement the flexible detection function model using SPDEs that was used in the Annals of Applied Statistics paper.

@fbachl
Copy link
Collaborator

fbachl commented Mar 31, 2018

Have a look at the essmod repository: essmod/tex/paper1_code/example_bwhales_semipar.R :)

@david-borchers
Copy link
Collaborator Author

david-borchers commented Apr 1, 2018 via email

@finnlindgren
Copy link
Collaborator

I’ll take a look at it; IIRC this is a kappa=0 model so pcmatern won’t work.

@finnlindgren finnlindgren self-assigned this Apr 1, 2018
@finnlindgren
Copy link
Collaborator

finnlindgren commented Apr 1, 2018

In the INLA package, objects of type inla.model.class have elements model and f with parameters for the INLA::f() function, so that f(name, model=mod) is interpreted as f(name, model=mod$model, par1 = mod$f$par1, par2 = mod$f$par2).

We could implement the same technique in inlabru, with its own model class:

# Helper function for constructing the semiparametric model:
model.detect.semipar <- function(max.dist, n) {
  knots = seq(0, max.dist, length.out = n+1)
  mesh <- inla.mesh.1d(knots, degree = 2, boundary=c("neumann", "free"))
  spde <- inla.spde2.matern(mesh, B.tau=cbind(0), B.kappa=cbind(-10))
  Q <- inla.spde.precision(spde, theta=c())[-1,-1,drop=FALSE]
  msk = c(FALSE,rep(TRUE,length(knots)-1))
  model <- list(model = "generic0",
                Cmatrix = Q,
                A.msk = msk,
                mesh = mesh)
  class(model) <- "inlabru_model_class"
  model
}

A user would then only need to do this:

mod <- model.detect.semipar(6, 29)
cmp2 = coordinates +distance ~ spdf(map = distance, model = mod) + ...

This could also be combined with the INLA feature, and the inlabru parameters encapsulated:

model.inla <- list(model = "generic0", f = list(Cmatrix = Q))
class(model.inla) <- "inla.model.class"
model <- list(model = model.inla,
    inlabru = list(A.msk = msk, mesh = mesh))
class(model) <- "inlabru_model_class"

This version would more clearly separate basic INLA parameters from the special inlabru parameters.
Care would have to be taken to ensure that the variable scoping in the formula handling of both inlabru and INLA finds the correct variables.

In the current inlabru version that doesn't have that feature, the object made with the helper function above can be use like this:

cmp2 = coordinates + distance ~ spdf(map = distance, 
                                   model = mod$model, 
                                   Cmatrix = mod$Cmatrix, A.msk = mod$msk, mesh = mod$mesh) + 
  spat(map = coordinates,
       model = inla.spde2.matern(etp$mesh)) +
  Intercept

@finnlindgren
Copy link
Collaborator

The "encapsulating" approach is the way to go; we need to handle hyper.default (the prior, possibly a default prior, set when constructing the model object) and hyper (a prior set in the component using the model object), and other special features, and keeping INLA::f() parameters separate from inlabru parameters makes that easier.

@finnlindgren
Copy link
Collaborator

finnlindgren commented Apr 1, 2018

Possible package code:

model.detect.semipar <- function(max.dist, n) {
  knots = seq(0, max.dist, length.out = n+1)
  mesh <- inla.mesh.1d(knots, degree = 2, boundary=c("neumann", "free"))
  spde <- inla.spde2.matern(mesh, B.tau=cbind(0), B.kappa=cbind(-10))
  Q <- inla.spde.precision(spde, theta=c())[-1,-1,drop=FALSE]
  msk = c(FALSE,rep(TRUE,length(knots)-1))
  mod.inla <- list(model = "generic0", f = list(Cmatrix = Q))
  class(mod.inla) <- "inla.model.class"
  model <- list(model = mod.inla, ## This is what INLA will see
                bru = list(A.msk = msk, ## Additional bru parameters
                           mesh = mesh))
  ## Keep track of what kind of model it is:
  class(model) <- c("bru_model_detect_semipar", "bru_model_class")
  model
}

User code:

mod <- model.detect_semipar(6, 29) # 29 intervals, to match the 30 knots in the example
cmp <- ... + spdf(map = distance, model = mod) + ...

In inlabru v2.1.4 the model object from the helper function above can be used like this:

cmp2 <- ... + spdf(map = distance, 
                   model = mod$model,
                   A.msk = mod$bru$msk,
                   mesh = mod$bru$mesh) + ...

@finnlindgren
Copy link
Collaborator

This might be combined with #4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants