implementing apply function in Rcpp

前端 未结 2 1208
不思量自难忘°
不思量自难忘° 2021-01-13 18:38

I have been trying to implement apply function in Rcpp so far the code looks like this

//[[Rcpp::export]]
NumericVector apply(NumericMatrix x,int dim,Functio         


        
相关标签:
2条回答
  • 2021-01-13 18:42

    The answers are, in order, "yes" and "yes", and you may want to read the "Rcpp Introduction" which contains the following lapply() example:

    R> src <- '
    +   Rcpp::List input(data);
    +   Rcpp::Function f(fun);
    +   Rcpp::List output(input.size());
    +   std::transform(input.begin(), input.end(), output.begin(), f);
    +   output.names() = input.names();
    +   return output;
    +   '
    R> cpp_lapply <- cxxfunction(signature(data = "list", fun = "function"),
    +    src, plugin = "Rcpp")
    

    This was written for inline rather than Rcpp Attributes because that is how we rolled back in the day. We have more apply-alike functions in other examples and unit tests...

    You have not specified what arguments your function f() takes and returns which makes fixing your question a little trickier.

    0 讨论(0)
  • 2021-01-13 18:57

    There is no sugar function for apply. The easiest way of doing what you want is to call as<double>, i.e.:

    output[i]=as<double>(f(x(i,_)));
    

    You could also embed this in a type that would call as for you, something like:

    template <typename T>
    class F {
    public: 
      F( SEXP f_) : f(f_){}
    
      inline T operator()(NumericVector x){
        return as<T>(f(x)) ;  
      }
    
    private:
      Function f ;
    } ;
    

    so that you could do:

    // [[Rcpp::export]]
    NumericVector apply_cpp(NumericMatrix x,int dim,F<double> f){
      if(dim==1){
        NumericVector output(x.nrow());
        for(int i=0;i<x.nrow();i++){
          output[i]=f(x(i,_));
        } 
        return output ;
      }
      else {
        NumericVector output(x.ncol());
    
        for(int i=0;i<x.ncol();i++){
          output[i]=f(x(_,i));
        }  
        return output ;
      }
    } 
    

    The F template from above assumes that the function takes a NumericVector and returns something that can be converted to a double. You could also embed type information about both inputs and outputs. Something like this (expressed in C++11):

    template <typename T, typename... Args>
    class F {
    public: 
      F( SEXP f_) : f(f_){}
    
      inline T operator()(Args... args){
        return as<T>(f(args...)) ;  
      }
    
    private:
      Function f ;
    } ;
    

    Then the signature would become:

    // [[Rcpp::export]]
    NumericVector apply_cpp(NumericMatrix x,int dim,F<double,NumericVector> f){
    
    0 讨论(0)
提交回复
热议问题