首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >向量化依赖于以前元素的乘积计算?

向量化依赖于以前元素的乘积计算?
EN

Stack Overflow用户
提问于 2011-08-23 05:03:03
回答 4查看 3.4K关注 0票数 21

我正在尝试加速/向量化时间序列中的一些计算。我可以在一个for循环中向量化一个可以依赖于早期迭代结果的计算吗?例如:

代码语言:javascript
复制
z <- c(1,1,0,0,0,0)
zi <- 2:6
for  (i in zi) {z[i] <- ifelse (z[i-1]== 1, 1, 0) }

使用在前面的步骤中更新的ZI值:

代码语言:javascript
复制
> z
[1] 1 1 1 1 1 1

在我将其向量化的过程中

代码语言:javascript
复制
z <- c(1,1,0,0,0,0)
z[zi] <- ifelse( z[zi-1] == 1, 1, 0)

逐元素操作不使用在操作中更新的结果:

代码语言:javascript
复制
> z
[1] 1 1 1 0 0 0

因此,这种向量化操作是以“并行”而不是迭代的方式进行的。有没有一种方法可以让我编写/向量化它来获得for循环的结果?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-08-23 05:35:20

ifelse是矢量化的,如果你在for循环中一次只在一个元素上使用它,会有一些损失。在您的示例中,您可以通过使用if而不是ifelse获得相当好的加速比。

代码语言:javascript
复制
fun1 <- function(z) {
  for(i in 2:NROW(z)) {
    z[i] <- ifelse(z[i-1]==1, 1, 0)
  }
  z
}

fun2 <- function(z) {
  for(i in 2:NROW(z)) {
    z[i] <- if(z[i-1]==1) 1 else 0
  }
  z
}

z <- c(1,1,0,0,0,0)
identical(fun1(z),fun2(z))
# [1] TRUE
system.time(replicate(10000, fun1(z)))
#   user  system elapsed 
#   1.13    0.00    1.32
system.time(replicate(10000, fun2(z)))
#   user  system elapsed 
#   0.27    0.00    0.26 

您可以通过编译fun2获得一些额外的速度提升。

代码语言:javascript
复制
library(compiler)
cfun2 <- cmpfun(fun2)
system.time(replicate(10000, cfun2(z)))
#   user  system elapsed 
#   0.11    0.00    0.11

因此,在没有矢量化的情况下,速度提高了10倍。正如其他人所说(有些人已经说明了),有一些方法可以向量化您的示例,但这可能不会转化为您的实际问题。希望这是通用的,可以应用。

如果您知道如何用自回归过程或移动平均过程来表示问题,那么filter函数可能对您也很有用。

票数 20
EN

Stack Overflow用户

发布于 2011-08-23 06:39:17

有时你只需要以完全不同的方式思考它。你要做的是创建一个向量,如果它是1或0,那么每一项都与第一项相同。

代码语言:javascript
复制
z <- c(1,1,0,0,0,0)
if (z[1] != 1) z[1] <- 0
z[2:length(z)] <- z[1]
票数 0
EN

Stack Overflow用户

发布于 2018-05-28 17:41:14

有一个函数可以完成这个特殊的计算:cumprod (累积乘积)

代码语言:javascript
复制
> cumprod(z[zi])
[1] 1 0 0 0 0

> cumprod(c(1,2,3,4,0,5))
[1]  1  2  6 24  0  0

否则,使用Rccp进行矢量化,如其他答案所示。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7153586

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档