[Rcpp-commits] r620 - papers/rjournal

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sun Feb 7 03:23:35 CET 2010


Author: edd
Date: 2010-02-07 03:23:34 +0100 (Sun, 07 Feb 2010)
New Revision: 620

Modified:
   papers/rjournal/EddelbuettelFrancois.tex
Log:
yet more spit and polish -- the large floating 'table' of code now works somewhat


Modified: papers/rjournal/EddelbuettelFrancois.tex
===================================================================
--- papers/rjournal/EddelbuettelFrancois.tex	2010-02-07 01:37:40 UTC (rev 619)
+++ papers/rjournal/EddelbuettelFrancois.tex	2010-02-07 02:23:34 UTC (rev 620)
@@ -341,7 +341,7 @@
 
 \section{R and C++ data interchange}
 
-In addition to classes, the \pkg{Rcpp} package contains two additional
+In addition to classes, the \pkg{Rcpp} package contains two %additional
 functions to perform conversion of C++ objects to R objects and back. 
 
 \subsection{C++ to R : wrap}
@@ -363,7 +363,7 @@
 Currently wrappable types are :
 \begin{itemize}
 \item primitive types, \code{int}, \code{double}, ... which are converted 
-into atomic R vectors of the appropriate type;
+into the corresponding atomic R vectors;
 \item \code{std::string} which are converted to R atomic character vectors;
 \item STL containers such as \code{std::vector<T>} or \code{std::list<T>}, 
 as long as the template parameter type \code{T} is itself wrappable;
@@ -400,17 +400,15 @@
 composition:
 
 \begin{example}
-std::vector< std::map<std::string,int> > v ;
+std::vector< std::map<std::string,int> > v;
+std::map< std::string, int > m1;
+std::map< std::string, int > m2;
 
-std::map< std::string, int > m1 ;
-m1["foo"] = 1 ; m1["bar"] = 2 ;
-
-std::map< std::string, int > m2 ;
+m1["foo"] = 1; m1["bar"] = 2;
 m2["foo"] = 1; m2["bar"] = 2; m2["bling"] = 3;
 
 v.push_back( m1) ;
 v.push_back( m2) ;
-
 Rcpp::wrap( v ) ;
 \end{example}
 
@@ -423,12 +421,13 @@
       c( bar = 2L, bling = 3L, foo = 1L) )
 \end{example}
 
-The C++ type \code{std::vector< std::map< std::string,int > >} is wrappable because: 
-\texttt{int} is wrappable (as a primitive type), therefore 
-\texttt{std::map<std::string,int>} is wrappable (as a STL map 
-of wrappable types keyed by strings), and finally 
-\texttt{std::vector< std::map<std::string,int> >} is wrappable 
-(as an STL container of wrappable types).
+% [Dirk] Is the following redundant?
+%The C++ type \code{std::vector< std::map< std::string,int > >} is wrappable because: 
+%\texttt{int} is wrappable (as a primitive type), therefore 
+%\texttt{std::map<std::string,int>} is wrappable (as a STL map 
+%of wrappable types keyed by strings), and finally 
+%\texttt{std::vector< std::map<std::string,int> >} is wrappable 
+%(as an STL container of wrappable types).
 
 \subsection{R to C++ : as}
 
@@ -491,8 +490,19 @@
 
 \begin{figure*}[t]
   \begin{minipage}[t]{0.465\linewidth}
-    \underline{Using the R API}
+    \centering{\underline{Environment: Using the \pkg{Rcpp} API}}
     \begin{example}
