r - 数据的递归依赖——使用rcpp的for循环
问题描述
我有一个函数写在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
和。但是,现在我需要进行一些调整,即我需要采用额外的参数来告诉该行在向量中的非零值之后输出向量应该为 0。请参阅下面的所需输出,使用, 。i
y
c
c
y
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
is 0
,因为参数c
等于4
所以我们不再乘以之前的值z
。但是11
-th 的值z
是8.916000
因为我们不仅将先前的值乘以0.9
,而且还6.0
从y
列中相加。
我试图在名为 as的新列中创建一个新0-1
列,以指示是否仍考虑减少,然后尝试调整上述函数,但以下不起作用(值 of不重置 where )。data.frame
c
0.9
z
c = 0
cppFunction("NumericVector adjust_cpp (NumericVector y, double k, NumericVector ctrl) {
int n = y.size();
NumericVector z(n);
int i; double *p1, *p2, *p3, *end = &z[n];
double tmp = 1.0;
for (i = 0; i < n; i++) {
for (p1 = &z[i], p2 = &y[0], p3 = &ctrl[0]; p1 < end; p1++, p2++, p3++) {
*p1 += tmp * (*p2);
*p1 *= *p3;
}
tmp *= k;
}
return z;
}"
)
我怎样才能做到这一点?
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")
使用R中的上述数据,这将是:
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)
}
解决方案
将这样一个简单的 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 已经更快了。
推荐阅读
- redirect - Identity Server 4 - 取消重定向到登录并返回 401
- node.js - shopify结账支付api上的404
- domain-driven-design - DDD - 执行需要了解多个聚合根的规则
- jquery - 检查输入值是否与 ids 值相同
- node.js - 将限制设置为最大行数
- date - 根据当前周的天数获取 Teradata 中的最后/当前星期二日期
- python - Python MysqlClient(MYSQLDB)无法连接到远程服务器
- r - 根据 POSIxct 值创建新变量 <
- php - 无法通过 PHPExcel 从 Excel 获取公式结果
- javascript - 功能作为反应孩子无效,为什么我会得到这个?