我有一个用Rcpp
编写的函数:
library(Rcpp)
cppFunction("NumericVector MatVecMul_cpp (NumericVector y, double k) {
int n = y.size();
NumericVector z(n);
int i; double *p1, *p2, *end = &z[n];
double tmp = 1.0;
for (i = 0; i < n; i++) {
for (p1 = &z[i], p2 = &y[0]; p1 < end; p1++, p2++) *p1 += tmp * (*p2);
tmp *= k;
}
return z;
}")
该函数的基本目标是获取数值向量和参数k
并计算输出向量,其中第i
个元素是第i-1
个元素的和由k
和输入向量i
的第y
个元素组成。但是,现在我需要进行一些调整,即需要附加参数c
,它将告诉c
向量中非零值之后的y
行是输出向量{{1 }}应该为0。请参见下面的z
,c = 4
。
k = 0.9
再一次,structure(list(y = c(0.7, 0, 0, 0, 0, 0, 0, 4, 0, 0, 6, 0, 0,
0), z = c(0.7, 0.63, 0.567, 0.5103, 0.45927, 0, 0, 4, 3.6, 3.24,
8.916, 8.0244, 7.22196, 6.499764)), row.names = c(NA, -14L), class = "data.frame")
的第5
个值为z
,因为参数0
等于c
,所以我们不再乘以4
的先前值。但是z
的第11
个值为z
,因为我们不仅将先前的值乘以8.916000
,而且还从{{1 }}列。
我尝试在0.9
中创建一个名为6.0
的新y
列,该列将指示是否仍然考虑减少0-1
,然后尝试进行调整上面的函数,但以下命令不起作用(data.frame
的值不会在c
的位置重置)。
0.9
我该怎么做?
z
使用 R 中的上述数据将为:
c = 0
答案 0 :(得分:1)
只需很少的更改就可以逐行将这种简单的R函数转换为Rcpp:
#include <Rcpp.h>
using Rcpp::NumericVector;
// [[Rcpp::export]]
NumericVector funC(NumericVector y, double k, NumericVector ctrl) {
R_xlen_t n = y.length();
NumericVector z(n);
z(0) = y(0);
for (R_xlen_t i = 0; i < n - 1; ++i) {
z(i + 1) = (y(i + 1) + z(i) * k) * ctrl(i + 1);
}
return z;
}
/*** R
df <- structure(list(y = c(0.7, 0, 0, 0, 0, 0, 0, 4, 0, 0, 6, 0, 0,
0), z = c(0.7, 0.63, 0.567, 0.5103, 0.45927, 0, 0, 4, 3.6, 3.24,
8.916, 8.0244, 7.22196, 6.499764), ctrl = c(1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1)), .Names = c("y", "z", "ctrl"), row.names = c(NA,
-14L), class = "data.frame")
fun <- function(y, k, ctrl) {
n <- length(y)
z <- numeric(n)
z[1] <- y[1]
for (i in 1:(n - 1)) {
z[i + 1] <- (y[i + 1] + z[i] * k) * ctrl[i + 1]
}
return(z)
}
z <- fun(df$y, 0.9, df$ctrl)
all.equal(df$z, z)
z <- funC(df$y, 0.9, df$ctrl)
all.equal(df$z, z)
*/
对于提供的长度为14的向量,R版本在此计算机上仍然更快。将y
和ctrl
复制十次可得出向量,而Rcpp已经更快。