楼主: 天狮
20727 22

[有偿编程] 关于R和C的混合编程 [推广有奖]

  • 1关注
  • 10粉丝

已卖:3425份资源

教授

34%

还不是VIP/贵宾

-

威望
1
论坛币
6260 个
通用积分
354.9819
学术水平
20 点
热心指数
35 点
信用等级
13 点
经验
18386 点
帖子
1396
精华
0
在线时间
533 小时
注册时间
2008-10-10
最后登录
2025-9-4

楼主
天狮 发表于 2011-6-28 22:25:26 |AI写论文
10论坛币
因为R是解释类型语言,所以考虑到效率问题我们多采用主要部分用R、迭代部分用C。但是我不知道如何将R和C进行混合编程。
譬如我们求1+2^3+3^3+4^3+....+n^3 (当然这个用R的向量计算也相当方便),我们可以很容易地写出用R循环来计算该问题的代码。
sum=function(n){
for(i in 1:n)
循环部分
}

下面我们写出用C来计算循环
#include<stdio.h>
main()
{int sum=0,n,i;
scanf("%d",&n);
for(i=1;i<=n;i++)
sum+=i*i*i;
printf("\n%d",sum);
getch();
}
我们将上面的c代码命名为sum.c
我电脑上只安装了win-TC,上述代码运行通过(我输入3,返回36),并且产生了三个文件,分别是:
sum.c和sum.exe及sum.obj
好了,现在我的问题就是如何将c嵌入到R中去代替R的循环计算。
希望高手解答,以便以后碰到更复杂的循环可以节省大量时间,R有时候还是稍显慢。

最佳答案

epoh 查看完整内容

1.你可选择自行安装MinGW (GCC) Compiler http://www.mingw.org/wiki/InstallationHOWTOforMinGW 也可选择安装 Rtools (建议) http://www.murdoch-sutherland.com/Rtools/index.html 2. C:/Users/lenovo/Documents 建立文件夹convolve,放入文件convolve.c 然后在R运行: ############ setwd('C:/Users/lenovo/Documents/convolve') system("R CMD SHLIB convolve.c") #产生两个文件convolve.dll,convo ...
关键词:混合编程 function include scan Main function include 我不知道 如何

本帖被以下文库推荐

沙发
epoh 发表于 2011-6-28 22:25:27
1.你可选择自行安装MinGW (GCC) Compiler
   http://www.mingw.org/wiki/InstallationHOWTOforMinGW
  也可选择安装 Rtools (建议)
   http://www.murdoch-sutherland.com/Rtools/index.html


2. C:/Users/lenovo/Documents

建立文件夹convolve,放入文件convolve.c

然后在R运行:
############
setwd('C:/Users/lenovo/Documents/convolve')
system("R CMD SHLIB convolve.c")  #产生两个文件convolve.dll,convolve.o
                                  #windows 用到convolve.dll

dyn.load("convolve.dll")
conv <- function(a, b){
.C("convolve",
as.double(a), as.integer(length(a)),
as.double(b), as.integer(length(b)),
ab=double(length(a)+length(b)-1))$ab
}
a=3
b=4
conv(a,b)

##########
convolve.c, convolve.dll
convolve.rar (3.2 KB)

藤椅
ltx5151 发表于 2011-6-28 23:49:54
R中自带的两个函数.c()  .call()可以用来处理LZ想运行的C函数,两者的使用略有差别。比如lz可以另加一个wrapper函数,其中的变量类型用C和R接口的变量类型(具体参见CRAN manual),用这个函数来调用你写好的C函数。在R中运行的时候,通过.call()在R中调用wrapper函数。wrapper的作用主要就是让R和C函数中的变量可以相互转换使用,相当于一个接口。头文件可能需要稍做改动。

另外,更简单的方式是用package Rcpp 。 这个包绝对是一个非常出色的产品,LZ可以下载来看看,可以用于C或C++。

关于你所说的三个文件,在用上述方式调用的时候,不会产生exe等文件,你要做的就是有源文件即可。编译的工作由R调用你系统下的C编译器运行,结果直接返回R。我不用windows,不清楚在windows下面跑对编译器有没有什么特殊要求,但是常用的编译器应该可以正常工作。
已有 2 人评分论坛币 学术水平 热心指数 信用等级 收起 理由
zhangtao + 5 + 5 + 5 我很赞同
liuzhenzhu + 10 + 2 + 1 热心帮助其他会员

