//---------------------------------------------------------------------- // draws Sigma one element at a time using regular slice sampling // based on the separation strategy in Barnard, McCulloch, and Meng // (2000 statistica sinica). void SepStratSampler::stable_draw(){ int dim = nrow(sumsq_); cand_ = mod_->Sigma(); sd_ = sqrt(diag(cand_)); R_ = var2cor(cand_); Rinv_ = R_.inv(); for(int i = 0; i < dim; ++i){ draw_sigsq(i); } for(int i = 0; i < dim; ++i){ for(int j = 0; j < i; ++j){ draw_R(i,j);}} fill_sigma(); mod_->set_Sigma(cand_); }
//---------------------------------------------------------------------- // log of the prior distribution at an arbitrary value of Sigma double SepStratSampler::logprior(const Spd & Sigma)const{ // Prior is with respect to Sigma int d = Sigma.nrow(); R_ = var2cor(Sigma); sd_ = sqrt(diag(Sigma)); double ans = Rpri_->logp(R_); if(ans == BOOM::negative_infinity()) return ans; for(int i = 0; i < sd_.size(); ++i){ double sd = sd_[i]; if(sd <=0 ) return BOOM::negative_infinity(); ans += sinv_pri_[i]->logp(1.0/square(sd)); ans += (d-3) * log(sd); // d-3 comes from the Jacobian of two transformations: // Sigma -> (S,R) gives s^d // s -> 1/s^2 gives s^-3 } return(ans); }
//---------------------------------------------------------------------- void CS::draw() { const Vector &mu(mod_->mu()); int n = mu.size(); Sumsq_ = mod_->suf()->center_sumsq(mu); df_ = mod_->suf()->n(); Vector sigma = sqrt(diag(mod_->Sigma())); R_ = var2cor(mod_->Sigma()); for (int i = 0; i < n; ++i) { Sumsq_.row(i) /= sigma[i]; Sumsq_.col(i) /= sigma[i]; } for (int i = 1; i < n; ++i) { i_ = i; for (int j = 0; j < i; ++j) { j_ = j; draw_one(); } } for (int i = 0; i < sigma.size(); ++i) { R_.row(i) *= sigma[i]; R_.col(i) *= sigma[i]; } mod_->set_Sigma(R_); }