User defined function not working in model

Skip to first unread message


May 30, 2021, 8:01:52 PMMay 30
to nimble-users
Hi all,

I've made a simple nimble function to calculate the nearest grid cell to estimated locations (thanks for your previous help debugging this!) but when I use it in my code I get the error "replacement has length zero" and I can't see why. 

My function (which compiles without error): 
nearest <- nimbleFunction(
run = function(mu_lon = double(1), 
mu_lat = double(1),
S_x = double(1),
S_y = double(1)) {
dist <- numeric(length(S_y))
for(i in 1:length(S_y)) {
dist[i] <- sqrt(((mu_lon - S_x[i]) ^2) + ((mu_lat - S_y[i]) ^2))[1] }
id <- which(dist == min(dist))
returnType(integer(1)) #double(0) should also work

My model is for animal movement with measurement error around locations (I will be using a block sampler for lat/lon but for now have things separated while I'm in the initial stages): 

#mu is latent state (real locations)
#y is location data with measurement error
#S is raster with grid cell ID
#x are environmental covariates

testModelCode <- nimbleCode({
beta1 ~ dnorm(0, 10)
beta2 ~ dnorm(0, 10)
beta3 ~ dnorm(0, 10)

psi_lat ~ dt(mu = 0, tau = 1, df = 3)
psi_lon ~ dt(mu = 0, tau = 1, df = 3)
#first time step
mu_lon[1] ~ dt(mu = y_lon[1], sigma = psi_lon*sigma_lon[1], df = nu_lon[1]) 
mu_lat[1] ~ dt(mu = y_lat[1], sigma = psi_lat*sigma_lat[1], df = nu_lat[1]) 

#for each subsequent time step
for (t in 2:TT){  #TT is total length of observed data 
#observation model
y_lon[t] ~ dt(mu = mu_lon[t], sigma = psi_lon*sigma_lon[t], df = nu_lon[t]) 
y_lat[t] ~ dt(mu = mu_lat[t], sigma = psi_lat*sigma_lat[t], df = nu_lat[t]) 
#select covariate data x at location mu[t-1]
cell[t-1] <- nearest(mu_lon[t-1], mu_lat[t-1], S_x[1:SS], S_y[1:SS]) 
mu_lon[t] <- exp((beta1*x1[S_x[cell[t-1]]] + beta2*x2[S_x[cell[t-1]]] + beta3*x3[S_x[cell[t-1]]]) )
mu_lat[t] <- exp((beta1*x1[S_y[cell[t-1]]] + beta2*x2[S_y[cell[t-1]]] + beta3*x3[S_y[cell[t-1]]]) )
} #t time step
}) #end

Thank you for any help!

Chris Paciorek

May 31, 2021, 4:39:53 PMMay 31
to Rowenna, nimble-users
hi Rowenna,

It looks like mu_lon and mu_lat should be double(0) not double(1). Right?

Also in general, it's best to just return double not integer as we compute with the double type under the hood. That said, it might work fine with integer returnType.

You received this message because you are subscribed to the Google Groups "nimble-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
To view this discussion on the web visit

Rowenna Gryba

May 31, 2021, 5:05:32 PMMay 31
to Chris Paciorek, nimble-users
Hi Chris,

I had that originally but then I get an error when compiling the function:

Error: Error, wrong number of indices provided for sqrt((pow((ARG1_mu_lon_ - ARG3_S_x_[i]),2)) + (pow((ARG2_mu_lat_ - ARG4_S_y_[i]),2)))[1].

Because of this I had thought that it may want vectors for both values due to the math?

Rowenna Gryba

May 31, 2021, 5:11:31 PMMay 31
to Chris Paciorek, nimble-users
Fixed by moving my indexing out to the last line of the code :)
Reply all
Reply to author
0 new messages