相关疑难解决方法(0)

Rcpp通过引用传递而不是通过值传递

我第一次尝试了Rcpp功能inline,它解决了我的速度问题(感谢Dirk!): R:将负值替换为零

初始版本看起来像这样:

library(inline)
cpp_if_src <- '
  Rcpp::NumericVector xa(a);
  int n_xa = xa.size();
  for(int i=0; i < n_xa; i++) {
    if(xa[i]<0) xa[i] = 0;
  }
  return xa;
'
cpp_if <- cxxfunction(signature(a="numeric"), cpp_if_src, plugin="Rcpp")
Run Code Online (Sandbox Code Playgroud)

但是当被调用时cpp_if(p),它会p用输出覆盖,这不是预期的.所以我认为它是通过引用传递的.

所以我用以下版本修复它:

library(inline)
cpp_if_src <- '
  Rcpp::NumericVector xa(a);
  int n_xa = xa.size();
  Rcpp::NumericVector xr(a);
  for(int i=0; i < n_xa; i++) {
    if(xr[i]<0) xr[i] = 0;
  }
  return xr;
'
cpp_if <- cxxfunction(signature(a="numeric"), cpp_if_src, plugin="Rcpp")
Run Code Online (Sandbox Code Playgroud)

这似乎有效.但是现在,当我将其重新加载到R中时,原始版本不再覆盖其输入(即,相同的确切代码现在不会覆盖其输入):

> cpp_if_src <- '
+   Rcpp::NumericVector …
Run Code Online (Sandbox Code Playgroud)

r rcpp

15
推荐指数
1
解决办法
4404
查看次数

在C++函数中,Rcpp对象如何传递给其他函数(通过引用或通过复制)?

我刚刚用Rcpp编写了一个新版本的ABCoptim包.大约30倍的加速,我对新版本的性能(与旧版本)非常满意,但我仍然有一些担心,如果我有空间来提高性能而不需要修改太多的代码.

在ABCoptim的主要功能(用C++编写)中,我传递一个包含"蜜蜂位置"(NumericMatrix)的Rcpp :: List对象和一些带有算法本身重要信息的NumericVectors.我的问题是,当我将Rcpp :: List对象传递给其他函数时,例如

#include <Rcpp.h>

using namespace Rcpp;

List ABCinit([some input]){[some code here]};
void ABCfun2(List x){[some code here]};
void ABCfun3(List x){[some code here]};

List ABCmain([some input])
{
  List x = ABCinit([some input]);
  while ([some statement])
  {
    ABCfun2(x);
    ABCfun3(x);
  }
  ...

  return List::create(x["results"]);
}
Run Code Online (Sandbox Code Playgroud)

Rcpp在while循环中做了什么?请问x对象是通过引用或深拷贝的功能传递ABCfun2ABCfun3?我已经看到'const List&x'的用法,它告诉我可以使用指针传递Rcpp对象,但问题是我需要这个列表是可变的(并且没有常量),无论如何要改进它吗?我担心这个x List的迭代拷贝可能会减慢我的代码速度.

PS:我还是C++的新手,而且我正在使用Rcpp来学习C++.

performance pointers r rcpp

12
推荐指数
2
解决办法
4100
查看次数

通过引用传递data.frame并使用rcpp更新它

看看rcpp文档和Rcpp::DataFrame库中我意识到我不知道如何通过引用修改DataFrame.谷歌搜索了一下我在SO上找到了这篇文章,这篇文章在档案上.没有什么明显的,所以我怀疑我会错过一些像"已经是这种情况因为"或"因为它没有意义"的大事.

我尝试了以下编译,但data.frame传递给updateDFByRefR 的对象 保持不变

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void updateDFByRef(DataFrame& df) {
    int N = df.nrows();
    NumericVector newCol(N,1.);
    df["newCol"] = newCol;
    return;
}
Run Code Online (Sandbox Code Playgroud)

r rcpp

11
推荐指数
1
解决办法
3906
查看次数

将大型矩阵传递给RcppArmadillo函数而不创建副本(高级构造函数)

我想将一个大矩阵传递给一个RcppArmadillo函数(大约30,000*30,000)并且感觉这个过去只会消耗所有的性能提升.这里还提出了一个问题,建议使用带有copy_aux_mem = false参数的高级构造函数.这似乎也是一个很好的解决方案,因为我只需要从矩阵中读取行而不需要改变任何东西.我在正确实施解决方案时遇到问题.这可能只是一个简单的语法问题.

