优化递归序列的计算

时间:2009-09-25 18:01:25

标签: algorithm r recursion

R中计算定义为

的递归序列的最快方法是什么
x[1] <- x1 
x[n] <- f(x[n-1])

我假设正确分配了适当长度的向量x。有没有比循环更聪明的方法?

变体:将其扩展为向量:

 x[,1] <- x1 
 x[,n] <- f(x[,n-1])

5 个答案:

答案 0 :(得分:4)

关于这是否可以以任何方式完全“矢量化”的问题,我认为答案可能是“不”。数组编程背后的基本思想是操作同时应用于整个值集。类似地,对于“令人尴尬的并行”计算的问题。在这种情况下,由于递归算法取决于每个先前状态,因此无法从并行处理中获得速度:它必须以串行方式运行。

话虽如此,加速你的计划的通常建议适用。例如,尽可能多地执行递归函数之外的计算。排序一切。预定义数组长度,以便在循环期间不必增长。等等See this question for a similar discussionTim Hesterberg's article on efficient S-Plus Programming中还有一个伪代码示例。

答案 1 :(得分:4)

解决重现关系;)

答案 2 :(得分:2)

您可以考虑在C / C ++ / Fortran中编写它,并使用方便的inline包来处理编译,链接和加载。

当然,如果需要保留R函数,那么函数f()可能是一个真正的约束。在Rcpp中有一个来自C ++ - to-R的回调示例,但这需要比使用内联更多的工作。

答案 3 :(得分:1)

如果您需要整个序列的速度有多快?假设函数是O(1),你不能比O(n)做得更好,循环将会给你这个。

答案 4 :(得分:1)

通常,语法x $ y&lt; -f(z)每次都必须重新分配x,如果x是一个大对象,这将非常慢。但是,事实证明R有一些技巧,所以列表替换函数[[<-不会每次都重新分配整个列表。所以我认为你可以合理有效地做到:

x[[1]] <- x1 
for (m in seq(2, n))
    x[[m]] <- f(x[[m-1]])

这里唯一浪费的方面是你必须为for循环生成一个长度为n-1的数组,这不是理想的,但它可能不是一个巨大的问题。如果您愿意,可以通过while循环替换它。通常的矢量化技巧(lapply等)在这里不起作用......

(双括号为您提供了一个列表元素,这是您可能想要的,而不是单个列表。)

有关详细信息,请参阅Chambers(2008)。数据分析软件。页。 473-474。