Rcpp and the new R:: namespace for Rmath.h

November 14, 2012

(This article was first published on Thinking inside the box , and kindly contributed to R-bloggers)

We released Rcpp 0.10.0 earlier today. This post will just provide a
simple example for one of the smaller new features — the new namespace for functions from Rmath.h — and illustrate one of the
key features (Rcpp attributes) in passing.

R, as a statistical language and environment, has very well written and tested statistical distribution functions providing
probability density, cumulative distribution, quantiles and random number draws for dozens of common and not so common distribution functions.
This code is used inside R, and available for use from standalone C or C++ programs via the standalone R math library which Debian /
Ubuntu have as a package r-mathlib (and which can be built from R sources).

User sometimes write code against this interface, and then want to combine the code with other code, possibly even with Rcpp. We allowed
for this, but it required a bit of an ugly interface. R provides a C interface; these have no namespaces. Identifiers can clash, and to be
safe one can enable a generic prefix Rf_. So functions which could clash such as length or error
become Rf_length and Rf_error and are less likely to conflict with symbols from other libraries. Unfortunately, the side-effect
is that calling, say, the probability distribution function for the Normal distribution becomes Rf_pnorm5() (with the 5
denoting the five parameters: quantile, mean, std.deviation, lowerTail, logValue). Not pretty, and not obvious.

So one of the things we added was another layer of indirection by adding a namespace R with a bunch of inline’d wrapper
functions (as well as several handful of unit tests to make sure we avoided typos and argument transposition and what not).

The short example below shows this for a simple function taking a vector, and returning its pnorm computed three different ways:

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::DataFrame mypnorm(Rcpp::NumericVector x) {
    int n = x.size();
    Rcpp::NumericVector y1(n), y2(n), y3(n);

    for (int i=0; i<n; i++) {

        // the way we used to do this
        y1[i] = ::Rf_pnorm5(x[i], 0.0, 1.0, 1, 0);

        // the way we can do it now
        y2[i] = R::pnorm(x[i], 0.0, 1.0, 1, 0);

    // or using Rcpp sugar in one go
    y3 = Rcpp::pnorm(x);

    return Rcpp::DataFrame::create(Rcpp::Named("Rold")  = y1,
                                   Rcpp::Named("Rnew")  = y2,
                                   Rcpp::Named("sugar") = y3);

This example also uses the new Rcpp attributes described briefly in the announcement blog post and of course in more detail in the
corresponding vignette. Let us just state here that we simply provide a complete C++ function, using standard Rcpp types — along with one
‘attribute’ declaration of an export via Rcpp. That’s it — even easier than using inline.

Now in R we simply do

R> sourceCpp("mypnorm.cpp")

to obtain a callable R function with the C++ code just shown behind it. No Makefile, no command-line tool invocation — nothing but a single
call to sourceCpp() which takes care of things — and brings us a compiled C++ function to R just given the source file with
its attribute declaration.

We can now use the new function to compute the probaility distribution both the old way, the new way with the ‘cleaner’
R::pnorm(), and of course the Rcpp sugar way in a single call. We build a data frame in C++, and assert that all
three variants are the same:

R> x <- seq(0, 1, length=1e3)
R> res <- mypnorm(x)
R> head(res)
      Rold     Rnew    sugar
1 0.500000 0.500000 0.500000
2 0.500399 0.500399 0.500399
3 0.500799 0.500799 0.500799
4 0.501198 0.501198 0.501198
5 0.501597 0.501597 0.501597
6 0.501997 0.501997 0.501997
R> all.equal(res[,1], res[,2], res[,3])
[1] TRUE

This example hopefully helped to illustrate how Rcpp 0.10.0 brings both something really powerful (Rcpp attributes — more on this another
time, hopefully) and convenient in the new namespace for statistical functions.

To leave a comment for the author, please follow the link and comment on their blog: Thinking inside the box .

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...

If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Comments are closed.


Mango solutions

RStudio homepage

Zero Inflated Models and Generalized Linear Mixed Models with R

Quantide: statistical consulting and training



CRC R books series

Contact us if you wish to help support R-bloggers, and place your banner here.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)