User defined function not working in model

33 views
Skip to first unread message

Rowenna

unread,
May 30, 2021, 8:01:52 PM5/30/21
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))
return(id)
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({
#priors
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!
Cheers,
Rowenna

Chris Paciorek

unread,
May 31, 2021, 4:39:53 PM5/31/21
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 nimble-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nimble-users/fab86831-c353-46fc-8d68-ba751100df9bn%40googlegroups.com.

Rowenna Gryba

unread,
May 31, 2021, 5:05:32 PM5/31/21
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

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