# [Rcpp-devel] Rcpp equivalent of sample()?

Chris DuBois chris.dubois at gmail.com
Sun May 15 03:46:00 CEST 2011

```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?
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 <edd at 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.
> |
> | (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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20110514/e7cd3a4f/attachment-0001.htm>
```