// This Stan block defines a Bayesian PCA, Joseph H. Sakaya & Suleiman A. Khan but
// with the dependent variable changed to Binomial (by Sean van der Merwe, UFS)
data {
	int<lower=0> N; // Number of samples
	int<lower=0> K; // The maximum latent dimension, must be < D
	real x1[N];
	real x2[N];
	int<lower=0> x3[N];
	int<lower=0, upper=1> x4[N];
	int<lower=0, upper=5> x5[N];
}
parameters {
	matrix[N, K] Z; // The latent matrix
	matrix[5, K] W; // The weight matrix
	vector<lower=0>[K] alpha; // ARD prior
	real<lower=0.5> nu;
	real<lower=0> s1;
	real<lower=0> s2;
}
transformed parameters{
	vector<lower=0>[K] t_alpha;
	vector[N*5] zw;
  t_alpha = inv(sqrt(alpha));
  zw = to_vector(Z*W');
}
model {
	to_vector(Z) ~ normal(0,1);
	alpha ~ gamma(1e-3,1e-3);				
	for (k in 1:K) W[,k] ~ normal(0, t_alpha[k]);
	x1 ~ normal(zw[1:N], s1);
	x2 ~ student_t(nu, zw[(N+1):(N*2)], s2);
	x3 ~ poisson_log(zw[(N*2+1):(N*3)]);
	x4 ~ binomial_logit(1, zw[(N*3+1):(N*4)]);
	x5 ~ binomial_logit(5, zw[(N*4+1):(N*5)]);
	nu ~ exponential(1);
	s1 ~ exponential(0.1);
	s2 ~ exponential(0.1);
}

CXXFLAGS = -O2 -Wall $(DEBUGFLAG) -mfpmath=sse -msse2 -mstackrealign $(LTO)

std::vector<double, std::allocator<double> > constrain_pars(std::vector<double, std::allocator<double> >)

std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > constrained_param_names(bool, bool)

Rcpp::NumericVector grad_log_prob(std::vector<double, std::allocator<double> >, bool)

Rcpp::NumericVector log_prob(std::vector<double, std::allocator<double> >, bool, bool)

std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > param_fnames_oi()

std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > param_names()