У меня очень длинный вектор параметров (приблизительно 4^10 элементов) и вектор индексов. Моя цель - объединить все значения параметров, индексированных в векторе индексов.Функция Rcpp для добавления элементов вектора
Например, если бы у меня были парас = [1,2,3,4,5,5,5] и индексы = [3,3,1,6], то я бы хотел найти кумулятивную сумму третье значение (3) дважды, первое значение (1) и шестое (5), чтобы получить 12. Существует дополнительно возможность деформирования значений параметров в соответствии с их местоположением.
Я пытаюсь ускорить реализацию 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]
})))
}
}
Ниже приведен код для тестирования и бенчмаркинга с использованием пакета микрообъективов:
# 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'. Почему бы не использовать один или другой против обоих? –