dimanche 14 novembre 2021

Extend sum function implementation Rcpp

I have a sum function written in Rcpp. It works on numeric data. I am trying to extend it to work on lists datatype(in R).

R version: R-3.5.3 (Rtools35, mingw_64 c++11 compiler)

library('Rcpp')
library('RcppArmadillo')
    
cppFunction('double sumCPP(arma::vec& obj){
  // Input
  // Numeric vector : Integer / Double: 
    // sumCPP(c(1L, 6L, 10L))
    // sumCPP(c(1L, 6.5, 10L))
    // sumCPP(c(1, 6, 10))

  double result;
  result = arma::accu(obj);
  return result;
}',depends="RcppArmadillo")

Output:

> sumCPP(c(1L, 6L, 10L))
[1] 17

list data (using education expenditure data set)

education <- read.csv("https://vincentarelbundock.github.io/Rdatasets/csv/robustbase/education.csv", stringsAsFactors = FALSE)
colnames(education) <- c("X","State","Region","Urban.Population","Per.Capita.Income","Minor.Population","Education.Expenditures")
education['Minor.Population']

Result from the inbuilt sum function in R

> sum(education['Minor.Population'])
[1] 16287

My sum function implementation in Rcpp and RcppArmadillo

Error in sumCPP(education["Minor.Population"]) : 
  Not compatible with requested type: [type=list; target=double].

I came across a workaround, but this would require knowing the type beforehand and I am not planning to use this.

> sumCPP(unlist(education['Minor.Population']))
[1] 16287

I don't have much experience with C++ but here is the pseudocode. The parameter to the sumV2CPP function(trying to use c++ stl to create a general function) can be numeric data or list(VECSXP type). Then I use typeid to find the type of input and do the sum in the if else condition. Can someone help with this.

cppFunction('double sumV2CPP(pass_paramater_here){
  #include <typeinfo>

  template <typename T>
  std::string the_type(T a_variable) {
      
      std::double result;
      
      if (typeid(T) == typeid(arma::vec)) {
      // calculate interger/double vector sum
              result = arma::accu(obj);
      } else if(typeid(T) == typeid(Rcpp::List)) {
      // calculate list sum with for loop
              result = list_sum; 
          }
      }
      return result;
}', depends="RcppArmadillo")

Aucun commentaire:

Enregistrer un commentaire