我有很長的參數向量(約4^10個元素)和一個向量向量。我的目標是將所有在索引向量中索引的參數值相加。例如,如果我有paras = [1,2,3,4,5,5,5]和indices = [3,3,1,6],那麼我想要找到的累計和第三個值(3)兩次,第一個值(1)和第六個(5),得到12.此外,還可以根據參數值的位置來翹曲參數值。用於添加矢量元素的Rcpp函數
我想加快R實現,因爲我稱它爲數百萬次。
我當前的代碼總是返回NA
,我不能看到它是怎麼了?
這裏的RCPP功能:
double dot_prod_c(NumericVector indices, NumericVector paras,
NumericVector warp = NA_REAL) {
int len = indices.size();
LogicalVector indices_ok;
for (int i = 0; i < len; i++){
indices_ok.push_back(R_IsNA(indices[i]));
}
if(is_true(any(indices_ok))){
return NA_REAL;
}
double counter = 0;
if(NumericVector::is_na(warp[1])){
for (int i = 0; i < len; i++){
counter += paras[indices[i]];
}
} else {
for (int i = 0; i < len; i++){
counter += paras[indices[i]] * warp[i];
}
}
return counter;
}
這裏是工作[R版本:
dot_prod <- function(indices, paras, warp = NA){
if(is.na(warp[1])){
return(sum(sapply(indices, function(ind) paras[ind + 1])))
} else {
return(sum(sapply(1:length(indices), function(i){
ind <- indices[i]
paras[ind + 1] * warp[i]
})))
}
}
下面是一些測試代碼,並使用microbenchmark軟件包進行基準測試:
# testing
library(Rcpp)
library(microbenchmark)
parameters <- list()
indices <- list()
indices_trad <- list()
set.seed(2)
for (i in 4:12){
size <- 4^i
window_size <- 100
parameters[[i-3]] <- runif(size)
indices[[i-3]] <- floor(runif(window_size)*size)
temp <- rep(0, size)
for (j in 1:window_size){
temp[indices[[i-3]][j] + 1] <- temp[indices[[i-3]][j] + 1] + 1
}
indices_trad[[i-3]] <- temp
}
microbenchmark(
x <- sapply(1:9, function(i) dot_prod(indices[[i]], parameters[[i]])),
x_c <- sapply(1:9, function(i) dot_prod_c(indices[[i]], parameters[[i]])),
x_base <- sapply(1:9, function(i) indices_trad[[i]] %*% parameters[[i]])
)
all.equal(x, x_base) # is true, does work
all.equal(x_c, x_base) # not true - C++ version returns only NAs
首先'indices'應一個'IntegerVector'。其次,我不明白經線周圍的控制塊。 「warp」是矢量還是標量?爲什麼你要引用第二個元素(C++索引從0開始,而不是1)?你不需要將默認值轉換爲矢量嗎? –
我也很困惑你爲什麼使用'R_IsNA'和Rcpp糖':: is_na'。爲什麼不使用其中一個或另一個? –