//---------------------------------------------------------------------- // TODO(stevescott): This code currently discards the tim_sampler void BLCSSS::tim_draw(){ int nvars = m_->coef().nvars(); if(nvars == 0) return; int chunk_size = compute_chunk_size(max_tim_chunk_size_); int number_of_chunks = compute_number_of_chunks(max_tim_chunk_size_); assert(number_of_chunks * chunk_size >= nvars); for(int chunk = 0; chunk < number_of_chunks; ++chunk) { clock_t mode_start = clock(); TIM tim_sampler(log_posterior(chunk, max_tim_chunk_size_), tdf_, &rng()); Vector beta = m_->included_coefficients(); int start = chunk_size * chunk; int elements_remaining = nvars - start; VectorView beta_chunk(beta, start, std::min(elements_remaining, chunk_size)); bool ok = tim_sampler.locate_mode(beta_chunk); move_accounting_.stop_time("tim mode finding", mode_start); if (ok) { move_accounting_.record_acceptance("tim mode finding"); tim_sampler.fix_mode(true); MoveTimer timer = move_accounting_.start_time("TIM chunk"); beta_chunk = tim_sampler.draw(beta_chunk); m_->set_included_coefficients(beta); if (tim_sampler.last_draw_was_accepted()) { move_accounting_.record_acceptance("TIM chunk"); } else { move_accounting_.record_rejection("TIM chunk"); } } else { move_accounting_.record_rejection("tim mode finding"); rwm_draw_chunk(chunk); } } }
//---------------------------------------------------------------------- void BLCSSS::rwm_draw_chunk(int chunk){ clock_t start = clock(); const Selector &inc(m_->coef().inc()); int nvars = inc.nvars(); Vec full_nonzero_beta = m_->beta(); // only nonzero components // Compute information matrix for proposal distribution. For // efficiency, also compute the log-posterior of the current beta. Vec mu(inc.select(pri_->mu())); Spd siginv(inc.select(pri_->siginv())); double original_logpost = dmvn(full_nonzero_beta, mu, siginv, 0, true); const std::vector<Ptr<BinomialRegressionData> > &data(m_->dat()); int nobs = data.size(); int full_chunk_size = compute_chunk_size(); int chunk_start = chunk * full_chunk_size; int elements_remaining = nvars - chunk_start; int this_chunk_size = std::min(elements_remaining, full_chunk_size); Selector chunk_selector(nvars, false); for(int i = chunk_start; i< chunk_start + this_chunk_size; ++i) { chunk_selector.add(i); } Spd proposal_ivar = chunk_selector.select(siginv); for(int i = 0; i < nobs; ++i){ Vec x = inc.select(data[i]->x()); double eta = x.dot(full_nonzero_beta); double prob = plogis(eta); double weight = prob * (1-prob); VectorView x_chunk(x, chunk_start, this_chunk_size); // Only upper triangle is accessed. Need to reflect at end of loop. proposal_ivar.add_outer(x_chunk, weight, false); int yi = data[i]->y(); int ni = data[i]->n(); original_logpost += dbinom(yi, ni, prob, true); } proposal_ivar.reflect(); VectorView beta_chunk(full_nonzero_beta, chunk_start, this_chunk_size); if(tdf_ > 0){ beta_chunk = rmvt_ivar_mt( rng(), beta_chunk, proposal_ivar / rwm_variance_scale_factor_, tdf_); }else{ beta_chunk = rmvn_ivar_mt( rng(), beta_chunk, proposal_ivar / rwm_variance_scale_factor_); } double logpost = dmvn(full_nonzero_beta, mu, siginv, 0, true); Vec full_beta(inc.expand(full_nonzero_beta)); logpost += m_->log_likelihood(full_beta, 0, 0, false); double log_alpha = logpost - original_logpost; double logu = log(runif_mt(rng())); ++rwm_chunk_attempts_; if(logu < log_alpha){ m_->set_beta(full_nonzero_beta); ++rwm_chunk_successes_; } clock_t end = clock(); rwm_chunk_times_ += double(end - start) / CLOCKS_PER_SEC; }
//---------------------------------------------------------------------- void BLCSSS::rwm_draw_chunk(int chunk){ const Selector &inc(m_->coef().inc()); int nvars = inc.nvars(); Vector full_nonzero_beta = m_->included_coefficients(); // Compute information matrix for proposal distribution. For // efficiency, also compute the log-posterior of the current beta. Vector mu(inc.select(pri_->mu())); SpdMatrix siginv(inc.select(pri_->siginv())); double original_logpost = dmvn(full_nonzero_beta, mu, siginv, 0, true); const std::vector<Ptr<BinomialRegressionData> > &data(m_->dat()); int nobs = data.size(); int full_chunk_size = compute_chunk_size(max_rwm_chunk_size_); int chunk_start = chunk * full_chunk_size; int elements_remaining = nvars - chunk_start; int this_chunk_size = std::min(elements_remaining, full_chunk_size); Selector chunk_selector(nvars, false); for(int i = chunk_start; i< chunk_start + this_chunk_size; ++i) { chunk_selector.add(i); } SpdMatrix proposal_ivar = chunk_selector.select(siginv); for(int i = 0; i < nobs; ++i){ Vector x = inc.select(data[i]->x()); double eta = x.dot(full_nonzero_beta); double prob = plogis(eta); double weight = prob * (1-prob); VectorView x_chunk(x, chunk_start, this_chunk_size); // Only upper triangle is accessed. Need to reflect at end of loop. proposal_ivar.add_outer(x_chunk, weight, false); original_logpost += dbinom(data[i]->y(), data[i]->n(), prob, true); } proposal_ivar.reflect(); VectorView beta_chunk(full_nonzero_beta, chunk_start, this_chunk_size); if(tdf_ > 0){ beta_chunk = rmvt_ivar_mt( rng(), beta_chunk, proposal_ivar / rwm_variance_scale_factor_, tdf_); }else{ beta_chunk = rmvn_ivar_mt( rng(), beta_chunk, proposal_ivar / rwm_variance_scale_factor_); } double logpost = dmvn(full_nonzero_beta, mu, siginv, 0, true); Vector full_beta(inc.expand(full_nonzero_beta)); logpost += m_->log_likelihood(full_beta, 0, 0, false); double log_alpha = logpost - original_logpost; double logu = log(runif_mt(rng())); if (logu < log_alpha) { m_->set_included_coefficients(full_nonzero_beta); move_accounting_.record_acceptance("rwm_chunk"); } else { move_accounting_.record_rejection("rwm_chunk"); } }
//---------------------------------------------------------------------- void BLCSSS::tim_draw(){ int nvars = m_->coef().nvars(); if(nvars == 0) return; int chunk_size = compute_chunk_size(); int number_of_chunks = compute_number_of_chunks(); assert(number_of_chunks * chunk_size >= nvars); for(int chunk = 0; chunk < number_of_chunks; ++chunk) { ++tim_chunk_attempts_; clock_t mode_start = clock(); TIM tim_sampler(log_posterior(chunk), tdf_); Vec beta = m_->beta(); int start = chunk_size * chunk; int elements_remaining = nvars - start; VectorView beta_chunk(beta, start, std::min(elements_remaining, chunk_size)); bool ok = tim_sampler.locate_mode(beta_chunk); clock_t mode_end = clock(); double mode_time = double(mode_end - mode_start) / CLOCKS_PER_SEC; tim_mode_finding_times_ += mode_time; if(ok){ tim_sampler.fix_mode(true); clock_t trial_start = clock(); beta_chunk = tim_sampler.draw(beta_chunk); m_->set_beta(beta); tim_chunk_successes_ += tim_sampler.last_draw_was_accepted(); clock_t trial_end = clock(); tim_trial_times_ += double(trial_end - trial_start) / CLOCKS_PER_SEC; }else{ rwm_draw_chunk(chunk); tim_mode_finding_wasted_time_ += mode_time; ++tim_chunk_mode_failures_; } } }