对于有经验的人来说,这应该很简单.我想用R求解方程.我知道你可以使用Solve()求解不同的线性/二次方程.
但我有这样的事情:
1/20 = 1/8 * (1/(12+x)) + 1/4*(1/(40+x)) + 3/4*(1/(50+x))
Run Code Online (Sandbox Code Playgroud)
在这种情况下如何解决x?它不能手工完成.它需要一些数字方法来解决这个问题,就像在TI83中一样.
有没有一种简单快捷的方法在R中执行此操作而无需编写代码行?谢谢!
正如你所说,确实存在根源.首先是绘制函数:
f <- function(x) {1/20 - 1/8 * (1/(12+x)) + 1/4*(1/(40+x)) + 3/4*(1/(50+x))}
x <- seq(-100,100)
par(mar=c(2,2,1,2)) # this just minimizes plot margins
plot(x,f(x), type="l")
abline(0,0,col="blue",lty=2)
Run Code Online (Sandbox Code Playgroud)

很明显,f(x)交叉0,几次.
下一步是估计交叉点.一种方法是查找符号的变化:
x <- seq(-75,0,0.001)
y <- sign(f(x)) # vector of +1 or -1
plus.to.minus <- which(diff(y)<0) # diff(y)<0 when f crosses from (+) to (-)
minus.to.plus <- which(diff(y)>0) # diff(y)>0 when f crosses from (-) to (+)
# first two roots are (+) to (-); third is (-) to (+)
lower <- c(plus.to.minus[1:2],minus.to.plus[3])
roots <- sapply(lower,function(i)uniroot(f,interval=c(x[i],x[i+1]))$root)
lapply(roots,function(x) points(roots,c(0,0,0),col="red",pch=16))
roots
# [1] -67.38961 -41.72593 -10.38446
Run Code Online (Sandbox Code Playgroud)

此代码试图寻找x其中f(x)的变化迹象.实际上有两个原因f(x)可以改变符号:根或渐近线.在你的情况下,有三个根和三个渐近线.这里的成功取决于在x中有足够小的增量,这样你就不会完全错过一个交叉点.根据上图,看起来0.001足够小.
这里,y是一个向量,它包含x在-75和0之间的f(作为+1或-1)的符号,增量为0.001.通过检查上图来选择极限(-75,0).我们可以直观地看到有三个根.前两个从(+)到( - )交叉,第三个从( - )到(+)交叉.因此,我们确定交叉发生的x的索引(使用which(...)),然后创建一个包含前两个元素plus.to.minus和第三个元素的向量minus.to.plus.然后我们调用uniroot(...)使用increment=c(x[i],x[i+1])where i是适当交叉的索引.
最后,我们绘制结果以确认我们实际上找到了根.这非常重要 - 始终,始终绘制结果.事实证明,uniroot(...)会找到一个存在渐近线的"根",所以你必须确保找到了真正的根.