Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 运行编译的C++;带Rcpp的代码_C++_R_Rcpp - Fatal编程技术网

C++ 运行编译的C++;带Rcpp的代码

C++ 运行编译的C++;带Rcpp的代码,c++,r,rcpp,C++,R,Rcpp,我一直在学习Dirk Eddelbuettel的Rcpp教程: 我已经学会如何保存一个目录中的C++文件并调用它,并从R中运行它。我运行的C++文件叫做“Logab2.2. CCP”,它的内容直接来自Dirk的幻灯片之一: #include <Rcpp.h> using namespace Rcpp; inline double f(double x) { return ::log(::fabs(x)); } // [[Rcpp::export]] std::vector&l

我一直在学习Dirk Eddelbuettel的
Rcpp
教程:

<>我已经学会如何保存一个目录中的C++文件并调用它,并从R中运行它。我运行的C++文件叫做“Logab2.2. CCP”,它的内容直接来自Dirk的幻灯片之一:

#include <Rcpp.h>

using namespace Rcpp;

inline double f(double x) { return ::log(::fabs(x)); }

// [[Rcpp::export]]
std::vector<double> logabs2(std::vector<double> x) {
    std::transform(x.begin(), x.end(), x.begin(), f);
    return x;
}
我在Windows7机器上运行的代码来自默认安装的R GUI。我还安装了最新版本的
Rtools
。上面的R代码似乎需要相对较长的时间才能运行。我猜想大部分时间都是用来编译C++代码的,一旦C++代码被编译,它运行得就非常快。code>Microbenchmark显然表明
Rcpp
减少了计算时间

<>我以前从未使用过C++,但是我知道当我编译C代码时,我得到了一个*.exe文件。我从名为
logabs2.exe的文件中搜索了我的硬盘,但找不到。我想知道上面的C++代码是否可能运行得更快,如果创建了<代码> LogABS2.exe < /C>文件。是否可以创建一个
logabs2.exe
文件并将其存储在某个文件夹中,然后让Rcpp随时调用该文件?我不知道这是否有道理。如果我可以在**exe文件中存储C++函数,那么也许每次我想用RCPP使用它时,我就不必编译函数,那么RCPP代码可能会更快。 对不起,如果这个问题没有意义或重复。如果可以将C++函数存储为*.exe文件,我希望有人会告诉我如何修改上面的R代码来运行它。谢谢你在这方面的任何帮助,或者让我明白为什么我的建议不可能或不被推荐

我期待着看德克的新书。

你说呢

我以前从来没有使用过C++,但是我知道编译C代码时 我得到一个*.exe文件

如果并且只有您构建了一个可执行文件,这才是真的。在这里,我们构建了可动态加载的库,这些库根据操作系统的不同而具有不同的扩展名:.dll用于Windoze,.so用于Linux,.dynlib用于OS X


所以这里没有错,你只是有一个错误的假设

如果你想得到一些可以保留的实体,你需要的是一个
R
包。网上有很多资源可以学习如何制作它们(例如)

我们有
Rcpp.package.skeleton
您可能会发现它很有用


因此,在安装包时,函数只需编译一次,然后您就可以使用它了

感谢user1981275、Dirk Eddelbuettel和Romain Francois的回复。下面是我编译C++文件并创建**dll的方法,然后调用并使用*.dll文件在<代码> r>代码> < /p> 第一步。我创建了一个名为“c:\users\mmiller21\myrpackages”的新文件夹,并将文件“logabs2.cpp”粘贴到该新文件夹中。“logabs2.cpp”文件是按照我的原始帖子中的描述创建的

第二步。在新文件夹中,我使用我编写的名为“new package creation.R”的
R
文件创建了一个名为“logabs2”的新
R
包。“新建包创建.r”的内容包括:

setwd('c:/users/mmiller21/myrpackages/')

library(Rcpp)

Rcpp.package.skeleton("logabs2", example_code = FALSE, cpp_files = c("logabs2.cpp"))
我在Hadley Wickham的一个网站上找到了
Rcpp.package.skeleton
的上述语法:

第三步。我使用DOS命令窗口中的以下行在
R
中安装了新的
R
包“logabs2”:

C:\Program Files\R\R-3.0.1\bin\x64>R CMD INSTALL -l c:\users\mmiller21\documents\r\win-library\3.0\ c:\users\mmiller21\myrpackages\logabs2
其中:

