[Rcpp-devel] Organization of C++ classes for glm families
Romain Francois
romain at r-enthusiasts.com
Tue Mar 16 23:28:21 CET 2010
Le 16/03/10 23:19, Romain Francois a écrit :
>
> 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
Last try, maybe something like this :
fx <- cfunction( signature(),
'
typedef pointer_to_unary_function <double,double> link_fun ;
link_fun* log_link = new link_fun(log);
Rcpp::XPtr<link_fun> xp( log_link, true );
return xp ;
', Rcpp = TRUE, includes =
c("using namespace Rcpp; ", "using namespace std;" ) )
> fx()
<pointer: 0x100584930>
... maybe when I wake up tomorrow, none of this will make sense
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