我正在尝试计算以下值:
1/N * sum[i=0 to N-1]( log(abs(r_i - 2 * r_i * x_i)) )
其中 x_i递归计算如下:
x_{i+1} = r_i * x_i * (1 - x_i)
其中所有的r_i
s 都被给出(尽管它们随着 改变i
),并且x_0
被给出。(据我所知,没有任何棘手的数学方法可以将此计算简化为非迭代公式以加快速度)。
我的问题是它很慢,我想知道是否有一些外部观点可以帮助我加快速度。
# x0: a scalar. rs: a numeric vector, length N
# N: typically ~5000
f <- function (x0, rs, N) {
lambda <- 0
x <- x0
for (i in 1:N) {
r <- rs[i]
rx <- r * x
lambda <- lambda + log(abs(r - 2 * rx))
# calculate the next x value
x <- rx - rx * x
}
return(lambda / N)
}
现在就其本身而言,这个函数相当快,但我想调用它约 4,000,000 次(2000 x 2000 矩阵中的每个单元格一次),每个都有不同的rs
向量。
但是,如果我只调用它 2500 次(N=1000),它需要大约 25 秒,具有以下配置文件:
self.time self.pct total.time total.pct
"f" 19.98 81.22 24.60 100.00
"*" 2.00 8.13 2.00 8.13
"-" 1.32 5.37 1.32 5.37
"+" 0.70 2.85 0.70 2.85
"abs" 0.56 2.28 0.56 2.28
":" 0.04 0.16 0.04 0.16
有谁知道我如何加快速度?看起来乘法需要一段时间,但我已经预先缓存了任何重复的乘法。
我还尝试利用 与减少对and的调用sum( log(stuff(i)) )
相同的优势,但结果证明这是不可行的,因为长度向量(以千计)和典型值至少为 1,因此最终成为R。log(prod(stuff(i))
log
abs
stuff
N
prod(stuff)
Inf