在 R 中求解类似于 Excel 求解器参数函数的方程
Solving equations in R similar to the Excel solver parameters function
我有一个关于在 R 中求解函数的可能性的问题,并使用 excel 做同样的事情。
但是我想用 R 来做,以表明 R 对我的同事更好:)
公式如下:
f0<-1e-9
t_pw<-30e-9
a<-30.7397582453682
c<-6.60935546184612
P<-1-exp((-t_pw)*f0*exp(-a*(1-b/c)^2))
我想找到 P<-0.5
的 b
值。在 Excel 中,我们可以通过选择 P 值列并将其设置为 0.5,然后使用求解器参数函数来实现。
不知道哪种方法最好?或者有其他方法吗?
谢谢。
如果你想解方程,最简单的方法就是使用 base-R 中的 uniroot
。
f0<-1e-9
t_pw<-30e-9
a<-30.7397582453682
c<-6.60935546184612
func <- function(b) {
1-exp((-t_pw)*f0*exp(-a*(1-b/c)^2)) - 0.5
}
#interval is the range of values of b to look for a solution
#it can be -Inf, Inf
> uniroot(func, interval=c(-1000, 1000), extendInt='yes')
Error in uniroot(func, interval = c(-1000, 1000), extendInt = "yes") :
no sign change found in 1000 iterations
正如您在上面看到的,我的 unitroot
函数失败了。这是因为你的方程没有单一的解,也很容易看到。 exp(-0.0000000000030 * <positive number between 0-1>)
实际上(非常接近)1 所以你的等式变成 1 - 1 - 0.5 = 0
不成立。您也可以通过绘图看到相同的内容:
curve(func) #same result for curve(func, from=-1000, to=1000)
在这个函数中,对于任何 b,结果都是 -0.5。
因此,一种快速完成的方法是 uniroot
,但可能适用于不同的方程式。
还有一个工作示例:
myfunc2 <- function(x) x - 2
> uniroot(myfunc2, interval=c(0,10))
$root
[1] 2
$f.root
[1] 0
$iter
[1] 1
$init.it
[1] NA
$estim.prec
[1] 8
我强烈怀疑你的等式应该包括 -t_pw/f0
,而不是 -t_pw*f0
,并且 t_pw
应该是 3.0e-9
,而不是 30e-9
.
Pfun <- function(b,f0=1e-9,t_pw=3.0e-9,
a=30.7397582453682,
c=6.60935546184612) {
1-exp((-t_pw)/f0*exp(-a*(1-b/c)^2))
}
那么@Lyzander 的 uniroot()
建议就可以了:
u1 <- uniroot(function(x) Pfun(x)-0.5,c(6,10))
这里的估计值为8.05。
par(las=1,bty="l")
curve(Pfun,from=0,to=10,xname="b")
abline(h=0.5,lty=2)
abline(v=u1$root,lty=3)
我有一个关于在 R 中求解函数的可能性的问题,并使用 excel 做同样的事情。
但是我想用 R 来做,以表明 R 对我的同事更好:)
公式如下:
f0<-1e-9
t_pw<-30e-9
a<-30.7397582453682
c<-6.60935546184612
P<-1-exp((-t_pw)*f0*exp(-a*(1-b/c)^2))
我想找到 P<-0.5
的 b
值。在 Excel 中,我们可以通过选择 P 值列并将其设置为 0.5,然后使用求解器参数函数来实现。
不知道哪种方法最好?或者有其他方法吗?
谢谢。
如果你想解方程,最简单的方法就是使用 base-R 中的 uniroot
。
f0<-1e-9
t_pw<-30e-9
a<-30.7397582453682
c<-6.60935546184612
func <- function(b) {
1-exp((-t_pw)*f0*exp(-a*(1-b/c)^2)) - 0.5
}
#interval is the range of values of b to look for a solution
#it can be -Inf, Inf
> uniroot(func, interval=c(-1000, 1000), extendInt='yes')
Error in uniroot(func, interval = c(-1000, 1000), extendInt = "yes") :
no sign change found in 1000 iterations
正如您在上面看到的,我的 unitroot
函数失败了。这是因为你的方程没有单一的解,也很容易看到。 exp(-0.0000000000030 * <positive number between 0-1>)
实际上(非常接近)1 所以你的等式变成 1 - 1 - 0.5 = 0
不成立。您也可以通过绘图看到相同的内容:
curve(func) #same result for curve(func, from=-1000, to=1000)
在这个函数中,对于任何 b,结果都是 -0.5。
因此,一种快速完成的方法是 uniroot
,但可能适用于不同的方程式。
还有一个工作示例:
myfunc2 <- function(x) x - 2
> uniroot(myfunc2, interval=c(0,10))
$root
[1] 2
$f.root
[1] 0
$iter
[1] 1
$init.it
[1] NA
$estim.prec
[1] 8
我强烈怀疑你的等式应该包括 -t_pw/f0
,而不是 -t_pw*f0
,并且 t_pw
应该是 3.0e-9
,而不是 30e-9
.
Pfun <- function(b,f0=1e-9,t_pw=3.0e-9,
a=30.7397582453682,
c=6.60935546184612) {
1-exp((-t_pw)/f0*exp(-a*(1-b/c)^2))
}
那么@Lyzander 的 uniroot()
建议就可以了:
u1 <- uniroot(function(x) Pfun(x)-0.5,c(6,10))
这里的估计值为8.05。
par(las=1,bty="l")
curve(Pfun,from=0,to=10,xname="b")
abline(h=0.5,lty=2)
abline(v=u1$root,lty=3)