Hello,
I’m trying to fit a state space model of the form;
I would like to specify a user-defined PDF (multivariate) on the errors, \epsilon_s, \epsilon_o. Currently I’ve been using the below Stan code to sample the state sequence, x_t, and state transition matrix, G ;
data{
int<lower=1> t_max; // Time series length
array[t_max] vector[5] y; // Observations
cov_matrix[5] W; // Variance of state noise
cov_matrix[5] V; // Variance of observation noise
row_vector[5] m0; // Mean of prior distribution--A 2D row vector
cov_matrix[5] C0; // Variance of prior distribution
matrix[5,5] Fmat; // Factor loadings
}
parameters{
row_vector[5] x0; // State [0]
array[t_max] vector[5] x; // State [1:t_max]
vector<lower=-1, upper=1>[5] Gmat; // Vector containing autocorrelations
}
model{
// Pre-compute array of mean vectors;
array[t_max] vector[5] y_mu;
array[t_max] vector[5] x_mu_prev;
for(t in 1:t_max){
if(t == 1){
x_mu_prev[t] = diag_matrix(Gmat) * x0';
}else{
x_mu_prev[t] = diag_matrix(Gmat) * x[t-1];
}
y_mu[t] = Fmat * x[t];
}
// Initial state
x0 ~ multi_normal(m0, sqrt(C0));
target += multi_normal_lpdf(x | x_mu_prev, sqrt(W)) + multi_normal_lpdf( y | y_mu, sqrt(V));
//Prior on the diagonal elements of Gmat;
for(n in 1:5){
Gmat[n] ~ uniform(-1, 1);
}
Which performs satisfactorily. But when I define the PDF;
functions{
real MVPE_lpdf( vector x, vector mu, matrix sigma, real beta){
int n = num_elements(x);
return log(n) + lgamma(n * 0.5) -0.5*log_determinant(sigma) - 0.5*n*log(pi()) -lgamma(1 + n/(2*beta)) -(1+n/(2*beta))*log(2) -0.5*((x - mu)' * inverse(sigma) * (x - mu))^beta;
}
}
And run the model;
model{
// Pre-compute array of mean vectors;
array[t_max] vector[5] y_mu;
array[t_max] vector[5] x_mu_prev;
for(t in 1:t_max){
if(t == 1){
x_mu_prev[t] = diag_matrix(Gmat) * x0;
}else{
x_mu_prev[t] = diag_matrix(Gmat) * x[t-1];
}
y_mu[t] = Fmat * x[t];
}
// Initial state
x0 ~ multi_normal(m0, sqrt(C0));
target += MVPE_lpdf(x | x_mu_prev, W, beta_s) + MVPE_lpdf(y | y_mu, V, beta_o);
//Prior on the diagonal elements of Gmat;
for(n in 1:5){
Gmat[n] ~ uniform(-1, 1);
}
I get the following error message;
Error in stanc(file = file, model_code = model_code, model_name = model_name, :
0
Semantic error in 'string', line 54, column 12 to column 47:
Ill-typed arguments supplied to function 'MVPE_lpdf'. Available signatures:
(vector, vector, matrix, real) => real
Instead supplied arguments of incompatible type: vector[], vector[], matrix, real.
So, I would like to have my MVPE_lpdf function behave like multi_normal_lpdf does in the above model block, but I don’t know how to accomplish this. My guess is that I want MVPE_lpdf to accept an array of vectors(?) for its first two arguments. I’ve dabbled with changing the argument types, but to no avail.
Thank you!