简体   繁体   中英

Solving equations in R similar to the Excel solver parameters function

I have a question concerning the possibility to solve functions in R, and doing the same using excel.

However I want to do it with R to show that R is better for my colleagues :)

Here is the equation:

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))

I want to find the b value for P<-0.5 . In Excel we can do it by selecting P value column and setting it to 0.5 and then by using the solver parameters function.

I don't know which method is the best? Or any other way to do it?

Thankx.

If you want to solve an equation the simplest thing is to do is to use uniroot which is in base-R.

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

As you see above my unitroot function fails. This is because there is no single solution to your equation which is easy to see as well. exp(-0.0000000000030 * <positive number between 0-1>) is practically (very close to) 1 so your equation becomes 1 - 1 - 0.5 = 0 which doesn't hold. You can see the same with a plot as well:

curve(func) #same result for curve(func, from=-1000, to=1000)

在此输入图像描述

In this function the result will be -0.5 for any b.

So one way to do it fast, is uniroot but probably for a different equation.

And a working example:

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

I have a strong suspicion that your equation was supposed to include -t_pw/f0 , not -t_pw*f0 , and that t_pw was supposed to be 3.0e-9 , not 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))
           }

Then @Lyzander's uniroot() suggestion works fine:

 u1 <- uniroot(function(x) Pfun(x)-0.5,c(6,10))

The estimated value here is 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)

在此输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM