logo资料库

R 和 C,C++语言函数调用.pdf

第1页 / 共7页
第2页 / 共7页
第3页 / 共7页
第4页 / 共7页
第5页 / 共7页
第6页 / 共7页
第7页 / 共7页
资料共7页,全文预览结束
机器学习与数据挖掘重点实验室 R 和 C 语言、C++ 语言函数调用 -----开发平台建设·基础篇(6) 机器学习与数据挖掘重点实验室 刘江伟 (majorliujw◎gmail.com) 2014-5-18 实验说明 关键词:R; C;C++;DLL;编译运行效率;.Call ;Rcpp 包;inline 包 摘 要: 1)如何 用 R 调用 C 函数,使底层运算(如循环等)速度加快。 2)R 和 C++各自优势如何对接起来(如 R 的矩阵运算,向量运算以及各种统计算法等;C++ 的底层运算速度,标准库函数 STL 等)。 3)本实验以操作为主。 实验一:R 语言和 C 语言 函数调用 实验目的:如何 用 R 调用 C 函数,使底层运算(如循环等)速度加快。 1.下载 Rtools: (如 Rtools30.exe); 2.添加环境变量 path: 添加 R 环境变量:
机器学习与数据挖掘重点实验室 D:\Program Files\R\R-3.0.2\bin\i386(要用到这个路径下的 Rcmd.exe) 添加 RTools 环境变量: D:\Program Files\Rtools\bin; D:\Program Files\Rtools\gcc-4.6.3\bin 配置完后,在 CMD 窗口输入以后命令,用来测试环境变量是否 OK! gcc --help Rcmd Rcmd SHLIB --help 3.编写 testR.c 文件: R 和 C 传递数据都是指针形式。 其中数据类型对应如下: testR.c 文件 ///////////////////////////////////////////////////////////////////// /////////////////////////////// #include void myadd(double *a, double *b, double *c) { *c=*a+*b; } void myprint(const char **msg){ Rprintf("msg is: %s",*msg); } //double 型数据 void myMultiAdd1 (double *n, double *prod, const char **msg) {
机器学习与数据挖掘重点实验室 * prod=0; int i,j,k; for(i=1;i<=*n;i++) for(j=1;j<=*n;j++) for(k=1;k<=*n;k++) *prod=*prod+(i+j+k); Rprintf("%s 说,%f 以内所有数(可重复)相加的结果 是: %f\n",*msg,*n,*prod); } //只是换数据类型;测试数据比较大时,可以用 long int,或者 long long int void myMultiAdd2 (int *n, long long int *prod, const char **msg) { *prod=0; int i,j,k; for(i=1;i<=*n;i++) for(j=1;j<=*n;j++) for(k=1;k<=*n;k++) *prod=*prod+(i+j+k); Rprintf("%s 说,%d 以内所有数(可重复)相加的结果 是: %d\n",*msg,*n,*prod); } ///////////////////////////////////////////////////////////////////// /////////////////////////////// 4.生成 dll: 把 testR.c 放到 F 某个盘文件夹下,windows cmd cd 到这个文件夹去 Rcmd SHLIB testR.c 命令,生成 testR.dll 和 testR.o 两个文件。 .dll 文件成 功生成~~ 把 testR.dll 拷贝到你的 R 工程目录 5.R 文件中测试及调用: RC.R 文件 ################################################# ## R 调用 C 函数方法 ## 优点:C 运行时间大大减少;特别是循环之类的情况。 ## C 编译 DLL 命令: Rcmd SHLIB testR.c ################################################## ##-----------------------R 循环函数-------------------------- myMultiAdd<-function(n){ num=0; for(i in 1:n) for (j in 1:n) for (k in 1:n) { num=num+(i+j+k);
机器学习与数据挖掘重点实验室 } cat("R 的循环结果为:",num,"\n"); } #myMultiAdd(3) #测试 #加载动态链接库 dyn.load('testR.dll') ##-----------------简单函数调用--------------- .C("myadd", as.numeric(1.2),as.numeric(3.4),as.numeric(1)) .C("myprint", as.character("hello, world")) ##-----------------注意数据类型--------------- #R 默认的数据类型是 double .C("myMultiAdd1",a1=3,b1=0,c1="Master1") #以整数调用;注意 C 函数的整型数据表示范围, a2=as.integer(3); b2=as.integer(0); .C("myMultiAdd2",a2,b2,c2="Master2") ##-----------------测试时间,C 和 R 时间差别--------------- system.time(myMultiAdd(150)) a2=as.integer(150); b2=as.integer(0); system.time(.C("myMultiAdd2",a2,b2,c2="C 语的结果")) #卸载动态链接库 dyn.unload("testR.dll") 6.主要循环时间对比: 通过一个三重循环对比了 R 和 C 的运行时间,R 大约是 8 秒多,C 函数大约 0.02
秒,如图所示。 机器学习与数据挖掘重点实验室 实验二:R 语言和 C++ 语言 函数调用 实验目的: 1)R 和 C++各自优势如何对接起来(如 R 的矩阵运算,向量运算以及各种统计算法等;C++ 的底层运算速度,标准库函数 STL 等) 。安装 RTools 之后,自动安装了 g++编译器,直接 使用 RStudio 编写,C++ code 和 R code。 2).Call ;Rcpp 包;inline 包 3)本次试验以操作为主 方式一:Rcpp API 方式调用 (library("Rcpp"))。 -----------------// C++ code 开始---------------------------- //Rcpp API 方式调用 #include RcppExport SEXP convolve3cpp(SEXP a, SEXP b) { Rcpp::NumericVector xa(a); Rcpp::NumericVector xb(b); int n_xa = xa.size(), n_xb = xb.size(); int nab = n_xa + n_xb - 1; Rcpp::NumericVector xab(nab); for (int i = 0; i < n_xa; i++)
机器学习与数据挖掘重点实验室 for (int j = 0; j < n_xb; j++) xab[i + j] += xa[i] * xb[j]; return xab; } -----------------------// C++ code 结束-------------------------- -----------------# Rcode 开始---------------------------- #Rcpp API 方式调用 library("Rcpp"); ##Rcpp API 方式调用 f3 <- function(x,y) .Call("convolve3cpp", x,y); f3(1:3,1:4) -----------------------# R code 结束-------------------------- 方式二:直接在 R 中嵌入 C++代码(使用到了 inline 包)。 ##-----------------------------------------------inline 方式 开始 ----------------------------------------------- src<-' Rcpp::NumericVector xa(a); Rcpp::NumericVector xb(b); int n_xa = xa.size(), n_xb = xb.size(); int nab = n_xa + n_xb - 1; Rcpp::NumericVector xab(nab); for (int i = 0; i < n_xa; i++) for (int j = 0; j < n_xb; j++) xab[i + j] += xa[i] * xb[j]; //注意是"+=" return xab; ' ; # cxxfunction(provided by the inline package), fun <- cxxfunction(signature(a = "numeric", b = "numeric"), src, plugin = "Rcpp") fun(1:3, 1:4) #结果是 [1] 1 4 10 16 17 12 ##—————Using Standard Template Library algorithms————————— # 用 STL 库中的 transform 模拟 R 中的 lapply 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; ' ; cpp_lapply <- cxxfunction(signature(data = "list", fun = "function"), src, plugin = "Rcpp") ## 用 R 中的 faithful 数据集测试;summary 查看数据集 cpp_lapply(faithful, summary) #-----------------------------------------------------------inline 方 式 结束 -------------------------------------------- 参考文献 [1] Rcpp: Seamless R and C++ Integration ver.2014 [2] 网络资源
分享到:
收藏