是否可以矢量化以下函数,(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
答案 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))
}
总之,有时您只需分析问题的数学以及/与数字实现相对,就可以实现加速。