# 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