[Rd] Getting started with .C

Dirk Eddelbuettel edd at debian.org
Tue Apr 13 04:47:43 CEST 2010


On 12 April 2010 at 18:11, Sharpie wrote:
| Jeff Brown wrote:
| > I'm trying to learn to use .C, which lets one invoke compiled C code from
| > within R.  To do that, one has to first get the C code into R as a shared
| > object, which (I think) means first compiling it (with COMPILE or SHLIB)
| > and then loading it (with dyn.load()).  
| > 
| 
| I would suggest taking it a step further and building an R package to hold
| your compiled code.  The pros are:
| 
|   *  It keeps the R wrapper scripts and other things you will end up
| creating packaged together with your code.
| 
|   *  It handles compilation automagically during installation.
| 
|   *  It handles loading the dylib for you.

All good reasone, but see below for an even easier solution to get going.
 
| The only con I can think of is:
| 
|   *  It takes ~2 extra minutes of your time to set up.  But compared to
| other languages I have used this is a ridiculously small price to pay for
| the portability and organization offered by packages.
| 
| I wrote a post that goes through step-by-step how to do this for the .Call()
| interface, including example code.  You can find it at:
| 
|  
| http://n4.nabble.com/Writing-own-simulation-function-in-C-td1580190.html#a1580423
| 
| 
| 
| In "Writing R Extensions", p. 79, they give the following example of a C
| program for convolution of two vectors.  (The details aren't important; it's
| just a function that does something to some stuff.)
| 
| void convolve (double *a, int *na, double *b, int *nb, double *ab) {
| 	int i, j, nab = *na + *nb - 1;
| 	for(i = 0; i < nab; i++)
| 		ab[i] = 0.0;
| 	for(i = 0; i < *na; i++)
| 		for(j = 0; j < *nb; j++)
| 			ab[i + j] += a[i] * b[j]
| }

And all this is even easier if you use the excellent inline package. No
Makefiles, no linking, no loading, it all "just works" on all three major
platforms:

 - define the code you want in a variable, here 'code'
   this does not include the function header

 - define the function signature

 - call the 'cfunction' from package inline to compile, link and load the 
   generated function

 - use it!

Here is a live example:

  R> library(inline)       # load inline
  R> code <- "int i, j, nab = *na + *nb - 1;
  +    for(i = 0; i < nab; i++)
  +      ab[i] = 0.0;
  +    for(i = 0; i < *na; i++) {
  +      for(j = 0; j < *nb; j++)
  +            ab[i + j] += a[i] * b[j];
  +          }"
  R> fun <- cfunction(signature(a="numeric", na="numeric", b="numeric", nb="numeric", ab="numeric"),
  +                  code, language="C", convention=".C")
  R> str(fun)              # check what the new fun object is
  Formal class 'CFunc' [package "inline"] with 2 slots
    ..@ .Data:function (a, na, b, nb, ab)  
    ..@ code : chr "#include <R.h>\n\n\nvoid file46e87ccd ( double * a, double * na, double * b, double * nb, double * ab ) {\nint i, j, nab = *na "| __truncated__
  R> fun( 1:10, 10, 4:12, 9, numeric(18))$ab
  [1]   4  13  28  50  80 119 168 228 300 372 400 413 410 390 352 295 218 120
  R> 

Voila, and we extended R at the command prompt.  I'd still recommed .Call
over .C, whether you use C++ (which I also recommend :) or C.

I have a number of examples for this in the 'Introduction to High-Performance
Computing with R' tutorials I have given the last few years, see the slides
at 

   http://dirk.eddelbuettel.com/presentations.html 

as well as the recent UCLA talks on more inline examples with Rcpp (if you
want C++).

Cheers, Dirk

-- 
  Registration is open for the 2nd International conference R / Finance 2010
  See http://www.RinFinance.com for details, and see you in Chicago in April!



More information about the R-devel mailing list