The below Stan code works.
functions{
real cumulative_exposure(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 Beta = theta[1];
real eta = theta[2];
return exp(Beta*(eta + log(x)));
}
}
data {
int<lower=1> n; // Sample size
int<lower=1> n_cens; // Right censored sample size
int<lower=1> n_obs; // Failed unit sample size
int<lower=1> N; // Total number of times considered (all times for all units)
real<lower=0> tt[N]; //All times for all units
real y_tt[N]; //All of the use-rates
int w_ind[N]; //Indices for w
real<lower=0> tt_fail[n_obs]; //Failure times for units that failed
int w_ind_fail[n_obs]; //Indices for w for units that failed
real<lower=0> tt_cens[n_cens];
}
transformed data {
real x_r[0];
int x_i[0];
}
parameters {
real <lower = 0> mu0;
real <lower = 0> sigma0;
real <lower = 0> sig;
real <lower = 0> sig1;
real <lower = 0> sig2;
real <lower = -1, upper = 1>rho;
real eta;
real Beta;
matrix[2, n] w;
}
model {
//cumulative exposure for failed units and for censored units
vector[n_obs] u_obs;
vector[n_cens] u_cens;
//Defining covariance matrix, cholesky decomposition and mean and variance of mixed effects model
matrix[2,2] Sigma;
matrix[2,2] L;
real Mu[N];
vector[n_obs] Mu_DFD;
matrix[2, n] w2;
//Covariance matrix
Sigma[1,1] = sig1^2;
Sigma[1,2] = rho*sig1*sig2;
Sigma[2,1] = rho*sig1*sig2;
Sigma[2,2] = sig2^2;
//Cholesky decomposition
L = cholesky_decompose(Sigma);
w2 = L*w;
//Parameters used in mixed effects model
for(i in 1:N){
Mu[i] = eta + w2[1,w_ind[i]] + w2[2,w_ind[i]]*log(tt[i]);
}
//Calculating mu_DFD
for(i in 1:n_obs){
Mu_DFD[i] = eta + w2[1,w_ind_fail[i]] + w2[2,w_ind_fail[i]]*log(tt_fail[i]);
u_obs[i] = integrate_1d(cumulative_exposure, 0, tt_fail[i], {Beta, eta}, x_r, x_i, 1e-8);
}
for(i in 1:n_cens){
u_cens[i] = integrate_1d(cumulative_exposure, 0, tt_cens[i], {Beta, eta}, x_r, x_i, 1e-8);
}
//Likelihood
target += weibull_lpdf(u_obs| 1/sigma0, exp(mu0));
target += Beta*Mu_DFD;
target += weibull_lccdf(u_cens|1/sigma0, exp(mu0));
target += normal_lpdf(y_tt|Mu, sig);
// Prior:
Beta ~ normal(0, 10);
mu0 ~ normal(0, 10);
sigma0 ~ normal(0, 10);
eta ~ normal(0, 10);
to_vector(w) ~ normal(0, 1);
sig ~ normal(0, 10);
sig1 ~ normal(0, 10);
sig2 ~ normal(0, 10);
rho ~ normal(0, 10);
}
But, I would like to change the return in the cumulative_exposure
function to be
return exp(Beta*(eta + w2[1,w_ind_fail[i]] + w2[2,w_ind_fail[i]]*log(x)));
, c.f, the definition of Mu[i]
in the model block.
I attempted a reparameterization of my model (which I would like to avoid because I am actually doing the opposite of what is suggested, i.e. I am going from a non-centered parameterization to a centered parameterization) in order to be able to include the w’s as parameters in the cumulative_exposure
function.
I tried the following Stan code
functions{
real cumulative_exposure(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 Beta = theta[1];
real eta = theta[2];
real w2_1 = theta[3];
real w2_2 = theta[4];
return exp(Beta*(eta + w2_1 + w2_2*log(x)));
}
}
data {
int<lower=1> n; // Sample size
int<lower=1> n_cens; // Right censored sample size
int<lower=1> n_obs; // Failed unit sample size
int<lower=1> N; // Total number of times considered (all times for all units)
real<lower=0> tt[N]; //All times for all units
real y_tt[N]; //All of the use-rates
int w_ind[N]; //Indices for w
real<lower=0> tt_fail[n_obs]; //Failure times for units that failed
int w_ind_fail[n_obs]; //Indices for w for units that failed
int w_ind_cens[n_cens];
real<lower=0> tt_cens[n_cens];
vector[2] w_M;
}
transformed data {
real x_r[0];
//int x_i[0];
}
parameters {
real <lower = 0> mu0;
real <lower = 0> sigma0;
real <lower = 0> sig;
real <lower = 0> sig1;
real <lower = 0> sig2;
real <lower = -1, upper = 1>rho;
real eta;
real Beta;
vector[2] w2[n];
}
model {
//cumulative exposure for failed units and for censored units
vector[n_obs] u_obs;
vector[n_cens] u_cens;
//Defining covariance matrix, cholesky decomposition and mean and variance of mixed effects model
matrix[2,2] Sigma;
real Mu[N];
vector[n_obs] Mu_DFD;
//Covariance matrix
Sigma[1,1] = sig1^2;
Sigma[1,2] = rho*sig1*sig2;
Sigma[2,1] = rho*sig1*sig2;
Sigma[2,2] = sig2^2;
//Parameters used in mixed effects model
for(i in 1:N){
Mu[i] = eta + w2[w_ind[i]][1] + w2[w_ind[i]][2]*log(tt[i]);
}
//Calculating mu_DFD
for(i in 1:n_obs){
Mu_DFD[i] = eta + w2[w_ind_fail[i]][1] + w2[w_ind_fail[i]][2]*log(tt_fail[i]);
u_obs[i] = integrate_1d(cumulative_exposure, 0, tt_fail[i],
{Beta, eta, w2[w_ind_fail[i]][1], w2[w_ind_fail[i]][2]},
x_r, w_ind_fail[i], 1e-8);
}
for(i in 1:n_cens){
u_cens[i] = integrate_1d(cumulative_exposure, 0, tt_cens[i],
{Beta, eta, w2[w_ind_cens[i]][1], w2[w_ind_cens[i]][2]},
x_r, w_ind_cens[i], 1e-8);
}
//Likelihood
target += weibull_lpdf(u_obs| 1/sigma0, exp(mu0));
target += Beta*Mu_DFD;
target += weibull_lccdf(u_cens|1/sigma0, exp(mu0));
target += normal_lpdf(y_tt|Mu, sig);
// Prior:
Beta ~ normal(0, 10);
mu0 ~ normal(0, 10);
sigma0 ~ normal(0, 10);
eta ~ normal(0, 10);
w2 ~ multi_normal(w_M, Sigma);
sig ~ normal(0, 10);
sig1 ~ normal(0, 10);
sig2 ~ normal(0, 10);
rho ~ normal(0, 10);
}
The idea being that w2_1
and w2_2
in the cumulative_exposure
function will be inputted into the function as w2[1,w_ind_fail[i]]
and w2[2,w_ind_fail[i]]
(see for loops in model code).
From what I can diagnose, the issue seems to be that w_ind_fail[i]
and w_ind_cens[i]
are int
and not int[]
. I am not too sure what to do now, as I think I am overcomplicating this more than enough already. I would also like to stay with the non-centered parameterization (but in that code w2
are not parameters, although I could put w2
in the transformed parameter block. But, this would mean I have to put Sigma
in the transformed parameter block, too; and I have found that having a covariance matrix in the transformed parameter block increases the run time drastically.)
Error message:
SYNTAX ERROR, MESSAGE(S) FROM PARSER:
sixth argument to integrate_1d, the integer data, must have type int[]; found type = int.
To help clarify, I have a group of units, and I would like to calculate the integral
\int^{T_i}_0 \exp\{\beta \times [\eta + w_{0i} + w_{1i}\log(t)]\}
for each unit. Here, tt_fail
and tt_obs
are vectors containing the upper limits of the integrals, and w_ind_fail
and w_ind_cens
are vectors that subset the w2
matrix (or array depending on which version of the code) for each unit.
Does anyone know a simpler way that I can achieve this goal?