总评分: 论坛币 + 10  学术水平 + 7  热心指数 + 6  信用等级 + 5   查看全部评分

板凳
soccy 发表于 2011-6-29 00:38:52
只能用GCC。

报纸
zhangtao 发表于 2011-6-29 21:55:17
版主正解,Rcpp有PDF帮助文件,看完就会了。
数学好就是要天天学

地板
天狮 发表于 2011-6-30 00:51:03
首先感谢版主ltx5151 。但是我给出具体例子的初衷还是想请教高人结合具体例子给出详细操作,我也有看过不少资料,其中李东风书上给出了一个计算卷积的例子,算是写的比较详细的。但是我不知道“C程序编译成了一个DLL库testdll.dll放在当前工作目录中”这句话,因为后面好像要用到testdll.dll。我用Win-TC编译C源程序得到了sum.c、sum.exe和sum.obj三个文件(就上面例子而言),并没有什么.dll文件啊。所以,我还是等等看。谨再谢!

7
天狮 发表于 2011-6-30 00:53:45
我把它们贴出来吧
C计算卷积的源程序为:
void convolve(double *a, int *na,
double *b, int *nb, double *ab){
int i, j, nab = *na + *nb - 1;
for(i = 0; i < nab; i++)
ab[i] = 0.0;
for(i = 0; i < *na; i++)
for(j = 0; j < *nb; j++)
ab[i + j] += a[i] * b[j];
}
为了在R中调用这个C函数需要如下步骤:
conv <- function(a, b){
dll.filename <-
file.path(paste("testdll",
.Platform$dynlib.ext, sep=""))
if(!is.loaded(symbol.C("convolve"),
PACKAGE="testdll")){
dyn.load(dll.filename)
}
.C("convolve",
as.double(a), as.integer(length(a)),
as.double(b), as.integer(length(b)),
ab=double(length(a)+length(b)-1))$ab
}

8
天狮 发表于 2011-6-30 00:55:00
是不是要用什么特别的C编辑器才能产生dll文件?

9
天狮 发表于 2011-6-30 01:00:42
把R里面运行的结果也贴出来吧:
> conv <- function(a, b){
+ dll.filename <-
+ file.path(paste("testdll",
+ .Platform$dynlib.ext, sep=""))
+ if(!is.loaded(symbol.C("convolve"),
+ PACKAGE="testdll")){
+ dyn.load(dll.filename)
+ }
+ .C("convolve",
+ as.double(a), as.integer(length(a)),
+ as.double(b), as.integer(length(b)),
+ ab=double(length(a)+length(b)-1))$ab
+ }
> a=3
> b=4
> conv(a,b)
symbol.C("convolve")里有警告:
  'symbol.C' is not needed: please remove it
错误于inDL(x, as.logical(local), as.logical(now), ...) :
  无法载入共享目标对象‘C:/Users/lenovo/Documents/testdll.dll’::
  LoadLibrary failure:  找不到指定的模块。
>

10
epoh 发表于 2011-6-30 10:09:34
1.你可选择自行安装MinGW (GCC) Compiler
   http://www.mingw.org/wiki/InstallationHOWTOforMinGW
  也可选择安装 Rtools (建议)
   http://www.murdoch-sutherland.com/Rtools/index.html


2. C:/Users/lenovo/Documents

建立文件夹convolve,放入文件convolve.c

然后在R运行:
###########
setwd('C:/Users/lenovo/Documents/convolve')
system("R CMD SHLIB convolve.c")  #产生两个文件convolve.dll,convolve.o
                                  #windows 用到convolve.dll
dyn.load("convolve.dll")
conv <- function(a, b){
.C("convolve",
as.double(a), as.integer(length(a)),
as.double(b), as.integer(length(b)),
ab=double(length(a)+length(b)-1))$ab
}
a=3
b=4
conv(a,b)
###########




已有 2 人评分学术水平 热心指数 信用等级 收起 理由
tulipsliu + 5 + 5 + 5 精彩帖子epoh不愧是论坛第一大神
zhangtao + 5 + 5 + 5 我很赞同

总评分: 学术水平 + 10  热心指数 + 10  信用等级 + 10   查看全部评分

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-22 22:34