[Rcpp-devel] Patch to Rcpp-quickref: R/C++ interface

Christian Gunning xian at unm.edu
Mon Jan 3 03:31:39 CET 2011


Attached is a patch that adds a section describing the R/C++
interface.  Package creation and building is addressed, as well as
behavior related to pointer use.

To avoid orphaned sections, I removed the 2nd \newline from all
sections, and reordered sections to avoid excess vertical space.

best,
Christian
-------------- next part --------------
Index: Rcpp-quickref.Rnw
===================================================================
--- Rcpp-quickref.Rnw	(revision 2820)
+++ Rcpp-quickref.Rnw	(working copy)
@@ -49,7 +49,6 @@
 % a newline between paragraph and code disconnects them and can orphan heading
 \paragraph{Create simple vectors}~ 
   \newline
-  \newline
 <<lang=cpp>>=
 SEXP x; std::vector<double> y(10);
 
@@ -74,7 +73,6 @@
 
 \paragraph{Extract and set single elements}~
   \newline
-  \newline
 <<lang=cpp>>=
 // extract single values
 double x0 = xx[0];
@@ -93,18 +91,42 @@
 yy["foobar"] = 10.0;
 @
 
-\paragraph{STL interface}~
+\paragraph{Using matrices}~
   \newline
-  \newline
 <<lang=cpp>>=
-std::accumulate( xx.begin(), xx.end(),
-    std::plus<double>(), 0.0 );
-int n = xx.size();
+// Initializing from SEXP, 
+// dimensions handled automatically
+SEXP x; 
+NumericMatrix xx(x);
+
+// Matrix of 4 rows & 5 columns (filled with 0)
+NumericMatrix xx(4, 5);
+
+// Fill with value
+int xsize = xx.nrow() * xx.ncol();
+for (int i = 0; i < xsize; i++) {
+    xx[i] = 7;
+}
+// Same as above, using STL fill
+std::fill(xx.begin(), xx.end(), 8);
+
+// Assign this value to single element 
+// (1st row, 2nd col)
+xx(0,1) = 4;
+
+// Reference the second column
+// Changes propagate to xx (same applies for Row)
+NumericMatrix::Column zzcol = xx( _, 1);
+zzcol = zzcol * 2;
+
+// Copy the second column into new object
+NumericVector zz1 = xx( _, 1);
+// Copy the submatrix (top left 3x3) into new object
+NumericMatrix zz2 = xx( Range(0,2), Range(0,2));
 @
 
 \paragraph{Inline}~
   \newline
-  \newline
 <<lang=cpp>>=
 ## Note - this is R code. inline allows rapid testing.
 require(inline)
@@ -119,10 +141,62 @@
 testfun(1:5, 3)
 @
 
-\paragraph{Function}~
+\paragraph{Interface with R}~
   \newline
+<<lang=cpp>>=
+## In R, create a package shell. For details, see the "Writing R Extensions" manual. 
+
+Rcpp.package.skeleton("myPackage")
+
+## Add R code to pkg R/ directory. Call C++ function. Do type-checking in R.
+
+myfunR = function(Rx, Ry) {
+    ret = .Call("myCfun", Rx, Ry, 
+            package="myPackage")
+    return(ret) 
+}
+
+// Add C++ code to pkg src/ directory. 
+using namespace Rcpp;
+// Define function as extern with RcppExport
+RcppExport SEXP myCfun( SEXP x, SEXP y) {
+    // If R/C++ types match, use pointer to x.  Pointer is faster, but changes to xx propagate to R ( xx -> x == Rx).
+    NumericVector xx(x);
+    // clone is slower and uses extra memory. Safe, R-like. 
+    NumericVector yy(clone(y));
+    xx[0] = yy[0] = -1.5;
+    int zz = xx[0];
+    // use wrap() to return non-SEXP objects, e.g:
+    // return(wrap(zz));
+    // Build and return a list
+    List ret; ret["x"] = xx; ret["y"] = yy;
+    return(ret);
+}
+
+## From shell, above package directory
+R CMD check myPackage  ## Optional
+R CMD INSTALL myPackage
+
+## In R:
+require(myPackage)
+aa = 1.5; bb = 1.5; cc =  myfunR(aa, bb)
+aa == bb ## FALSE, C++ modifies aa
+aa = 1:2; bb = 1:2; cc =  myfunR(aa, bb)
+identical(aa, bb) 
+## TRUE, R/C++ types don't match
+@
+
+\paragraph{STL interface}~
   \newline
 <<lang=cpp>>=
+std::accumulate( xx.begin(), xx.end(),
+    std::plus<double>(), 0.0 );
+int n = xx.size();
+@
+
+\paragraph{Function}~
+  \newline
+<<lang=cpp>>=
 Function rnorm("rnorm");
 rnorm(100, _["mean"] = 10.2, _["sd"] = 3.2 );
 @
@@ -165,7 +239,6 @@
 
 \paragraph{Rcpp sugar}~
   \newline
-  \newline
 <<lang=cpp>>=
 NumericVector x = NumericVector::create(
   -2.0, -1.0, 0.0, 1.0, 2.0 );
@@ -199,41 +272,8 @@
 IntegerVector yy = rev( y );
 @
 
-\paragraph{Using matrices}~
-  \newline
-<<lang=cpp>>=
-// Initializing from SEXP, 
-// dimensions handled automatically
-SEXP x; 
-NumericMatrix xx(x);
 
-// Matrix of 4 rows & 5 columns (filled with 0)
-NumericMatrix xx(4, 5);
 
-// Fill with value
-int xsize = xx.nrow() * xx.ncol();
-for (int i = 0; i < xsize; i++) {
-    xx[i] = 7;
-}
-// Same as above, using STL fill
-std::fill(xx.begin(), xx.end(), 8);
-
-// Assign this value to single element 
-// (1st row, 2nd col)
-xx(0,1) = 4;
-
-// Reference the second column
-// Changes propagate to xx (same applies for Row)
-NumericMatrix::Column zzcol = xx( _, 1);
-zzcol = zzcol * 2;
-
-// Copy the second column into new object
-NumericVector zz1 = xx( _, 1);
-// Copy the submatrix (top left 3x3) into new object
-NumericMatrix zz2 = xx( Range(0,2), Range(0,2));
-@
-
-
 \paragraph{Random functions}~
   \newline
 <<lang=cpp>>=


More information about the Rcpp-devel mailing list