Error in _rng function in Rstan

Hi all stan users,

Does anyone know why this error occurs when the below _rng function defined in functions block? The error is A non-returning function was expected but a returning function 'pred_rng' was supplied

real pred_rng( 
    real x1,
    real x2){ 
          real y = normal_rng(80,20);
          if(x1 < y && y < x2){
          return(y);
          } else {
          pred_rng(x1,x2);
     }
    }

Thank you all

I believe you need to fix up how you are returning from this function – when you hit the else statement, you don’t actually return pred_rng(x1,x2), you just call it. (Also not quite sure why you wrote return(y), typically return statements are followed by a space and then the value they are returning.

Try the following:

real pred_rng(real x1, real x2){ 
    real y = normal_rng(80,20);
    if (x1 < y && y < x2)
        return y;
    else
        return pred_rng(x1,x2);
}
1 Like

Hi @amas0,

I mistakenly wrote return(y), and after making changes to return pred_rng(x1,x2); it worked.
That’s amazing.

Many thanks to you.

1 Like

Hi @amas0 ,

I am here again with a mess. I am trying to use algebra_solver_newton described in section 9.1 in stan functions reference to solve user defined CDF function for t. This is what I tried in functions block and model block, but it seems like there are lots of errors when calling to the newton algebraic solver in the model block.

functions{
  vector CDF_func(vector t, vector theta, real[] x_r, // Data (real)
    int[] x_i){
    real NC = theta[1];
    real mu = theta[2];
    real nu = theta[2]; 
    real alpha1 = theta[3];
    real alpha2 = theta[4];
    real gamma_ns = theta[5];
    real alpha_ns = theta[6];
    real q = theta[7]; // CPD
    vector[1] CDF;
    real alpha = alpha_ns * (1 + alpha1* pow(q,alpha2));
    real gamma = gamma_ns * (1 + alpha1* pow(q,alpha2)); // alpha - beta - mu , beta - apoptosis rate of initiated cells, alpha - division rate of initiated cells
    real B = (-gamma + sqrt(gamma^2 + 4 * alpha * mu))/2;
    CDF = 1 - (1/(gamma + 2*B))*(exp(t)*(gamma^(-(nu*mu*NC)^2/(B*(gamma+B)^2)) + (B^(-(nu*mu*NC)^2/(B*(gamma+B)^2)))) + exp((((-gamma-2*B)/B) + 1)*(nu*mu*NC/(gamma+B))*t)*B^((nu*mu*NC)/(gamma*B+B^2)));
    return CDF;
  }
}
model{
.
.
.
    for(i in 1:n){
      real q = df[i,3];
      if(df[i,2] == 0){ // for females
        tmal[i] = algebra_solver_newton(CDF_func, {15}, {NC, nu_fns, alpha1f, alpha2f, gamma_fns, alpha_fns, q}, {0.0}, {0});
        Vmal[i] = exp((s/m) * (1-exp(-(m * tmal[i])))) * V_0;
      }
  }
.
.
.
}

Errors:

Ill-typed arguments supplied to function 'algebra_solver_newton'. Available signatures: 
((vector, vector, data array[] real, data array[] int) => vector, vector, vector, data array[] real, data array[] int) => vector
((vector, vector, data array[] real, data array[] int) => vector, vector, vector, data array[] real, data array[] int, data real, data real, data real) => vector
|
Instead supplied arguments of incompatible type: (vector, vector, array[] real, array[] int) => vector, array[] int, array[] real, array[] real, array[] int

Can someone kindly suggest how can I make it works for me? @bbbales2 can you help me here?
Thank you.

@evihas, can you please share which errors you are getting? That makes it much easier to diagnose any potential issues.

1 Like

Hi @amas0

I have edited the above code with the error message given to me. Could you please look at it and help me here.

Thank you

Well, the error kind of tells you what’s going on – you aren’t calling algebra_solver_newton correctly. In particular:

{15}, {NC, nu_fns, alpha1f, alpha2f, gamma_fns, alpha_fns, q}

These two arguments are defined with curly braces making them arrays whereas the solver requires that these arguments be vectors. Changing these two arguments to be square bracket enclosed will define them as vectors. So you’d have:

tmal[i] = algebra_solver_newton(CDF_func, 
                                [15],
                                [NC, nu_fns, alpha1f, alpha2f, gamma_fns, alpha_fns, q],
                                {0.0}, {0});

That should at least correct this error, although there could be others.

Yes, I got the error you mentioned but then it gives me other errors, Please see this,

Ill-typed arguments supplied to function 'algebra_solver_newton'. Available signatures: 
((vector, vector, data array[] real, data array[] int) => vector, vector, vector, data array[] real, data array[] int) => vector
((vector, vector, data array[] real, data array[] int) => vector, vector, vector, data array[] real, data array[] int, data real, data real, data real) => vector
/
Instead supplied arguments of incompatible type: (vector, vector, array[] real, array[] int) => vector, row_vector, row_vector, array[] real, array[] int

I am not sure whether CDF is declared correct or not in the functions block. Should it be returned as a vector to pass into the algebra_solver_newton?

Also [15] and [NC, nu_fns, alpha1f, alpha2f, gamma_fns, alpha_fns, q] are row_vectors insteaad of column_vectors. Is it?

Thanks for your time here

Yes this is correct, the signature (vector, vector, data array[] real, data array[] int) => vector indicates that the first argument to the solver is a function that takes vector, vector, array real, array int and returns a vector. It looks like yours is correct to me.

And on the row vs column vectors, my bad. Standard square brackets are row vectors – to convert them to column vectors, you add a ' at the end like:

[15]' and [NC, nu_fns, alpha1f, alpha2f, gamma_fns, alpha_fns, q]'

Thank you for staying here. It game me an another error on tmal (I defined it as vector[n] tmal;)

 tmal[i] = algebra_solver_newton(CDF_func, [15]', [NC, nu_fns, alpha1f, alpha2f, gamma_fns, alpha_fns, q]', {0.0}, {0});
                 ^
Ill-typed arguments supplied to assignment operator =: lhs has type real and rhs has type vector

I changed it as tmal[i] = algebra_solver_newton(CDF_func, [15]', [NC, nu_fns, alpha1f, alpha2f, gamma_fns, alpha_fns, q]', {0.0}, {0})[1];

Is it correct?

The error is telling you the the right hand side (the function) returns a vector – whereas your left hand side is tmal[i], which is one element of vector[n] which makes it a real. Based on your initial guess [15]', it looks like you want tmal[i] to be a vector of length 1, so perhaps define it as matrix[n, 1] or something?

1 Like

Hi @amas0 ,

I am here again for some clarifications in stan. Can you tell me the matrices in Stan is row-major or column-major, I couldn’t find related notes in the stan reference manual. For example, (this is related to my work), let’s say I need to make a matrix of 2 columns first,

vector[n] Gender;
vector[n] InitialAges;
matrix[n,2] df = [[InitialAges], [Gender]];

and need to add a third column named CPD to the matrix df.

vector[n] CPD;
matrix[n,3] df1 = append_col(df, CDP);

Why does it give me errors as

Row_vector expression must have all int or real entries. Found type vector

Thank you

Matrix expressions like you have:

matrix[n,2] df = [[InitialAges], [Gender]];

Must be defined using row vectors, so you could do:

matrix[n,2] df = [InitialAges', Gender']';

So the inner expression defines a 2\times N matrix and then you take the transpose of that to get the N\times 2 matrix that you want.

That’s perfect @amas0 and thank you very much. I have one question for you.
In my work, I have several _rng functions which should be linked to the likelihood of the model and so I am trying to define them within a user-defined function as follows:

functions{
matrix data_rng(){ //return a data-matrix
     .
     .
     .
real fun1_rng(real x1, real x2){ 
     real y = exponential_rng(1/83.5);
     if (x1 < y && y < x2)
        return y;
     else
        return fun1_rng(x1,x2);
    }
    .
    .
    .
    for(i in 1:n){
      if(df[i,2] == 0) // for females
        Age_other[i] = fun1_rng(df[i,2],100);
      else  // for males
        Age_other[i] = fun2_rng(df[i,2],100);
    }
.
.
.
}
}

It gives me this error.

   -------------------------------------------------
  
    64:      real fun1_rng(real x1, real x2){ 
                          ^
    65:       real y = exponential_rng(1/83.5);
    66:       if (x1 < y && y < x2)
   -------------------------------------------------
";" or plain assignment expected after variable declaration.

Could you please explain why it appears? @amas0 @bbbales2 @jsocolar

Thank you.

No time to test this explicitly right now, but I imagine that while you can use functions inside other functions, you cannot define functions inside other functions. Try defining fun1_rng first in the functions block, then defining data_rng below. Also, if fun1_rng is called inside data_rng and either function is supposed to be “linked to the likelihood”, then it doesn’t make sense to me that data_rng could achieve this linkage without accepting any arguments. Surely the value returned by data_rng would depend on at least some of the parameters?

Hi @jsocolar ,

Yes, first want to note that data_rng depends on all parameters I used here.
Okay, I’ll then try to define fun1_rng in the functions block and then will call it within data_rng.

Thank you