/* Model Objectives:
Estimate the mean value at each site and the grand mean.
Allow for standard deviation to vary among sites
Account for spatial autocorrelation of means among sites
*/
data{
int n; // observations
int nSite; // sites
int siteID[n]; // which site belongs to each obs.
vector[n] x;
matrix[nSite,nSite] Dist; // Distance matrix, pre-scaled so the minimum distance is 1
}
transformed data{
real xScale; // the range of x divided by 4, to establish a reasonable scale for priors
real xMean;
matrix[nSite,nSite] sqDist; // pre-compute squared distance matrix
xMean <- mean(x);
xScale <- (max(x) - min(x))/4;
for(i in 1:nSite) for(j in 1:nSite)
sqDist[i,j] <- Dist[i,j]^2;
}
parameters{
real<lower=0> spatialScale; // spatial lengthscale;
real grandMean; // overall mean of x
// Non-central parameterizations; use is defined in next block
vector[nSite] raw_siteMean;
real<lower=0,upper=pi()/2> raw_siteSD;
real<lower=0,upper=pi()/2> raw_indSDHier;
vector<lower=0,upper=pi()/2>[nSite] raw_indSD;
}
transformed parameters{
vector[nSite] siteMean; // mean of x at each site
real siteSD; // stdev of siteMean
real indSDHier; // overall stdev of x around the sitemeans
vector[nSite] indSD; // each site's scaling of indSDHier
matrix[nSite, nSite] Sigma_spatial; // Spatial matrix
matrix[nSite,nSite] L_Sigma_spatial; // cholesky of spatial matrix
Sigma_spatial <- exp(-sqDist/(2*spatialScale^2)); // squared exponential covariance
L_Sigma_spatial <- cholesky_decompose(Sigma_spatial);
siteSD <- tan(raw_siteSD) * xScale; // ~half-cauchy(0, xScale)
siteMean <- siteSD *
L_Sigma_spatial * // comment out this line to remove spatial dependence
raw_siteMean + grandMean; // ~ MVN_chol(grandMean, siteSD*L_Sigma_spatial);
indSDHier <- tan(raw_indSDHier) * xScale; // ~half-cauchy(0, xScale)
for(i in 1:nSite)
indSD[i] <- indSDHier * tan(raw_indSD[i]); // ~half-cauchy(0, indSDHier)
}
model{
grandMean ~ normal(xMean,xScale);
raw_siteMean ~ normal(0,1);
spatialScale ~ cauchy(0, 1); // A variety of other priors have been attempted, including student_t and exponential
x ~ normal(siteMean[siteID], indSD[siteID]);
}