Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops RcppArmadillo:for循环中的负索引_Loops_Indexing_Rcpp_Rcpparmadillo - Fatal编程技术网

Loops RcppArmadillo:for循环中的负索引

Loops RcppArmadillo:for循环中的负索引,loops,indexing,rcpp,rcpparmadillo,Loops,Indexing,Rcpp,Rcpparmadillo,我是Rcpp新手,正在尝试使用RcppArmadillo在for()-循环中基于负索引执行计算。 我已经发现RcppArmadillo中的负索引并不是那么简单,但是它可以通过应该保留的元素向量来完成。当要删除的元素是循环索引时,这对我来说似乎有点困难。我试图在中实现最后一种方法,但没有成功。是否有一种简单的方法来指定元素的向量,不包括具有循环索引的元素 因此,我试图在RcppArmadillo中为以下MWE中的y[-I]找到一个等价物: # In R: # Input n <- 10 y

我是Rcpp新手,正在尝试使用RcppArmadillo在
for()
-循环中基于负索引执行计算。 我已经发现RcppArmadillo中的负索引并不是那么简单,但是它可以通过应该保留的元素向量来完成。当要删除的元素是循环索引时,这对我来说似乎有点困难。我试图在中实现最后一种方法,但没有成功。是否有一种简单的方法来指定元素的向量,不包括具有循环索引的元素

因此,我试图在RcppArmadillo中为以下MWE中的
y[-I]
找到一个等价物:

# In R:
# Input 
n <- 10
y <- 1:20

# Computation
x <- rep(NA, n)
for(i in 1:n){
x[i] <- sum(y[-i])
}
R中的
#
#输入

n对于这样的任务,最好跳过有问题的索引。在标准
C++
中,我们将检查索引并跳过它。大概是这样的:

// [[Rcpp::export]]
arma::vec rcpp_sum (arma::vec y, int n){
    
    arma::vec x(n);
    
    for (int i = 0; i < n; i++) {
        x[i] = 0; // Initialize value
        
        for (int j = 0; j < y.size(); ++j) {
            if (i != j) {
                x[i] += y[j];
            }
        }
    }
    
    return x;
}
验证输出:

all.equal(as.vector(rcpp_sum(y, n)), x)
[1] TRUE

all.equal(pure_rcpp_sum(y, n), x)
[1] TRUE
更新 根据OP的要求,我们在base
R
中为此特定目的提供了一种优化方法。上面演示了如何解决在
C++
中只对向量的值求和而忽略一个值这一非常具体的问题。这是教学性质的,不一定是完成这项特定任务的最佳方式(我们将在下面展示)

在我们展示简单的
R
代码之前,我想指出,OP担心在
C++
的内部循环中有一个简单的条件语句,这一点不值得担心(就像base
R
中的情况一样)。据我所知,在OP的链接中演示的子集是O(n),并且具有额外逻辑向量的额外开销。我们上面提出的解决方案应该更有效,因为它本质上做同样的事情,而不需要额外的对象

现在,更新代码:

baseR <- function(y, n) {
    mySum <- sum(y)
    vapply(1:n, function(x) mySum - y[x], FUN.VALUE = 1)    
}

## Here is the OP code for reference
OP <- function(y, n) {
    x <- rep(NA, n)
    for(i in 1:n) {x[i] <- sum(y[-i])}
    x
}

baseR好的,谢谢!事实上,我需要对一个小矩阵进行子集划分,因此这样一个带有if语句的for循环可以填充矩阵。然而,对于大型矩阵来说,这感觉有点像是一项耗时的工作。对于更大的问题,您是否也会建议此解决方案?@Suzanne,请参阅更新的解决方案。一般来说,
C++
中的if语句不如
R
中的模拟语句密集。
C++
解决方案比我提供的优化
R
解决方案慢得多的原因是它们实现了完全不同的算法。希望这有帮助!
all.equal(as.vector(rcpp_sum(y, n)), x)
[1] TRUE

all.equal(pure_rcpp_sum(y, n), x)
[1] TRUE
baseR <- function(y, n) {
    mySum <- sum(y)
    vapply(1:n, function(x) mySum - y[x], FUN.VALUE = 1)    
}

## Here is the OP code for reference
OP <- function(y, n) {
    x <- rep(NA, n)
    for(i in 1:n) {x[i] <- sum(y[-i])}
    x
}
huge_y <- rnorm(1e6)
huge_n <- 1e3

system.time(t1 <- baseR(huge_y, huge_n))
 user  system elapsed 
 0.003   0.000   0.003

system.time(t2 <- pure_rcpp_sum(huge_y, huge_n))
 user  system elapsed 
2.776   0.003   2.779 

system.time(t3 <- OP(huge_y, huge_n))
 user  system elapsed 
9.555   1.248  10.805

all.equal(t1, t2)
[1] TRUE

all.equal(t1, t3)
[1] TRUE