所以,我应该写代码来执行牛顿方法来计算任意数字的平方根到指定的精度(公差)。
这是我的代码:
MySqrt <- function(x, eps = 1e-6, itmax = 100, verbose = TRUE) {
GUESS <- 11
myvector <- integer(0)
i <- 1
if (x < 0) {
stop("Square root of negative value")
}
else {
myvector[i] <- GUESS
while (i <= itmax) {
GUESS <- (GUESS + (x/GUESS)) * 0.5
myvector[i+1] <- GUESS
if (abs(GUESS-myvector[i]) < eps) {
break()
}
if (verbose) {
cat("Iteration: ", formatC(i, width = 1), formatC(GUESS, digits = 10, width = 12), "\n")
}
i <- i + 1
}
}
myvector[i]
}
eps是容忍度。当我使用函数来计算21的平方根时,我得到了这个作为输出:
> MySqrt(21, eps = 1e-1, verbose = TRUE)
Iteration: 1 6.454545455
Iteration: 2 4.854033291
Iteration: 3 4.59016621
然而,我不确定函数是否应该停止执行迭代。有人可以验证我的代码是否正确吗?非常感谢!
答案 0 :(得分:3)
您的代码几乎是正确的。它正在迭代正确的次数。唯一的错误是你不会在break语句之后增加i
,因此你不会返回最近的近似值。相反,你将返回前一个。
为了验证它是否在正确的时间停止,您可以在中断上方移动跟踪线。您还可以将GUESS-myvector[i]
添加到跟踪中,这样您就可以在差异变得足够小时立即停止跟踪。如果你这样做并运行该函数,那么它在正确的时间停止的事实,以及它返回错误值的事实将是显而易见的:
> MySqrt(21,eps=1e-1)
Iteration: 1 6.454545 -4.545455
Iteration: 2 4.854033 -1.600512
Iteration: 3 4.590166 -0.2638671
Iteration: 4 4.582582 -0.007584239
[1] 4.590166
虽然您的代码(几乎)正确,但它不是以非常好的R风格编写的。例如,除非您想要返回整个估算向量,否则您没有理由需要将它们全部保留。此外,不是使用while循环,而是使用for循环更有意义。这是一个可能的功能改进版本:
MySqrt <- function(x, eps = 1e-6, itmax = 100, verbose = TRUE) {
GUESS <- 11
if (x < 0) {
stop("Square root of negative value")
}
for(i in 1:itmax){
nextGUESS <- (GUESS + (x/GUESS)) * 0.5
if (verbose)
cat("Iteration: ", i, nextGUESS, nextGUESS-GUESS, "\n")
if (abs(GUESS-nextGUESS) < eps)
break
GUESS<- nextGUESS
}
nextGUESS
}