[Rcpp-devel] Rcpp 0.10.0

Ian Fellows ian.fellows at stat.ucla.edu
Wed Nov 14 22:46:59 CET 2012


So,… um… Wow!

This is some pretty incredible work, and lines up almost to the letter with the real world issues that I was experiencing with my package. Reading over the vignette, a couple of questions popped into my head.

With the //Rcpp::interfaces(cpp) declaration
1. Are classes also exported as transparently as functions.
2. If my package already has a namespace named ernm, is an extra one wrapped around it, so that extending packages would have to use ernm::ernm::bar()?
3. Just to be clear… this removes the need to make an inline plug-in because you can just use cppFunction(depends="MyPacakge",…) with no additional glue except for the interface statement.

I do a lot of passing of objects up and down between R and C++ using home grown code to make the process transparent. Can you speak a little about how the new module object passing is implemented? Are copy constructors called? Is shallow or deep the default? How does one use the new macros?

Best,
Ian




On Nov 14, 2012, at 5:17 AM, rcpp-devel-request at lists.r-forge.r-project.org wrote:

> Send Rcpp-devel mailing list submissions to
> 	rcpp-devel at lists.r-forge.r-project.org
> 
> To subscribe or unsubscribe via the World Wide Web, visit
> 	https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
> 
> or, via email, send a message with subject or body 'help' to
> 	rcpp-devel-request at lists.r-forge.r-project.org
> 
> You can reach the person managing the list at
> 	rcpp-devel-owner at lists.r-forge.r-project.org
> 
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Rcpp-devel digest..."
> 
> 
> Today's Topics:
> 
>   1. [ANN] Rcpp 0.10.0 (Dirk Eddelbuettel)
>   2. Sample function(s) for inclusion in RcppArmadillo
>      (Christian Gunning)
>   3. Re: Sample function(s) for inclusion in RcppArmadillo
>      (Dirk Eddelbuettel)
>   4. Re: Sample function(s) for inclusion in RcppArmadillo
>      (Romain Francois)
> 
> 
> ----------------------------------------------------------------------
> 
> Message: 1
> Date: Wed, 14 Nov 2012 06:42:15 -0600
> From: Dirk Eddelbuettel <edd at debian.org>
> To: rcpp-devel <rcpp-devel at lists.r-forge.r-project.org>
> Subject: [Rcpp-devel] [ANN] Rcpp 0.10.0
> Message-ID: <20643.37287.636306.45784 at max.nulle.part>
> Content-Type: text/plain; charset=us-ascii
> 
> 
> We are very excited about Rcpp 0.10.0 which appeared on CRAN this morning.
> The announcement text included in the package is below -- see in particular
> the new vignette Rcpp-attributes. 
> 
> We will probably provide more example in the following days and weeks.
> 
> Cheers, Dirk
> 
> 
> 
> ===== Summary =====
> 
> Version 0.10.0 of the Rcpp package is now on CRAN and its mirrors.  
> 
> This new release brings a number of new features, as well as extensions to
> existing features, to the package.  Several key aspects are highlighted
> below, and further details can be found in the NEWS and ChangeLog files which
> are included in the package.
> 
> 
> 
> ===== Overview =====
> 
> Rcpp is an R package and associated C++ library for seamless integration
> between C++ and R.  
> 
> It has been described in a recent paper in the Journal of Statistical
> Software (Vol 40, Issue 08) which is also included in the package as the
> "Rcpp-introduction" pdf vignette.
> 
> As of late 2012, Rcpp is used by over 80 other CRAN packages making it the
> most widely-used language interface for R.
> 
> Several key features of the new 0.10.0 release are described below.
> 
> 
> 
> ===== Rcpp attributes =====
> 
> Rcpp attributes are a new feature of Rcpp version 0.10.0 that provide 
> infrastructure for seamless language bindings between R and C++. With
> attributes we hope to eliminate the need to write boilerplate conversion
> and marshaling code, make it much easier to use C++ within interactive
> R sessions, and reduce the learning curve associated with using C++
> and R together. 
> 
> Rcpp attributes derive their syntax from C++11 style attributes and
> are included in C++ source files using specially formatted comments.
> For example, the following source file includes the definition of 
> a fibonacci function with an Rcpp::export attribute included 
> immediately above the function definition:
> 
> #include <Rcpp.h>
> using namespace Rcpp;
> 
> // [[Rcpp::export]]
> int fibonacci(const int x) {
>   if (x < 2)
>      return x;
>   else
>      return (fibonacci(x - 1)) + fibonacci(x - 2);
> }
> 
> The export attribute indicates that we'd like the function to be callable
> from R. We can now "source" this C++ file at the R prompt and then call
> the function as follows:
> 
> R> source("fibonacci.cpp")
> R> fibonacci(20)
> [1] 6765
> 
> Rcpp attributes build upon Rcpp modules (described in another vignette in the
> package), as well as the automatic type converters Rcpp::as<>() and Rcpp::wrap.  
> The converters can already be used for a wide variety of standard C and C++
> types, and can also be adapted to other C++ types and libraries as described
> in the Rcpp-extending vignette.
> 
> Rcpp attributes and their supporting functions include: 
> 
> - Rcpp::export attribute to export a C++ function to R
> - sourceCpp function to source exported functions from a file
> - cppFunction and evalCpp functions for inline declarations and execution
> - Rcpp::depends attribute for specifying additional build dependencies
>   for sourceCpp
> 
> Attributes can also be used for package development via the `compileAttributes`
> function, which generates an Rcpp module for all exported functions within
> an R package.
> 
> More details are provided in the new vignette Rcpp-attributes.  We also intend
> to provide further illustrations via our blogs following the release.
> 
> 
> 
> ===== Rcpp modules =====
> 
> Rcpp modules provide an easy way to expose C++ functions and classes to R using 
> a declarative syntax. We declare which functions and which classes we want to 
> make available to R and modules takes care of automatically (via the compiler, 
> through template deduction ...) creating the interface code between the C++
> code and R. 
> 
> Rcpp modules have been extended for the new release.  A brief
> summary of new key features is:
> 
> - inheritance: A class can now declare that it inherits from another class;
>   the exposed class gains methods and properties (fields) from its parent class. 
> - Functions and methods can now return objects from classes that are exposed
>   through modules. The macro RCPP_EXPOSED_CLASS and RCPP_EXPOSED_CLASS_NODECL 
>   can be used to declared the required type traits.
> - Classes exposed through modules can also be used as parameters of exposed
>   functions or methods.  
> - Exposed classes can declare factories, i.e. a C++ function returning a
>   pointer to the target class, providing an alternative way to construct
>   objects. 
> - "converter" can be used to declare a way to convert ("cast") an object of
>   a type to another type. This is translated at the R level in terms of an "as"
>   method.
> 
> We intend to provide example packages using these new features in the near future.
> 
> 
> 
> ===== New sugar functions =====
> 
> Rcpp sugar provides "syntactic sugar" familiar to R programmers at the C++
> level, including a large number of vectorised functions.  In this release, we
> added 
> - which_min() and which_max() returning the index of the first object
>   matching the condition
> - unique() and sort_unique()
> 
> 
> 
> ===== New I/O facilities =====
> 
> The Rcpp::Rcout object now supports the std::flush manipulator, which calls
> R_FlushConsole. A new object Rcpp::Rcerr has been added with passes content
> for error messages to REprintf().
> 
> 
> 
> ===== New namespace "R::" for Rmath functions =====
> 
> A side-effect of Rcpp sugar providing vectorised d/p/q/r functions for the
> various statistical distribution was that the scalar variants of these
> functions (available from Rmath.h) were masked behind a Rf_ prefix.
> Previously, one had to call ::Rf_pnorm5() to compute pnorm() -- but now a
> cleaner interface R::pnorm() is available.  Unit tests were added as well.
> 
> 
> 
> ===== Links =====
> 
> Rcpp main page: 
>    http://dirk.eddelbuettel.com/code/rcpp.html
> 
> R-forge project page: 
>    http://r-forge.r-project.org/projects/rcpp/
> 
> Dirk's blog section about Rcpp 
>    Rcpp: http://dirk.eddelbuettel.com/blog/code/rcpp/
> 
> Romain's blog section about Rcpp: 
>    http://romainfrancois.blog.free.fr/index.php?category/R-package/Rcpp
> 
> RStudio blog:
>    http://blog.rstudio.org
> 
> Google+: 
>    https://plus.google.com/b/107029540907667241299/107029540907667241299/posts
> 
> Facebook:
>    http://www.facebook.com/pages/Rcpp/213047595425775
> 
> Twitter:
>    https://twitter.com/eddelbuettel
>    https://twitter.com/romain_francois
> 
> 
> 
> ===== Support =====
> 
> Questions about Rcpp should be directed to the Rcpp-devel mailing list
>    https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
> 
> While we prefer the mailing list, StackOverflow has also become a frequently
> used resource under the [rcpp] tag:
>    http://stackoverflow.com/questions/tagged/rcpp
> 
> 
> Dirk Eddelbuettel, Romain Francois, Doug Bates, John Chambers and JJ Allaire
> November 2012
> 
> 
> 
> 
> -- 
> Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com  
> 
> 
> ------------------------------
> 
> Message: 2
> Date: Wed, 14 Nov 2012 06:05:48 -0700
> From: Christian Gunning <xian at unm.edu>
> To: rcpp-devel at lists.r-forge.r-project.org
> Subject: [Rcpp-devel] Sample function(s) for inclusion in
> 	RcppArmadillo
> Message-ID:
> 	<CADNH-Puxd0bVd_VtYzi3eEHqcXN_=+8jFypBk0MczT_ZMtPi_Q at mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
> 
> Dear all,
> 
> The attached file is for inclusion in RcppArmadillo/src.  It's a templated
> implementation of R's sample that relies on a few Armadillo functions.  It
> should produce results identical to R, except when R uses Walker's alias
> method (with replacement, more than 200 nonzero probabilities given).
> 
> This is intended to be used solely in C++ code, and is not exported.
> 
> best,
> Christian
> University of New Mexico
> 
> -- 
> A man, a plan, a cat, a ham, a yak, a yam, a hat, a canal ? Panama!
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20121114/2b4a422b/attachment-0001.html>
> -------------- next part --------------
> A non-text attachment was scrubbed...
> Name: sample.cpp
> Type: text/x-c++src
> Size: 5664 bytes
> Desc: not available
> URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20121114/2b4a422b/attachment-0001.cpp>
> 
> ------------------------------
> 
> Message: 3
> Date: Wed, 14 Nov 2012 07:14:51 -0600
> From: Dirk Eddelbuettel <edd at debian.org>
> To: xian at unm.edu
> Cc: rcpp-devel at lists.r-forge.r-project.org
> Subject: Re: [Rcpp-devel] Sample function(s) for inclusion in
> 	RcppArmadillo
> Message-ID: <20643.39243.770474.293480 at max.nulle.part>
> Content-Type: text/plain; charset=utf-8
> 
> 
> Christian,
> 
> On 14 November 2012 at 06:05, Christian Gunning wrote:
> | Dear all,
> | 
> | The attached file is for inclusion in RcppArmadillo/src.? It's a templated
> | implementation of R's sample that relies on a few Armadillo functions.? It
> | should produce results identical to R, except when R uses Walker's alias method
> | (with replacement, more than 200 nonzero probabilities given).?
> | 
> | This is intended to be used solely in C++ code, and is not exported.
> 
> Thank you, got both emails!  Will take a closer look -- we were busy with
> releasing Rcpp 0.10.0 which will rock :)
> 
> Would this make sense "upstream" in Armadillo? Or do you want the R RNG for
> reproducibility? Also, you may need to add RNGScope() if you use R's RNG.
> 
> Dirk
> 
> 
> | best,
> | Christian
> | University of New Mexico
> | 
> | --
> | A man, a plan, a cat, a ham, a yak, a yam, a hat, a canal ? Panama!
> | 
> | ----------------------------------------------------------------------
> | // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
> | //
> | // sample.cpp: Rcpp/Armadillo equivalent to R's sample().  
> | // This is to be used in C++ functions, and should *not* be called from R.
> | // It should yield identical results to R in most cases
> | // (note that Walker's alias method is not implemented).
> | //
> | // Copyright (C)  2012 Christian Gunning
> | //
> | // This file is part of RcppArmadillo.
> | //
> | // RcppArmadillo is free software: you can redistribute it and/or modify it
> | // under the terms of the GNU General Public License as published by
> | // the Free Software Foundation, either version 2 of the License, or
> | // (at your option) any later version.
> | //
> | // RcppArmadillo is distributed in the hope that it will be useful, but
> | // WITHOUT ANY WARRANTY; without even the implied warranty of
> | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> | // GNU General Public License for more details.
> | //
> | // You should have received a copy of the GNU General Public License
> | // along with RcppArmadillo.  If not, see <http://www.gnu.org/licenses/>.
> | 
> | #include <RcppArmadillo.h>
> | 
> | using namespace Rcpp;
> | 
> | //Declarations
> | void SampleReplace( IntegerVector &index, int nOrig, int size);
> | void SampleNoReplace( IntegerVector &index, int nOrig, int size);
> | void ProbSampleReplace(IntegerVector &index, int nOrig, int size, arma::vec &prob);
> | void ProbSampleNoReplace(IntegerVector &index, int nOrig, int size, arma::vec &prob);
> | void FixProb(NumericVector &prob, int size, bool replace);
> | 
> | template <class T> 
> | T sample(const T &x, const int size, const bool replace, NumericVector prob_ = NumericVector(0) ) {
> |     // Templated sample -- should work on any Rcpp Vector
> |     int ii, jj;
> |     int nOrig = x.size();
> |     int probsize = prob_.size();
> |     // Create return object
> |     T ret(size);
> | 	if ( size > nOrig && !replace) throw std::range_error( "Tried to sample more elements than in x without replacement" ) ;
> |     // Store the sample ids here, modify in-place
> |     IntegerVector index(size);
> |     if (probsize == 0) { // No probabilities given
> |         if (replace) {
> |             SampleReplace(index, nOrig, size);
> |         } else {
> |             SampleNoReplace(index, nOrig, size);
> |         }
> |     } else { 
> |         if (probsize != nOrig) throw std::range_error( "Number of probabilities must equal input vector length" ) ;
> |         // normalize, error-check probability vector
> |         // Will be modified in-place
> |         FixProb(prob_, size, replace);
> |         // 
> |         // Copy the given probabilities into an arma vector
> |         arma::vec prob(prob_.begin(), prob_.size());
> |         if (replace) {
> |             // check for walker alias conditions here??
> |             ProbSampleReplace(index, nOrig, size, prob);
> |         } else {
> |             ProbSampleNoReplace(index, nOrig, size, prob);
> |         }
> |     }
> |     // copy the results into the return vector
> |     for (ii=0; ii<size; ii++) {
> |         jj = index[ii];
> |         ret[ii] = x[jj];
> |     }
> |     return(ret);
> | }
> | 
> | void SampleReplace( IntegerVector &index, int nOrig, int size) {
> |     int ii;
> |     for (ii = 0; ii < size; ii++) {
> |         index[ii] = nOrig * unif_rand();
> |     }
> | }
> | 
> | void SampleNoReplace( IntegerVector &index, int nOrig, int size) {
> |     int ii, jj;
> |     IntegerVector sub(nOrig);
> |     for (ii = 0; ii < nOrig; ii++) {
> |         sub[ii] = ii;
> |     }
> |     for (ii = 0; ii < size; ii++) {
> |         jj = nOrig * unif_rand();
> |         index[ii] = sub[jj];
> |         // replace sampled element with last, decrement
> |         sub[jj] = sub[--nOrig];
> |     }
> | }
> | 
> | void FixProb(NumericVector &prob, const int size, const bool replace) {
> |     // prob is modified in-place.  
> |     // Is this better than cloning it?
> |     double sum = 0.0;
> |     int ii, nPos = 0;
> |     int nn = prob.size();
> |     for (ii = 0; ii < nn; ii++) {
> |         if (!R_FINITE(prob[ii])) //does this work??
> |             throw std::range_error( "NAs not allowed in probability" ) ;
> |         if (prob[ii] < 0)
> |             throw std::range_error( "Negative probabilities not allowed" ) ;
> |         if (prob[ii] > 0) {
> |             nPos++;
> |             sum += prob[ii];
> |         }
> |     }
> |     if (nPos == 0 || (!replace && size > nPos)) {
> |         throw std::range_error("Not enough positive probabilities");
> |     }
> |     prob = prob / sum;  //sugar
> | }
> | 
> | // Unequal probability sampling with replacement 
> | void ProbSampleReplace(IntegerVector &index, int nOrig, int size, arma::vec &prob){
> |     double rU;
> |     int ii, jj;
> |     int size_1 = size - 1;
> |     arma::uvec perm = arma::sort_index(prob, 1); //descending sort of index
> |     prob = arma::sort(prob, 1);  // descending sort of prob
> |     // cumulative probabilities 
> |     prob = arma::cumsum(prob);
> |     // compute the sample 
> |     for (ii = 0; ii < size; ii++) {
> |         rU = unif_rand();
> |         for (jj = 0; jj < size_1; jj++) {
> |             if (rU <= prob[jj])
> |                 break;
> |         }
> |         index[ii] = perm[jj];
> |     }
> | }
> | 
> | // Unequal probability sampling without replacement 
> | void ProbSampleNoReplace(IntegerVector &index, int nOrig, int size, arma::vec &prob){
> |     int ii, jj, kk;
> |     int size_1 = size - 1;
> |     double rT, mass, totalmass = 1.0;
> |     arma::uvec perm = arma::sort_index(prob, 1); //descending sort of index
> |     prob = arma::sort(prob, 1);  // descending sort of prob
> |     // compute the sample 
> |     for (ii = 0; ii < size; ii++, size_1--) {
> |         rT = totalmass * unif_rand();
> |         mass = 0;
> |         for (jj = 0; jj < size_1; jj++) {
> |             mass += prob[jj];
> |             if (rT <= mass)
> |                 break;
> |         }
> |         index[ii] = perm[jj];
> |         totalmass -= prob[jj];
> |         for ( kk = jj; kk < size_1; kk++) {
> |             prob[kk] = prob[kk+1];
> |             perm[kk] = perm[kk+1];
> |         }
> |     }
> | }
> | 
> | ----------------------------------------------------------------------
> | _______________________________________________
> | Rcpp-devel mailing list
> | Rcpp-devel at lists.r-forge.r-project.org
> | https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
> -- 
> Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com  
> 
> 
> ------------------------------
> 
> Message: 4
> Date: Wed, 14 Nov 2012 14:16:59 +0100
> From: Romain Francois <romain at r-enthusiasts.com>
> To: rcpp-devel at lists.r-forge.r-project.org
> Subject: Re: [Rcpp-devel] Sample function(s) for inclusion in
> 	RcppArmadillo
> Message-ID: <50A399CB.5060009 at r-enthusiasts.com>
> Content-Type: text/plain; charset=windows-1252; format=flowed
> 
> Le 14/11/12 14:05, Christian Gunning a ?crit :
>> Dear all,
>> 
>> The attached file is for inclusion in RcppArmadillo/src.  It's a
>> templated implementation of R's sample that relies on a few Armadillo
>> functions.  It should produce results identical to R, except when R uses
>> Walker's alias method (with replacement, more than 200 nonzero
>> probabilities given).
>> 
>> This is intended to be used solely in C++ code, and is not exported.
>> 
>> best,
>> Christian
>> University of New Mexico
>> 
>> --
>> A man, a plan, a cat, a ham, a yak, a yam, a hat, a canal ? Panama!
> 
> Interesting. With some more work, we could even make this sugary. i.e. 
> have this signature:
> 
> template <int RTYPE, bool NA, typename T>
> Rcpp::Vector<RTYPE> sample(const Rcpp::VectorBase<RTYPE,NA,T> &x, const 
> int size, const bool replace, NumericVector prob_ = NumericVector(0) ) {
> 
> 	typedef Rcpp::Vector<RTYPE> TARGET ;
> 	// Templated sample -- should work on any Rcpp Vector
>     int ii, jj;
>     int nOrig = x.size();
>     int probsize = prob_.size();
>     // Create return object
>     TARGET ret(size);
> 	if ( size > nOrig && !replace) throw std::range_error( "Tried to sample 
> more elements than in x without replacement" ) ;
> 	
>     ...
> 
> }
> 
> So that we could sample sugar expressions :-)
> 
> Romain
> 
> -- 
> Romain Francois
> Professional R Enthusiast
> +33(0) 6 28 91 30 30
> 
> R Graph Gallery: http://gallery.r-enthusiasts.com
> `- http://bit.ly/SweN1Z : SuperStorm Sandy
> 
> blog:            http://romainfrancois.blog.free.fr
> |- http://bit.ly/RE6sYH : OOP with Rcpp modules
> `- http://bit.ly/Thw7IK : Rcpp modules more flexible
> 
> 
> 
> ------------------------------
> 
> _______________________________________________
> Rcpp-devel mailing list
> Rcpp-devel at lists.r-forge.r-project.org
> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
> 
> End of Rcpp-devel Digest, Vol 37, Issue 13
> ******************************************



More information about the Rcpp-devel mailing list