+Environment stats("package:stats");
+Function rnorm = stats.get("rnorm");
+return rnorm(10, Named("sd", 100.0) );
+    \end{example}
+  \end{minipage}
+  \begin{minipage}{0.06\linewidth}
+    \phantom{XXX}
+  \end{minipage}
+  \begin{minipage}[t]{0.465\linewidth}
+    \centering{\underline{Environment: Using the R API}}
+    \begin{example}
 SEXP stats = PROTECT( 
 \ \ R_FindNamespace( mkString("stats") ) );
 SEXP rnorm = PROTECT( 
@@ -507,38 +517,50 @@
 return res ;
     \end{example}
   \end{minipage}
+
+  \begin{minipage}[t]{0.465\linewidth}
+    \centering{\underline{Language: Using the \pkg{Rcpp} API}}
+    \begin{example}
+Language call("rnorm", 10, Named("sd", 100));
+call.eval();
+    \end{example}
+  \end{minipage}
   \begin{minipage}{0.06\linewidth}
     \phantom{XXX}
   \end{minipage}
   \begin{minipage}[t]{0.465\linewidth}
-\underline{Using the \pkg{Rcpp} API}
+    \centering{\underline{Language: Using the R API}}
     \begin{example}
-Environment stats("package:stats");
-Function rnorm = stats.get("rnorm");
-return rnorm(10, Named("sd", 100.0) );
+SEXP call  = PROTECT( 
+\ \ LCONS( install("rnorm"), 
+\ \ \ \ CONS(ScalarInteger(10), 
+\ \ \ \ \ \ CONS(ScalarReal(100.0), R_NilValue))));
+SET_TAG( CDDR(call), install("sd") ) ;
+SEXP res = PROTECT( eval( call, R_GlobalEnv));
+UNPROTECT(2) ;
+return res ;
     \end{example}
   \end{minipage}
-  \caption{R API versus \pkg{Rcpp}: Calling \code{rnorm(10, sd=100)} in C or
-    C++ using an Environment}
+  \caption{\pkg{Rcpp} versus the R API: Four ways of calling \code{rnorm(10, sd=100)} in C / C++}
+  \label{fig:rnormCode}
 \end{figure*}
 
-The last example shows how to use \pkg{Rcpp} to emulate the R code below:
-\begin{example}
-> rnorm( 10L, sd = 100.0 )
-\end{example}
-
-The code can be expressed in several ways in \pkg{Rcpp}, the first version
-shows the use of the \code{Environment} and \code{Function} classes
-\footnote{We have removed the \code{Rcpp::} prefix from the following
-  examples for readability; this corresponds to adding a statement
+The next example shows how to use \pkg{Rcpp} to emulate the R code
+\code{rnorm( 10L, sd=100.0)}.
+%
+As shown in figure~\ref{fig:rnormCode}, the code can be expressed in several
+ways in either \pkg{Rcpp} or the standard R API. The first version shows the
+use of the \code{Environment} and \code{Function} classes by
+\pkg{Rcpp}.\footnote{We have removed the \code{Rcpp::} prefix from the
+  following examples for readability; this corresponds to adding a statement
   \texttt{using namespace Rcpp;} in the code}.
-
-\begin{example}
-Environment stats("package:stats");
-Function rnorm = stats.get("rnorm");
-return rnorm(10, Named("sd", 100.0) );
-\end{example}
-
+%
+%\begin{example}
+%Environment stats("package:stats");
+%Function rnorm = stats.get("rnorm");
+%return rnorm(10, Named("sd", 100.0) );
+%\end{example}
+%
 We first pull out the \code{rnorm} function from the environment 
 called \samp{package:stats} in the search path, then simply call the function 
 using syntax similar to calling the function in R. The \code{Rcpp::Named} 
@@ -546,12 +568,12 @@
 
 The second version shows the use of the \code{Language} class, which 
 manage calls (LANGSXP). 
-
-\begin{example}
-Language call("rnorm", 10, Named("sd", 100 ));
-call.eval();
-\end{example}
-
+%
+%\begin{example}
+%Language call("rnorm", 10, Named("sd", 100 ));
+%call.eval();
+%\end{example}
+%
 In this version, we first create a call to the symbol "rnorm" and
 evaluate the call in the global environment. In both cases, \code{wrap}
 is used implicitely to convert \code{10} and \code{100} 
@@ -560,41 +582,44 @@
 to find the \code{rnorm} function. 
 % [Romain] should we quote luke's : http://www.cs.uiowa.edu/~luke/R/bytecode.html
 % [Dirk]   space constraints....
-For comparison, using the standard R API, the first example using the actual \code{rnorm} function
-translates to :
 
-\begin{example}
-SEXP stats = PROTECT( 
-\ \ R_FindNamespace( mkString("stats") ) );
-SEXP rnorm = PROTECT( 
-\ \ findVarInFrame( stats, install("rnorm") ) );
-SEXP call  = PROTECT( 
-\ \ LCONS( rnorm, 
-\ \ \ \ CONS(ScalarInteger(10), 
-\ \ \ \ \ \ CONS(ScalarReal(100.0), R_NilValue))));
-SET_TAG( CDDR(call), install("sd") );
-SEXP res = PROTECT( eval( call, R_GlobalEnv));
-UNPROTECT(4) ;
-return res ;
-\end{example}
+For comparison, we also version using the standard R API.
+% 
+%The first example using the actual \code{rnorm} function translates to 
+%
+% \begin{example}
+% SEXP stats = PROTECT( 
+% \ \ R_FindNamespace( mkString("stats") ) );
+% SEXP rnorm = PROTECT( 
+% \ \ findVarInFrame( stats, install("rnorm") ) );
+% SEXP call  = PROTECT( 
+% \ \ LCONS( rnorm, 
+% \ \ \ \ CONS(ScalarInteger(10), 
+% \ \ \ \ \ \ CONS(ScalarReal(100.0), R_NilValue))));
+% SET_TAG( CDDR(call), install("sd") );
+% SEXP res = PROTECT( eval( call, R_GlobalEnv));
+% UNPROTECT(4) ;
+% return res ;
+% \end{example}
 
-and the second example, using the \samp{rnorm} symbol, can be written as:
+% and the second example, using the \samp{rnorm} symbol, can be written as:
 
-\begin{example}
-SEXP call  = PROTECT( 
-\ \ LCONS( install("rnorm"), 
-\ \ \ \ CONS(ScalarInteger(10), 
-\ \ \ \ \ \ CONS(ScalarReal(100.0), R_NilValue))));
-SET_TAG( CDDR(call), install("sd") ) ;
-SEXP res = PROTECT( eval( call, R_GlobalEnv));
-UNPROTECT(2) ;
-return res ;
-\end{example}
+% \begin{example}
+% SEXP call  = PROTECT( 
+% \ \ LCONS( install("rnorm"), 
+% \ \ \ \ CONS(ScalarInteger(10), 
+% \ \ \ \ \ \ CONS(ScalarReal(100.0), R_NilValue))));
+% SET_TAG( CDDR(call), install("sd") ) ;
+% SEXP res = PROTECT( eval( call, R_GlobalEnv));
+% UNPROTECT(2) ;
+% return res ;
+% \end{example}
+%
 
-showing that the \pkg{Rcpp} API permits us to work with code that is easier
-to read, write and maintain. More examples are available as part of the documentation
-included in the \pkg{Rcpp} package, as well as among its over one hundred and
-fifty unit tests.
+This example illustrates that the \pkg{Rcpp} API permits us to work with code
+that is easier to read, write and maintain. More examples are available as
+part of the documentation included in the \pkg{Rcpp} package, as well as
+among its over one hundred and fifty unit tests.
 
 
 \section{Using code `inline'}
@@ -646,16 +671,14 @@
   int n_xa = xa.size(), n_xb = xb.size();
 
   Rcpp::NumericVector xab(n_xa + n_xb - 1);
-
   for (int i = 0; i < n_xa; i++)
     for (int j = 0; j < n_xb; j++)
        xab[i + j] += xa[i] * xb[j];
-
   return xab;
 '
 fun <- cfunction( 
-	signature(a="numeric", b="numeric"), 
-	src, Rcpp=TRUE)
+\ \ \ \	signature(a="numeric", b="numeric"), 
+\ \ \ \	src, Rcpp=TRUE)
 \end{example}
 
 The main difference to the previous solution is that the input parameters are
@@ -665,35 +688,6 @@
 initialized because the constructor already performs initialization
 to match the behaviour of the R function \code{numeric}.
 
-\begin{figure*}[t]
-  \begin{minipage}[t]{0.465\linewidth}
-    \underline{Using the R API}
-    \begin{example}
-SEXP call  = PROTECT( 
-\ \ LCONS( install("rnorm"), 
-\ \ \ \ CONS(ScalarInteger(10), 
-\ \ \ \ \ \ CONS(ScalarReal(100.0), R_NilValue))));
-SET_TAG( CDDR(call), install("sd") ) ;
-SEXP res = PROTECT( eval( call, R_GlobalEnv));
-UNPROTECT(2) ;
-return res ;
-    \end{example}
-  \end{minipage}
-  \begin{minipage}{0.06\linewidth}
-    \phantom{XXX}
-  \end{minipage}
-  \begin{minipage}[t]{0.465\linewidth}
-\underline{Using the \pkg{Rcpp} API}
-    \begin{example}
-Language call("rnorm", 10, Named("sd", 100 ));
-call.eval();
-    \end{example}
-  \end{minipage}
-  \caption{R API versus \pkg{Rcpp}: Calling \code{rnorm(10, sd=100)} in C or
-    C++ using a LANGSXP}
-\end{figure*}
-
-
 \section{Error handling}
 
 Code that uses both R and C++ has to deal with two concurrent
@@ -808,7 +802,7 @@
   \code{inst/examples/ConvolveBenchmarks} in the \pkg{Rcpp} package.} The timings
 are summarized in the table below:
 
-\begin{table}[H]  
+\begin{table}[H]
   \begin{center}
     \begin{small}
       \begin{tabular}{lrr}



More information about the Rcpp-commits mailing list