R - use primitive functions like max(), sum() in Rcpp

房东的猫 提交于 2019-12-03 17:09:52

This is a perfect use case for Rcpp Sugar

http://dirk.eddelbuettel.com/code/rcpp/Rcpp-sugar.pdf

http://adv-r.had.co.nz/Rcpp.html#rcpp-sugar

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
NumericVector FFF(){
  NumericVector LB(3);
  LB[0] = max(NumericVector::create(12.3,1.2,13.3,34,10,12.45));
  LB[1] = min(NumericVector::create(12.31,1.24,13.35,340,109,121.45));
  LB[2] = sum(NumericVector::create(12.37,1.21,13.43,34));
  return LB;
}

I like Eigen:

// [[Rcpp::depends(RcppEigen)]]
#include <RcppEigen.h>
using namespace Rcpp;
using  Eigen::Map;
using  Eigen::VectorXd;
typedef  Map<VectorXd>  MapVecd;

// [[Rcpp::export]]
NumericVector RcppEigenFun(NumericVector xx) {
  const MapVecd x(as<MapVecd>(xx));
  NumericVector LB(3);
  LB[0] = x.minCoeff();
  LB[1] = x.maxCoeff();
  LB[2] = x.sum();
  return LB;
}

Using it:

RcppEigenFun(3:7)
#[1]  3  7 25

Here is the corresponding function that uses sugar:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector RcppFun(NumericVector x) {
  NumericVector LB(3);
  LB[0] = min(x);
  LB[1] = max(x);
  LB[2] = sum(x);
  return LB;
}

Benchmarks:

set.seed(42)
x <- rnorm(1e5)

library(microbenchmark)
microbenchmark(RcppEigenFun(x), RcppFun(x))

#Unit: microseconds
#            expr      min       lq   median        uq      max neval
# RcppEigenFun(x)  101.425  101.807  101.948  102.1785  123.095   100
#      RcppFun(x) 1480.187 1480.552 1480.889 1489.0045 1550.173   100
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!