SlideShare una empresa de Scribd logo
1 de 31
Descargar para leer sin conexión
Rcpp: Seamless R and C++
                   Romain François
        romain@r-enthusiasts.com
            Joint work with Dirk Eddelbuettel




                RMetrics, June 2010, Meielsalp.
Fine for Indiana Jones
Le viaduc de Millau
Background API Sugar Modules




                                       Plat du jour


  1    Appetizers : Some background on R and C++


  2    Main course : The Rcpp API


  3    Desert : Rcpp sugar


  4    Coffee : Rcpp modules




Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

R support for C/C++


          R is a C program
          R supports C++ out of the box, just use a .cpp file extension
          R exposes a API based on low level C functions and MACROS.
          R provides several calling conventions to invoke compiled code.


   SEXP foo( SEXP x1, SEXP x2 ){
      ...
   }

   > .Call( "foo", 1:10, rnorm(10) )



 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

.Call example

   #include <R.h>
   #include <Rdefines.h>
   extern "C" SEXP convolve2(SEXP a, SEXP b){
     int i, j, na, nb, nab;
     double *xa, *xb, *xab; SEXP ab;
     PROTECT(a = AS_NUMERIC(a));
     PROTECT(b = AS_NUMERIC(b));
     na=LENGTH(a); nb=LENGTH(b); nab=na+nb-1;
     PROTECT(ab = NEW_NUMERIC(nab));
     xa=NUMERIC_POINTER(a); xb=NUMERIC_POINTER(b);
     xab=NUMERIC_POINTER(ab);
     for(i=0; i<nab; i++) xab[i] = 0.0;
     for(i=0; i<na; i++) for(j=0; j<nb; j++)
        xab[i+j] += xa[i]*xb[j];
     UNPROTECT(3);
     return(ab);
   }
 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

.Call example: character vectors


   > c( "foo", "bar" )

   #include <R.h>
   #include <Rdefines.h>
   extern "C" SEXP foobar(){
     SEXP res = PROTECT(allocVector(STRSXP, 2));
     SET_STRING_ELT( res, 0, mkChar( "foo" ) ) ;
     SET_STRING_ELT( res, 1, mkChar( "bar" ) ) ;
     UNPROTECT(1) ;
     return res ;
   }




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

.Call example: calling an R function

   > eval( call( "rnorm", 3L, 10.0, 20.0 ) )

   #include <R.h>
   #include <Rdefines.h>
   extern "C" SEXP callback(){
     SEXP call = PROTECT( LCONS( install("rnorm"),
         CONS( ScalarInteger( 3 ),
           CONS( ScalarReal( 10.0 ),
            CONS( ScalarReal( 20.0 ), R_NilValue )
          )
       )
     ) );
     SEXP res = PROTECT(eval(call, R_GlobalEnv)) ;
     UNPROTECT(2) ;
     return res ;
   }

 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
The Rcpp API
Background API Sugar Modules

