[英]Newton–Raphson method for square root in R
我是 R 的初學者,並被要求編寫代碼以在 R 中通過牛頓-拉夫森方法計算平方根。 我接近它如下:
square.root<-function(x,tol=1e-6,r=x/2) #function to calculate the square roots
{
n.iter=0 #number of iterations
while(abs(r^2-x)>=tol) #condition to check for a defined level of tolerance
{
r=(r+x/r)/2 #
n.iter=n.iter+1 #number of iterations is incremented
}
output<-list(r,n.iter)
names(output)<-c("x.sqrt","n.iter")
return(output)
}
上面的代碼是完整 function 的原型,我計划在其中插入檢查 arguments 的健全性,例如,傳遞的參數是否為字符類型等。請注意,我沒有編寫這些檢查這里。 此代碼工作正常,如下所示:
square.root(10)
$x.sqrt
[1] 3.162278
$n.iter
[1] 4
square.root(99)
$x.sqrt
[1] 9.949874
$n.iter
[1] 6
square.root(100)
$x.sqrt
[1] 10
$n.iter
[1] 6
這段代碼唯一的缺點是:當輸入是數字向量時不起作用,如下面的 output 所述:
square.root(c(10,99,100))
$x.sqrt
[1] 3.162278 9.979213 10.030495
$n.iter
[1] 4
Warning messages:
1: In while (abs(r^2 - x) >= tol) { :
the condition has length > 1 and only the first element will be used
2: In while (abs(r^2 - x) >= tol) { :
the condition has length > 1 and only the first element will be used
3: In while (abs(r^2 - x) >= tol) { :
the condition has length > 1 and only the first element will be used
4: In while (abs(r^2 - x) >= tol) { :
the condition has length > 1 and only the first element will be used
5: In while (abs(r^2 - x) >= tol) { :
the condition has length > 1 and only the first element will be used
現在,我想添加甚至可以將向量作為參數傳遞的功能。 我的想法是我創建了一個名為output
的空白data frame
。 然后遍歷向量x
元素和 go 以將新行附加到數據幀output
。
我寫了以下關於上述“想法”的代碼。
square.root1<-function(x,tol=1e-6,r=x/2)#function to calculate the square roots
{
output<-data.frame(x.sqrt=double(),n.iter=double()) #create a blank data frame
n.iter=rep(0,times=length(x)) #a vector of zeroes
i=1 #iteration counter
while(i<=length(x)) #iterate through all the values of the vector
{
while(abs(r[i]^2-x[i])>=tol) #the checking condition for the tolerance
{
r[i]=(r[i]+x[i]/r[i])/2
n.iter[i]=n.iter[i]+1 #the number of iterations is incremented
}
result<-data.frame(r[i],n.iter) #store the results in another data frame
names(result)<-c("x.sqrt","n.iter") #name the columns
rbind(output,result) #append the result data frame to the output data frame
i=i+1 #iterate the looping counter
}
return(output) #return the output data frame
}
我似乎在某個地方搞砸了。 該代碼創建了一個我沒有准備好的 output,即使是數值:
square.root1(5)
[1] x.sqrt n.iter
<0 rows> (or 0-length row.names)
查看上面的 output 似乎控件沒有進入第一個while
循環。 我不知道如何繼續創建這個允許向量作為參數的 function。 非常感謝任何幫助/提示。
注意:我一定會在這個 function 中使用 while 循環。
另一個注意事項:這個問題可能類似,但它並沒有解決問題。 以下是我通過運行此代碼獲得的 output:
MySqrt(c(99,10,100))
Iteration: 1 10 5.954545455 10.04545455
Iteration: 2 9.95 3.816967384 10.00010284
Iteration: 3 9.949874372 3.218424149 10
[1] 9.949874
這與我從我為平方根編寫的以向量作為參數的第一個代碼中獲得的結果幾乎相同。
根據評論,使用Vectorize
可能是最簡單的方法,但也可以對原始代碼進行一些小的更改,以便一切都在矢量上運行......
square.root<-function(x, tol=1e-6, r=x/2) #function to calculate the square roots
{
n.iter=0 #number of iterations
while(any(abs(r^2-x)>=tol)) #"any" added here - loops while any values greater than tol
{
n.iter=n.iter+(abs(r^2-x)>=tol) #only increases n.iter for errors greater than tol
r=(r+x/r)/2 #swapped with line above to get right value in n.iter calculation
}
output<-list(r,n.iter)
names(output)<-c("x.sqrt","n.iter")
return(output)
}
square.root(c(10,99,100))
$x.sqrt
[1] 3.162278 9.949874 10.000000
$n.iter
[1] 4 6 6
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.