1

是否可以对以下函数 ( 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
4

1 回答 1

10

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

您的问题可以通过检查您的函数f实际执行的操作来简化。由于我很懒惰,所以我将写x[i, 'multiplier']为 m ix[i, 'cumulative']y ix[i, 'x']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, ..., nrow(x)

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

查看您的函数f,您要计算的是 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(x, p),我们只需:

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

n在哪里nrow(x)。也就是说,计算p * x[i, 'x'] + 1每个i并将它们相乘。


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

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

让我们在几件事上对其进行测试:

x <- rep(c(rep(c(0.2,-0.2),4),0.2,0.2,-0.2,0.2),20)                         

> f(0.5, x)                                                                 
[1] 16.56635                                                                
> f_version2(0.5, x)                                                        
[1] 16.56635                                                                

总之,有时您可以通过分析问题的数学以及/反对数值实现来实现加速。

于 2012-11-05T05:33:03.077 回答