The Rcpp API



          Encapsulation of R objects (SEXP) into C++ classes:
          NumericVector, IntegerVector, ..., Function,
          Environment, Language, ...

          Conversion from R to C++ : as

          Conversion from C++ to R : wrap

          Interoperability with the Standard Template Library (STL)




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : classes


             Rcpp class                                      R typeof
      Integer(Vector|Matrix)                        integer vectors and matrices
      Numeric(Vector|Matrix)                                numeric ...
      Logical(Vector|Matrix)                                logical ...
     Character(Vector|Matrix)                              character ...
        Raw(Vector|Matrix)                                    raw ...
      Complex(Vector|Matrix)                                complex ...
                List                                list (aka generic vectors) ...
    Expression(Vector|Matrix)                             expression ...
            Environment                                   environment
             Function                                       function
                XPtr                                      externalptr
             Language                                       language
                 S4                                             S4
                 ...                                            ...

 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : example

   SEXP foo( SEXP x, SEXP y ){
       Rcpp::NumericVector xx(x), yy(y) ;
       int n = xx.size() ;
       Rcpp::NumericVector res( n ) ;
       double x_ = 0.0, y_ = 0.0 ;
       for( int i=0; i<n; i++){
            x_ = xx[i] ; y_ = yy[i] ;
            if( x_ < y_ ){
                 res[i] = x_ * x_ ;
            } else {
                 res[i] = -( y_ * y_) ;
                    }
           }
           return res ;
   }


 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : example


   using namespace Rcpp ;
   SEXP bar(){
        std::vector<double> z(10) ;
        List res = List::create(
           _["foo"] = NumericVector::create(1,2),
           _["bar"] = 3,
           _["bla"] = "yada yada",
           _["blo"] = z
           ) ;
        res.attr("class") = "myclass" ;
        return res ;
   }




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : example



   using namespace Rcpp ;
   SEXP bar(){
        Language call( "rnorm",
             _["n"] = 100, _["mean"] = 10 ) ;
        NumericVector res = call.eval() ;
        double sum = std::accumulate(
             res.begin(), res.end(),
             0.0 ) ;
        return wrap( sum ) ;
   }




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : conversion from R to C++

  Rcpp::as<T> handles conversion from SEXP to T.

   template <typename T> T as( SEXP m_sexp)
       throw(not_compatible) ;

  T can be:
          primitive type : int, double, bool, long, std::string
          any type that has a constructor taking a SEXP
          ... that specializes the as template
          ... that specializes the Exporter class template
          containers from the STL
  more details in the Rcpp-extending vignette.


 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : conversion from C++ to R

  Rcpp::wrap<T> handles conversion from T to SEXP.

   template <typename T>
   SEXP wrap( const T& object ) ;

  T can be:
          primitive type : int, double, bool, long, std::string
          any type that has a an operator SEXP
          ... that specializes the wrap template
          ... that has a nested type called iterator and member
          functions begin and end
          containers from the STL vector<T>, list<T>,
          map<string,T>, etc ... (where T is itself wrappable)
  more details in the Rcpp-extending vignette.

 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : conversion examples

   typedef std::vector<double> Vec ;
   int x_ = as<int>( x ) ;
   double y_ = as<double>( y_ ) ;
   VEC z_ = as<VEC>( z_ ) ;

   wrap( 1 ) ; // INTSXP
   wrap( "foo" ) ; // STRSXP

   typedef std::map<std::string,Vec> Map ;
   Map foo( 10 ) ;
   Vec f1(4) ;
   Vec f2(10) ;
   foo.insert( "x", f1 ) ;
   foo.insert( "y", f2 ) ;
   wrap( foo ) ; // named list of numeric vectors


 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : implicit conversion examples


   Environment env = ... ;
   List list = ... ;
   Function rnorm( "rnorm") ;

   // implicit calls to as
   int x = env["x"] ;
   double y = list["y"];

   // implicit calls to wrap
   rnorm( 100, _["mean"] = 10 ) ;
   env["x"] = 3;
   env["y"] = "foo" ;
   List::create( 1, "foo", 10.0, false ) ;




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Rcpp sugar
Background API Sugar Modules

Sugar : motivation


     int n = x.size() ;
     NumericVector res1( n ) ;
     double x_ = 0.0, y_ = 0.0 ;
     for( int i=0; i<n; i++){
             x_ = x[i] ;y_ = y[i] ;
             if( R_IsNA(x_) || R_IsNA(y_) ){
                  res1[i] = NA_REAL;
             } else if( x_ < y_ ){
                  res1[i] = x_ * x_ ;
             } else {
                  res1[i] = -( y_ * y_) ;
                    }
           }



 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Sugar : motivation


  We missed the R syntax :
   > ifelse( x < y, x*x, -(y*y) )




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Sugar : motivation


  We missed the R syntax :
   > ifelse( x < y, x*x, -(y*y) )


  sugar brings it into C++

   SEXP foo( SEXP xx, SEXP yy){
       NumericVector x(xx), y(yy) ;
       return ifelse( x < y, x*x, -(y*y) ) ;
   }




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Sugar : another example



   double square( double x){
     return x*x ;
   }

   SEXP foo( SEXP xx ){
     NumericVector x(xx) ;
     return sapply( x, square ) ;
   }




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Sugar : contents


          logical operators: <, >, <=, >=, ==, !=
          arithmetic operators: +, -, *, /
          functions: abs, all, any, ceiling, diff, exp, ifelse,
          is_na, lapply, pmin, pmax, pow, sapply, seq_along,
          seq_len, sign


  Sugar uses Expression Templates (Blitz++, Armadillo, ...) to
  achieve lazy evaluation of expressions.

  More information in the Rcpp-sugar vignette.



 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Sugar : benchmarks




                      expression                                   sugar                R         R / sugar
            any(x*y<0)                                         0.0008771             29.58            33721
    ifelse(x<y, x*x, -(y*y) )                                    5.217               35.88            6.879
        sapply(x,square)                                         0.6322              259.4            410.2

  Benchmarks performed on fedora 12 / R 2.12.0 (under development) on a 2 years old dell inspiron 1525 laptop.




 Romain François      romain@r-enthusiasts.com               Seamless R anc C++ integrations, RMetrics 2010
