Problem on how to use Integrate_1d function

I want to use integrate_1d function to calculate the integral of a complex function. But I met an error when parsing it.

Here is the error:
Ill-typed arguments supplied to function ‘integrate_1d’. Available signatures:
((real, real, real[], data real[], data int[]) => real, real, real, real[], data real[], data int[]) => real
((real, real, real[], data real[], data int[]) => real, real, real, real[], data real[], data int[], data real) => real
Instead supplied arguments of incompatible type: (real, real, real[], real[], int[]) => real, real, real, real, real[,], int[].

This is my code. I think I have already put x_i into transformed data block, and use the variable in data for x_r. But I have no idea why there is such error. Is there any idea how to solve this problem?

functions {
  real normal_density_nc(real x,          // Function argument
                    real xc,         // Complement of function argument
                                     //  on the domain (defined later)
                    real[] theta,    // parameters
                    real[] x_r,      // data (real)
                    int[] x_i) {     // data (integer)
  real mu = x_r[1];
  real sigma = x_r[2];

  return 1 / (sqrt(2 * pi()) * sigma) * exp(-0.5 * ((x - mu) / sigma)^2) * (-1/sigma + (1 / sigma ^ 2) * (x - mu)^2 );

}
}
data {

    // Gaussian model
    int W;                                                          // Number of weeks (typically 12)
    int N;                                                          // Number of subjects
    int Xdim;                                                       // Dimension of X - latent low dimensional structure of the phenotype

    // Exogenous variables
    int exo_q_num;                                                  // number of exogenous survey questions
    real U[N,W,exo_q_num];                                       // exogenous survey questions - missing weeks were linearly interpolated outside of Stan 

    // Change detection
    int<lower=1> W_nc_obs[N];                                          // Number of weeks WITH data
    int<lower=0> W_nc_mis[N];                                          // Number of weeks WITHOUT data
    int<lower=0> idx_nc_obs[N,W];                              // Indices of weeks WITH data
    int<lower=1> P_nc;                                              // Number of parameters
    int<lower=0> T_max_nc;                                          // Max number of trials across subjects across weeks
    int<lower=0> Tr_nc[N, W];                                // Number of trials for each subj for each week
    int deltaM[N, W, T_max_nc];                              // Mu of dots - subj x weeks x trials
    real TotalS[N, W, T_max_nc];                             // Sd of dots - subj x weeks x trials
    int choice_nc[N, W, T_max_nc];                           // choice nc - subj x weeks x trials
    
    real reward[N, W];
    int x_i[0];
}

//transformed data{
    
    //}

parameters {
    matrix[Xdim, exo_q_num] B;
    real weber_nc_pr_std[N,W];                  // nc
    matrix[1,Xdim] C;
    matrix[N, Xdim] X1;
    real<lower=0, upper=1> eta[N]; //eta
    vector[1] mu_d;                     // constant offset
    vector<lower=0>[1] sigma_r;
}

model {
    to_vector(B) ~ normal(0, 0.1);
    to_vector(C) ~ normal(0, 0.1);
    to_vector(X1) ~ normal(0, 0.1);
    mu_d ~ normal(0, 0.1);
    sigma_r ~ normal(0, 0.1);
    eta ~ normal(0.01, 0.1);// prior for eta
    
    real weber_nc_pr[N,W];           // cd    
    real weber_nc[N,W];
    
    real X[N,W,Xdim];
    

    real reward_sum;
    real nc_grad_sum[N, W, 1];

     for (s in 1:N) {
        reward_sum = 0; 
        int w1 = 1;
        real weeks =0;               
        for (w in 1:W) {

            reward_sum += reward[s, w];
            matrix[1, Tr_nc[s,w]] nc_grad ;
            
            if (idx_nc_obs[s,w] != 0) {
                weeks = weeks + 1;
                             }

            nc_grad_sum[s,w, ] = to_array_1d(rep_array(0, 1));
            
            weber_nc_pr_std[s,w] ~ std_normal();

            
            if (w == 1) {
                    X[s,w,] = to_array_1d(inv_logit(X1[s,])); 
            } else {
                    X[s,w,] = to_array_1d(inv_logit(to_vector(X[s,w1,]) + eta[s].*(reward[s, w] - reward_sum/(weeks + 0.0000001))* to_matrix(C)' * to_vector(nc_grad_sum[s, w1])));
            }  

            weber_nc_pr[s,w] =  to_array_1d(mu_d[1] + B * to_vector(U[s,w,]) + C[1,] * to_vector(X[s,w,]) + sigma_r[1] * weber_nc_pr_std[s, w])[1];
            weber_nc[s,w]= exp(weber_nc_pr[s,w]);          // nc        

           	        
	        if (idx_nc_obs[s,w] != 0) {                                  // if week exists

   	            vector[Tr_nc[s,w]] z = - to_vector(deltaM[s,w,:Tr_nc[s,w]]) ./ (weber_nc[s,w] * to_vector(TotalS[s,w,:Tr_nc[s,w]]));
	            choice_nc[s,w,:Tr_nc[s,w]] ~ bernoulli(Phi(z));	

                vector[Tr_nc[s,w]] itc_p = Phi(z);
                vector[Tr_nc[s,w]] log_likelihood_p_grad_nc = to_vector(choice_nc[s,w,:Tr_nc[s,w]]) ./ (itc_p + 0.00001) - (1 - to_vector(choice_nc[s,w,:Tr_nc[s,w]])) ./ (1 - itc_p + 0.00001);

                
                real theta[0];
                
                for(t in 1: Tr_nc[s,w]){
                        nc_grad[t] = integrate_1d(normal_density_nc,
                                                  negative_infinity(),
                                                  0.0,
                                                  weber_nc[s, w], 
                                                  { deltaM[s, w, t],  TotalS[s, w, t] }, 
                                                  x_i);
                        }
                

                
                
                  nc_grad_sum[s, w, ] = to_array_1d(nc_grad * to_vector(rep_array(1, Tr_nc[s,w])));  
                  w1 = w;
                  
                   
	        }    

 	    }  
    }                                     
}  
1 Like

Hi and sorry about the delay. This is not my area but I searched around on the forums here and found something similar here Parametrised integrals

At the very least this will get bumped up so folks who work with integrate_1d might see it!

1 Like

I believe the issue is that the integrand function (normal_density_nc) is expecting the theta input to be of type real[] (an array of reals), but you’re passing a single real (weber_nc[s, w]).

Try adding curly braces around weber_nc[s, w] in your integrate_1d call:

nc_grad[t] = integrate_1d(normal_density_nc,
                          negative_infinity(),
                          0.0,
                          { weber_nc[s, w] }, 
                          { deltaM[s, w, t],  TotalS[s, w, t] }, 
                          x_i);
2 Likes