Hi all, I'm just getting my feet wet with some Rcpp. I'm comfortable with R but new to C++. In the Rcpp vignettes, I found some of the R-like functions for sampling from distributions (runif, rnorm, etc), but I didn't see a function mimicking sample(). I checked the list of unit tests and didn't see it there either. Have I missed it? Is there a C++ function I should be using to sample (with replacement in my particular situation) from a vector (with provided weights). Thanks for any pointers, Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20110514/09b7779b/attachment.htm>
[Rcpp-devel] Rcpp equivalent of sample()?
7 messages · Dirk Eddelbuettel, Chris DuBois
On 14 May 2011 at 14:11, Chris DuBois wrote:
| I'm just getting my feet wet with some Rcpp. ?I'm comfortable with R but new | to C++. ?In the Rcpp vignettes, I found some of the R-like functions for | sampling from distributions (runif, rnorm, etc), but I didn't see a function | mimicking sample(). I checked the list of unit tests and didn't see it there | either. ?Have I missed it? ?Is there a C++ function I should be using to | sample (with replacement in my particular situation) from a vector (with | provided weights). No, sorry, I think you'd have to write a local version. Dirk
Gauss once played himself in a zero-sum game and won $50.
-- #11 at http://www.gaussfacts.com
Thanks Dirk. Quick newbie followup question: Can we put functions within
the inline C++ code? The following doesn't compile, for example:
src <- '
int addition (int a, int b)
{
int r;
r=a+b;
return (r);
}
NumericVector xx(x);
return(xx);
'
testfun = cxxfunction(signature(x="numeric"),body=src,plugin="Rcpp")
On a related note, would you mind showing a quick working example using
std::accumulate? The one below from the quick reference doesn't compile for
me.
Thanks in advance.
Chris
std::accumulate( xx.begin(), xx.end(),std::plus<double>(), 0.0 );
On Sat, May 14, 2011 at 2:54 PM, Dirk Eddelbuettel <edd at debian.org> wrote:
On 14 May 2011 at 14:11, Chris DuBois wrote:
| I'm just getting my feet wet with some Rcpp. I'm comfortable with R but
new
| to C++. In the Rcpp vignettes, I found some of the R-like functions for
| sampling from distributions (runif, rnorm, etc), but I didn't see a
function
| mimicking sample(). I checked the list of unit tests and didn't see it
there
| either. Have I missed it? Is there a C++ function I should be using to
| sample (with replacement in my particular situation) from a vector (with
| provided weights).
No, sorry, I think you'd have to write a local version.
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/ce466c71/attachment.htm>
On 14 May 2011 at 17:13, Chris DuBois wrote:
| Thanks Dirk. ?Quick newbie followup question: Can we put functions within the
| inline C++ code? ?The following doesn't compile, for example:
| src <- '
| int addition (int a, int b)
| {
| ??int r;
| ??r=a+b;
| ??return (r);
| }
| NumericVector xx(x);
| return(xx);
| '
| testfun = cxxfunction(signature(x="numeric"),body=src,plugin="Rcpp")
Use the 'verbose=TRUE' to cxxfunction() and it will become clear
why -- a function is written around the 'body=...' argument,
hence no chance that that part may contain another C++ function.
The remedy is simple: use the "include=..." argument as in
inc <- '
int addition (int a, int b) {
int r = a + b;
return (r);
}
'
src = '
NumericVector xx(x);
return(xx);
'
testfun = cxxfunction(signature(x="numeric"), body=src, include=inc, plugin="Rcpp")
That trick is used a couple of time in the documentation and examples.
| On a related note, would you mind showing a quick working example using
| std::accumulate? ?The one below from the quick reference doesn't compile for
| me.
Try Google for something like that, eg a query that is restricted to my site as in
site:dirk.eddelbuettel.com "std::accumulate"
show five immediate hits. You can similarly constrict the search
to the rcpp-devel list.
Can you send a small example for inline that shows how/where it quickref
example fails for you?
Dirk
Gauss once played himself in a zero-sum game and won $50.
-- #11 at http://www.gaussfacts.com
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<http://www.cppreference.com/wiki/algorithm/accumulate>), as the following works just fine: std::accumulate( xx.begin(), xx.end(),0.0,std::plus<double>()) Chris
On Sat, May 14, 2011 at 5:29 PM, Dirk Eddelbuettel <edd at debian.org> wrote:
On 14 May 2011 at 17:13, Chris DuBois wrote:
| Thanks Dirk. Quick newbie followup question: Can we put functions within
the
| inline C++ code? The following doesn't compile, for example:
| src <- '
| int addition (int a, int b)
| {
| int r;
| r=a+b;
| return (r);
| }
| NumericVector xx(x);
| return(xx);
| '
| testfun = cxxfunction(signature(x="numeric"),body=src,plugin="Rcpp")
Use the 'verbose=TRUE' to cxxfunction() and it will become clear
why -- a function is written around the 'body=...' argument,
hence no chance that that part may contain another C++ function.
The remedy is simple: use the "include=..." argument as in
inc <- '
int addition (int a, int b) {
int r = a + b;
return (r);
}
'
src = '
NumericVector xx(x);
return(xx);
'
testfun = cxxfunction(signature(x="numeric"), body=src, include=inc,
plugin="Rcpp")
That trick is used a couple of time in the documentation and examples.
| On a related note, would you mind showing a quick working example using
| std::accumulate? The one below from the quick reference doesn't compile
for
| me.
Try Google for something like that, eg a query that is restricted to my
site as in
site:dirk.eddelbuettel.com "std::accumulate"
show five immediate hits. You can similarly constrict the search
to the rcpp-devel list.
Can you send a small example for inline that shows how/where it quickref
example fails for you?
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/ed55ffb0/attachment.htm>
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
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 <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.
|
| 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
-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20110514/e7cd3a4f/attachment-0001.htm>