[Rcpp-devel] more sugar
Romain Francois
romain at r-enthusiasts.com
Thu Jun 17 22:54:14 CEST 2010
Hi,
Following up on http://news.gmane.org/gmane.comp.lang.r.rcpp
I've commited quite a bit of code today.
The idea of sugar really is to bring a subset of the R syntax right into
C++.
First I had to change a few implementation details of the Vector class
so that one of its base class implements CRTP:
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
Then, I made the previously advertised functions any, all, etc ... more
generic through the base template class VectorBase.
Then, I added some more syntax. Currently sugar has the functions:
any, all, is_na, seq_along, seq_len
and knows about the operators <,>,<=,>=,!=,==,+
Here are a few selected examples (from the unit test suite):
test.sugar.plus <- function( ){
fx <- cxxfunction( signature( x = "integer" ), '
IntegerVector xx(x) ;
return List::create(
xx + 10,
10 + xx,
xx + xx
) ;
', plugin = "Rcpp" )
checkEquals( fx(1:10) , list( 11:20,11:20,1:10+1:10) )
}
We start of with
IntegerVector xx(x) ;
which should be familiar to people using the Rcpp API... nothing new here.
Then the expressions "xx + 10", "10 + xx", and "xx + xx" are new things.
They do what you would do in R like this:
> x <- 1:10
> x + 10
[1] 11 12 13 14 15 16 17 18 19 20
> 10 + x
[1] 11 12 13 14 15 16 17 18 19 20
> x + x
[1] 2 4 6 8 10 12 14 16 18 20
The big difference is that, unlike R, Rcpp sugar expressions are managed
at compile time, thanks to the technique of expression templates (see
also Armadillo or Blitz++).
Another example:
fx <- cxxfunction( signature( x = "numeric" ), '
NumericVector xx(x) ;
return all( xx <= 5.0 ) ;
', plugin = "Rcpp" )
fx( c(1:1000000) )
Here, R would first allocate a logical vector to store the result of "xx
<= 5.0" (a logical vector of size 1000000) and then apply "all".
The "all" function in Rcpp is lazy, so it does not allocate the vector,
and only has to do 6 comparisons (1,2,3,4,5,6) to decide that the result
is FALSE.
sugar expressions can be combined, so for example this works:
test.sugar.plus.all <- function( ){
fx <- cxxfunction( signature( x = "integer" ), '
IntegerVector xx(x) ;
return all( (xx+xx) < 10 ) ;
', plugin = "Rcpp" )
checkEquals( fx(1:10) , FALSE )
}
There is still much work to be done (see the TODO file), but I think
this has quite some potential.
Romain
--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/98Uf7u : Rcpp 0.8.1
|- http://bit.ly/c6YnCi : graph gallery collage
`- http://bit.ly/bZ7ltC : inline 0.3.5
More information about the Rcpp-devel
mailing list