rcmd.exe文件的位置为:

C:\Program Files\R\R-3.0.1\bin\x64>
我的计算机上已安装的
R
软件包的位置是:

c:\users\mmiller21\documents\r\win-library\3.0\
我的新
R
软件包在安装前的位置是:

c:\users\mmiller21\myrpackages\
DOS命令窗口中使用的语法是通过反复试验发现的,可能并不理想。在某个时候,我在“C:\Program Files\R\R-3.0.1\bin\x64>”中粘贴了一份“logabs2.cpp”,但我认为这并不重要

第四步。安装新的
R
软件包后,我使用一个名为“new package usage.R”的
R
文件运行它,该文件位于“c:/users/mmiller21/myrpackages/”文件夹中(尽管我认为该文件夹并不重要)。“new package usage.r”的内容包括:

library(logabs2)
logabs2(seq(-5, 5, by=2))
结果是:

# [1] 1.609438 1.098612 0.000000 0.000000 1.098612 1.609438
此文件在我未询问的情况下加载了包
Rcpp

在这种情况下,如果我做得正确,base
R
更快

#> microbenchmark(logabs2(seq(-5, 5, by=2)), times = 100)
#Unit: microseconds
#                        expr    min     lq  median     uq     max neval
# logabs2(seq(-5, 5, by = 2)) 43.086 44.453 50.6075 69.756 190.803   100

#> microbenchmark(log(abs(seq(-5, 5, by=2))), times=100)
#Unit: microseconds
#                         expr    min     lq median    uq     max neval
# log(abs(seq(-5, 5, by = 2))) 38.298 38.982 39.666 40.35 173.023   100
但是,使用dll文件比调用外部cpp文件更快:

system.time(

cppFunction("
NumericVector logabs(NumericVector x) {
    return log(abs(x));
}
")

)

#   user  system elapsed 
#   0.06    0.08    5.85 
虽然在本例中,base R似乎更快或与*.dll文件一样快,但我毫不怀疑,在大多数情况下,将*.dll文件与
Rcpp
一起使用将比base
R
更快

这是我第一次尝试创建R包或使用Rcpp,毫无疑问,我没有使用最有效的方法。另外,我为这篇文章中的任何印刷错误道歉

编辑

在下面的评论中,我认为Romain Francois建议我将*.cpp文件修改为以下内容:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]

NumericVector logabs(NumericVector x) {
return log(abs(x));
}
基本
R
仍然稍微快一点,或者没有什么不同:

Unit: microseconds
                         expr    min     lq median     uq       max neval
   logabs(seq(-5, 5, by = 2)) 42.401 45.137 46.505 69.073 39754.598 1e+05
 log(abs(seq(-5, 5, by = 2))) 37.614 40.350 41.718 62.234  3422.133 1e+05

这可能是因为base
R
已经矢量化了。我怀疑对于更复杂的函数base
R
会慢得多。或者我仍然没有使用最有效的方法,或者我只是在某个地方犯了一个错误。

您看过命令
R CMD SHLIB
?这样你就可以编译你的C++函数到一个DLL文件,然后用<代码> Dyn。有关详细信息,请查看
?SHLIB
?dyn.load
@user1981275感谢您的评论。到目前为止,我已经做到了这一点:C:\ProgramFiles\R\R-3.0.1\bin\x64>rcmd SHLIB-o C:\users\mmiller21\documents\R\win library\3.0\rcpp\include\logabs2.dll C:\users\mmiller21\documents\R\win library\3.0\rcpp\include\logabs2.cpp我得到了以下消息:make:**无规则生成目标'c:\users\mmiller21\documents\r\win library\3.0\rcpp\include\logabs2.o',n
library(logabs)

logabs(seq(-5, 5, by=2))
log(abs(seq(-5, 5, by=2)))

library(microbenchmark)

microbenchmark(logabs(seq(-5, 5, by=2)), log(abs(seq(-5, 5, by=2))), times = 100000)
Unit: microseconds
                         expr    min     lq median     uq       max neval
   logabs(seq(-5, 5, by = 2)) 42.401 45.137 46.505 69.073 39754.598 1e+05
 log(abs(seq(-5, 5, by = 2))) 37.614 40.350 41.718 62.234  3422.133 1e+05