inline std::pair<T, T> sample_pair_from_urn ( rng_t & rng, const std::vector<T> & urn) { DIST_ASSERT(urn.size() >= 2, "urn is too small to sample pair from"); size_t f1 = sample_int(rng, 0, urn.size() - 1); size_t f2 = sample_int(rng, 0, urn.size() - 2); if (f2 >= f1) { f2 += 1; } DIST_ASSERT(0 <= f1 and f1 < urn.size(), "bad value: " << f1); DIST_ASSERT(0 <= f2 and f2 < urn.size(), "bad value: " << f2); DIST_ASSERT(f1 != f2, "bad pair: " << f1 << ", " << f2); return std::make_pair(urn[f1], urn[f2]); }
inline T sample_from_urn ( rng_t & rng, const std::vector<T> & urn) { DIST_ASSERT(urn.size() >= 1, "urn is too small to sample from"); size_t f = sample_int(rng, 0, urn.size() - 1); DIST_ASSERT(0 <= f and f < urn.size(), "bad value: " << f); return urn[f]; }
// sample a random permutation void sample_permutation(int n, vector<int> &out_p) { out_p.resize(n); for (int i = 0; i < n; ++i) { out_p[i] = i; } // randomly swap with rest for (int i = 0; i < n; ++i) { int j = sample_int(i, n-1); if (j > i) { swap(out_p[i], out_p[j]); } } }
void sim_geno(int n_ind, int n_pos, int n_gen, int n_draws, int *geno, double *rf, double *rf2, double error_prob, int *draws, double initf(int, int *), double emitf(int, int, double, int *), double stepf(int, int, double, double, int *)) { int i, k, j, v, v2; double s, **beta, *probs; int **Geno, ***Draws, curstate; int cross_scheme[2]; /* cross scheme hidden in draws argument; used by hmm_bcsft */ cross_scheme[0] = draws[0]; cross_scheme[1] = draws[1]; draws[0] = 0; draws[1] = 0; /* allocate space for beta and reorganize geno and draws */ /* Geno indexed as Geno[pos][ind] */ /* Draws indexed as Draws[rep][pos][ind] */ reorg_geno(n_ind, n_pos, geno, &Geno); reorg_draws(n_ind, n_pos, n_draws, draws, &Draws); allocate_alpha(n_pos, n_gen, &beta); allocate_double(n_gen, &probs); /* Read R's random seed */ GetRNGstate(); for(i=0; i<n_ind; i++) { /* i = individual */ R_CheckUserInterrupt(); /* check for ^C */ /* do backward equations */ /* initialize beta */ for(v=0; v<n_gen; v++) beta[v][n_pos-1] = 0.0; /* backward equations */ for(j=n_pos-2; j>=0; j--) { for(v=0; v<n_gen; v++) { beta[v][j] = beta[0][j+1] + stepf(v+1,1,rf[j], rf2[j], cross_scheme) + emitf(Geno[j+1][i],1,error_prob, cross_scheme); for(v2=1; v2<n_gen; v2++) beta[v][j] = addlog(beta[v][j], beta[v2][j+1] + stepf(v+1,v2+1,rf[j],rf2[j], cross_scheme) + emitf(Geno[j+1][i],v2+1,error_prob, cross_scheme)); } } for(k=0; k<n_draws; k++) { /* k = simulation replicate */ /* first draw */ /* calculate probs */ s = (probs[0] = initf(1, cross_scheme)+emitf(Geno[0][i],1,error_prob, cross_scheme)+beta[0][0]); for(v=1; v<n_gen; v++) { probs[v] = initf(v+1, cross_scheme) + emitf(Geno[0][i], v+1, error_prob, cross_scheme) + beta[v][0]; s = addlog(s, probs[v]); } for(v=0; v<n_gen; v++) probs[v] = exp(probs[v] - s); /* make draw: returns a value from {1, 2, ..., n_gen} */ curstate = Draws[k][0][i] = sample_int(n_gen, probs); /* move along chromosome */ for(j=1; j<n_pos; j++) { /* calculate probs */ for(v=0; v<n_gen; v++) probs[v] = exp(stepf(curstate,v+1,rf[j-1],rf2[j-1], cross_scheme) + emitf(Geno[j][i],v+1,error_prob, cross_scheme) + beta[v][j] - beta[curstate-1][j-1]); /* make draw */ curstate = Draws[k][j][i] = sample_int(n_gen, probs); } } /* loop over replicates */ } /* loop over individuals */ /* write R's random seed */ PutRNGstate(); }