For now I am using the following, which seems to work. I didn't really need all the functionality from sample(); I just needed to get a random index (but with non-uniform probabilities). It might be cleaner to use std::accumulate in rcategorical, but I got this working first. Also, rcategorical requires a double[K]; how do I cast my probabilities argument P as a doubles array? I naively thought P would already be an array of doubles, but rcategorical(P,K) doesn't compile.
Any thoughts/suggestions on how to improve on this first attempt? Thanks in advance, Chris ### inc <- 'int rcategorical(double probs[],int K) { double total = 0; double cumpr = 0; int k = 0; for (k = 0; k < K; k++) { total += probs[k]; } double u = unif_rand(); for (k = 0; k < K; k++) { cumpr += probs[k] / total; if (u < cumpr) break; } return(k); }' src <- ' Rcpp:NumericVector probs(P); int K = probs.size(); double pr[K]; for (int k = 0; k < K; k++) { // copy elements over one-by-one? Noob status, but works. :-) pr[k] = probs[k]; } int R = rcategorical(pr,K); return wrap(R); ' fun <- cxxfunction(signature(P="numeric"),includes=inc,body = src, plugin="Rcpp") p <- c(.2,.3,.4,.1) fun(p) On Sat, May 14, 2011 at 6:19 PM, Dirk Eddelbuettel <e...@debian.org> wrote: > > On 14 May 2011 at 18:01, Chris DuBois wrote: > | Thanks Dirk. Passing the addition function in the includes argument > worked > | great. > | > | Also, one of the links from your suggested Google search led me to this > | (working) example for std::accumulate: > | > | src <- 'NumericVector xx(x); > | return wrap( std::accumulate( xx.begin(), xx.end(), 0.0));' > | fx <- cxxfunction(signature( x = "numeric" ),body=src,plugin = "Rcpp") > | fx(1:10) # 55 > | > | I had been copying the quickref and using: std::accumulate( xx.begin(), > | xx.end(),std::plus<double>(),0.0) > | > | I think this might be a typo where the last two arguments are transposed > (which > | I shouldn't have noticed after browsing the function's c++ reference), as > the > | following works just fine: std::accumulate( xx.begin(), xx.end > | (),0.0,std::plus<double>()) > > Good catch. The arguments are > > start, end, intial value, (optional) operator function > > and std::plus<double>() is the default for summation. So that was an error, > and hence a Thank You! for catching it. I just committed this new section: > > > \paragraph{STL interface}~ > \newline > <<lang=cpp>>= > // sum a vector from beginning to end > double s = std::accumulate(x.begin(), > x.end(), 0.0); > // prod of elements from beginning to end > int p = std::accumulate(vec.begin(), > vec.end(), 1, std::multiplies<int>()); > // inner_product to compute sum of squares > double s2 = std::inner_product(res.begin(), > res.end(), res.begin(), 0.0); > @ > > > which shows std::multiplies<int>() as an alternative operator for > accumulate > as well as inner_product for a sum-of-squares computation (as once > suggested > by Doug). > > Dirk > > -- > Gauss once played himself in a zero-sum game and won $50. > -- #11 at http://www.gaussfacts.com >
_______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel