[Rcpp-devel] type information about elements in Rcpp::List

Bob Carpenter carp at alias-i.com
Thu May 10 00:59:31 CEST 2012


This list is really helpful!   Comments inline below.
There aren't any questions -- just more of an explanation
of what we're trying to do.

On 5/9/12 6:19 PM, Steve Lianoglou wrote:

> On Wed, May 9, 2012 at 5:34 PM, Jiqiang Guo<guojq28 at gmail.com>  wrote:

>> As Dirk previously points out, every element of Rcpp::List is of type SEXP.
>>   So I looked at
>> some R's doc, we should be able to get information (attributes in R's term:
>> int or real, names, dims)
>> from the SEXP at least using R's C functions such as examples at
>> http://cran.r-project.org/doc/manuals/R-exts.html#Attributes
>> and the functions used in Dirk's example.
>
> Assuming I'm following along here:
>
> As someone who trusts my R skills much more than my C(++) ones,

We're in the opposite camp!

Let me try to explain what we're doing a bit more thoroughly.

We have an MCMC sampler written in C++, where models get
written in a BUGS/JAGS-like language.  We want to produce
an R interface very much like R2WinBUGS or R2jags that
takes a model specification, data, optionally initial values,
and returns a Coda-like object for the samples.  From the R
side, the call would look something like this:

    fit <-
    stan(model, data, inits, ...);

When we mentioned this, everyone we talked to said "use Rcpp".
So that's what we're trying to do.

All of our functionality exists in C++.  The question at
hand is how we are going to get data out of the data list
(or inits list) and into C++.  Because our sampling language
is strongly typed, we know the dimensionality of all of
our variables and the integer/real type distinction before
we read them in.  But nothing on the R side knows anything
about what's going to happen with the model.

We also plan to to implement the Coda-like fit object
in C++ for the return value.  Rcpp modules look perfect
for that.  We also want to use it in Python and
Matlab interfaces and the computations will be easier
for *us* to write, test and maintain in C++.  And it'll
probably be faster than what *we* could come up with in R.

Let's say we have a model to fit a univariate normal location and
scale parameter mu and sigma and we have N observations.
The model will look like:

   data {
     int(0,) N;
     real y[N];
   }
   parameters {
     real mu;
     real(0,) sigma;
   }
   model {
     for (n in 1:N)
       y[n] ~ normal(mu,sigma);
   }

(Yes, we allow improper priors like in this model; we
could also add priors for mu and sigma.)

We compile this model to C++, then compile the C++.
The compiled model knows about its data types.
Jiqiang has the compilation and dynamic loading working.

The call to stan() from R then calls a C++ program
passing in an Rcpp::List for the data and optionally for inits.
 From C++, we're going to want to read the value of "N"
out of the list into an integer and the value of "y" out
of it and read it into a size N vector.  We want to
check the types are right on the R side and halt with
an error message if they're not.

In general, we allow basic values as well as
arbitrarily dimensioned arrays of continuous or integer
values (double and long, specifically).

So if we can get the dims and values, we're home free.

After the last bit of advice from Dirk and Jiqiang's
diving into the SEXP doc, I think we have enough to
do it.

 > I feel
> like I'd jimmy this scenario into one which I'd do the "heavy lifting"
> of type-checking the elements of a list and dispatching them to
> appropriate C++ code given their class in R, then collate the results
> back in R.

I don't think we can do that because R doesn't
know about the types.

> (assuming the looping in R won't kill you, speedwise).

Speed's not an issue.  This is for reading data and initial
values into an MCMC simulation that will take way more time overall
than the data reads, even if they have to go through R.

> Know what I mean?
>
> For instance, I'd have some R function that takes the list and directs traffic:
>
> theFunction<- function(x) {
>    stopifnot(inherits(x, "list"))
>    result<- sapply(x, function(xx) {
>      cpp.fun.name<- paste("theFunction", class(xx), sep="_")
>      ## Check cpp.fun.name to make sure it's a valid function
>      ## you defined in your C++ code, else raise an error about
>      ## unsupported class
>      .Call(cpp.fun.name, xx, PACKAGE="yourpackage")
>    }, USE.NAMES=TRUE)
>
> And you'd have suitable functions defined in your C++ side for the
> different types of things you want to support, ie:
>
> RcppExport SEXP theFunction_integer(SEXP xx);
> RcppExport SEXP theFunction_numeric(SEXP xx);
> RcppExport SEXP theFunction_character(SEXP xx);
>
> and so on ...

We don't have a set of functions pre-packaged like this, so I
don't think this'll work for us.  If we did, this would be much
easier.

Thanks again for all the help.  We really appreciate it.

- Bob






More information about the Rcpp-devel mailing list