[Rcpp-commits] r3874 - in pkg/Rcpp: . R man
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Wed Oct 31 17:22:28 CET 2012
Author: jjallaire
Date: 2012-10-31 17:22:28 +0100 (Wed, 31 Oct 2012)
New Revision: 3874
Added:
pkg/Rcpp/man/cppFunction.Rd
Modified:
pkg/Rcpp/ChangeLog
pkg/Rcpp/NAMESPACE
pkg/Rcpp/R/Attributes.R
pkg/Rcpp/man/compileAttributes.Rd
pkg/Rcpp/man/sourceCpp.Rd
Log:
add cppFunction for inline-style definitions
Modified: pkg/Rcpp/ChangeLog
===================================================================
--- pkg/Rcpp/ChangeLog 2012-10-31 13:52:52 UTC (rev 3873)
+++ pkg/Rcpp/ChangeLog 2012-10-31 16:22:28 UTC (rev 3874)
@@ -1,11 +1,15 @@
2012-10-31 JJ Allaire <jj at rstudio.org>
- * R/Attributes.R: change 'local' param to (more explicit) 'envir'
- * src/Attributes.cpp: factored parser into it's own file; eliminated
- tranposition of roxygen comments.
- * src/AttributesParser.h: attributes parser header
- * src/AttributesParser.cpp: attributes parser implementation
- * man/source.Cpp.Rd: documentation updates
+ * R/Attributes.R: add cppFunction for inline-style definitions;
+ change 'local' param to (more clear and explicit) 'envir' param.
+ * src/Attributes.cpp: factored parser into it's own file; eliminated
+ tranposition of roxygen comments.
+ * src/AttributesParser.h: attributes parser header
+ * src/AttributesParser.cpp: attributes parser implementation
+ * man/sourceCpp.Rd: documentation updates
+ * man/compileAttributes.Rd: documentation updates
+ * man/cppFunction.Rd: documentation for cppFunction
+ * NAMESPACE: export for cppFunction
2012-10-31 Romain Francois <romain at r-enthusiasts.com>
Modified: pkg/Rcpp/NAMESPACE
===================================================================
--- pkg/Rcpp/NAMESPACE 2012-10-31 13:52:52 UTC (rev 3873)
+++ pkg/Rcpp/NAMESPACE 2012-10-31 16:22:28 UTC (rev 3874)
@@ -16,7 +16,7 @@
export(
Module, Rcpp.package.skeleton, populate, loadRcppModules, setRcppClass,
- loadModule, sourceCpp, compileAttributes
+ loadModule, cppFunction, sourceCpp, compileAttributes
)
exportClass(RcppClass)
Modified: pkg/Rcpp/R/Attributes.R
===================================================================
--- pkg/Rcpp/R/Attributes.R 2012-10-31 13:52:52 UTC (rev 3873)
+++ pkg/Rcpp/R/Attributes.R 2012-10-31 16:22:28 UTC (rev 3874)
@@ -130,17 +130,52 @@
invisible(context$exportedFunctions)
}
-# Define a single C++ function.
-cppFunction <- function(code) {
+# Define a single C++ function
+cppFunction <- function(code,
+ plugin = NULL,
+ includes = NULL,
+ envir = parent.frame(),
+ rebuild = FALSE,
+ verbose = getOption("verbose")) {
- # add scaffolding
- code <- paste("#include <Rcpp.h>", "using namespace Rcpp;",
- "// [[Rcpp::export]]", code, sep="\n")
+ # generate required scaffolding
+ if (!is.null(plugin)) {
+ depends <- paste(plugin, sep=", ")
+ scaffolding <- paste("// [[Rcpp::depends(", depends, ")]]", sep="")
+ scaffolding <- c(scaffolding, "", .rcppExportsIncludes(plugin),
+ recursive=T)
+ }
+ else {
+ scaffolding <- "#include <Rcpp.h>"
+ }
+ scaffolding <- c(scaffolding,
+ "",
+ "using namespace Rcpp;",
+ "",
+ includes,
+ "// [[Rcpp::export]]",
+ recursive = T)
+
+ # prepend scaffolding to code
+ code <- paste(c(scaffolding, code, recursive = T), collapse="\n")
- # source cpp into environment we create to hold the function
- envir <- new.env()
- exported <- sourceCpp(code = code, envir = envir)
+ # print the generated code if we are in verbose mode
+ if (verbose) {
+ cat("\nGenerated code for function definition:",
+ "\n--------------------------------------------------------\n\n")
+ cat(code)
+ }
+ # source cpp into specified environment. if envir is set to NULL
+ # then create a new one (the caller can get a hold of the function
+ # via the return value)
+ if (is.null(envir))
+ envir <- new.env()
+ exported <- sourceCpp(code = code,
+ envir = envir,
+ rebuild = rebuild,
+ verbose = verbose)
+
# verify that a single function was exported and return it
if (length(exported) == 0)
stop("No function definition found")
@@ -148,7 +183,7 @@
stop("More than one function definition")
else {
functionName <- exported[[1]]
- get(functionName, envir)
+ invisible(get(functionName, envir))
}
}
Modified: pkg/Rcpp/man/compileAttributes.Rd
===================================================================
--- pkg/Rcpp/man/compileAttributes.Rd 2012-10-31 13:52:52 UTC (rev 3873)
+++ pkg/Rcpp/man/compileAttributes.Rd 2012-10-31 16:22:28 UTC (rev 3874)
@@ -12,10 +12,10 @@
%- maybe also 'usage' for other objects documented here.
\arguments{
\item{pkgdir}{
- Directory containing the package to compile attributes for (defaults to the current working directory)
+ Directory containing the package to compile attributes for (defaults to the current working directory).
}
\item{verbose}{
- \code{TRUE} to print detailed information about generated code to the console
+ \code{TRUE} to print detailed information about generated code to the console.
}
}
\details{
Added: pkg/Rcpp/man/cppFunction.Rd
===================================================================
--- pkg/Rcpp/man/cppFunction.Rd (rev 0)
+++ pkg/Rcpp/man/cppFunction.Rd 2012-10-31 16:22:28 UTC (rev 3874)
@@ -0,0 +1,82 @@
+\name{cppFunction}
+\alias{cppFunction}
+\title{
+Define an R Function with a C++ Implementation
+}
+\description{
+Dynamically define an R function with C++ source code. Compiles and links a shared library with bindings to the C++ function then defines an R function that uses \code{.Call} to invoke the library.
+}
+\usage{
+cppFunction(code, plugin = NULL, includes = NULL,
+ envir = parent.frame(), rebuild = FALSE,
+ verbose = getOption("verbose"))
+}
+
+\arguments{
+ \item{code}{
+ Source code for the function definition.
+}
+ \item{plugin}{
+ The name of an \link[inline:plugins]{inline plugin} to use for the compilation.
+}
+ \item{includes}{
+ User includes, inserted after the includes provided by the plugin.
+}
+ \item{envir}{
+ The \link[base:environment]{environment} in which to define the R function. May be \code{NULL} in which case the defined function can be obtained from the return value of \code{cppFunction}.
+}
+ \item{rebuild}{
+ Force a rebuild of the shared library.
+}
+ \item{verbose}{
+ \code{TRUE} to print detailed information about generated code to the console.
+}
+}
+\details{
+ Functions defined using \code{cppFunction} must have return types that are compatible with \code{Rcpp::wrap} and parameter types that are compatible with \code{Rcpp::as}.
+
+ The shared library will not be rebuilt if the underlying code has not changed since the last compilation.
+}
+\value{
+ An R function that uses \code{.Call} to invoke the underlying C++ function.
+}
+
+\note{
+ You can also define R functions with C++ implementations using the \code{\link{sourceCpp}} function, which allows you to separate the C++ code into it's own source file. For many use cases this is an easier and more maintainable approach.
+}
+
+
+\seealso{
+\code{\link{sourceCpp}}
+}
+\examples{
+\dontrun{
+
+cppFunction(
+ 'int fibonacci(const int x) {
+ if (x == 0) return(0);
+ if (x == 1) return(1);
+ return (fibonacci(x - 1)) + fibonacci(x - 2);
+ }')
+
+cppFunction(plugin = "RcppArmadillo",
+ 'List fastLm(NumericVector yr, NumericMatrix Xr) {
+
+ int n = Xr.nrow(), k = Xr.ncol();
+
+ arma::mat X(Xr.begin(), n, k, false);
+ arma::colvec y(yr.begin(), yr.size(), false);
+
+ arma::colvec coef = arma::solve(X, y);
+ arma::colvec resid = y - X*coef;
+
+ double sig2 = arma::as_scalar(arma::trans(resid)*resid/(n-k) );
+ arma::colvec stderrest = arma::sqrt(
+ sig2 * arma::diagvec(arma::inv(arma::trans(X)*X)));
+
+ return List::create(Named("coefficients") = coef,
+ Named("stderr") = stderrest
+ );
+ }')
+}
+}
Modified: pkg/Rcpp/man/sourceCpp.Rd
===================================================================
--- pkg/Rcpp/man/sourceCpp.Rd 2012-10-31 13:52:52 UTC (rev 3873)
+++ pkg/Rcpp/man/sourceCpp.Rd 2012-10-31 16:22:28 UTC (rev 3874)
@@ -16,24 +16,21 @@
A character string giving the pathname of a file
}
\item{code}{
- A character string with C++ source code to compile
+ A charcter string with source code. If supplied, the code is taken from this string instead of a file.
}
\item{envir}{
- Environment where the R functions should be made available
+ Environment where the R functions should be made available.
}
\item{rebuild}{
- Force a rebuild of the shared library by passing \code{--preclean} to \code{R CMD SHLIB}
+ Force a rebuild of the shared library.
}
\item{show.output}{
- \code{TRUE} to print \code{R CMD SHLIB} output to the console
+ \code{TRUE} to print \code{R CMD SHLIB} output to the console.
}
\item{verbose}{
- \code{TRUE} to print detailed information about generated code to the console
+ \code{TRUE} to print detailed information about generated code to the console.
}
- \item{code}{
- Code. If supplied, the code is taken from this string instead of a file.
}
-}
\details{
If the \code{code} parameter is provided then the \code{file} parameter is ignored.
More information about the Rcpp-commits
mailing list