【问题标题】:What does this R code mean?这个 R 代码是什么意思?
【发布时间】:2016-10-24 20:44:44
【问题描述】:
f <- function(x,q){ ## one step of the Newton iteration
  x-(pnorm(x)-q)/dnorm(x)
  }

x <- 0; #starting value
xj <- x # I don't know what is happening from this point onward! 
for (i in 1:10){
  x <- f(x,0.99);
  xj <- c(xj,x)
  }
print(xj)

基本上,我在这里尝试使用牛顿算法计算正态分布的 0.99 分位数,显然这就是解决方案。但是,我不遵循我在上面指出的步骤中发生的事情。有人可以简单地向我解释一下吗? for 循环中到底发生了什么?主要是,在 xj

谢谢!

【问题讨论】:

    标签: r loops for-loop


    【解决方案1】:

    这似乎是糟糕的编程。基本上,for 循环的第一步采用f(x,0.99)x=0 的结果并将其存储为x 的新值。然后将这个新值存储为 xj 的新元素,第一个元素为 0。当 for 循环进行迭代时,从f(x,0.99) 计算出新的 x 并存储为 xj 的新元素。

    我说这是不好的编程习惯,因为当您执行xj &lt;- c(xj,x) 之类的操作时,向量“xj”没有空间容纳新元素“x”,因此 R 创建了一个长度为 (xj) 的新向量+1 个元素并将 整个 xj 复制到新向量中。 R 每次通过xj &lt;- c(xj,x) 时都会这样做。如果算法在少量步骤中收敛,这很好(牛顿方法通常就是这种情况),但对于需要大量步骤才能收敛的其他算法,它会变得很慢。

    xj &lt;- c(xj,x) 的更好但不是完美的替代方案是首先将 xj 声明为长度为 n 的向量,例如 xj = rep(NA, n)(其中 n 是算法收敛的近似步数或更大),然后只返回不是 NA 的 xj 个元素。这样,即使你选择一个大的n,它仍然会比xj &lt;- c(xj,x)快很多。

    【讨论】:

      【解决方案2】:

      您正在运行定义为 f 的函数 10 次,每次都使用上次运行的结果更新插入其中的值 (x)。函数第一次运行时,x 的值是0,所以等式0-(pnorm(0)-0.99)/dnorm(0) 被计算为1.228248。然后,此结果将附加到数字向量 xj。函数f 然后第二次运行,第一个结果插入为x -- 1.228248-(pnorm(1.228248)-0.99)/dnorm(1.228248)=1.759464。然后,此结果将附加到向量 xj 的末尾。

      当循环结束时,这将持续 10 次迭代。最后,xj 被打印到控制台:

      [1] 0.000000 1.228248 1.759464 2.104157 2.280355 2.324003 2.326341 2.326348
       [9] 2.326348 2.326348 2.326348  
      

      如您所见,算法在第 7 次迭代后收敛,因此增加循环运行的次数将导致程序不断地将向量 xj 附加到相同的最终值 2.326348。如果您想单独观察每个迭代,您可以简单地从第六行中删除 for 语句及其周围的大括号,然后重复运行最后四行。

      【讨论】:

      • “算法收敛后for循环继续运行”的优点。设置一些基本情况条件来确定牛顿法是否收敛可能会使算法更加稳健。
      猜你喜欢
      • 1970-01-01
      • 2011-05-28
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多