标签: rcpp

为什么这种天真的矩阵乘法比基数R更快?

在R中,矩阵乘法非常优化,即实际上只是对BLAS/LAPACK的调用.但是,我很惊讶这个非常天真的C++代码用于矩阵向量乘法似乎可靠地快了30%.

 library(Rcpp)

 # Simple C++ code for matrix multiplication
 mm_code = 
 "NumericVector my_mm(NumericMatrix m, NumericVector v){
   int nRow = m.rows();
   int nCol = m.cols();
   NumericVector ans(nRow);
   double v_j;
   for(int j = 0; j < nCol; j++){
     v_j = v[j];
     for(int i = 0; i < nRow; i++){
       ans[i] += m(i,j) * v_j;
     }
   }
   return(ans);
 }
 "
 # Compiling
 my_mm = cppFunction(code = mm_code)

 # Simulating data to use
 nRow = 10^4
 nCol = 10^4

 m = matrix(rnorm(nRow * nCol), …
Run Code Online (Sandbox Code Playgroud)

performance r matrix-multiplication rcpp

29
推荐指数
2
解决办法
1452
查看次数

Rcpp的基本文档

我想研究一下rcpp,以提高我的一些R代码的速度,而不必诉诸凌乱的C++代码(我已经取得了一些成功,但它看起来像是来自地狱的代码).

因此,我检查了Rcpp提供的文档,以及Dirk Eddelbuettel网站上提供的文档包.我安装并查看了RcppExamples,但是(至少从它的文档中)大多数都引用了RcppClassic?.除此之外,我做了一些谷歌搜索,但这并没有导致看起来像基本问题的答案.

  • Rcpp中的索引是从零开始还是从一开始工作
  • 名单同时提供了operator()operator[],但显然不是 operator[[]].目前尚不清楚哪些[][[]]R 相似.
  • 是否有任何支持Rcpp的因素(似乎没有)?

注意:事实上我从Rcpp-introduction.pdf的第一个例子中找到了一些答案,但这感觉就像运气.

此外,我stl非常生疏,所以如果有人能给我一个简单的例子,其中List的每个元素都是(例如)print-ed与stl风格的循环,那将是整洁的.

如果有人想因为没有找到这些信息而称我为白痴:继续前进,让你的一天.然后制作我的并指向我需要的文档:-)

作为对Eddelbuettel先生和其他Rcpp作者的建议(我希望他们中的一些人能够读到这一点):doxygen提供的类层次结构等,当你已经深入Rcpp时,它真的很整洁,但对于初学者来说(在Rcpp),我更感兴趣的是这个类中的这个方法的列表就像R中的那个函数一样,而不是'你可以在这个头文件中找到这个运算符的声明'.毕竟,我理解Rcpp的目标之一是降低在R中使用C++的门槛?注意:从我所看到和理解的内容来看,我非常重视Rcpp的实际代码,并对其创建者表示最高的敬意.如果缺乏基本文档仅仅是"缺乏资源"的结果,我愿意成为一种资源(例如:一旦我自己完成了"基本"文档的工作).

r rcpp

27
推荐指数
1
解决办法
1947
查看次数

在OS X上分析Rcpp代码

我有兴趣在OS X(Mountain Lion 10.8.2)下分析一些Rcpp代码,但是分析器在运行时崩溃了.

玩具示例,使用inline,只是为了让探查器注意到足够的时间.

library(Rcpp)
library(inline)

src.cpp <- "
  RNGScope scope;
  int n = as<int>(n_);
  double x = 0.0;
  for ( int i = 0; i < n; i++ )
    x += (unif_rand()-.5);
  return wrap(x);"

src.c <- "
  int i, n = INTEGER(n_)[0];
  double x = 0.0;
  GetRNGstate();
  for ( i = 0; i < n; i++ )
    x += (unif_rand()-.5);
  PutRNGstate();
  return ScalarReal(x);"

f.cpp <- cxxfunction(signature(n_="integer"), src.cpp, plugin="Rcpp")
f.c <- cfunction(signature(n_="integer"), src.c)
Run Code Online (Sandbox Code Playgroud)

如果我使用GUI Instruments(在Xcode,版本4.5(4523)中)或命令行sample,两者都崩溃:仪器立即崩溃,而样本在崩溃前完成处理样本: …

profiling r rcpp

24
推荐指数
1
解决办法
2056
查看次数

无法在foreach中运行Rcpp函数 - "NULL值作为符号地址传递"

首先我要说的是我读过写R扩展,Rcpp包的插图,以及我已经构建了一个包Rcpp.package.skeleton().

自从构建我的包之后,我添加了一个函数,multiGenerateCSVrow()然后compileAttributes()在R CMD build/R CMD安装之前在包目录上运行.之后予加载我包,我可以直接地或通过运行我功能foreach()%do%方法.

当我尝试并行运行时,我收到一个错误:

