矢量化for循环

h.l*_*l.m 1 parallel-processing r vectorization data.table

是否可以矢量化以下函数,(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
Run Code Online (Sandbox Code Playgroud)

mat*_*fee 10

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

通过检查函数f实际执行的操作可以简化您的问题.因为我很懒,所以我要写x[i, 'multiplier']为m i,x[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)

哪里nnrow(x).也就是说,计算p * x[i, 'x'] + 1每个i并将它们全部相乘.


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

f_version2 <- function(p, x) {                                              
    return(prod(p * x + 1))                                                 
}                                                                           
Run Code Online (Sandbox Code Playgroud)

让我们测试一下:

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                                                                
Run Code Online (Sandbox Code Playgroud)

总之,有时您可以通过分析问题的数学,以及/与数字实现相对立来实现加速.