void HDP::sample_first_level_concentration(double gamma_a, double gamma_b) { /// (p 585 in escobar and west) double shape = gamma_a; double scale = gamma_b; int n = 0; RNGScope scope; for (int k = 0; k < hdp_state_->num_topics_; ++k) { n += hdp_state_->beta_u_[k]; } double eta = Rf_rbeta(hdp_state_->gamma_ + 1, n); double pi = shape + hdp_state_->num_topics_ - 1; double rate = 1.0 / scale - log(eta); pi = pi / (pi + rate * n); unsigned int cc = Rf_rbinom(1,pi); if (cc == 1) hdp_state_->gamma_ = Rf_rgamma(shape + hdp_state_->num_topics_, 1.0 / rate); else hdp_state_->gamma_ = Rf_rgamma(shape + hdp_state_->num_topics_ - 1, 1.0 / rate); }
void HDP::sample_top_level_proportions() { double total = 0; RNGScope scope; for (int k = 0; k < hdp_state_->num_topics_; ++k) { hdp_state_->pi_[k] = Rf_rgamma(hdp_state_->beta_u_[k], 1.0); total += hdp_state_->pi_[k]; } hdp_state_->pi_left_ = Rf_rgamma(hdp_state_->gamma_, 1.0); total += hdp_state_->pi_left_; for (int k = 0; k < hdp_state_->num_topics_; ++k) { hdp_state_->pi_[k] /= total; } hdp_state_->pi_left_ /= total; double etaW = hdp_state_->size_vocab_ * hdp_state_->eta_; smoothing_prob_sum_ = 0.0; for (int k = 0; k < hdp_state_->num_topics_; ++k) { smoothing_prob_[k] = hdp_state_->alpha_ * hdp_state_->pi_[k] / (hdp_state_->word_counts_by_topic_[k] + etaW); smoothing_prob_sum_ += smoothing_prob_[k]; } }
// [[Rcpp::interfaces(cpp)]] arma::rowvec dir(arma::rowvec a) { int l=a.n_cols; arma::rowvec x(l); GetRNGstate(); for (int i=0;i<l;i++){ x[i]=Rf_rgamma(a[i],1); } PutRNGstate(); double sm=sum(x); return x/sm; }
void HDP::sample_second_level_concentration(double alpha_a, double alpha_b) { double shape = alpha_a; double scale = alpha_b; RNGScope scope; int n = 0; for (int k = 0; k < hdp_state_->num_topics_; ++k) { n += hdp_state_->beta_u_[k]; } double rate, sum_log_w, sum_s; for (int step = 0; step < 20; ++step) { sum_log_w = 0.0; sum_s = 0.0; for (int d = 0; d < num_docs_; ++d) { sum_log_w += log(Rf_rbeta(hdp_state_->alpha_ + 1, doc_states_[d]->doc_length_)); sum_s += (double)Rf_rbinom(1,doc_states_[d]->doc_length_ / (doc_states_[d]->doc_length_ + hdp_state_->alpha_)); } rate = 1.0 / scale - sum_log_w; hdp_state_->alpha_ = Rf_rgamma(shape + n - sum_s, 1.0 / rate); } }
Type rgamma(Type shape, Type scale) { return Rf_rgamma(asDouble(shape), asDouble(scale)); }
// [[Rcpp::export]] Rcpp::NumericVector bayes_lm_rcpp_arma_(int n, int p, int nsamp, double prop_nonzero, double true_beta_sd, double true_sigma, double sd_x, bool print_stats, bool write_samples, Rcpp::CharacterVector samples_file_loc, char decomp_method) { // Declare model data structures ----------------------- arma::vec true_beta; // true coefficient vector arma::vec y; // response values arma::mat X; // predictor coefficient matrix arma::vec beta; // current value of beta sample double gamma; // current value of gamma sample arma::mat Sigma_inv_0; // inverse of beta variance hyperparam double nu_0; // hyperparam 1 for inverse-gamma prior double sigma_sq_0; // hyperparam 2 for inverse-gamma prior arma::mat out_beta; // memory for beta samples arma::vec out_gamma; // memory for gamma samples // Declare storage and timer data structures ----------- std::ofstream ctime_file; // sampler loop computational time file std::ofstream samples_file; // samples file struct timespec start[3]; // store event starting time information struct timespec finish[3]; // store event ending time information double elapsed[3] = { 0, 0, 0 }; // tracks event cumulative elapsed time arma::vec::iterator curr; // iterator steps through current val arma::vec::iterator end; // iterator to mark one past the last val // Set values of model objects ------------------------- // Set values of beta true_beta = sample_beta(p, prop_nonzero, true_beta_sd); // Sample data X.randn(n, p); X *= sd_x; y = (X * true_beta) + (true_sigma * arma::vec(n, arma::fill::randn)); /* Set the priors; see Hoff pgs. 154-155 for the meanings of the priors. * Note: we are implicitely specifying the mean hyperparameter for beta to * be 0 by ommitting the term in the Gibbs sampler conditional mean * calculation. */ Sigma_inv_0.eye(p, p); nu_0 = 1; sigma_sq_0 = 1; // Write param vals to file ---------------------------- // Write true values of beta, sigma^{-2} to the first row of output file if (write_samples) { samples_file.open(samples_file_loc[0].begin()); curr = true_beta.begin(); end = true_beta.end(); for ( ; (curr != end); curr++) { samples_file << *curr << " "; } samples_file << 1 / (true_sigma * true_sigma) << "\n"; samples_file.close(); } // Preliminary calculations ---------------------------- arma::mat tXX; // value of X^{T} X arma::vec tXy; // value of X^{T} y double shapeval; // shape parameter for gamma distribution samples double nu_sigma_sq_0; // product of nu_0 and sigma^2_0 tXX = X.t() * X; tXy = X.t() * y; nu_sigma_sq_0 = nu_0 * sigma_sq_0; shapeval = (nu_0 + n) / 2; // Sampler loop ---------------------------------------- arma::mat V; // variance of current beta sample arma::vec m; // mean of current beta sample arma::vec err; // model error, i.e. y - X \beta double root_SSR; // square root of SSR double SSR; // SSR (sum of squared errors) double scaleval; // scale parameter for gamma distribution samples // Set pointer to desired multivariate normal sampling function arma::vec (*samp_mvnorm)(arma::vec&, arma::mat&); switch (decomp_method) { case 'c': samp_mvnorm = &mvrnorm_chol; break; case 'e': samp_mvnorm = &mvrnorm_eigen; break; default: throw std::runtime_error("Illegal value of decomp_method"); } // Conditionally allocate memory for samples if (print_stats) { out_beta.set_size(p, nsamp); out_gamma.set_size(nsamp); } // Conditionally open samples file stream if (write_samples) { samples_file.open(samples_file_loc[0].begin(), std::fstream::app); } // Clock timer objects and initialization; requires POSIX system CLOCK_START(OVERALL); // Initial value for gamma gamma = 1; for (int s = 0; s < nsamp; s++) { // Sample beta CLOCK_START(INVERSE) V = inv_sympd(Sigma_inv_0 + (gamma * tXX)); CLOCK_STOP(INVERSE); m = gamma * V * tXy; CLOCK_START(SAMP_NORM) beta = samp_mvnorm(m, V); CLOCK_STOP(SAMP_NORM); // Sample gamma err = y - (X * beta); root_SSR = norm(err); SSR = root_SSR * root_SSR; scaleval = 2 / (nu_sigma_sq_0 + SSR); gamma = Rf_rgamma(shapeval, scaleval); // Conditionally store data in memory / write to file if (write_samples) { curr = beta.begin(); end = beta.end(); for ( ; (curr != end); curr++) { samples_file << *curr << " "; } samples_file << gamma << "\n"; } if (print_stats) { out_beta.col(s) = beta; out_gamma(s) = gamma; } // Allow user to interrupt and return to the R REPL if (s % 1000 == 0) { Rcpp::checkUserInterrupt(); } } // Calculate elapsed time CLOCK_STOP(OVERALL); // Print summary statistics ---------------------------- if (print_stats) { // Create tables with true values and empirical quantiles arma::mat table_beta_quant; arma::mat table_gamma_quant; // Declare and initialize probs, true_gamma arma::vec probs; arma::vec true_gamma; probs << 0.025 << 0.500 << 0.975; true_gamma << 1 / (true_sigma * true_sigma); // Calculate empirical quantiles out_beta = out_beta.t(); table_beta_quant = quantile_table(true_beta, out_beta, probs); table_gamma_quant = quantile_table(true_gamma, out_gamma, probs); Rcpp::Rcout << "\n" << "Parameter specifications:\n" << "-------------------------\n" << "n: " << n << "\n" << "p: " << p << "\n" << "prop_nonzero: " << prop_nonzero << "\n" << "true_beta_sd: " << true_beta_sd << "\n" << "true_sigma: " << true_sigma << "\n" << "sd_x: " << sd_x << "\n" << "nsamp: " << nsamp << "\n" << "print_stats: " << print_stats << "\n" << "write_samples: " << write_samples << "\n" << "samples_file_loc: " << samples_file_loc << "\n" << "decomp_method: " << decomp_method << "\n"; Rcpp::Rcout << "\n" << "Elapsed time:\n" << "-------------\n" << "Inverse: " << elapsed[INVERSE] << "\n" << "Sampling normal: " << elapsed[SAMP_NORM] << "\n" << "Overall: " << elapsed[OVERALL] << "\n" << "\n"; Rcpp::Rcout << "true beta 2.5% 50% 97.5%\n" << "------------------------------------\n" << table_beta_quant << "\n" << " true gam 2.5% 50% 97.5%\n" << "------------------------------------\n" << table_gamma_quant << "\n"; } // Return computational time return Rcpp::NumericVector::create(Rcpp::Named("inverse") = elapsed[INVERSE], Rcpp::Named("mvnsamp") = elapsed[SAMP_NORM], Rcpp::Named("overall") = elapsed[OVERALL]); }