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
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
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