【问题标题】:Recursive manipulation of vector elements向量元素的递归操作
【发布时间】:2012-05-02 08:21:05
【问题描述】:

我有一个向量 a 并希望将每个元素与 b 递归相乘,而不使用循环。

a <- rep(0, 10)
a[1] <- 1
b <- 2

# with a loop
for (i in 2:length(a)) a[i] <- a[i-1] * b

如果您提供有关如何在不使用循环的情况下解决此问题的提示,我将不胜感激。

【问题讨论】:

  • 一般递归很难向量化。请参阅此处获取想法:stackoverflow.com/questions/7153586/… 如果您能解释为什么要避免循环(速度?)以及这是您要解决的实际问题(因为有时可以重新构思问题以避免递归),这将有所帮助完全)。
  • 感谢您的评论和链接。速度并不是真正的问题。这更多是出于好奇。我已经考虑了一段时间,想知道是否可以对其进行矢量化。

标签: r


【解决方案1】:

通常,如果没有显式循环,您将无法执行此操作。在这种特定情况下,您可以使用cumprod提供的隐式循环:

a <- rep(2, 10)
a[1] <- 1
cumprod(a)
#  [1]   1   2   4   8  16  32  64 128 256 512

【讨论】:

  • 可能值得注意的是cumprod() 也会快得多,因为它是.Primitive()...我的测试表明,它比原生 for loop 快 4 倍,但如果你只有 1.2 倍使用包compiler 中的cmpfun() 编译这两个函数。 +1
【解决方案2】:

对于形式的一般递归系列:

y[i] = x[i] + f[1]*y[i-1] + ... + f[p]*y[i-p]

您可以使用filter 函数。在您的情况下,您有x[i] = 0f[1] = 2f[i] = 0 用于i &gt; 1。这转化为:

filter(rep(0,10), 2, method="recursive", init=1/2)
# Time Series:
# Start = 1 
# End = 10 
# Frequency = 1 
#  [1]   1   2   4   8  16  32  64 128 256 512

在你学会如何使用它之后,filter 非常强大和高效。但是,对于您的几何案例来说,这可能是矫枉过正。

【讨论】:

  • 您如何概括一般情况下使用的过滤器?
【解决方案3】:

指数函数^是矢量化的,非常简单:

2^(0:9)
# [1]   1   2   4   8  16  32  64 128 256 512

你可能还想写

2^seq(from=0, to=9)

对于长向量,我很确定@JoshuaUlrich 的方法会快得多,但这个方法肯定非常紧凑。你还说你不是特别在意速度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 2021-05-01
    • 1970-01-01
    • 2021-02-28
    相关资源
    最近更新 更多