solve complex number equation in R - r

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:

Related

Is there a way to solve an equation in R?

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

Writing an R function that evens out both sides of equation

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

can you use variable limits of integration with the Cubature library

I'm trying to use a variable limit of integration using the Cubature library.
For example:
adaptIntegrate(function(x) {x[1]*x[2]},
lowerLimit = c(0,0),
upperLimit = c(x[2],1))$integral
This doesn't work
Thanks
The integral has form \int_O^1 \int_0^{x[2]} f dx[1] dx[2]
The domain of integration is a triangle (make a picture!) with vertices (0,0), (0,1), (1,1). For such a domain, use the SimplicialCubature package.
> f <- function(x) x[1]*x[2]
> S <- cbind(c(0,0),c(0,1),c(1,1)) # the triangle (simplex)
> library(SimplicialCubature)
> adaptIntegrateSimplex(f, S)
$integral
[1] 0.125
$estAbsError
[1] 1.25e-13
$functionEvaluations
[1] 32
Cubature is a package for adaptive multidimensional integration over hypercubes. I am also looking for packages which do multidimensional integration over any specific region (i.e. use variable as limits), anyone knows?
In addition, the definition of the function is not appropriate. I guess what you want is
function(x1,x2) x1*x2

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

Why is nlogn so hard to invert?

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

Resources