Rcpp modules
Background API Sugar Modules

Modules: expose C++ to R


   const char* hello( const std::string& who ){
       std::string result( "hello " ) ;
       result += who ;
       return result.c_str() ;
   }

   RCPP_MODULE(yada){
       using namespace Rcpp ;
       function( "hello", &hello ) ;
   }

   > yada <- Module( "yada" )
   > yada$hello( "world" )



 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Modules: expose C++ classes to R

   class World {
   public:
        World() : msg("hello"){}
        void set(std::string msg) {
            this->msg = msg;
           }
           std::string greet() {
               return msg;
           }
   private:
        std::string msg;
   };

   void clearWorld( World* w){
       w->set( "" ) ;
   }

 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Modules: expose C++ classes to R



   RCPP_MODULE(yada){
       using namespace Rcpp ;

           class_<World>( "World" )
               .method( "greet", &World::greet )
               .method( "set", &World::set )
               .method( "clear", &clearWorld )
           ;

   }




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Modules: on the R side


   > w <- new( yada$World )
   > w$greet()
   [1] "hello"

   > w$set( "hello world")
   > w$greet()
   [1] "hello world"

   > w$clear()
   > w$greet()
   [1] ""




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Want to learn more ?

  Check the vignettes

  Questions on the Rcpp-devel mailing list

  Hands-on training courses

  Commercial support



Romain François               romain@r-enthusiasts.com
Dirk Eddelbuettel                       edd@debian.org

Más contenido relacionado

La actualidad más candente

C++20 the small things - Timur Doumler
C++20 the small things - Timur DoumlerC++20 the small things - Timur Doumler
C++20 the small things - Timur Doumlercorehard_by
 
Contravariant functors in scala
Contravariant functors in scalaContravariant functors in scala
Contravariant functors in scalaPiotr Paradziński
 
Introduction To Lisp
Introduction To LispIntroduction To Lisp
Introduction To Lispkyleburton
 
Class 11: Deeper List Procedures
Class 11: Deeper List ProceduresClass 11: Deeper List Procedures
Class 11: Deeper List ProceduresDavid Evans
 
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)changehee lee
 
C++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabsC++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabsStephane Gleizes
 
Apache PIG - User Defined Functions
Apache PIG - User Defined FunctionsApache PIG - User Defined Functions
Apache PIG - User Defined FunctionsChristoph Bauer
 
Advance LISP (Artificial Intelligence)
Advance LISP (Artificial Intelligence) Advance LISP (Artificial Intelligence)
Advance LISP (Artificial Intelligence) wahab khan
 
C++11 concurrency
C++11 concurrencyC++11 concurrency
C++11 concurrencyxu liwei
 
Native interfaces for R
Native interfaces for RNative interfaces for R
Native interfaces for RSeth Falcon
 
Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4Ismar Silveira
 
Tiramisu をちょっと、味見してみました。
Tiramisu をちょっと、味見してみました。Tiramisu をちょっと、味見してみました。
Tiramisu をちょっと、味見してみました。Mr. Vengineer
 
Pydiomatic
PydiomaticPydiomatic
Pydiomaticrik0
 
25 лет истории C++, пролетевшей на моих глазах
25 лет истории C++, пролетевшей на моих глазах25 лет истории C++, пролетевшей на моих глазах
25 лет истории C++, пролетевшей на моих глазахcorehard_by
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Sumant Tambe
 

La actualidad más candente (20)

C++20 the small things - Timur Doumler
C++20 the small things - Timur DoumlerC++20 the small things - Timur Doumler
C++20 the small things - Timur Doumler
 
Contravariant functors in scala
Contravariant functors in scalaContravariant functors in scala
Contravariant functors in scala
 
