如何在R中解决这样的符号函数

pur*_*lau 2 r

对于有经验的人来说,这应该很简单.我想用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中执行此操作而无需编写代码行?谢谢!

jlh*_*ard 5

正如你所说,确实存在根源.首先是绘制函数:

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(...)会找到一个存在渐近线的"根",所以你必须确保找到了真正的根.