这是一个版本的基础上汤米的答案,但避免了所有的循环:
library(multicore) # or library(parallel) in 2.14.x
set.seed(42)
m = 100
n = 30
system.time({
arms.C <- getNativeSymbolInfo("arms")$address
bounds <- 0.3 + convex.bounds(0.3, dir = 1, function(x) (x>1e-4)*(x<20))
if (diff(bounds) < 1e-07) stop("pointless!")
# create the vector of z values
zval <- 0.00001 * rep(seq.int(n), m) * rep(seq.int(m), each = n)
# apply the inner function to each grid point and return the matrix
dmat <- matrix(unlist(mclapply(zval, function(z)
sum(unlist(lapply(seq.int(100), function(i)
.Call(arms.C, bounds, function(x) (3.5 + z * i) * log(x) - x,
0.3, 1L, parent.frame())
)))
)), m, byrow=TRUE)
})
在多核机器,这将是非常快,因为它在核传播的负载。在单核机器上(或者对于Windows用户较差的用户),您可以使用lapply
替换上面的mclapply
,与Tommy的答案相比,只能稍微提高速度。但请注意,并行版本的结果会有所不同,因为它将使用不同的RNG序列。
请注意,任何需要评估R函数的C代码本质上都很慢(因为解释代码很慢)。我添加了arms.C
只是为了消除所有R-> C开销以使moli高兴;)但它没有任何区别。
通过使用列专业处理(问题代码为row-major,需要重新复制,因为R矩阵始终为列专业),您可以挤出更多的毫秒。
编辑:我注意到,摩力变化不大,因为汤米回答了这个问题 - 这样,而不是你必须使用一个循环,因为y[i]
都依赖于sum(...)
部分,所以function(z)
看起来像
function(z) { y <- 0
for (i in seq.int(99))
y <- y + .Call(arms.C, bounds, function(x) (3.5 + z * y) * log(x) - x,
0.3, 1L, parent.frame())
y }
你有三个嵌套for循环。你基本上在O(n^3)中运行。你真的需要他们吗? – simchona 2012-02-09 18:49:13
@simchona是的。我需要他们。 – moli 2012-02-09 18:50:32
如果你想要循环,你每次都会有可怕的运行时间。您需要完全修改它以打破糟糕的时间。 – simchona 2012-02-09 18:54:13