Introduction To Lisp
Introduction To LispIntroduction To Lisp
Introduction To Lisp
 
Class 11: Deeper List Procedures
Class 11: Deeper List ProceduresClass 11: Deeper List Procedures
Class 11: Deeper List Procedures
 
Macro
MacroMacro
Macro
 
R/C++ talk at earl 2014
R/C++ talk at earl 2014R/C++ talk at earl 2014
R/C++ talk at earl 2014
 
Summary of C++17 features
Summary of C++17 featuresSummary of C++17 features
Summary of C++17 features
 
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
 
C++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabsC++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabs
 
Intro to Pig UDF
Intro to Pig UDFIntro to Pig UDF
Intro to Pig UDF
 
Apache PIG - User Defined Functions
Apache PIG - User Defined FunctionsApache PIG - User Defined Functions
Apache PIG - User Defined Functions
 
C++11
C++11C++11
C++11
 
Advance LISP (Artificial Intelligence)
Advance LISP (Artificial Intelligence) Advance LISP (Artificial Intelligence)
Advance LISP (Artificial Intelligence)
 
C++11 concurrency
C++11 concurrencyC++11 concurrency
C++11 concurrency
 
Native interfaces for R
Native interfaces for RNative interfaces for R
Native interfaces for R
 
Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4
 
Tiramisu をちょっと、味見してみました。
Tiramisu をちょっと、味見してみました。Tiramisu をちょっと、味見してみました。
Tiramisu をちょっと、味見してみました。
 
Pydiomatic
PydiomaticPydiomatic
Pydiomatic
 
25 лет истории C++, пролетевшей на моих глазах
25 лет истории C++, пролетевшей на моих глазах25 лет истории C++, пролетевшей на моих глазах
25 лет истории C++, пролетевшей на моих глазах
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)
 

Similar a Rcpp: Seemless R and C++

Integrating R with C++: Rcpp, RInside and RProtoBuf
Integrating R with C++: Rcpp, RInside and RProtoBufIntegrating R with C++: Rcpp, RInside and RProtoBuf
Integrating R with C++: Rcpp, RInside and RProtoBufRomain Francois
 
Extend R with Rcpp!!!
Extend R with Rcpp!!!Extend R with Rcpp!!!
Extend R with Rcpp!!!mickey24
 
Lesson 24. Phantom errors
Lesson 24. Phantom errorsLesson 24. Phantom errors
Lesson 24. Phantom errorsPVS-Studio
 
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Chris Adamson
 
What's new in Apache SystemML - Declarative Machine Learning
What's new in Apache SystemML  - Declarative Machine LearningWhat's new in Apache SystemML  - Declarative Machine Learning
What's new in Apache SystemML - Declarative Machine LearningLuciano Resende
 
Leveraging R in Big Data of Mobile Ads (R在行動廣告大數據的應用)
Leveraging R in Big Data of Mobile Ads (R在行動廣告大數據的應用)Leveraging R in Big Data of Mobile Ads (R在行動廣告大數據的應用)
Leveraging R in Big Data of Mobile Ads (R在行動廣告大數據的應用)Craig Chao
 
Implement an MPI program to perform matrix-matrix multiplication AB .pdf
Implement an MPI program to perform matrix-matrix multiplication AB .pdfImplement an MPI program to perform matrix-matrix multiplication AB .pdf
Implement an MPI program to perform matrix-matrix multiplication AB .pdfmeerobertsonheyde608
 
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data EcosystemWprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data EcosystemSages
 
Design Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on ExamplesDesign Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on ExamplesGanesh Samarthyam
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftReactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftFlorent Pillet
 

Similar a Rcpp: Seemless R and C++ (20)

Integrating R with C++: Rcpp, RInside and RProtoBuf
Integrating R with C++: Rcpp, RInside and RProtoBufIntegrating R with C++: Rcpp, RInside and RProtoBuf
Integrating R with C++: Rcpp, RInside and RProtoBuf
 
Rcpp
RcppRcpp
Rcpp
 
Rcpp11 genentech
Rcpp11 genentechRcpp11 genentech
Rcpp11 genentech
 
R and C++
R and C++R and C++
R and C++
 
Extend R with Rcpp!!!
Extend R with Rcpp!!!Extend R with Rcpp!!!
Extend R with Rcpp!!!
 
