[Rcpp-commits] r2243 - pkg/Rcpp/inst/doc
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Wed Sep 29 14:07:12 CEST 2010
Author: edd
Date: 2010-09-29 14:07:11 +0200 (Wed, 29 Sep 2010)
New Revision: 2243
Modified:
pkg/Rcpp/inst/doc/Makefile
pkg/Rcpp/inst/doc/Rcpp-introduction.Rnw
pkg/Rcpp/inst/doc/Rcpp.bib
Log:
rolled Rcpp-introduction.Rnw (and .bib) to current version of paper
Modified: pkg/Rcpp/inst/doc/Makefile
===================================================================
--- pkg/Rcpp/inst/doc/Makefile 2010-09-29 04:04:59 UTC (rev 2242)
+++ pkg/Rcpp/inst/doc/Makefile 2010-09-29 12:07:11 UTC (rev 2243)
@@ -34,7 +34,6 @@
rm Rcpp-package.Rnw ; cp Rcpp-package/Rcpp-package-fake.Rnw Rcpp-package.Rnw
rm Rcpp-quickref.Rnw ; cp Rcpp-quickref/Rcpp-quickref-fake.Rnw Rcpp-quickref.Rnw
rm Rcpp-sugar.Rnw ; cp Rcpp-sugar/Rcpp-sugar-fake.Rnw Rcpp-sugar.Rnw
-
index.html: rcpp.index.html
cp rcpp.index.html index.html
@@ -53,6 +52,7 @@
Rcpp-introduction.pdf: Rcpp-introduction.Rnw
R CMD Sweave Rcpp-introduction.Rnw
+ bibtex Rcpp-introduction
ifeq ($(whoami),edd)
pdflatex Rcpp-introduction.tex
pdflatex Rcpp-introduction.tex
Modified: pkg/Rcpp/inst/doc/Rcpp-introduction.Rnw
===================================================================
--- pkg/Rcpp/inst/doc/Rcpp-introduction.Rnw 2010-09-29 04:04:59 UTC (rev 2242)
+++ pkg/Rcpp/inst/doc/Rcpp-introduction.Rnw 2010-09-29 12:07:11 UTC (rev 2243)
@@ -22,7 +22,7 @@
%% do not edit, for illustration only
\fancyhf{}
-\fancyhead[LO,RE]{\textsc{Submitted Article currently under Review}}
+\fancyhead[LO,RE]{\textsc{Revised Article currently under Review}}
\fancyhead[RO,LE]{\thepage}
%\fancyfoot[L]{The R Journal Vol. X/Y, Month, Year}
%\fancyfoot[R]{ISSN 2073-4859}
@@ -49,7 +49,7 @@
R is an extensible system. The `Writing R Extensions' manual \citep{R:exts}
describes in detail how to augment R with compiled code,
-focussing mostly on the C language. The R API described in `Writing R Extensions' is
+focusing mostly on the C language. The R API described in `Writing R Extensions' is
based on a set of functions and macros operating on \code{SEXP}, the internal
representation of R objects.
%
@@ -59,15 +59,16 @@
a short review of other approaches and give some historical
background on the development of \pkg{Rcpp}.
-The current version of \pkg{Rcpp} combines two distinct
+The \pkg{Rcpp} package combines two distinct
APIs. The first---which we call `classic \pkg{Rcpp} API'---exists since
-the first version of \pkg{Rcpp}. The second API, enclosed in the
-\code{Rcpp} C++ namespace, is a newer codebase which we started to develop
-more recently. This article
-highlights some of the key design and implementation choices:
-lightweight encapsulation of R objects in C++ classes, automatic
-garbage collection strategy, code inlining, data interchange between
-R and C++ and error handling.
+the first version of \pkg{Rcpp}. While still contained in the package to
+ensure compatibility, its use is otherwise deprecated. All new development should
+use the richer second API. It is enclosed in the \pkg{Rcpp} C++
+namespace, and corresponds to the redesigned code base.
+This article highlights some of the key design and implementation choices of
+the new API: lightweight encapsulation of R objects in C++ classes, automatic
+garbage collection strategy, code inlining, data interchange between R and
+C++ and error handling.
Several examples are included to illustrate the benefits of using \pkg{Rcpp}
as opposed to the traditional R API. Many more examples are available within
@@ -75,26 +76,28 @@
\subsection{Historical Context}
-\pkg{Rcpp} first appeared in 2005 as a contribution to the \pkg{RQuantLib}
-package \citep{eddelbuettelkhan09:rquantlib} before becoming a CRAN
-package in early 2006. Several releases followed in quick succession; all of
-these were under the name \pkg{Rcpp}. The package was then renamed to
-\pkg{RcppTemplate} and several more releases followed during 2006 under the
-new name. However, no new releases or updates were made during 2007, 2008
-and most of 2009.
+\pkg{Rcpp} first appeared in 2005 as a contribution (by Samperi) to the
+\pkg{RQuantLib} package \citep{cran:rquantlib} before becoming a CRAN package
+in early 2006. Several releases (all by Samperi) followed in quick succession
+under the name \pkg{Rcpp}. The package was then renamed to
+\pkg{RcppTemplate}; several more releases followed during 2006 under the new
+name. However, no new releases were made during 2007, 2008 or most of
+2009. Following a few updates in late 2009, it has since been withdrawn from CRAN.
-Given the continued use of the package, it was revitalized. New
+Given the continued use of the package, Eddelbuettel decided to revitalize it. New
releases, using the initial name \pkg{Rcpp}, started in November 2008. These
already included an improved build and distribution process, additional
documentation, and new functionality---while retaining the existing
-interface. This constitutes the `classic \pkg{Rcpp}' interface (described in
-the next section) which will be maintained for the foreseeable future.
+interface. This constitutes the `classic \pkg{Rcpp}' interface
+(not described in this article) which will be maintained for the foreseeable future.
Yet C++ coding standards continued to evolve \citep{meyers:effectivecplusplus}.
-So starting in 2009 the codebase was significantly extended and numerous new
-features were added. Several of these are described below in the section on
-the `new \pkg{Rcpp}' interface. This new API is our current focus, and we
-intend to both extend and support it going forward.
+In 2009, Eddelbuettel and Fran\c{c}ois started a significant redesign of the
+code base which added numerous new features. Several of these are described
+below in the section on the \pkg{Rcpp} API interface, as well as in the
+eight vignettes included with the package. This new API is our current focus,
+and we intend to both extend and support it in future development of the
+package.
\subsection{Comparison}
@@ -103,7 +106,7 @@
An unpublished paper by \cite{javagailemanly07:r_cpp} expresses several ideas
that are close to some of our approaches, though not yet fully fleshed out.
%
-The \pkg{Rserve} package \citep{cran:Rserve} was another early approach,
+The \pkg{Rserve} package \citep{urbanek2003:rserve,cran:Rserve} was another early approach,
going back to 2002. On the server side, \pkg{Rserve} translates R data
structures into a binary serialization format and uses TCP/IP for
transfer. On the client side, objects are reconstructed as instances of Java
@@ -114,11 +117,11 @@
\citep{armstrong09:RObjects} are all implemented using C++ templates.
However, neither has matured to the point of a CRAN release and it is
unclear how much usage these packages are seeing beyond their own authors.
-%
-CXXR \citep{runnalls09:cxxr} comes to this topic from the other side:
+
+\pkg{CXXR} \citep{runnalls09:cxxr} comes to this topic from the other side:
its aim is to completely refactor R on a stronger C++ foundation.
-CXXR is therefore concerned with all aspects of the R interpreter,
-REPL loop, threading---and object interchange between R and C++ is but one
+\pkg{CXXR} is therefore concerned with all aspects of the R interpreter,
+REPL, threading---and object interchange between R and C++ is but one
part. A similar approach is discussed by \cite{templelang09:modestproposal}
who suggests making low-level internals extensible by package developers in
order to facilitate extending \R.
@@ -126,25 +129,18 @@
Another slightly different angle is offered by
\cite{templelang09:rgcctranslationunit} who uses compiler output for
references on the code in order to add bindings and wrappers.
-%
-Lastly, the \pkg{RcppTemplate} package \citep{samperi09:rcpptemplate}
-recently introduced a few new ideas yet decided to break with the
-`classic \pkg{Rcpp}' API.
-A critical comparison of these packages that addresses relevant aspects such
-API features, performance, usability and documentation would be a welcome
-addition to the literature, but is beyond the scope of this article.
-
-\section{Classic Rcpp API}
+\subsection{Rcpp Use Cases}
\label{sec:classic_rcpp}
-The core focus of \pkg{Rcpp}---particularly for the earlier API described in
-this section---has always been on allowing the programmer to add C++-based
-functions. We use this term in the standard mathematical sense of providing
-results (output) given a set of parameters or data (input). This was
+The core focus of \pkg{Rcpp} has always been on allowing the
+programmer to add C++-based functions.
+Here, we use `function' in the standard mathematical sense of providing
+results (output) given a set of parameters or data (input).
+This was
facilitated from the earliest releases using C++ classes for receiving
various types of R objects, converting them to C++ objects and allowing the
-programmer to return the results to R with relative use.
+programmer to return the results to R with relative ease.
This API therefore supports two typical use cases. First, one can think of
replacing existing R code with equivalent C++ code in order to reap
@@ -157,72 +153,57 @@
and parameters are passed via \pkg{Rcpp} to a function set-up to call code
from an external library.
-An illustration can be provided using the time-tested example of a
-convolution of two vectors. This example is shown in sections 5.2 (for the
-\code{.C()} interface) and 5.9 (for the \code{.Call()} interface) of 'Writing
-R Extensions' \citep{R:exts}. We have rewritten it here using classes of the
-classic \pkg{Rcpp} API:
+\section{The \pkg{Rcpp} API}
+\label{sec:new_rcpp}
+More recently, the \pkg{Rcpp} API has been redesigned and extended,
+based on the usage experience of several
+years of \pkg{Rcpp} deployment, needs from other projects, knowledge
+of the internal R API, as well as current C++ design approaches.
+The new features in \pkg{Rcpp} were also motivated by the needs of other
+projects such as \pkg{RInside} \citep{cran:rinside} for easy embedding
+of R in C++ applications and \pkg{RProtoBuf} \citep{cran:rprotobuf}
+that interfaces with the Protocol Buffers library.
+
+\subsection{A First Example}
+
\begin{example}
#include <Rcpp.h>
-RcppExport SEXP convolve2cpp(SEXP a,SEXP b) \{
- RcppVector<double> xa(a);
- RcppVector<double> xb(b);
- int nab = xa.size() + xb.size() - 1;
+RcppExport SEXP convolve3cpp(SEXP a, SEXP b) \{
+ Rcpp::NumericVector xa(a);
+ Rcpp::NumericVector xb(b);
+ int n_xa = xa.size(), n_xb = xb.size();
+ int nab = n_xa + n_xb - 1;
+ Rcpp::NumericVector xab(nab);
- RcppVector<double> xab(nab);
- for (int i = 0; i < nab; i++) xab(i) = 0.0;
+ for (int i = 0; i < n_xa; i++)
+ for (int j = 0; j < n_xb; j++)
+ xab[i + j] += xa[i] * xb[j];
- for (int i = 0; i < xa.size(); i++)
- for (int j = 0; j < xb.size(); j++)
- xab(i + j) += xa(i) * xb(j);
-
- RcppResultSet rs;
- rs.add("ab", xab);
- return rs.getReturnList();
+ return xab;
\}
\end{example}
We can highlight several aspects. First, only a single header file
\code{Rcpp.h} is needed to use the \pkg{Rcpp} API. Second, given two
-\code{SEXP} types, a third is returned.
-Third, both inputs are converted to templated\footnote{C++ templates
-allow functions or classes to be written somewhat independently from the
-template parameter. The actual class is instantiated by the compiler
-by replacing occurrences of the templated parameter(s).}
-C++ vector types, here a standard \code{double}
-type is used to create a vector of doubles from the template type.
-Fourth, the usefulness of these classes can be seen when we query the
-vectors directly for their size---using the \code{size()} member function---in
-order to reserve a new result type of appropriate length whereas use based
-on C arrays would have required additional parameters for the length of
-vectors $a$ and $b$, leaving open the possibility of mismatches between the
-actual length and the length reported by the programmer.
-Fifth, the computation itself is straightforward embedded looping just as in the
-original examples in the 'Writing R Extensions' manual \citep{R:exts}.
-Sixth, a return type (\code{RcppResultSet}) is prepared as a named
-object which is then
-converted to a list object that is returned. We should note that the
-\code{RcppResultSet} supports the return of numerous (named) objects which can
-also be of different types.
+arguments of type \code{SEXP}, a third is returned. Third, both inputs are
+converted to C++ vector types provided by \pkg{Rcpp} (and we have more to say about these
+conversions below). Fourth, the
+usefulness of these classes can be seen when we query the vectors directly
+for their size---using the \code{size()} member function---in order to
+reserve a new result type of appropriate length,
+and with the use of the
+\verb|operator[]| to extract and set individual elements of the vector.
+Fifth, the computation itself is
+straightforward embedded looping just as in the original examples in the
+'Writing R Extensions' manual \citep{R:exts}. Sixth, the return conversion
+from the \code{NumericVector} to the \code{SEXP} type is also automatic.
-We argue that this usage is already much easier to read, write and debug than the
-C macro-based approach supported by R itself. Possible performance issues and
-other potential limitations will be discussed throughout the article and
-reviewed at the end.
+We argue that this \pkg{Rcpp}-based usage is much easier to read, write and debug than the
+C macro-based approach supported by R itself.
-\section{New \pkg{Rcpp} API}
-\label{sec:new_rcpp}
-More recently, the \pkg{Rcpp} API has been dramatically extended, leading to a
-complete redesign, based on the usage experience of several
-years of \pkg{Rcpp} deployment, needs from other projects, knowledge
-of the internal R API, as well as current C++ design approaches.
-This redesign of \code{Rcpp} was also motivated by the needs of other
-projects such as \code{RInside} \citep{cran:rinside} for easy embedding
-of R in a C++ applications and \code{RProtoBuf} \citep{cran:rprotobuf}
-that interfaces with the protocol buffers library.
\subsection{Rcpp Class hierarchy}
@@ -235,8 +216,8 @@
a very thin wrapper around the \code{SEXP} it encapsulates. The
\code{SEXP} is indeed the only data member of an \code{RObject}. The
\code{RObject} class does not interfere with the way R manages its
-memory, does not perform copies of the object into a suboptimal
-C++ representation, but instead merely acts as a proxy to the
+memory and does not perform copies of the object into a suboptimal
+C++ representation. Instead, it merely acts as a proxy to the
object it encapsulates so that methods applied to the \code{RObject}
instance are relayed back to the \code{SEXP} in terms of the standard
R API.
@@ -250,7 +231,7 @@
is protected from the garbage collector, and the destructor
assumes the responsibility to withdraw that protection.
-By assuming the entire responsibility of garbage collection, \code{Rcpp}
+By assuming the entire responsibility of garbage collection, \pkg{Rcpp}
relieves the programmer from writing boiler plate code to manage
the protection stack with \code{PROTECT} and \code{UNPROTECT} macros.
@@ -258,29 +239,29 @@
to any R object, regardless of its type. This ranges from
querying properties of the object (\texttt{isNULL}, \texttt{isObject},
\texttt{isS4}), management of the attributes
-(\texttt{attributeNames}, \texttt{hasAttribute}, \texttt{attr}) and
+(\texttt{attributeNames}, \texttt{hasAttribute}, \texttt{attr}) to
handling of slots\footnote{The member functions that deal with slots
-are only applicable on S4 objects; otherwise an exception is thrown.}
+are only applicable to S4 objects; otherwise an exception is thrown.}
(\texttt{hasSlot}, \texttt{slot}).
\subsection{Derived classes}
Internally, an R object must have one type amongst the set of
-predefined types, commonly referred to as SEXP types. R internals
-\citep{R:ints} documents these various types.
-\pkg{Rcpp} associates a dedicated C++ class for most SEXP types,
+predefined types, commonly referred to as SEXP types. The `R Internals'
+manual \citep{R:ints} documents these various types.
+\pkg{Rcpp} associates a dedicated C++ class for most SEXP types, and
therefore only exposes functionality that is relevant to the R object
that it encapsulates.
For example \code{Rcpp::Environment} contains
member functions to manage objects in the associated environment.
-Similarly, classes related to vectors (\code{IntegerVector}, \code{NumericVector},
+Similarly, classes related to vectors---\code{IntegerVector}, \code{NumericVector},
\code{RawVector}, \code{LogicalVector}, \code{CharacterVector},
-\code{GenericVector} and \code{ExpressionVector}) expose functionality
-to extract and set values from the vectors.
+\code{GenericVector} (also known as \code{List}) and
+\code{ExpressionVector}---expose functionality to extract and set values from the vectors.
The following sub-sections present typical uses of \pkg{Rcpp} classes in
-comparison with the same code expressed using functions of the R API.
+comparison with the same code expressed using functions and macros of the R API.
\subsection{Numeric vectors}
@@ -297,12 +278,11 @@
\end{example}
Although this is one of the simplest examples in Writing R extensions,
-it seems verbose and it is not obvious at first sight to understand what is happening.
+it seems verbose and it is not obvious at first sight what is happening.
Memory is allocated by \code{allocVector}; we must also supply it with
the type of data (\code{REALSXP}) and the number of elements. Once
allocated, the \code{ab} object must be protected from garbage
-collection\footnote{Since the garbage collection can be triggered at any time, not
-protecting an object means its memory might be reclaimed too soon.}.
+collection.
Lastly, the \code{REAL} macro returns a pointer to the
beginning of the actual array; its indexing does not resemble either R or
C++.
@@ -310,27 +290,31 @@
Using the \code{Rcpp::NumericVector} class, the code can be rewritten:
\begin{example}
-Rcpp::NumericVector ab(2) ;
+Rcpp::NumericVector ab(2);
ab[0] = 123.45;
ab[1] = 67.89;
\end{example}
The code contains fewer idiomatic decorations. The \code{NumericVector}
-constructor is given the number of elements the vector contains (2), this
+constructor is given the number of elements the vector contains (2), which
hides a call to the \code{allocVector} we saw previously. Also hidden is
protection of the object from garbage collection, which is a behavior that
\code{NumericVector} inherits from \code{RObject}. Values are assigned to
the first and second elements of the vector as \code{NumericVector} overloads
the \code{operator[]}.
-With the most recent compilers (e.g. GNU g++ >= 4.4) which already implement
-parts of the next C++ standard (C++0x) currently being drafted, the preceding
-code may even be reduced to this:
+The snippet can also be written more concisely using the \code{create}
+static member function of the \code{NumericVector} class:
\begin{example}
-Rcpp::NumericVector ab = \{123.45, 67.89\};
+Rcpp::NumericVector ab =
+ Rcpp::NumericVector::create(123.45, 67.89);
\end{example}
+It should be noted that although the copy constructor of the
+\code{NumericVector} class is used, it does not imply copies of the
+underlying array, only the \code{SEXP} (\textsl{i.e.} a simple pointer) is copied.
+
\subsection{Character vectors}
A second example deals with character vectors and emulates this R code
@@ -352,13 +336,13 @@
This imposes on the programmer knowledge of \code{PROTECT}, \code{UNPROTECT},
\code{SEXP}, \code{allocVector}, \code{SET\_STRING\_ELT}, and \code{mkChar}.
-Using the \pkg{Rcpp::CharacterVector} class, we can express the same
+Using the \code{Rcpp::CharacterVector} class, we can express the same
code more concisely:
\begin{example}
-CharacterVector ab(2) ;
-ab[0] = "foo" ;
-ab[1] = "bar" ;
+Rcpp::CharacterVector ab(2);
+ab[0] = "foo";
+ab[1] = "bar";
\end{example}
\section{R and C++ data interchange}
@@ -369,24 +353,25 @@
\subsection{C++ to R : wrap}
The C++ to R conversion is performed by the \code{Rcpp::wrap} templated
-function. It uses advanced template meta programming techniques\footnote{A
- discussion of template meta programming is beyond the scope of this
- article.} to convert a wide and extensible set of types and classes to the
-most appropriate type of R object. The signature of the \code{wrap} template
-is:
+function. It uses advanced template metaprogramming techniques\footnote{A
+ discussion of template metaprogramming
+ \citep{Vandevoorde+Josuttis:2003,Abrahams+Gurtovoy:2004} is beyond the
+ scope of this article.} to convert a wide and extensible set of types and
+classes to the most appropriate type of R object. The signature of the
+\code{wrap} template is:
\begin{example}
template <typename T>
-SEXP wrap(const T& object) ;
+SEXP wrap(const T& object);
\end{example}
-The templated function takes a reference to a `wrappable`
+The templated function takes a reference to a `wrappable'
object and converts this object into a \code{SEXP}, which is what R expects.
Currently wrappable types are :
\begin{itemize}
-\item primitive types, \code{int}, \code{double}, ... which are converted
+\item primitive types: \code{int}, \code{double}, ... which are converted
into the corresponding atomic R vectors;
-\item \code{std::string} which are converted to R atomic character vectors;
+\item \code{std::string} objects 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;
\item STL maps which use \code{std::string} for keys
@@ -394,16 +379,15 @@
the type \code{T} is wrappable;
\item any type that implements implicit conversion to \code{SEXP} through the
\code{operator SEXP()};
-\item any type for which the \code{wrap} template is partially or fully
-specialized.
+\item any type for which the \code{wrap} template is
+fully specialized.
\end{itemize}
-%One example for the specialisation of the templated \code{wrap} function is
-%provided in \pkg{RInside} \citep{cran:rinside} by \code{vector< vector<
-% double > >} and \code{vector< vector< int > >} which are used for
-%representing numeric matrices.
Wrappability of an object type is resolved at compile time using
-modern techniques of template meta programming and class traits.
+modern techniques of template meta programming and class traits. The
+\code{Rcpp-extending} vignette discusses in depth how to extend \code{wrap}
+to third-party types. The \pkg{RcppArmadillo} package
+\citep*{cran:rcpparmadillo} features several examples.
The following code snippet illustrates that the design allows
composition:
@@ -416,9 +400,9 @@
m1["foo"] = 1; m1["bar"] = 2;
m2["foo"] = 1; m2["bar"] = 2; m2["baz"] = 3;
-v.push_back( m1) ;
-v.push_back( m2) ;
-Rcpp::wrap( v ) ;
+v.push_back( m1);
+v.push_back( m2);
+Rcpp::wrap( v );
\end{example}
The code creates a list of two named vectors, equal to the
@@ -431,19 +415,28 @@
\subsection{R to C++ : as}
-The reversed conversion is implemented by variations of the
-\code{Rcpp::as} template. It offers less flexibility and currently
+The reverse conversion is implemented by variations of the
+\code{Rcpp::as} template whose signature is:
+\begin{example}
+template <typename T>
+T as(SEXP x) throw(not_compatible);
+\end{example}
+
+It offers less flexibility and currently
handles conversion of R objects into primitive types (bool, int, std::string, ...),
STL vectors of primitive types (\code{std::vector<bool>},
\code{std::vector<double>}, etc ...) and arbitrary types that offer
a constructor that takes a \code{SEXP}. In addition \code{as} can
be fully or partially specialized to manage conversion of R data
-structures to third-party types.
+structures to third-party types as can be seen for example in the
+\pkg{RcppArmadillo} package which eases transfer of R matrices and vectors to
+the optimised data structures in the Armadillo linear algebra library \citep{Armadillo}.
+
\subsection{Implicit use of converters}
The converters offered by \code{wrap} and \code{as} provide a very
-useful framework to implement the logic of the code in terms of C++
+useful framework to implement code logic in terms of C++
data structures and then explicitly convert data back to R.
In addition, the converters are also used implicitly
@@ -455,36 +448,40 @@
// assuming the global environment contains
// a variable 'x' that is a numeric vector
Rcpp::Environment global =
-\ \ \ \ Rcpp::Environment::global_env()
+\ \ \ \ Rcpp::Environment::global_env();
// extract a std::vector<double> from
// the global environment
-std::vector<double> vx = global["x"] ;
+std::vector<double> vx = global["x"];
// create a map<string,string>
-std::map<std::string,std::string> map ;
-map["foo"] = "oof" ;
-map["bar"] = "rab" ;
+std::map<std::string,std::string> map;
+map["foo"] = "oof";
+map["bar"] = "rab";
// push the STL map to R
-global["y"] = map ;
+global["y"] = map;
\end{example}
In the first part of the example, the code extracts a
-\code{std::vector<double>} from the global environment. This is
-achieved by the templated \code{operator[]} of \code{Environment}
-that first extracts the requested object from the environment as a \code{SEXP},
-and then outsources to \code{Rcpp::as} the creation of the
-requested type.
+\code{std::vector<double>} from the global environment. In order to achieve this,
+the \code{operator[]} of \code{Environment} uses the proxy pattern
+\citep{meyers:moreeffectivecplusplus}
+to distinguish between left hand side (LHS) and right hand side (RHS) use.
+%
+The output of the operator is an instance of the nested class
+\code{Environment::Binding}, which defines a templated implicit conversion
+operator that allows a \code{Binding} to be assigned to any type that
+\code{Rcpp::as} is able to handle.
-In the second part of the example, the \code{operator[]}
-delegates to wrap the production of an R object based on the
-type that is passed in (\code{std::map<std::string,std::string>}),
-and then assigns the object to the requested name.
+In the second part of the example, LHS use of the \code{Binding} instance is
+implemented through its assignment operator, which is also templated and uses
+\code{Rcpp::wrap} to perform the conversion to a \code{SEXP} that can be
+assigned to the requested symbol in the global environment.
The same mechanism is used throughout the API. Examples include access/modification
of object attributes, slots, elements of generic vectors (lists),
-function arguments, nodes of dotted pair lists and language calls and more.
+function arguments, nodes of dotted pair lists, language calls and more.
\section{Function calls}
@@ -513,8 +510,8 @@
\ \ \ \ \ \ CONS(ScalarReal(100.0),R_NilValue))));
SET_TAG( CDDR(call), install("sd") );
SEXP res = PROTECT(eval(call, R_GlobalEnv));
-UNPROTECT(4) ;
-return res ;
+UNPROTECT(4);
+return res;
\end{example}
\end{minipage}
@@ -536,23 +533,22 @@
\ \ LCONS( install("rnorm"),
\ \ \ \ CONS(ScalarInteger(10),
\ \ \ \ \ \ CONS(ScalarReal(100.0),R_NilValue))));
-SET_TAG( CDDR(call), install("sd") ) ;
+SET_TAG( CDDR(call), install("sd") );
SEXP res = PROTECT(eval(call, R_GlobalEnv));
-UNPROTECT(2) ;
-return res ;
+UNPROTECT(2);
+return res;
\end{example}
\end{minipage}
\caption{\pkg{Rcpp} versus the R API: Four ways of calling \code{rnorm(10L, sd=100)} in C / C++.
- We have removed the \code{Rcpp::} prefix from the
- examples for readability; this corresponds to adding a statement
- \texttt{using namespace Rcpp;} in the code}
+ We have removed the \code{Rcpp::} prefix for readability; this corresponds to adding a directive
+ \texttt{using namespace Rcpp;} in the code.}
\label{fig:rnormCode}
\end{table*}
The next example shows how to use \pkg{Rcpp} to emulate the R code
\code{rnorm(10L, sd=100.0)}.
%
-As shown in table~\ref{fig:rnormCode}, the code can be expressed in several
+As shown in Table~\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}.
@@ -563,22 +559,20 @@
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 ninety unit tests.
+among its over seven hundred and seventy unit tests.
-
\section{Using code `inline'}
\label{sec:inline}
Extending R with compiled code also needs to address how to reliably compile,
link and load the code. While using a package is preferable in the long run,
-it may be too involved for for quick explorations. An alternative is
+it may be too involved for quick explorations. An alternative is
provided by the \pkg{inline} package \citep{cran:inline} which compiles,
links and loads a C, C++ or Fortran function---directly from the R prompt
-using a simple function \code{cfunction}. It was recently extended to work
-with \pkg{Rcpp} by allowing for the use of additional header files and
-libraries. This works particularly well with the \pkg{Rcpp} package where
-headers and the library are automatically found if the appropriate option
-\code{Rcpp} to \texttt{cfunction} is set to \code{TRUE}.
+using simple functions \code{cfunction} and \code{cxxfunction}. The latter provides an extension which
+works particularly well with \pkg{Rcpp} via so-called `plugins' which provide
+information about additional header file and
+library locations.
The use of \pkg{inline} is possible as \pkg{Rcpp} can be installed and
updated just like any other R package using \textsl{e.g.} the
@@ -593,50 +587,42 @@
or upgrades.}
The library and header files provided by \pkg{Rcpp} for use by other packages
-are installed along with the \pkg{Rcpp} package making it possible for
-\pkg{Rcpp} to provide the appropriate \code{-I} and \code{-L} switches needed
-for compilation and linking. So internally, \pkg{inline} makes uses of the
-two functions \code{Rcpp:::CxxFlags()} and \code{Rcpp:::LdFlags()} that
-provide this information (and which are also used by \code{Makevars} files of
-other packages). Here, however, all this is done behind the scenes
-without the need for explicitly setting compiler or linker options.
+are installed along with the \pkg{Rcpp} package. The \code{LinkingTo:~Rcpp}
+directive in the DESCRIPTION file lets R compute the location of the header
+file. The \pkg{Rcpp} package provides appropriate information for the \code{-L}
+switch needed for linking via the function \code{Rcpp:::LdFlags()} that
+provide this information. It can be used by \code{Makevars} files of other
+packages, and \pkg{inline} makes use of it internally so that all of this is
+done behind the scenes without the need for explicitly setting compiler or
+linker options.
The convolution example provided above can be rewritten for use by
\pkg{inline} as shown below. The function body is provided by the character
variable \code{src}, the function header is defined by the argument
-\code{signature}---and we only need to enable \code{Rcpp=TRUE} to obtain a
-new function \code{fun} based on the C++ code in \code{src} where we also
-switched from the classic \pkg{Rcpp} API to the new one:
+\code{signature}---and we only need to enable \code{plugin="Rcpp"} to obtain a
+new function \code{fun} based on the C++ code in \code{src}:
\begin{example}
-src <- '
- Rcpp::NumericVector xa(a);
- Rcpp::NumericVector xb(b);
- 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)
+> src <- '
++ Rcpp::NumericVector xa(a);
++ Rcpp::NumericVector xb(b);
++ 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 <- cxxfunction(
++ \ \ \ \ signature(a="numeric", b="numeric"),
++ \ \ \ \ src, plugin="Rcpp")
+> fun( 1:3, 1:4 )
+[1] 1 4 10 16 17 12
\end{example}
-The main difference to the previous solution is that the input parameters are
-directly passed to types \code{Rcpp::NumericVector}, and that the return
-vector is automatically converted to a \code{SEXP} type through implicit
-conversion. Also in this version, the vector \code{xab} is not
-initialized because the constructor already performs initialization
-to match the behavior of the R function \code{numeric}.
-
\section{Using STL algorithms}
-% This is taken from :
-% http://www.cplusplus.com/reference/algorithm/
-
The C++ Standard Template Library (STL) offers a variety of generic
algorithms designed to be used on ranges of elements
\citep{plauger_et_al:stlbook}. A range is any sequence of objects that can be
@@ -647,34 +633,30 @@
The following code illustrates how \pkg{Rcpp} might be used
[TRUNCATED]
To get the complete diff run:
svnlook diff /svnroot/rcpp -r 2243
More information about the Rcpp-commits
mailing list