这是我当前设置的函数调用(当然简化):

#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::vec test(arma::mat M) {
    return(M.row(0))
}
Run Code Online (Sandbox Code Playgroud)

这是非常慢的大矩阵M(例如M=matrix(rnorm(30000*30000), nrow=30000, ncol=30000),所以我想使用这里记录的高级构造函数.语法是mat(aux_mem*, n_rows, n_cols, copy_aux_mem = true, strict = true)并且copy_aux_mem应该设置false为'传递引用'.我只是不确定语法功能定义.我该如何使用它arma::vec test(arma::mat M) {

r rcpp

8
推荐指数
2
解决办法
2100
查看次数

为什么我的Rcpp实现用于查找比基本R慢的唯一项目数?

我正在尝试编写一个函数来计算字符串向量中唯一项的数量(我的问题稍微复杂一点,但这是可重现的.我根据我在C++中找到的答案做了这个.这是我的代码:

C++

int unique_sort(vector<string> x) {
    sort(x.begin(), x.end());
    return unique(x.begin(), x.end()) - x.begin();
}

int unique_set(vector<string> x) {
    unordered_set<string> tab(x.begin(), x.end());
    return tab.size();
}
Run Code Online (Sandbox Code Playgroud)

R:

x <- paste0("x", sample(1:1e5, 1e7, replace=T))
microbenchmark(length(unique(x)),unique_sort(x), unique_set(x), times=3)
Run Code Online (Sandbox Code Playgroud)

结果:

Unit: milliseconds
              expr        min         lq       mean     median         uq
 length(unique(x))   365.0213   373.4018   406.0209   381.7823   426.5206
    unique_sort(x) 10732.1918 10847.0532 10907.6882 10961.9146 10995.4363
     unique_set(x)  1948.6517  2230.3383  2334.4040  2512.0249  2527.2802
Run Code Online (Sandbox Code Playgroud)

查看该unique函数的R源代码(它有点难以理解),它似乎在数组上使用循环向哈希添加唯一元素,并检查该哈希是否已存在元素.

因此,我认为它应该等同于unordered_set方法.我不明白为什么unordered_set方法慢了5倍.

TLDR:为什么我的C++代码变慢?

c++ r rcpp

2
推荐指数
1
解决办法
553
查看次数

是否在Rcpp和C ++之间转换向量(使用Rcpp :: as或Rcpp :: wrap)创建新的向量并复制元素?

以我的理解,在Rcpp和C ++之间转换向量将创建新向量,如下所示。我的理解正确吗?

将Rcpp向量转换为C ++向量时,我们使用Rcpp::as<T>()(例如Rcpp::as<std::string>用于Rcpp::CharacterVector)。 std::vector<std::string>创建后,原始Rcpp元素将被复制到C ++向量中std::string。这意味着修改新创建的C ++矢量元素不会影响原始的Rcpp矢量元素。

将C ++向量转换为Rcpp向量时,我们使用Rcpp::wrap()。创建具有相应类型的Rcpp向量,并将C ++元素作为Rcpp对象复制到Rcpp向量中。这意味着修改新创建的Rcpp矢量元素不会影响原始的C ++矢量元素。

c++ r vector rcpp

2
推荐指数
1
解决办法
47
查看次数

如何在R中的rcpp中正确更改ListMatrix的列表

我想在rcpp中更改ListMatrix列表的元素,但始终无法做到这一点.请参阅以下玩具示例:

library("Rcpp")
cppFunction('
ListMatrix ListMatrixType(ListMatrix x){
            NumericMatrix a = x(0,0);
            a(0,0) = 100;
            return x;
            }
            ')
x = matrix(list(matrix(0,3,2)),2,2)
a = ListMatrixType(x)
a[[1,1]]
a[[2,2]]
Run Code Online (Sandbox Code Playgroud)

我希望只会a[[1,1]改变,但为什么a[[2,2]]也会改变?

> a[[1,1]]
     [,1] [,2]
[1,]  100    0
[2,]    0    0
[3,]    0    0
> a[[2,2]]
     [,1] [,2]
[1,]  100    0
[2,]    0    0
[3,]    0    0
Run Code Online (Sandbox Code Playgroud)

我必须误解rcpp中的索引规则.所以我的问题是如何正确更改每个列表的元素?我想每个列表都包含一个矩阵.

indexing r rcpp

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

标签 统计

r ×7

rcpp ×7

c++ ×2

indexing ×1

performance ×1

pointers ×1

vector ×1