Lesson 24. Phantom errors
Lesson 24. Phantom errorsLesson 24. Phantom errors
Lesson 24. Phantom errors
 
Rcpp11
Rcpp11Rcpp11
Rcpp11
 
R Language Introduction
R Language IntroductionR Language Introduction
R Language Introduction
 
R and cpp
R and cppR and cpp
R and cpp
 
Monadic parsers in C++
Monadic parsers in C++Monadic parsers in C++
Monadic parsers in C++
 
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
 
What's new in Apache SystemML - Declarative Machine Learning
What's new in Apache SystemML  - Declarative Machine LearningWhat's new in Apache SystemML  - Declarative Machine Learning
What's new in Apache SystemML - Declarative Machine Learning
 
Leveraging R in Big Data of Mobile Ads (R在行動廣告大數據的應用)
Leveraging R in Big Data of Mobile Ads (R在行動廣告大數據的應用)Leveraging R in Big Data of Mobile Ads (R在行動廣告大數據的應用)
Leveraging R in Big Data of Mobile Ads (R在行動廣告大數據的應用)
 
Qemu JIT Code Generator and System Emulation
Qemu JIT Code Generator and System EmulationQemu JIT Code Generator and System Emulation
Qemu JIT Code Generator and System Emulation
 
Implement an MPI program to perform matrix-matrix multiplication AB .pdf
Implement an MPI program to perform matrix-matrix multiplication AB .pdfImplement an MPI program to perform matrix-matrix multiplication AB .pdf
Implement an MPI program to perform matrix-matrix multiplication AB .pdf
 
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data EcosystemWprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
 
Design Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on ExamplesDesign Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on Examples
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftReactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwift
 
Ch9a
Ch9aCh9a
Ch9a
 

Más de Romain Francois (13)

R/C++
R/C++R/C++
R/C++
 
dplyr and torrents from cpasbien
dplyr and torrents from cpasbiendplyr and torrents from cpasbien
dplyr and torrents from cpasbien
 
dplyr use case
dplyr use casedplyr use case
dplyr use case
 
dplyr
dplyrdplyr
dplyr
 
user2015 keynote talk
user2015 keynote talkuser2015 keynote talk
user2015 keynote talk
 
SevillaR meetup: dplyr and magrittr
SevillaR meetup: dplyr and magrittrSevillaR meetup: dplyr and magrittr
SevillaR meetup: dplyr and magrittr
 
dplyr
dplyrdplyr
dplyr
 
Data manipulation with dplyr
Data manipulation with dplyrData manipulation with dplyr
Data manipulation with dplyr
 
Rcpp attributes
Rcpp attributesRcpp attributes
Rcpp attributes
 
Rcpp is-ready
Rcpp is-readyRcpp is-ready
Rcpp is-ready
 
Rcpp
RcppRcpp
Rcpp
 
Object Oriented Design(s) in R
Object Oriented Design(s) in RObject Oriented Design(s) in R
Object Oriented Design(s) in R
 
RProtoBuf: protocol buffers for R
RProtoBuf: protocol buffers for RRProtoBuf: protocol buffers for R
RProtoBuf: protocol buffers for R
 

Último

Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 

Último (20)

Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 

