矢量化for循环

时间:2012-11-05 04:53:19

标签: r parallel-processing data.table vectorization

是否可以矢量化以下函数,(f)?

我有一个向量x,我希望通过更改f来最大化函数p的输出值。

但是这个功能很慢,因为它无论如何都没有矢量化,并且想知道是否有一个很好的方法。我们的想法是在未来将其并行化,并且还可能使用data.table来加速它

我的真实数据要大得多......所以我提供了一个模拟示例......

# My mock data 
x <- data.frame(x=rep(c(rep(c(0.2,-0.2),4),0.2,0.2,-0.2,0.2),20))

# The function to optimise for
f <- function(p,x){
    # Generate columns before filling
    x$multiplier <- NA
    x$cumulative <- NA

    for(i in 1:nrow(x)){
        # Going through each row systematically
        if(i==1){
            # If first row do a slightly different set of commands
            x[i,'multiplier'] <- 1 * p
            x[i,'cumulative'] <- (x[i,'multiplier'] * x[i,'x']) + 1
        } else {
            # For the rest of the rows carry out these commands
            x[i,'multiplier'] <- x[i-1,'cumulative'] * p
            x[i,'cumulative'] <- (x[i,'multiplier'] * x[i,'x']) + x[i-1,'cumulative']
        }
    }

# output the final row's output for the cumulative column
as.numeric(x[nrow(x),'cumulative'])
}

# Checking the function works by putting in a test value of p = 0.5
f(0.5,x)

# Now optimise the function between the interval of p between 0 and 1
optim.p <- optimise(f=f, interval=c(0,1),x, maximum=TRUE)

# Viewing the output of optim.p
optim.p

1 个答案:

答案 0 :(得分:10)

(编辑 - 忘记了我写过的帖子的第一部分,现在把它放进去。)

通过检查f实际所做的功能,可以简化您的问题。因为我很懒,所以我要写x[i, 'multiplier']作为m i x[i, 'cumulative']作为y i x[i, 'x'] as x i

让我们看一下f中的等式。我们先看一下案例i > 1

  

m i = y i-1 * p
      y i = m i * x i + y i-1

替换上面的m_i:

  

y i =(y i-1 * p)* x i + y i-1 //让我们分解..
      y i = y i-1 *(p * x i + 1)

这省去了计算multipler列的需要。

现在看一下你的i == 1案例,我们看到如果我们将y 0 设置为1,则以下内容适用于所有i = 1,...,{ {1}}:

  

y i = y i-1 (px i + 1)----------(1)

查看您的函数nrow(x),您想要计算的是y n

  

y n = y n-1 (px n + 1)

如果我们用(1)中的y n-1 替换公式会发生什么?

  

y n = y n-2 (px n-1 + 1)(px n + 1)

现在我们用上面的y n-2 的公式代替:

  

y n = y n-3 (px n-2 + 1)(px n-1 + 1)(px n + 1)

你得到的模式,对吗?我们一直替换为y 1

  

y n = y 0 (px 1 + 1)(px 2 + 1).. 。(px n-1 + 1)(px n + 1)

但请记住,y 0 只是1.因此,要计算f的值,我们只需:

  

f(x,p)=(px 1 + 1)(px 2 + 1)...(px n-1 + 1)(px n + 1)

其中f(x, p)n。也就是说,为每个nrow(x)计算p * x[i, 'x'] + 1并将它们全部相乘。


要在R中将数字向量相乘,请使用i。所以,如果prod只是一个向量:

x

让我们测试一下:

f_version2 <- function(p, x) {                                              
    return(prod(p * x + 1))                                                 
}                                                                           

总之,有时您只需分析问题的数学以及/与数字实现相对,就可以实现加速。