[Rcpp-devel] Organization of C++ classes for glm families
Douglas Bates
bates at stat.wisc.edu
Tue Mar 16 21:01:46 CET 2010
On Tue, Mar 16, 2010 at 2:00 PM, Douglas Bates <bates at stat.wisc.edu> wrote:
> In profiling some of the code for generalized linear mixed models I
> discovered that a considerable amount of the time was being taken up
> in evaluation of some of the functions in the glm family. Many of
> these functions in the family are candidates for a std::transform
> application
>
>> str(poisson())
> List of 12
> $ family : chr "poisson"
> $ link : chr "log"
> $ linkfun :function (mu)
> $ linkinv :function (eta)
> $ variance :function (mu)
> $ dev.resids:function (y, mu, wt)
> $ aic :function (y, n, mu, wt, dev)
> $ mu.eta :function (eta)
> $ initialize: expression({ ...
> $ validmu :function (mu)
> $ valideta :function (eta)
> $ simulate :function (object, nsim)
> - attr(*, "class")= chr "family"
>
> In most cases the time is taken in linkinv, variance and mu.eta.
>
> I do have one implementation of glm families in C++ in the lme4a
> package from the lme4 project on R-forge but that implementation is
> based on a complex set of concrete classes using virtual functions and
> doesn't take advantage of containers like std::vector or
> Rcpp::NumericVector.
>
> I think a more idiomatic C++ implementation would use containers and
> the std::transform algorithm. The characteristics like the linkfun,
> linkinv and mu.eta functions are associated with the link name ("log"
> in the example above).
>
> Would it be feasible to associate the scalar transformation function,
> in this case it would be the log function from the math library but in
> other cases it could be like
>
> double inverseLink(double x) {return 1/x;}
>
> with the name of the link. I would think of using a std::map for that
> but I don't know what the class or type of the "value" slot would be.
> Some exploration indicates that it may be a struct that is derived
> from the std::unary_function<double, double> but right now my head is
> beginning to hurt reading documentation. Could someone give me an
> example of how I would use, say, the exp or the log function in a
> std::transform?
>
> The second level would be to associate the scalar transformation
> function with the name, say in a std::map but first I need to make
> std::transform work with a scalar function.
To follow up on my own posting, the things I have tried are various versions on
cpp <- '
Rcpp::NumericVector xv(x);
Rcpp::NumericVector y(xv.size());
std::transform(xv.begin(), y.begin(), ll);
return y;
'
ff <- cfunction(signature(x = "numeric"), cpp, Rcpp = TRUE, verbose = FALSE,
otherdefs = "double ll(const double xx){return log(xx);}",
includes = "#include <cmath>")
which always produces an error of the form
:14: error: no matching function for call to ‘transform(double*,
double*, double (&)(double))’
I'm at the point one often gets to with a new language that my code
will not compile and I have no idea of how to fix it.
More information about the Rcpp-devel
mailing list