Rcpp: Seemless R and C++

  • 1. Rcpp: Seamless R and C++ Romain François romain@r-enthusiasts.com Joint work with Dirk Eddelbuettel RMetrics, June 2010, Meielsalp.
  • 3. Le viaduc de Millau
  • 4. Background API Sugar Modules Plat du jour 1 Appetizers : Some background on R and C++ 2 Main course : The Rcpp API 3 Desert : Rcpp sugar 4 Coffee : Rcpp modules Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 5. Background API Sugar Modules R support for C/C++ R is a C program R supports C++ out of the box, just use a .cpp file extension R exposes a API based on low level C functions and MACROS. R provides several calling conventions to invoke compiled code. SEXP foo( SEXP x1, SEXP x2 ){ ... } > .Call( "foo", 1:10, rnorm(10) ) Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 6. Background API Sugar Modules .Call example #include <R.h> #include <Rdefines.h> extern "C" SEXP convolve2(SEXP a, SEXP b){ int i, j, na, nb, nab; double *xa, *xb, *xab; SEXP ab; PROTECT(a = AS_NUMERIC(a)); PROTECT(b = AS_NUMERIC(b)); na=LENGTH(a); nb=LENGTH(b); nab=na+nb-1; PROTECT(ab = NEW_NUMERIC(nab)); xa=NUMERIC_POINTER(a); xb=NUMERIC_POINTER(b); xab=NUMERIC_POINTER(ab); for(i=0; i<nab; i++) xab[i] = 0.0; for(i=0; i<na; i++) for(j=0; j<nb; j++) xab[i+j] += xa[i]*xb[j]; UNPROTECT(3); return(ab); } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 7. Background API Sugar Modules .Call example: character vectors > c( "foo", "bar" ) #include <R.h> #include <Rdefines.h> extern "C" SEXP foobar(){ SEXP res = PROTECT(allocVector(STRSXP, 2)); SET_STRING_ELT( res, 0, mkChar( "foo" ) ) ; SET_STRING_ELT( res, 1, mkChar( "bar" ) ) ; UNPROTECT(1) ; return res ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 8. Background API Sugar Modules .Call example: calling an R function > eval( call( "rnorm", 3L, 10.0, 20.0 ) ) #include <R.h> #include <Rdefines.h> extern "C" SEXP callback(){ SEXP call = PROTECT( LCONS( install("rnorm"), CONS( ScalarInteger( 3 ), CONS( ScalarReal( 10.0 ), CONS( ScalarReal( 20.0 ), R_NilValue ) ) ) ) ); SEXP res = PROTECT(eval(call, R_GlobalEnv)) ; UNPROTECT(2) ; return res ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 10. Background API Sugar Modules The Rcpp API Encapsulation of R objects (SEXP) into C++ classes: NumericVector, IntegerVector, ..., Function, Environment, Language, ... Conversion from R to C++ : as Conversion from C++ to R : wrap Interoperability with the Standard Template Library (STL) Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 11. Background API Sugar Modules The Rcpp API : classes Rcpp class R typeof Integer(Vector|Matrix) integer vectors and matrices Numeric(Vector|Matrix) numeric ... Logical(Vector|Matrix) logical ... Character(Vector|Matrix) character ... Raw(Vector|Matrix) raw ... Complex(Vector|Matrix) complex ... List list (aka generic vectors) ... Expression(Vector|Matrix) expression ... Environment environment Function function XPtr externalptr Language language S4 S4 ... ... Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 12. Background API Sugar Modules The Rcpp API : example SEXP foo( SEXP x, SEXP y ){ Rcpp::NumericVector xx(x), yy(y) ; int n = xx.size() ; Rcpp::NumericVector res( n ) ; double x_ = 0.0, y_ = 0.0 ; for( int i=0; i<n; i++){ x_ = xx[i] ; y_ = yy[i] ; if( x_ < y_ ){ res[i] = x_ * x_ ; } else { res[i] = -( y_ * y_) ; } } return res ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 13. Background API Sugar Modules The Rcpp API : example using namespace Rcpp ; SEXP bar(){ std::vector<double> z(10) ; List res = List::create( _["foo"] = NumericVector::create(1,2), _["bar"] = 3, _["bla"] = "yada yada", _["blo"] = z ) ; res.attr("class") = "myclass" ; return res ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 14. Background API Sugar Modules The Rcpp API : example using namespace Rcpp ; SEXP bar(){ Language call( "rnorm", _["n"] = 100, _["mean"] = 10 ) ; NumericVector res = call.eval() ; double sum = std::accumulate( res.begin(), res.end(), 0.0 ) ; return wrap( sum ) ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 15. Background API Sugar Modules The Rcpp API : conversion from R to C++ Rcpp::as<T> handles conversion from SEXP to T. template <typename T> T as( SEXP m_sexp) throw(not_compatible) ; T can be: primitive type : int, double, bool, long, std::string any type that has a constructor taking a SEXP ... that specializes the as template ... that specializes the Exporter class template containers from the STL more details in the Rcpp-extending vignette. Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 16. Background API Sugar Modules The Rcpp API : conversion from C++ to R Rcpp::wrap<T> handles conversion from T to SEXP. template <typename T> SEXP wrap( const T& object ) ; T can be: primitive type : int, double, bool, long, std::string any type that has a an operator SEXP ... that specializes the wrap template ... that has a nested type called iterator and member functions begin and end containers from the STL vector<T>, list<T>, map<string,T>, etc ... (where T is itself wrappable) more details in the Rcpp-extending vignette. Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 17. Background API Sugar Modules The Rcpp API : conversion examples typedef std::vector<double> Vec ; int x_ = as<int>( x ) ; double y_ = as<double>( y_ ) ; VEC z_ = as<VEC>( z_ ) ; wrap( 1 ) ; // INTSXP wrap( "foo" ) ; // STRSXP typedef std::map<std::string,Vec> Map ; Map foo( 10 ) ; Vec f1(4) ; Vec f2(10) ; foo.insert( "x", f1 ) ; foo.insert( "y", f2 ) ; wrap( foo ) ; // named list of numeric vectors Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 18. Background API Sugar Modules The Rcpp API : implicit conversion examples Environment env = ... ; List list = ... ; Function rnorm( "rnorm") ; // implicit calls to as int x = env["x"] ; double y = list["y"]; // implicit calls to wrap rnorm( 100, _["mean"] = 10 ) ; env["x"] = 3; env["y"] = "foo" ; List::create( 1, "foo", 10.0, false ) ; Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 20. Background API Sugar Modules Sugar : motivation int n = x.size() ; NumericVector res1( n ) ; double x_ = 0.0, y_ = 0.0 ; for( int i=0; i<n; i++){ x_ = x[i] ;y_ = y[i] ; if( R_IsNA(x_) || R_IsNA(y_) ){ res1[i] = NA_REAL; } else if( x_ < y_ ){ res1[i] = x_ * x_ ; } else { res1[i] = -( y_ * y_) ; } } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 21. Background API Sugar Modules Sugar : motivation We missed the R syntax : > ifelse( x < y, x*x, -(y*y) ) Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 22. Background API Sugar Modules Sugar : motivation We missed the R syntax : > ifelse( x < y, x*x, -(y*y) ) sugar brings it into C++ SEXP foo( SEXP xx, SEXP yy){ NumericVector x(xx), y(yy) ; return ifelse( x < y, x*x, -(y*y) ) ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 23. Background API Sugar Modules Sugar : another example double square( double x){ return x*x ; } SEXP foo( SEXP xx ){ NumericVector x(xx) ; return sapply( x, square ) ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 24. Background API Sugar Modules Sugar : contents logical operators: <, >, <=, >=, ==, != arithmetic operators: +, -, *, / functions: abs, all, any, ceiling, diff, exp, ifelse, is_na, lapply, pmin, pmax, pow, sapply, seq_along, seq_len, sign Sugar uses Expression Templates (Blitz++, Armadillo, ...) to achieve lazy evaluation of expressions. More information in the Rcpp-sugar vignette. Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 25. Background API Sugar Modules Sugar : benchmarks expression sugar R R / sugar any(x*y<0) 0.0008771 29.58 33721 ifelse(x<y, x*x, -(y*y) ) 5.217 35.88 6.879 sapply(x,square) 0.6322 259.4 410.2 Benchmarks performed on fedora 12 / R 2.12.0 (under development) on a 2 years old dell inspiron 1525 laptop. Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 27. Background API Sugar Modules Modules: expose C++ to R const char* hello( const std::string& who ){ std::string result( "hello " ) ; result += who ; return result.c_str() ; } RCPP_MODULE(yada){ using namespace Rcpp ; function( "hello", &hello ) ; } > yada <- Module( "yada" ) > yada$hello( "world" ) Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 28. Background API Sugar Modules Modules: expose C++ classes to R class World { public: World() : msg("hello"){} void set(std::string msg) { this->msg = msg; } std::string greet() { return msg; } private: std::string msg; }; void clearWorld( World* w){ w->set( "" ) ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 29. Background API Sugar Modules Modules: expose C++ classes to R RCPP_MODULE(yada){ using namespace Rcpp ; class_<World>( "World" ) .method( "greet", &World::greet ) .method( "set", &World::set ) .method( "clear", &clearWorld ) ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 30. Background API Sugar Modules Modules: on the R side > w <- new( yada$World ) > w$greet() [1] "hello" > w$set( "hello world") > w$greet() [1] "hello world" > w$clear() > w$greet() [1] "" Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 31. Want to learn more ? Check the vignettes Questions on the Rcpp-devel mailing list Hands-on training courses Commercial support Romain François romain@r-enthusiasts.com Dirk Eddelbuettel edd@debian.org