Issue in defining Function

I am trying to implement generalized fiducial inference in STAN using a function, however I am getting an error saying that my data cannot be a parameter. Why might this be the case, and how could I alter the parameter to pass into the function?

library(rstan)
x <- c(1,2,3,2,7,2,4,8,24,78,6,24,21,2,3,7,3,58,246)
ds <- list(N = length(x), y = x)

gfi_model = "
functions{
real genfid_log(ds,real mu){
for(i in 1:N){
1+(3/2)((Y[i]-mu)/mu)
}
}

}
data {
int<lower=0> N; // number of observations
vector [N] Y;

}
parameters {
real<lower=0> mu;
}
model {
mu~exponential(1);
Y~genfid(y,mu);

}
generated quantities {
real output;
output = mu < 1;
}
"
fit <- stan(model_code = gfi_model, data = ds, iter = 1000, chains = 4)

The scope of a user-defined function does not include data, parameters, etc. So, it does not know what N is or what Y is. Also, ds is unused but would need a real before it in the argument signature.

1 Like

Two things:

  1. Ending a function in “_log” is deprecated. Use “_lpdf” or “_lpmf” instead (depending on whether you’re defining a probability density function or probability mass function).

  2. Your function is ill-formed. Not only does it not return anything, but there’s not even any sort of assignment inside the “for” loop. It doesn’t make any sense.

Looks like svetak may be expecting ds to be visible to the Stan function because it’s defined as a variable in the R program.

I have adjusted it to the following.

library(rstan)
x <- c(1,2,3,2,7,2,4,8,24,78,6,24,21,2,3,7,3,58,246)
ds <- list(N = length(x), y = x)

gfi_model = "

functions{
real genfid_lpdf(vector t,real mu){
vector[num_elements(t)] jac;
vector[num_elements(t)] log_likl;

for(i in 1:num_elements(t)){
jac[i]<-abs(1+(3/2)((t[i]-mu)/mu));
log_likl[i]<-(t[i]-mu)^2/(2
mu^(3/2))+(3/4)*log(mu);
}
return log(sum(jac))-sum(log_likl);

}

}
data {
int<lower=1> N; // number of observations
vector [N] Y;
}
parameters {
real<lower=0> mu;
}

model {
Y~genfid(mu);
}

"
fit <- stan(model_code = gfi_model, data =ds)
f <- sampling(fit, iter = 100)

I still get an error that is.na() is applied to non-list/vector.

It would be easier for everyone to run your code if you put it inside triple backticks (```) at the start and the end. Markdown eats the asterisks for multiplication otherwise. Also, note the parser warnings about integer division; i.e. (3/2) in your code will evaluate to 1 rather than 1.5 unless you change it to 3.0/2, etc. Also, using abs will not compile on some platforms, so you should use fabs. At that point, the actual error message (that comes before the is.na stuff) is

Error in new_CppObject_xp(fields$.module, fields$.pointer, ...) : 
  Exception: variable does not exist; processing stage=data initialization; variable name=Y; base type=vector_d  (in 'model431f

which is because the data block of your Stan program declares Y but your in your list of data that you pass from R, it is named y. Both Stan and R are case sensitive.

Thank you! I am finding another error in my code:

library(rstan)
x <- c(1,2,3,2,7,2,4,8,24,78,6,24,21,2,3,7,3,58,246)
ds <- list(N = length(x), Y = x)

gfi_model = "

functions{ 
  real genfid_log(vector t,real mu){
  vector[num_elements(t)] jac;
  vector[num_elements(t)] log_likl;
  
  for(i in 1:num_elements(t)){
  jac[i]<-fabs(1+(3/2)*((t[i]-mu)/mu));
  log_likl[i]<-(t[i]-mu)^2/(2*mu^(3.0/2))+(3/4)*log(mu);
  }
  return log(sum(jac))-sum(log_likl);
  
  }

}
data {
    int<lower=1> N;  // number of observations
    vector [N] Y;
}
parameters {
    real<lower=0> mu;
}

model {
Y~genfid(mu);
} 

"
fitted_model <- stan(model_code = gfi_model, data = ds)
f <- sampling(fitted_model, iter = 100)

The error I receive is "Error in (function (classes, fdef, mtable) : unable to find an inherited method for function ‘sampling’ for signature ‘“stanfit”’. I am not sure why this is the case, as I think I am calling (and passing in the right parameters) to the sampling function.

But you are attempting to use the stan function to generate a stanmodel object, which is incorrect. The stan function returns a stanfit object. What you want is either

f <- stan(model_code = gfi_model, data = ds, iter = 100)

or

fitted_model <- stan_model(model_code = gfi_model)
f <- sampling(fitted_model, iter = 100, data = ds)
1 Like

Thank you!

I am getting this error: PARSER EXPECTED: <argument declaration or close paren ) to end argument declarations> thrown, where the error message points to this part of the code (the arrow points upward to ds):

1:
2: functions{
3: real genfid_log(ds,real mu){
^
4: for(i in 1:N){

I’ve tried redeclaring the vector t as an int foo (as per a suggestion online). I have also tried changing ds to a vector, rather than a list. Not sure how to proceed with debugging.

You haven’t defined the type of the argument ds.

Hi,

I was wondering what the notation was for defining a parameter to take on a set value for simulation purposes. I want to set my mu parameter value to 0.1, so i tried

parameters {
    real<lower=.9,upper=.11> mu;
}

but unfortunately this gives values in between the two. Is this the right approach to setting mu to a particular value or is there an easier way to go about doing this?

Set it in data or transformed data rather than the parameters block.

1 Like