Skip to content

Commit 54c0ede

Browse files
authored
Merge pull request #16 from osorensen/rng-fix
Native R and Rcpp random number generation
2 parents d8eff80 + d022620 commit 54c0ede

File tree

7 files changed

+24
-16
lines changed

7 files changed

+24
-16
lines changed

R/compute_sequentially.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,4 @@ compute_sequentially <- function(
9090

9191
ret <- run_smc(input_timeseries, hyperparameters, smc_options)
9292
}
93+

src/particle.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ StaticParameters::StaticParameters(const vec& alpha, const umat& rho, const vec&
1111
alpha { alpha }, rho { rho }, tau { tau } {}
1212

1313
StaticParameters::StaticParameters(const Prior& prior) :
14-
alpha { randg(prior.n_clusters, distr_param(prior.alpha_shape, 1 / prior.alpha_rate)) },
14+
alpha { Rcpp::rgamma(prior.n_clusters, prior.alpha_shape, 1 / prior.alpha_rate) },
1515
rho { umat(prior.n_items, prior.n_clusters) },
16-
tau { normalise(randg(prior.n_clusters, distr_param(prior.cluster_concentration, 1)), 1) }
16+
tau { normalise(Rcpp::as<vec>(Rcpp::rgamma(prior.n_clusters, prior.cluster_concentration, 1)), 1) }
1717
{
18-
rho.each_col([&prior](uvec& a){ a = shuffle(regspace<uvec>(1, prior.n_items)); });
18+
rho.each_col([&prior](uvec& a){
19+
a = Rcpp::as<uvec>(Rcpp::sample(prior.n_items, prior.n_items, false));
20+
});
1921
}
2022

2123
Particle::Particle(const Options& options, const StaticParameters& parameters,

src/rejuvenate.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
using namespace arma;
88

99
uvec leap_and_shift(const uvec& current_rho, unsigned int cluster, const Prior& prior) {
10-
unsigned int u = randi(distr_param(0, prior.n_items - 1));
10+
unsigned int u = Rcpp::sample(prior.n_items, 1, false)[0] - 1;
1111
uvec intermediate_rho = current_rho;
1212
uvec rho_proposal = intermediate_rho;
1313
int rho_u = intermediate_rho(u);
@@ -16,7 +16,7 @@ uvec leap_and_shift(const uvec& current_rho, unsigned int cluster, const Prior&
1616
uvec(rho_u)
1717
);
1818

19-
unsigned int index = randi(distr_param(0, support.size() - 1));
19+
unsigned int index = Rcpp::sample(support.size(), 1, false)[0] - 1;
2020
intermediate_rho(u) = support(index);
2121
for(size_t i{}; i < intermediate_rho.size(); i++) {
2222
if(current_rho(i) == current_rho(u)) {
@@ -85,7 +85,7 @@ bool Particle::rejuvenate(
8585
int proposed_particle_filter = Rcpp::sample(probs.size(), 1, false, probs, false)[0];
8686

8787
bool accepted{};
88-
if(log_ratio > log(randu())) {
88+
if(log_ratio > log(R::runif(0, 1))) {
8989
this->parameters = StaticParameters{alpha_proposal, rho_proposal, parameters.tau};
9090
this->conditioned_particle_filter = proposed_particle_filter;
9191
this->log_incremental_likelihood = proposal_particle.log_incremental_likelihood;

src/resampler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ ivec count_between_intervals(const vec& cumprob, const vec& u) {
2626

2727
ivec stratsys(int n_samples, vec probs, bool stratified) {
2828
vec u(n_samples);
29-
vec rn = stratified ? randu(n_samples) : vec(n_samples, fill::value(randu()));
29+
vec rn = stratified ? Rcpp::runif(n_samples) : vec(n_samples, fill::value(R::runif(0, 1)));
3030

3131
for(size_t i{}; i < n_samples; i++) u(i) = (i + rn(i)) / n_samples;
3232
return count_between_intervals(cumsum(probs), u);

src/sample_latent_rankings.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
using namespace arma;
99
namespace fs = std::filesystem;
1010

11+
uvec shuffle_rcpp(const uvec& values_in) {
12+
ivec inds = Rcpp::sample(values_in.size(), values_in.size(), false) - 1;
13+
return values_in(conv_to<uvec>::from(inds));
14+
}
15+
1116
LatentRankingProposal sample_latent_rankings(
1217
const std::unique_ptr<Data>& data, unsigned int t, const Prior& prior,
1318
std::string latent_rank_proposal,
@@ -45,7 +50,7 @@ LatentRankingProposal sample_latent_rankings(
4550
uvec tmp = ndit->second.observation;
4651

4752
if(latent_rank_proposal == "uniform") {
48-
tmp(ndit->second.available_items) = shuffle(ndit->second.available_rankings);
53+
tmp(ndit->second.available_items) = shuffle_rcpp(ndit->second.available_rankings);
4954
proposal.proposal = join_horiz(proposal.proposal, tmp);
5055
proposal.log_probability = join_vert(
5156
proposal.log_probability, vec{-lgamma(ndit->second.available_rankings.size() + 1.0)});
@@ -55,7 +60,7 @@ LatentRankingProposal sample_latent_rankings(
5560
}
5661
double logprob{0};
5762

58-
uvec available_items_shuffled = shuffle(ndit->second.available_items);
63+
uvec available_items_shuffled = shuffle_rcpp(ndit->second.available_items);
5964
uvec available_rankings = ndit->second.available_rankings;
6065

6166
while(available_items_shuffled.size() > 1) {
@@ -135,7 +140,7 @@ LatentRankingProposal sample_latent_rankings(
135140
Rcpp::stop("No files.");
136141
}
137142

138-
int random_index = randi(distr_param(0, file_count - 1));
143+
int random_index = Rcpp::sample(file_count, 1, false)[0] - 1;
139144

140145
fs::path random_file_path;
141146
size_t current_index = 0;

tests/testthat/test-compute_sequentially_complete.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,5 @@ test_that("compute_sequentially works with complete data", {
4040
)
4141
alpha_hat <- weighted.mean(x = as.numeric(mod$alpha), w = mod$importance_weights)
4242
expect_gt(alpha_hat, .99)
43-
expect_lt(alpha_hat, 1.05)
43+
expect_lt(alpha_hat, 1.06)
4444
})

tests/testthat/test-compute_sequentially_mixtures.R

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
test_that("s", {
1+
test_that("Mixture models work", {
22
set.seed(2)
33
mod <- compute_sequentially(
44
mixtures[1:50, ],
@@ -19,10 +19,10 @@ test_that("s", {
1919
tau[, i] <- tau[perm$permutations[i, ], i]
2020
}
2121

22-
expect_gt(weighted.mean(alpha[1, ], mod$importance_weights), 2)
23-
expect_lt(weighted.mean(alpha[1, ], mod$importance_weights), 3)
24-
expect_gt(weighted.mean(alpha[2, ], mod$importance_weights), .85)
25-
expect_lt(weighted.mean(alpha[2, ], mod$importance_weights), 1.15)
22+
expect_gt(weighted.mean(alpha[1, ], mod$importance_weights), 1)
23+
expect_lt(weighted.mean(alpha[1, ], mod$importance_weights), 1.1)
24+
expect_gt(weighted.mean(alpha[2, ], mod$importance_weights), 2)
25+
expect_lt(weighted.mean(alpha[2, ], mod$importance_weights), 2.5)
2626

2727
expect_gt(weighted.mean(tau[1, ], mod$importance_weights), .4)
2828
expect_lt(weighted.mean(tau[1, ], mod$importance_weights), .6)

0 commit comments

Comments
 (0)