关于Rcpp的问题
我用R写了下面的计算。 然而,这在许多“for循环”中使用缓慢 我尝试使用Rcpp编写类似的计算。 但这是一个错误 请更正我的密码关于Rcpp的问题,r,rcpp,R,Rcpp,我用R写了下面的计算。 然而,这在许多“for循环”中使用缓慢 我尝试使用Rcpp编写类似的计算。 但这是一个错误 请更正我的密码 # R data <- matrix(1: 100, ncol = 5, nrow = 20) Y <- 10 X <- Y - 1 Z <- matrix(ncol = 1, nrow = nrow(data) - X) for (i in 1:(nrow(data) - X)){ Z[i, ] <- sum(data[i:
# R
data <- matrix(1: 100, ncol = 5, nrow = 20)
Y <- 10
X <- Y - 1
Z <- matrix(ncol = 1, nrow = nrow(data) - X)
for (i in 1:(nrow(data) - X)){
Z[i, ] <- sum(data[i: (i + X), ])
}
> data
[,1] [,2] [,3] [,4] [,5]
[1,] 1 21 41 61 81
[2,] 2 22 42 62 82
[3,] 3 23 43 63 83
[4,] 4 24 44 64 84
[5,] 5 25 45 65 85
[6,] 6 26 46 66 86
[7,] 7 27 47 67 87
[8,] 8 28 48 68 88
[9,] 9 29 49 69 89
[10,] 10 30 50 70 90
[11,] 11 31 51 71 91
[12,] 12 32 52 72 92
[13,] 13 33 53 73 93
[14,] 14 34 54 74 94
[15,] 15 35 55 75 95
[16,] 16 36 56 76 96
[17,] 17 37 57 77 97
[18,] 18 38 58 78 98
[19,] 19 39 59 79 99
[20,] 20 40 60 80 100
> Z
[,1]
[1,] 2275
[2,] 2325
[3,] 2375
[4,] 2425
[5,] 2475
[6,] 2525
[7,] 2575
[8,] 2625
[9,] 2675
[10,] 2725
[11,] 2775
// Rcpp
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix myRcpp(NumericMatrix data, NumericVector Y) {
int X = Y - 1;
int i;
int nrow = data.nrow();
Rcpp::NumericMatrix Z();
for (i = 0; i < nrow - X; i++) {
Z[i] = Rcpp::sum(data( Range(i, (i + X)) , _ ));
}
return (Z);
}
#R
数据您有几个错误。大多数情况下,我建议解开复杂的表达式,这些表达式显然会产生编译器/模板错误
使用新代码,我得到:
R> sourceCpp("/tmp/so_question.cpp")
R> # R
R> data <- matrix(1: 100, ncol = 5, nrow = 20)
R> Y <- 10
R> X <- Y - 1
R> Z <- matrix(ncol = 1, nrow = nrow(data) - X)
R> for (i in 1:(nrow(data) - X)) {
+ Z[i, ] <- sum(data[i: (i + X), ])
+ }
R> #data
R> #Z
R>
R> myRcpp(data, Y)
[1] 2275 2325 2375 2425 2475 2525 2575 2625 2675 2725 2775
R>
R>sourceCpp(“/tmp/so\u question.cpp”)
R> #R
R> 数据Y X Z(i在1中:(nrow(数据)-X)){
+Z[i,]#数据
R> #Z
R>
R> myRcpp(数据,Y)
[1] 2275 2325 2375 2425 2475 2525 2575 2625 2675 2725 2775
R>
代码在下面——我把R和C++结合成一个文件。
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector myRcpp(NumericMatrix data, int y) {
int x = y - 1;
int i;
int n = data.nrow();
Rcpp::NumericVector z(n - x);
for (i = 0; i < n - x; i++) {
Rcpp::SubMatrix<REALSXP> sm = data( Range(i, (i + x)) , _ );
Rcpp::NumericMatrix m(sm);
double s = Rcpp::sum(m);
z[i] = s;
}
return z;
}
/*** R
# R
data <- matrix(1: 100, ncol = 5, nrow = 20)
Y <- 10
X <- Y - 1
Z <- matrix(ncol = 1, nrow = nrow(data) - X)
for (i in 1:(nrow(data) - X)) {
Z[i, ] <- sum(data[i: (i + X), ])
}
#data
#Z
myRcpp(data, Y)
*/
#包括
使用名称空间Rcpp;
//[[Rcpp::导出]]
数值向量myRcpp(数值矩阵数据,整数y){
int x=y-1;
int i;
int n=data.nrow();
Rcpp::数值向量z(n-x);
对于(i=0;i 数据在我看来,你和答案对每一行重复相同的计算(行和)Y次。所以一个向量化的解决方案
data %>%
rowSums %>%
cumsum %>%
{. - lag(., Y)}
((>%来自包magrittr,来自dplyr的lag方法)应该做您想要做的事情,它甚至比Rcpp快一点
Unit: milliseconds
expr min lq mean median uq max neval cld
myArma(data, Y) 10.363077 11.633387 17.963248 12.233787 14.772540 131.67896 100 b
vectorized(data) 3.172276 3.284239 5.492879 3.441609 4.664644 63.96084 100 a
您提到,您最终希望使用sd而不是sum,但即使在这种情况下,缓存平方和也会节省大量时间
data %>%
{(. - mu)^2} %>%
rowSums %>%
cumsum %>%
{. - lag(.,Y)} %>%
divide_by( Y*NCOL(data) - 1 )
mu作为一个组意味着你得到了另一个解决方案
一个C++实现,当然,它比R还要快,但我认为你不能为了简洁而超越上面的代码。
再见,
斯特凡
编辑:根据数据的结构和大小,您可能会遇到从累积和减去滞后累积和的减法取消问题(即,如果累积和比没有有效数字的单行和大16个数量级)。在这种情况下,您可以使用RcppRoll的roll_sum替换该步骤
作为一个解决方案,它实际上更短,我只是没有RcppRoll的经验,也不能说是否存在问题或陷阱
data %>%
rowSums %>%
roll_sum(Y)
你能详细说明你看到的错误吗?我已经附加了一条错误消息。谢谢。谢谢。在我显示的代码中,使用“sum”可以在RcppRoll中解决。但是,我有时想使用“sd”而不是“sum”。RcppRoll似乎无法应用“sd”在多个列中。如果zoo中的rollapply
足够,则它可以根据by.column=
参数按列或跨列应用函数。另外,请随意“向上投票”(单击向上箭头)问题,并且,作为提问者,也可以“接受”(单击勾号)。这就是StackOverflow的工作原理。但是,这需要将数据复制到m
。如果sum
知道如何处理矩阵糖表达式,那就更好了。当然,但运行时的成本很小。更紧凑的表达式有帮助,请查看更新后的答案及其Armadillo一行解决方案。这太好了,不可能是真的性能方面的ld get可能是rowsum(roll\u sum(data,Y))
其中roll\u sum
来自RcppRoll
。你的向量化的解决方案是计算一个完全不同的东西。诚然,滞后(,Y,默认值=0)
是必需的,但是all.equal(向量化的(data),myArma(data,Y))
返回TRUE
。你从哪里知道我们计算不同的东西?抱歉。我在没有加载dplyr的情况下运行了你的代码。很好的解决方案。我发现性能取决于求和
的效率。然而,并不是所有的滚动操作都是求和
,因此它的泛化能力有限。我怀疑你的sde> 示例工作。谢谢。您的解决方案也很有帮助。
Unit: milliseconds
expr min lq mean median uq max neval cld
myArma(data, Y) 10.363077 11.633387 17.963248 12.233787 14.772540 131.67896 100 b
vectorized(data) 3.172276 3.284239 5.492879 3.441609 4.664644 63.96084 100 a
data %>%
{(. - mu)^2} %>%
rowSums %>%
cumsum %>%
{. - lag(.,Y)} %>%
divide_by( Y*NCOL(data) - 1 )
data %>%
rowSums %>%
roll_sum(Y)