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&lt; -c(xj,x)步骤中发生了什么?我对编程很陌生,我非常感谢你的帮助!
谢谢!
答案 0 :(得分:1)
您正在运行您定义为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
语句,并重复运行最后四行。
答案 1 :(得分:1)
这似乎是糟糕的编程。基本上,for循环的第一步将f(x,0.99)
的结果与x=0
一起使用,并将其存储为x的新值。然后将这个新值存储为xj的新元素,第一个元素为0.当for循环经历迭代时,新的x从f(x,0.99)
计算并存储为xj的新元素。
我说这是糟糕的编程习惯,因为当你做xj <- c(xj,x)
之类的事情时,矢量&#34; xj&#34;为了获得一个新的元素&#34; x&#34;,所以R创建了一个长度为(xj)+1元素的新向量,并将整个 xj复制到新的向量中。 R每经过xj <- c(xj,x)
就会这样做。虽然如果算法以少量步骤收敛(并且通常是牛顿方法的情况),这很好,但是对于需要大量步骤来收敛的其他算法来说它变得很慢。
xj <- c(xj,x)
的一个更好但不完美的替代方法是首先将xj声明为长度为n的向量,比如xj = rep(NA, n)
(其中n是算法收敛的大致步数或更大) ,然后只返回不是NA的xj元素。这样,即使你选择一个大的n,它仍然会比xj <- c(xj,x)
快得多。