r - R中平方根的Newton-Raphson方法
问题描述
我是 R 的初学者,被要求编写代码来通过 R 中的Newton-Raphson 方法计算平方根。我按如下方式处理它:
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)
}
上面的代码是完整函数的原型,我计划在其中插入检查参数的完整性,例如,传递的参数类型是否为字符等。请注意,我没有编写这些检查这里。此代码工作正常,如下所示:
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
这段代码唯一的缺点是:当输入是数字向量时它不起作用,如下面的输出所述:
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
现在,我想添加甚至可以将向量作为参数传递的功能。我的想法是我创建了一个data frame
名为output
. 然后遍历向量x
元素并继续将新行附加到数据框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
}
结果和我卡在哪里:
我似乎在某个地方搞砸了。该代码创建了一个我没有准备好的输出,即使是数值:
square.root1(5)
[1] x.sqrt n.iter
<0 rows> (or 0-length row.names)
查看上面的输出,似乎控件没有进入第一个while
循环。我对如何继续创建允许向量作为参数的函数感到困惑。非常感谢任何帮助/提示。
注意:我一定会在这个函数中使用 while 循环。
另一个注意事项: 这个问题可能类似,但它并没有解决问题。以下是我运行此代码获得的输出:
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
推荐阅读
- python - 根据从 django 表单中的下拉列表中选择的值显示字段值
- google-data-studio - 如何在 Google Data Studio 中计算具有特定值的单元格的数量
- influxdb - influxDB 中的“事务安全”
- android - 在flutter项目中添加Facebook登录后出现“请配置Android SDK”错误
- reactjs - 请求 Google 日历权限时弹出额外授权
- python - 为使用 matplotlib 绘制 pandas 数据框设置不同的标记大小
- angular - Angular Observable unkown 不可分配。使用火力基地
- php - 将从 API 获取的日期转换为德语格式
- java - Gradle 在“Gradle Refresh”之后更改 JRE
- java - 使用 Activity 中的属性时的 Android 适配器最佳实践