//---------------------------------------------------------------------- void ProbitBartPosteriorSampler::impute_latent_data_point(DataType *data) { double eta = data->prediction(); int n = data->n(); int number_positive = data->y(); int number_negative = n - number_positive; double sum_of_probits = 0; if (number_positive > 5) { double mean = 0; double variance = 1; trun_norm_moments(eta, 1, 0, true, &mean, &variance); sum_of_probits += rnorm_mt(rng(), number_positive * mean, sqrt(number_positive * variance)); } else { for (int i = 0; i < number_positive; ++i) { sum_of_probits += rtrun_norm_mt(rng(), eta, 1, 0, true); } } if (number_negative > 5) { double mean = 0; double variance = 1; trun_norm_moments(eta, 1, 0, false, &mean, &variance); sum_of_probits += rnorm_mt(rng(), number_negative * mean, sqrt(number_negative * variance)); } else { for (int i = 0; i < number_negative; ++i) { sum_of_probits += rtrun_norm_mt(rng(), eta, 1, 0, false); } } data->set_sum_of_residuals(sum_of_probits - (n * eta)); }
inline Vector SimulateLocalLinearTrend( RNG &rng, int length, double initial_level, double initial_slope, double level_sd, double slope_sd) { Vector state = {initial_level, initial_slope}; Vector ans(length); Matrix transition = rbind(Vector{1, 1}, Vector{0, 1}); for (int i = 0; i < length; ++i) { ans[i] = state[0]; state = transition * state; state[0] += rnorm_mt(rng, 0, level_sd); state[1] += rnorm_mt(rng, 0, slope_sd); } return ans; }
double rlnorm_mt(RNG & rng, double logmean, double logsd) { if(!R_FINITE(logmean) || !R_FINITE(logsd) || logsd < 0.) ML_ERR_return_NAN; return exp(rnorm_mt(rng, logmean, logsd)); }
Vector rmvn_L_mt(RNG &rng, const Vector &mu, const Matrix &L) { // L is the lower cholesky triangle of Sigma. uint n = mu.size(); Vector wsp(n); for (uint i = 0; i < n; ++i) wsp[i] = rnorm_mt(rng, 0, 1); return Lmult(L, wsp) + mu; }
//====================================================================== Vector rmvn_mt(RNG &rng, const Vector &mu, const DiagonalMatrix &V) { Vector ans(mu); const ConstVectorView variances(V.diag()); for (int i = 0; i < mu.size(); ++i) { ans[i] += rnorm_mt(rng, 0, sqrt(variances[i])); } return ans; }
//---------------------------------------------------------------------- double PoissonBartPosteriorSampler::draw_mean(Bart::TreeNode *leaf) { const Bart::PoissonSufficientStatistics &suf( dynamic_cast<const Bart::PoissonSufficientStatistics &>( leaf->compute_suf())); double ivar = suf.sum_of_weights() + 1.0 / mean_prior_variance(); double posterior_mean = suf.weighted_sum_of_residuals() / ivar; double posterior_sd = sqrt(1.0 / ivar); return rnorm_mt(rng(), posterior_mean, posterior_sd); }
inline Vector SimulateLocalLevel(RNG &rng, int length, double initial_value, double sd) { Vector ans(length); ans[0] = initial_value; for (int i = 1; i < length; ++i) { ans[i] = rnorm_mt(rng, ans[i - 1], sd); } return ans; }
Vector rmvn_precision_upper_cholesky_mt( RNG &rng, const Vector &mu, const Matrix &precision_upper_cholesky) { // U is the upper cholesky factor of the inverse variance Matrix uint n = mu.size(); Vector z(n); for (uint i = 0; i < n; ++i) z[i] = rnorm_mt(rng, 0, 1); // if precision = L L^T then Sigma = (L^T)^{-1} L^{-1} = U U^T return Usolve_inplace(precision_upper_cholesky, z) + mu; }
Vector rmvn_suf_mt(RNG &rng, const SpdMatrix &Ivar, const Vector &IvarMu) { Cholesky L(Ivar); uint n = IvarMu.size(); Vector z(n); for (uint i = 0; i < n; ++i) z[i] = rnorm_mt(rng); LTsolve_inplace(L.getL(), z); // returns LT^-1 z which is ~ N(0, Ivar.inv) z += L.solve(IvarMu); return z; }
//---------------------------------------------------------------------- std::pair<double, double> BinomialLogitCltDataImputer::impute_large_sample( RNG &rng, double number_of_trials, double number_of_successes, double linear_predictor) const { double information = 0.0; const Vector &mixing_weights(mixture_approximation.weights()); const Vector &sigma(mixture_approximation.sigma()); double negative_logit_support = plogis(0, linear_predictor, 1, true); double positive_logit_support = plogis(0, linear_predictor, 1, false); Vector p0 = mixing_weights / negative_logit_support; Vector p1 = mixing_weights / positive_logit_support; for (int m = 0; m < mixture_approximation.dim(); ++m) { p0[m] *= pnorm(0, linear_predictor, sigma[m], true); p1[m] *= pnorm(0, linear_predictor, sigma[m], false); } // p0 is the probability distribution over the mixture component // indicators for the failures. N0 is the count of the number of // failures belonging to each mixture component. std::vector<int> N0 = rmultinom_mt(rng, number_of_trials - number_of_successes, p0 / sum(p0)); // p1 is the probability distribution over the mixture component // indicators for the successes. N1 is the count of the number // of successes in each mixture component. std::vector<int> N1 = rmultinom_mt(rng, number_of_successes, p1 / sum(p1)); double simulation_mean = 0; double simulation_variance = 0; for (int m = 0; m < N0.size(); ++m) { int total_obs = N0[m] + N1[m]; if (total_obs == 0) { continue; } double sigsq = square(sigma[m]); double sig4 = square(sigsq); information += total_obs / sigsq; double truncated_normal_mean; double truncated_normal_variance; double cutpoint = 0; if (N0[m] > 0) { trun_norm_moments(linear_predictor, sigma[m], cutpoint, false, &truncated_normal_mean, &truncated_normal_variance); simulation_mean += N0[m] * truncated_normal_mean / sigsq; simulation_variance += N0[m] * truncated_normal_variance / sig4; } if (N1[m] > 0) { trun_norm_moments(linear_predictor, sigma[m], cutpoint, true, &truncated_normal_mean, &truncated_normal_variance); simulation_mean += N1[m] * truncated_normal_mean / sigsq; simulation_variance += N1[m] * truncated_normal_variance / sig4; } } double information_weighted_sum = rnorm_mt(rng, simulation_mean, sqrt(simulation_variance)); return std::make_pair(information_weighted_sum, information); }
//---------------------------------------------------------------------- // Drawing the mean at a leaf node is like drawing the intercept in // a logistic regression model after the other linear effects have // been subtracted out. double LogitBartPosteriorSampler::draw_mean(Bart::TreeNode *leaf) { const Bart::LogitSufficientStatistics &suf( dynamic_cast<const Bart::LogitSufficientStatistics &>( leaf->compute_suf())); double prior_variance = mean_prior_variance(); double ivar = (1.0 / prior_variance) + suf.sum_of_information(); double posterior_mean = suf.information_weighted_residual_sum() / ivar; double posterior_sd = sqrt(1.0 / ivar); return rnorm_mt(rng(), posterior_mean, posterior_sd); }
//---------------------------------------------------------------------- double ProbitBartPosteriorSampler::draw_mean(Bart::TreeNode *leaf) { const Bart::ProbitSufficientStatistics &suf( dynamic_cast<const Bart::ProbitSufficientStatistics &>( leaf->compute_suf())); double prior_variance = mean_prior_variance(); double ivar = suf.sample_size() + (1.0 / prior_variance); double posterior_mean = suf.sum() / ivar; double posterior_sd = sqrt(1.0 / ivar); return rnorm_mt(rng(), posterior_mean, posterior_sd); }
double BinomialProbitDataImputer::impute(RNG &rng, double number_of_trials, double number_of_successes, double eta) const { int64_t n = lround(number_of_trials); int64_t y = lround(number_of_successes); if (y < 0 || n < 0) { report_error( "Negative values not allowed in " "BinomialProbitDataImputer::impute()."); } if (y > n) { report_error( "Success count exceeds trial count in " "BinomialProbitDataImputer::impute."); } double mean, variance; double ans = 0; if (y > clt_threshold_) { trun_norm_moments(eta, 1, 0, true, &mean, &variance); // If we draw y deviates from the same truncated normal and add // them up we'll have a normal with mean (y * mean) and variance // (y * variance). ans += rnorm_mt(rng, y * mean, sqrt(y * variance)); } else { for (int i = 0; i < y; ++i) { // TODO: If y is large-ish but not quite // clt_threshold_ then we might waste some time here // constantly rebuilding the same TnSampler object. ans += rtrun_norm_mt(rng, eta, 1, 0, true); } } if (n - y > clt_threshold_) { trun_norm_moments(eta, 1, 0, false, &mean, &variance); ans += rnorm_mt(rng, (n - y) * mean, sqrt((n - y) * variance)); } else { for (int i = 0; i < n - y; ++i) { ans += rtrun_norm_mt(rng, eta, 1, 0, false); } } return ans; }
double GaussianBartPosteriorSampler::draw_mean(Bart::TreeNode *leaf) { double sigsq = model_->sigsq(); const Bart::GaussianBartSufficientStatistics &suf( dynamic_cast<const Bart::GaussianBartSufficientStatistics &>( leaf->compute_suf())); double ivar = suf.n() / sigsq + 1.0 / mean_prior_variance(); double mean = (suf.sum() / sigsq) / ivar; double sd = sqrt(1.0 / ivar); double value = rnorm_mt(rng(), mean, sd); return value; }
double rig_mt(RNG & rng, double mu, double lambda){ double y = rnorm_mt(rng); y = y * y; double mu2 = mu * mu; double muy = mu * y; double mu2lam = .5 * mu/lambda; double x = mu + muy * mu2lam - mu2lam * sqrt(muy * (4*lambda + muy)); double z = runif_mt(rng); if(z > mu/(mu+x)) return mu2/x; return x; }
inline Vector SimulateSeasonal(RNG &rng, int length, const Vector &initial_pattern, double sd) { int num_seasons = initial_pattern.size() + 1; Matrix transition = SeasonalStateMatrix(num_seasons); Vector ans(length); Vector state = initial_pattern; for (int i = 0; i < length; ++i) { state = transition * state; state[0] += rnorm_mt(rng, 0, sd); ans[i] = state[0]; } return ans; }
Vector rmvn_robust_mt(RNG &rng, const Vector &mu, const SpdMatrix &V) { uint n = V.nrow(); Matrix eigenvectors(n, n); Vector eigenvalues = eigen(V, eigenvectors); for (uint i = 0; i < n; ++i) { // We're guaranteed that eigenvalues[i] is real and non-negative. We // can take the absolute value of eigenvalues[i] to guard against // spurious negative numbers close to zero. eigenvalues[i] = sqrt(fabs(eigenvalues[i])) * rnorm_mt(rng, 0, 1); } Vector ans(eigenvectors * eigenvalues); ans += mu; return ans; }
void GMS::draw(){ Ptr<GaussianSuf> s = mod_->suf(); double ybar = s->ybar(); double n = s->n(); double sigsq = mod_->sigsq(); double mu0 = pri->mu(); double tausq = pri->sigsq(); double ivar= (n/sigsq) + (1.0/tausq); double mean = (n*ybar/sigsq + mu0/tausq)/ivar; double sd = sqrt(1.0/ivar); double ans = rnorm_mt(rng(), mean, sd); mod_->set_mu(ans); }
void DynamicInterceptTestFramework::SimulateData(int time_dimension) { state_modules().SimulateData(time_dimension); Vector state = state_modules().StateContribution(); data_.clear(); for (int t = 0; t < time_dimension; ++t) { int nobs = 1 + rpois(poisson_rate_); Matrix predictors(nobs, true_beta_.size()); predictors.randomize(); Vector response = predictors * true_beta_; response += state[t]; for (int j = 0; j < nobs; ++j) { response[j] += rnorm_mt(GlobalRng::rng, 0, observation_sd_); } NEW(StateSpace::TimeSeriesRegressionData, data_point)( response, predictors, Selector(response.size(), true)); data_.push_back(data_point); xtx_ += predictors.inner(); total_nobs_ += nobs; } }
Vector ArModel::simulate(int n, const Vector &y0, RNG &rng) const { if (y0.size() != number_of_lags()) { ostringstream err; err << "Error in ArModel::simulate." << endl << "Initial state value y0 was size " << y0.size() << ", but the model has " << number_of_lags() << " lags." << endl; report_error(err.str()); } const Vector &phi(this->phi()); std::deque<double> lags(y0.rbegin(), y0.rend()); Vector ans; ans.reserve(n); for (int i = 0; i < n; ++i) { double mu = 0; for (int lag = 0; lag < number_of_lags(); ++lag) { mu += phi[lag] * lags[lag]; } double y = rnorm_mt(rng, mu, sigma()); lags.push_front(y); lags.pop_back(); ans.push_back(y); } return ans; }
void DRSM::simulate_state_error(RNG &rng, VectorView eta, int t) const { check_size(eta.size()); for (int i = 0; i < eta.size(); ++i) { eta[i] = rnorm_mt(rng, 0, coefficient_transition_model_[i]->sigma()); } }
//====================================================================== void ArStateModel::simulate_state_error(RNG &rng, VectorView eta, int t) const { assert(eta.size() == state_dimension()); eta = 0; eta[0] = rnorm_mt(rng) * sigma(); }
std::pair<double, double> BinomialLogitPartialAugmentationDataImputer::impute( RNG &rng, double number_of_trials, double number_of_successes, double linear_predictor) const { if (number_of_successes > number_of_trials) { ostringstream err; err << "The number of successes must not exceed the number of trials " << "in BinomialLogitPartialAugmentationDataImputer::impute()." << endl; debug_status_message(err, number_of_trials, number_of_successes, linear_predictor); report_error(err.str()); } if (number_of_successes < 0 || number_of_trials < 0) { ostringstream err; err << "The number of successes and the number of trials must both " << "be non-negative in " << "BinomialLogitPartialAugmentationDataImputer::impute()." << endl; debug_status_message(err, number_of_trials, number_of_successes, linear_predictor); report_error(err.str()); } double information_weighted_sum = 0; double information = 0; if (number_of_trials < clt_threshold_) { for (int i = 0; i < number_of_trials; ++i) { bool success = i < number_of_successes; double latent_logit = rtrun_logit_mt(rng, linear_predictor, 0, success); // mu is unused because the mixture is a scale-mixture only, // but we need it for the API. double mu, sigsq; mixture_approximation.unmix(rng, latent_logit - linear_predictor, &mu, &sigsq); double current_weight = 1.0 / sigsq; information += current_weight; information_weighted_sum += latent_logit * current_weight; } } else { // Large sample case. There are number_of_successes draws from // the positive side, and number_of_trials - number_of_successes // draws from the negative side. double mean_of_logit_sum = 0; double variance_of_logit_sum = 0; if (number_of_successes > 0) { mean_of_logit_sum += number_of_successes * trun_logit_mean(linear_predictor, 0, true); variance_of_logit_sum += number_of_successes * trun_logit_variance(linear_predictor, 0, true); } double number_of_failures = number_of_trials - number_of_successes; if (number_of_failures > 0) { mean_of_logit_sum += number_of_failures * trun_logit_mean(linear_predictor, 0, false); variance_of_logit_sum += number_of_failures * trun_logit_variance(linear_predictor, 0, false); } // The information_weighted_sum is the sum of the latent logits // (approximated by a normal), divided by the weight that each // term in the sum recieves (the variance of the logistic // distribution, pi^2/3). information_weighted_sum = rnorm_mt(rng, mean_of_logit_sum, sqrt(variance_of_logit_sum)); information_weighted_sum /= Constants::pi_squared_over_3; // Each latent logit carries the same amount of information: // 1/pi_squared_over_3. information = number_of_trials / Constants::pi_squared_over_3; } return std::make_pair(information_weighted_sum, information); }
Vector MvReg::simulate_fake_x(RNG &rng) const { uint p = xdim(); Vector x(p, 1.0); for (uint i = 1; i < p; ++i) x[i] = rnorm_mt(rng); return x; }