cl <- makePSOCKcluster(8)                                                                                     
registerDoParallel(cl)                                                                                        
rows <- foreach(i=1:8,.combine=rbind,.packages="myPackage") %dopar% multiGenerateCSVrow(scoreMatrix=NIsample,   
                                                                   validMatrix = matrix(1,nrow=10,ncol=10),   
                                                                   cutoffVector = rep(0,10),                  
                                                                   factorVector = randomsCutPlus1[i,],        
                                                                   actualVector = rep(1,10),                  
                                                                   scaleSample = 1)                           
stopCluster(cl)                                                                                               
~                                                                                                             

Error in multiGenerateCSVrow(scoreMatrix = NIsample, validMatrix = matrix(1,  : 
  task 1 failed - "NULL value passed as symbol address"
Run Code Online (Sandbox Code Playgroud)

这是NAMESPACE包:

# Generated by roxygen2 (4.0.1): do not edit by hand 
useDynLib(myPackage)                                   
exportPattern("^[[:alpha:]]+")                       
importFrom(Rcpp, evalCpp) 
Run Code Online (Sandbox Code Playgroud)

这是RcppExports.cpp的相关块:

// multiGenerateCSVrow
SEXP …
Run Code Online (Sandbox Code Playgroud)

r rcpp

23
推荐指数
3
解决办法
5910
查看次数

内联和Xcode 4.2.1出错

我正在尝试让内联包在我的macbook上运行.以下代码块(来自cxxfunction示例)失败:

library(inline)
fx <- cxxfunction( signature(x = "integer", y = "numeric" ) , '
    return ScalarReal( INTEGER(x)[0] * REAL(y)[0] ) ;
' )
fx( 2L, 5 )
Run Code Online (Sandbox Code Playgroud)

出现此错误:

Error in compileCode(f, code, language = language, verbose = verbose) : 
  Compilation ERROR, function(s)/method(s) not created! make: g++-4.2: No such file or directory
make: *** [file141b5882.o] Error 1
Run Code Online (Sandbox Code Playgroud)

这很奇怪,因为g ++可用:

g++ -v
Using built-in specs.
Target: i686-apple-darwin11
Configured with: /private/var/tmp/llvmgcc42/llvmgcc42-2336.1~22/src/configure --disable-checking --enable-werror --prefix=/Developer/usr/llvm-gcc-4.2 --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-prefix=llvm- --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin11 --enable-llvm=/private/var/tmp/llvmgcc42/llvmgcc42-2336.1~22/dst-llvmCore/Developer/usr/local …
Run Code Online (Sandbox Code Playgroud)

xcode r inline rcpp osx-lion

22
推荐指数
1
解决办法
3167
查看次数

将Rcpp :: CharacterVector转换为std :: string

我试图在Rcpp函数中打开一个文件,所以我需要文件名作为char*或std :: string.

到目前为止,我尝试过以下方法:

#include <Rcpp.h>
#include <boost/algorithm/string.hpp>
#include <fstream>
#include <string>

RcppExport SEXP readData(SEXP f1) {
    Rcpp::CharacterVector ff(f1);
    std::string fname = Rcpp::as(ff);
    std::ifstream fi;
    fi.open(fname.c_str(),std::ios::in);
    std::string line;
    fi >> line;
    Rcpp::CharacterVector rline = Rcpp::wrap(line);
    return rline;
}
Run Code Online (Sandbox Code Playgroud)

但显然,因为我得到编译时错误as不起作用Rcpp::CharacterVector.

foo.cpp: In function 'SEXPREC* readData(SEXPREC*)':
foo.cpp:8: error: no matching function for call to 'as(Rcpp::CharacterVector&)'
make: *** [foo.o] Error 1
Run Code Online (Sandbox Code Playgroud)

有没有一种简单的方法从参数中获取字符串或以某种方式从Rcpp函数参数中打开文件?

c++ r rcpp

21
推荐指数
2
解决办法
8052
查看次数

Rcpp矩阵:循环遍历行,一次一列

这是我第一次尝试Rcpp,这个非常简单的问题给了我麻烦.我想使用嵌套for循环来操作矩阵的各个值,一次一列.我瞄准的脚本看起来像这样:

src <- '
    Rcpp::NumericMatrix Am(A);
    int nrows = Am.nrow();
    int ncolumns = Am.ncol();
    for (int i = 0; i < ncolumns; i++){
        for (int j = 1; j < nrows; j++){
            Am[j,i] = Am[j,i] + Am[j-1,i];
        }
    }
    return Am;
'
fun <- cxxfunction(signature(A = "numeric"), body = src, plugin="Rcpp")
fun(matrix(1,4,4))
Run Code Online (Sandbox Code Playgroud)

期望的输出是这样的:

     [,1] [,2] [,3] [,4]
[1,]    1    1    1    1
[2,]    2    2    2    2
[3,]    3    3    3    3
[4,]    4    4    4    4
Run Code Online (Sandbox Code Playgroud)

问题显然在这一行,我不知道如何引用矩阵的各个元素.

Am[j,i] = …
Run Code Online (Sandbox Code Playgroud)

r rcpp

20
推荐指数
1
解决办法
1万
查看次数

在Windows下调试(逐行)Rcpp生成的DLL

最近我一直在尝试使用Rcpp(内联)来生成DLL,这些DLL在提供的R输入上执行各种任务.在给定一组特定的R输入的情况下,我希望能够逐行调试这些DLL中的代码.(我在Windows下工作.)

为了说明,让我们考虑一个任何人都应该能够运行的具体例子......

下面的代码是一个非常简单的cxx函数,它只是输入向量的两倍.但请注意,有一个额外的变量myvar可以更改值几次,但不会影响输出 - 这已添加,以便我们能够看到调试过程何时正确运行.

library(inline)
library(Rcpp)

f0 <- cxxfunction(signature(a="numeric"), plugin="Rcpp", body='
    Rcpp::NumericVector xa(a);
    int myvar = 19;
    int na = xa.size();
    myvar = 27;
    Rcpp::NumericVector out1(na);
    for(int i=0; i < na; i++) {
        out1[i] = 2*xa[i];
        myvar++;
    }
    myvar = 101;
    return(Rcpp::List::create( _["out1"] = out1));
')
Run Code Online (Sandbox Code Playgroud)

运行上面的命令之后,输入命令

getLoadedDLLs()
Run Code Online (Sandbox Code Playgroud)

在R会话中显示DLL列表.列出的最后一个应该是由上面的过程创建的DLL - 它有一个随机的临时名称,在我的情况下是

file7e61645c
Run Code Online (Sandbox Code Playgroud)

"Filename"列显示cxxfunction已将此DLL放在该位置tempdir(),这对我来说是当前的位置

C:/Users/TimP/AppData/Local/Temp/RtmpXuxtpa/file7e61645c.dll
Run Code Online (Sandbox Code Playgroud)

现在,调用DLL的明显方法是via f0,如下所示

> f0(c(-7,0.7,77))

$out1
[1] -14.0   1.4 154.0
Run Code Online (Sandbox Code Playgroud)

但我们当然也可以使用以下.Call命令直接通过名称调用DLL :

> .Call("file7e61645c",c(-7,0.7,77))

$out1
[1] -14.0 …
Run Code Online (Sandbox Code Playgroud)

debugging dll gdb r rcpp

20
推荐指数
1
解决办法
3246
查看次数

用 Rcpp 优化 R 目标函数变慢,为什么?

我目前正在研究一种贝叶斯方法,该方法需要在每次迭代中对多项式 logit 模型进行多个优化步骤。我正在使用 optim() 来执行这些优化,并使用 R 编写的目标函数。分析显示 optim() 是主要瓶颈。

在挖掘之后,我发现了这个问题,他们建议重新编码目标函数Rcpp可以加快进程。我遵循了建议并用 重新编码了我的目标函数Rcpp,但它最终变慢了(大约慢了两倍!)。

这是我第一次使用Rcpp(或任何与 C++ 相关的东西),我无法找到一种对代码进行矢量化的方法。知道如何使它更快吗?

Tl; dr:当前 Rcpp 中函数的实现不如矢量化 R 快;如何让它更快?

一个可重现的例子

  1. Rand 中定义目标函数Rcpp:仅截取多项式模型的对数似然
library(Rcpp)
library(microbenchmark)

llmnl_int <- function(beta, Obs, n_cat) {
  n_Obs     <- length(Obs)
  Xint      <- matrix(c(0, beta), byrow = T, ncol = n_cat, nrow = n_Obs)
  ind       <- cbind(c(1:n_Obs), Obs)
  Xby       <- Xint[ind]
  Xint      <- exp(Xint)
  iota      <- c(rep(1, (n_cat)))
  denom     <- log(Xint %*% iota)
  return(sum(Xby …
Run Code Online (Sandbox Code Playgroud)

optimization r rcpp

20
推荐指数
3
解决办法
974
查看次数

R:将负值替换为零

我们希望将数组中的所有值设置为负值.我尝试了很多东西,但还没有找到一个有效的解决方案.我想到了一个带有条件的for循环,但这似乎不起作用.

#pred_precipitation is our array
pred_precipitation <-rnorm(25,2,4)     

for (i in nrow(pred_precipitation))
{
  if (pred_precipitation[i]<0) {pred_precipitation[i] = 0}
  else{pred_precipitation[i] = pred_precipitation[i]}
}
Run Code Online (Sandbox Code Playgroud)

谢谢你的提示!

for-loop if-statement r conditional-statements rcpp

19
推荐指数
4
解决办法
5万
查看次数