[Rcpp-commits] r3617 - in pkg/Rcpp: . inst inst/doc/Rcpp-modules
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Thu May 24 19:14:28 CEST 2012
Author: edd
Date: 2012-05-24 19:14:27 +0200 (Thu, 24 May 2012)
New Revision: 3617
Modified:
pkg/Rcpp/ChangeLog
pkg/Rcpp/inst/NEWS
pkg/Rcpp/inst/doc/Rcpp-modules/Rcpp-modules.Rnw
Log:
expanded the vignette a little
Modified: pkg/Rcpp/ChangeLog
===================================================================
--- pkg/Rcpp/ChangeLog 2012-05-24 15:42:56 UTC (rev 3616)
+++ pkg/Rcpp/ChangeLog 2012-05-24 17:14:27 UTC (rev 3617)
@@ -16,6 +16,9 @@
* inst/unitTests/runit.Module.client.package.R: Added four simple
tests for Rcpp Modules
+ * inst/doc/Rcpp-modules/Rcpp-modules.Rnw: Some extensions and
+ clarifications added
+
2012-05-13 Dirk Eddelbuettel <edd at debian.org>
* inst/include/Rcpp/iostream/Rostream.h: Added Rstreambuf.h include
Modified: pkg/Rcpp/inst/NEWS
===================================================================
--- pkg/Rcpp/inst/NEWS 2012-05-24 15:42:56 UTC (rev 3616)
+++ pkg/Rcpp/inst/NEWS 2012-05-24 17:14:27 UTC (rev 3617)
@@ -11,7 +11,7 @@
o Support compilation in Cygwin thanks to a patch by Dario Buttari
- o Small extensions to the Rcpp-FAQ
+ o Small extensions to the Rcpp-FAQ and the Rcpp-modules vignettes
0.9.10 2012-02-16
Modified: pkg/Rcpp/inst/doc/Rcpp-modules/Rcpp-modules.Rnw
===================================================================
--- pkg/Rcpp/inst/doc/Rcpp-modules/Rcpp-modules.Rnw 2012-05-24 15:42:56 UTC (rev 3616)
+++ pkg/Rcpp/inst/doc/Rcpp-modules/Rcpp-modules.Rnw 2012-05-24 17:14:27 UTC (rev 3617)
@@ -1,6 +1,6 @@
\documentclass[10pt]{article}
%\VignetteIndexEntry{Rcpp-modules}
-\usepackage{vmargin}
+\usepackage[USletter]{vmargin}
\setmargrb{0.75in}{0.75in}{0.75in}{0.75in}
\usepackage{color, alltt}
@@ -15,6 +15,7 @@
urlcolor=link
}
+\newcommand{\code}[1]{\texttt{#1}}
\newcommand{\proglang}[1]{\textsf{#1}}
\newcommand{\pkg}[1]{{\fontseries{b}\selectfont #1}}
@@ -188,7 +189,10 @@
As it is generally a bad idea to expose external pointers `as is',
they usually get wrapped as a slot of an S4 class.
-<<echo=FALSE,results=hide>>=
+Using \code{cxxfunction()} from the \pkg{inline} package, we can build this
+example on the fly:
+
+<<>>=
f1 <- cxxfunction( , "", includes = '
using namespace Rcpp;
@@ -269,6 +273,7 @@
\section{Rcpp modules}
+\label{sec:modules}
The design of Rcpp modules has been influenced by \proglang{Python} modules which are generated by the
\texttt{Boost.Python} library \citep{Abrahams+Grosse-Kunstleve:2003:Boost.Python}.
@@ -303,14 +308,42 @@
the need for a wrapper function using either \pkg{Rcpp} or the \proglang{R} API.
On the \proglang{R} side, the module is retrieved by using the
-\Sexpr{link("Module")} function from \pkg{Rcpp}:
+\Sexpr{link("Module")} function from \pkg{Rcpp}
+<<>>=
+inc <- '
+using namespace Rcpp;
+
+double norm( double x, double y ) {
+ return sqrt( x*x + y*y );
+}
+
+RCPP_MODULE(mod) {
+ function( "norm", &norm );
+}
+'
+
+fx <- cxxfunction(signature(), plugin="Rcpp", include=inc)
+mod <- Module( "mod", getDynLib(fx) )
+mod$norm( 3, 4 )
+@
+
+Note that this example assumed that the previous code segment defining the
+module was returned by the \code{cxxfunction()} (from the \pkg{inline}
+package) as callable R function \code{fx} from which we can extract the
+relevant pointer using \code{getDynLib()}. In the case of using Rcpp modules
+via a package (which is detailed in Section~\ref{sec:package} below), modules
+are actually loaded differently and we would have used
+
<<eval=FALSE>>=
-require( Rcpp )
-mod <- Module( "mod" )
+require(nameOfMyModulePackage)
+mod <- new( mod )
mod$norm( 3, 4 )
@
+where the module is loaded upon startup and we use the constructor
+directly. More details on this aspect follow below.
+
A module can contain any number of calls to \texttt{function} to register
many internal functions to \proglang{R}. For example, these 6 functions :
@@ -360,15 +393,31 @@
<<eval=FALSE>>=
require( Rcpp )
-yada <- Module( "yada" )
-yada$bar( 2L )
-yada$foo( 2L, 10.0 )
-yada$hello()
-yada$bla()
-yada$bla1( 2L)
-yada$bla2( 2L, 5.0 )
+yd <- Module( "yada", getDynLib(fx) )
+yd$bar( 2L )
+yd$foo( 2L, 10.0 )
+yd$hello()
+yd$bla()
+yd$bla1( 2L)
+yd$bla2( 2L, 5.0 )
@
+In the case of a package (as for example the one created by
+\code{Rcpp.package.skeleton()} with argument \code{module=TRUE}; more on that
+below), we can use
+
+<<eval=FALSE>>=
+require( myModulePackage ) ## or whichever name was chose
+
+bar( 2L )
+foo( 2L, 10.0 )
+hello()
+bla()
+bla1( 2L)
+bla2( 2L, 5.0 )
+@
+
+
The requirements for a function to be exposed to \proglang{R} via Rcpp modules
are:
\begin{itemize}
@@ -415,9 +464,9 @@
function( "norm", &norm, "Provides a simple vector norm" );
}
', plugin = "Rcpp" )
-mod <- Module( "mod", getDynLib( fx ) )
@
<<>>=
+mod <- Module( "mod", getDynLib( fx ) )
show( mod$norm )
@
@@ -623,9 +672,10 @@
}
', plugin = "Rcpp" )
-unif_module <- Module( "unif_module", getDynLib(fx_unif ) )
@
<<>>=
+## assumes fx_unif <- cxxfunction(...) has ben run
+unif_module <- Module( "unif_module", getDynLib(fx_unif ) )
Uniform <- unif_module$Uniform
u <- new( Uniform, 0, 10 )
u$draw( 10L )
@@ -940,27 +990,17 @@
the class \texttt{std::vector<double>} from the STL.
<<lang=cpp>>=
-// convenience typedef
-typedef std::vector<double> vec;
-
-// helpers
-void vec_assign( vec* obj, Rcpp::NumericVector data ) {
+typedef std::vector<double> vec; // convenience typedef
+void vec_assign( vec* obj, Rcpp::NumericVector data ) { // helpers
obj->assign( data.begin(), data.end() );
}
-
void vec_insert( vec* obj, int position, Rcpp::NumericVector data) {
vec::iterator it = obj->begin() + position;
obj->insert( it, data.begin(), data.end() );
}
+Rcpp::NumericVector vec_asR( vec* obj ) { return Rcpp::wrap( *obj ); }
+void vec_set( vec* obj, int i, double value ) { obj->at( i ) = value; }
-Rcpp::NumericVector vec_asR( vec* obj ) {
- return Rcpp::wrap( *obj );
-}
-
-void vec_set( vec* obj, int i, double value ) {
- obj->at( i ) = value;
-}
-
RCPP_MODULE(mod_vec) {
using namespace Rcpp;
@@ -996,7 +1036,6 @@
// special methods for indexing
.const_method( "[[", &vec::at )
.method( "[[<-", &vec_set )
-
;
}
@
@@ -1063,11 +1102,14 @@
;
}
', plugin = "Rcpp" )
-mod_vec <- Module( "mod_vec", getDynLib(fx_vec), mustStart = TRUE )
@
<<>>=
+## for code compiled on the fly using cxxfunction() into 'fx_vec', we use
+mod_vec <- Module( "mod_vec", getDynLib(fx_vec), mustStart = TRUE )
vec <- mod_vec$vec
+## and that is not needed in a package setup as e.g. one created
+## via Rcpp.package.skeleton(..., module=TRUE)
v <- new( vec )
v$reserve( 50L )
v$assign( 1:10 )
@@ -1079,6 +1121,7 @@
@
\section{Using modules in other packages}
+\label{sec:package}
\subsection{Namespace import/export}
@@ -1108,8 +1151,10 @@
This will look in the package's DESCRIPTION file for the \texttt{RcppModules}
field, load each declared module and populate their contents into the
-package's namespace. For example, the \pkg{testRcppModule}
-(part of \pkg{Rcpp}'s testing) package has this declaration:
+package's namespace. For example, both the \pkg{testRcppModule} package
+(which is part of large unit test suite for \pkg{Rcpp}) and the package
+created via \code{Rcpp.package.skeleton("somename", module=TRUE)} have this
+declaration:
\begin{verbatim}
RcppModules: yada, stdVector, NumEx
@@ -1158,11 +1203,12 @@
We strongly recommend using a package when working with Modules. But in case a
manually compiled shared library has to loaded, the return argument of the
-\texttt{dyn.load()} function can be supplied as the \texttt{PACKAGE} argument to
+\texttt{getDynLib()} function can be supplied as the \texttt{PACKAGE} argument to
the \texttt{Module()} function as well.
\section{Future extensions}
+\label{sec:future}
\texttt{Boost.Python} has many more features that we would like to port
to Rcpp modules : class inheritance, default arguments, enum
More information about the Rcpp-commits
mailing list