[Rcpp-devel] Organization of C++ classes for glm families

Romain Francois romain.francois at dbmail.com
Tue Mar 16 23:19:55 CET 2010


Le 16/03/10 22:09, Douglas Bates a écrit :
>
> On Tue, Mar 16, 2010 at 3:24 PM, Dirk Eddelbuettel<edd at debian.org>  wrote:
>
>> That's an interesting problem.  AFAICT folks prefer iterators and transform()
>> and its ilk because it allows you to swap vector() for, say, list() with minimal
>> fuss.  It is less clear that you pick up speed that way.  Wouldn't the cost
>> of log() dominate the looping, whether it's old school C style or via iterators?
>
> I was not sufficiently explicit.  The large amounts of time spent in
> evaluating the inverse link and things like that are in the R
> versions.   They use R constructions like
>
>> poisson()$linkinv
> function (eta)
> pmax(exp(eta), .Machine$double.eps)
> <environment: 0x1c435e0>
>
> and it is (or, at least, was) the calls to pmax, pmin, etc. that
> gobbled up the time.
>
> Several years ago I wrote C code using .Call for the usual link
> functions in the binomial family, just to speed up such cases.  For
> example, the default link for the binomial is
>
>> binomial()$linkinv
> function (eta)
> .Call("logit_linkinv", eta, PACKAGE = "stats")
> <environment: 0x1c4b9e0>
>
> Using Rcpp I could certainly extract the R function from the family
> and set up the call but for the heavily used families I would prefer
> to set up a way to recognize the link name and use compiled code.
>
> In any case I now have code that seems to work
>
> otherd<- '
> '
> bod<- '
>    Rcpp::NumericVector xv(x);
>    Rcpp::NumericVector y(xv.size());
>
>    std::map<std::string, double(*)(double)>  lst;
>    lst["log"] =&log;
>    std::transform(xv.begin(), xv.end(), y.begin(), *(lst["log"]));
>    return y;
> '
> ff<- cfunction(signature(x = "numeric"), bod, Rcpp = TRUE, verbose = FALSE,
>                  otherdefs = otherd, includes = "#include<cmath>")

It seems you answered your own questions ?

Maybe it is worth investigating external pointers, which would offer a 
way to have some handle on the function pointer &log from the R side.

We have Rcpp::XPtr for that, but I'm not sure right now what the right 
incantation would be to hold function pointers

(... time passes ...) Maybe it would be easier to wrap the function into 
an std::unary_function<double,double> ..

(I need to think about this in the morning, with fresh coffee).

Romain

-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://tr.im/OIXN : raster images and RImageJ
|- http://tr.im/OcQe : Rcpp 0.7.7
`- http://tr.im/O1wO : highlight 0.1-5




More information about the Rcpp-devel mailing list