[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