I'm trying to write an equation in R, and then solve it. I'm fairly new to R, so it's probably a basic question, but I haven't been able to make much sense of the CRAN notes on several packages that come up with a google.
My equation:
F- b ln(|1+ (F/b)|) - 0.05t = 0
I'm trying to solve for F, and have other equations/variables in R that define b and t already.
I guess what I'm asking is, how do I translate this formula into something in R, and go about solving it for F?
Assuming b and t are scalars with known values (here we assume 1 for both) we can minimize the the square of the left hand side assuming the answer lies in the indicated interval and if it achieves zero (which it does below) we have solved it. Note that F means FALSE in R so we used FF for clarity.
fun <- function(FF, b, t) (FF - b * log(abs(1+ (FF/b))) - 0.05*t)^2
optimize(fun, c(-10, 10), b = 1, t = 1)
giving:
$minimum
[1] 0.3503927
$objective
[1] 7.525844e-12
Related
I am quite new to r, so I turned to the internet for some help.
My question is:
for the equation ln(n/n0) = kln(1+x/k),
I would like to write a function that estimates k (based of trial and error) if all other variables are known.
In other words: function that would solve the equation like
0.85 = k * ln(1+0.56/k).
In my work I have to estimate k over and over again so the automation of the process would save me alot of time.
Thanks
Too long for a comment...
The equation x*ln(1+a/x) = b (for suitable values of a and b) has a solution expressed with the Lambert W function, available in the gsl package under the name lambert_W0. This solution is -a*b/(a*W(-b/(a*exp(b/a)))+b) where W is the Lambert W function.
> library(gsl)
> a=0.56; b=0.85
> x <- -a*b/(a*lambert_W0(-b/(a*exp(b/a)))+b) # solution of the equation
> x*log(1+a/x)
[1] 0.85
I don't know exactly for which values of a and b this solution works. It seems to work whenever a<b.
For some cases of a>b, there is a solution in terms of the Lambert W_{-1} function, lambert_Wm1 in gsl:
> library(gsl)
> a=0.6; b=0.4
> x <- -a*b/(a*lambert_Wm1(-b/(a*exp(b/a)))+b)
> x*log(1+a/x)
[1] 0.4
The domains of definition of W and W_{-1} can be found in the documentation of the lamW package (section "Details" page 3).
Is there a function in R that generates the inverse of a given function?
To be more specific: I have a polynomial of a third order and I need the inverse of it. It's strictly monotonously.
I read a few times that uniroot and/or polyroot can help. But how? Uniroot yields the root of a function and polyroot the zeros of a function. How can I use that for the inverse?
Maybe a dumb question but I don't get it..
Sorry for the late reply, but you could try using this function:
inverse = function(fn, interval = NULL, lower = min(interval), upper = max(interval), ...){
Vectorize(function(y){
uniroot(f=function(x){fn(x)-y}, lower=lower, upper=upper, ...)$root
})
}
I've seen variants of this a few times, but never with Vectorize built in. I put the function above together to hopefully be a little more user friendly, e.g.:
x = 1:10
y = sqrt(x)
sqrt.inv = inverse(sqrt, lower=1, upper=10)
sqrt.inv(y)
# [1] 1 2 3 4 5 6 7 8 9 10
Hope that helps!
The package investr is able to apply an inverse regression.
I am getting an equation with this form
exp(az) = 1 + cz
which I wanna solve for z,
where c is a complex number, so expectedly z is complex also.
I cannot figure out how to solve an equation involving complex number in R.
I hope anybody can help me
Wolfram Alpha can get a solution in terms of the Lambert W function (which it calls the ProductLog function):
The emdbook package (among others) has an implementation of the Lambert W function. (In order to make this work I had to fix a bug, so you can't use the CRAN implementation. Instead, install the latest version from Github: library(devtools); install_github("bbolker/emdbook") ...
library(emdbook)
sfun <- function(a,c) {
w <- lambertW(-a/c*exp(-a/c))
-(c*w+a)/(a*c)
}
Example
a <- 2+1i; c <- 1+1i
(z <- sfun(a,c))
## [1] -0.1686391-0.2337278i
Check answer:
(exp(a*z)-(1+c*z))
## [1] 0+5.551115e-17i
This is zero to within expected numeric tolerance ...
The intermediate step in Ben Bolker's solution:
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.
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)
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
Let's say I have a function that is nlogn in space requirements, I want to work out the maximum size of input for that function for a given available space. i.e. I want to find n where nlogn=c.
I followed an approach to calculate n, that looks like this in R:
step = function(R, z) { log(log(R)-z)}
guess = function(R) log(log(R))
inverse_nlogn = function(R, accuracy=1e-10) {
zi_1 = 0
z = guess(R)
while(abs(z - zi_1)>accuracy) {
zi_1 = z
z = step(R, z)
}
exp(exp(z))
}
But I can't get understand why it must be solved iteratively. For the range we are interested (n>1), the function is non singular.
There's nothing special about n log n — nearly all elementary functions fail to have elementary inverses, and so have to be solved by some other means: bisection, Newton's method, Lagrange inversion theorem, series reversion, Lambert W function...
As Gareth hinted the Lambert W function (eg here) gets you almost there, indeed n = c/W(c)
A wee google found this, which might be helpful.
Following up (being completely explicit):
library(emdbook)
n <- 2.5
c <- 2.5*log(2.5)
exp(lambertW(c)) ## 2.5
library(gsl)
exp(lambert_W0(c)) ## 2.5
There are probably minor differences in speed, accuracy, etc. of the two implementations. I haven't tested/benchmarked them extensively. (Now that I tried
library(sos)
findFn("lambert W")
I discover that it's implemented all over the place: the games package, and a whole package that's called LambertW ...