[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