R中计算定义为
的递归序列的最快方法是什么x[1] <- x1
x[n] <- f(x[n-1])
我假设正确分配了适当长度的向量x。有没有比循环更聪明的方法?
变体:将其扩展为向量:
x[,1] <- x1
x[,n] <- f(x[,n-1])
答案 0 :(得分:4)
关于这是否可以以任何方式完全“矢量化”的问题,我认为答案可能是“不”。数组编程背后的基本思想是操作同时应用于整个值集。类似地,对于“令人尴尬的并行”计算的问题。在这种情况下,由于递归算法取决于每个先前状态,因此无法从并行处理中获得速度:它必须以串行方式运行。
话虽如此,加速你的计划的通常建议适用。例如,尽可能多地执行递归函数之外的计算。排序一切。预定义数组长度,以便在循环期间不必增长。等等See this question for a similar discussion。 Tim 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。