I have been browsing through quite some help pages, but I did not find the solution for my - probably - simple problem. I defined a function
funB <- function(x) (0.8042851 +
((3.9417843-0.8042851)/(1+((x/0.4039609)^(-3.285016)))))
and would like to solve it for a given x (say, x = 0.2). How do I do that? I have looked at uniroot()
and polyroot()
, but they did not seem to fit my function.
If you wanted to find the value of x
such that funB(x)
was equal to 0.2, you would do something like this:
funB <- function(x) (0.8042851 +
((3.9417843-0.8042851)/(1+((x/0.4039609)^(-3.285016)))))
target <- 0.2
uniroot(function(x) funB(x)-target, interval=c(-5,10))
but there's a problem. It's up to you to pick an interval
value that brackets a root (ie funB(x)<0.2
for the lower value and >0.2 for the upper value, or vice versa. funB
is NaN
for x<0, 0.8042851 for x==0, and increasing for x>0 (try curve(funB, from=-5, to=100, n=1001)
for example). So the solution you want (if I've guessed right about the meaning of your question) doesn't seem to exist.
note : in general a negative value raised to a negative power is NaN
in R (even in cases where the answer "should" be defined, eg (-8)^(1/3) is the cube root of -8, which is -2...). If you're sure you know what you're doing you could replace (x/a)^b
with sign(x)*(abs(x)/a)^b)
... (if you make this change, the function appears well-behaved for x>-0.4 and funB(x)-0.2
does have a root between -0.3 and -0.2... but I have no idea if this makes sense for your application or not )
Just to be sure that there is a root where you are expecting it, plot the graph of funB
.
curve(funB)
Define an auxiliary function, f
, taking an extra argument and solve this new function for a = <target_value>
.
f <- function(x, a) funB(x) - a
uniroot(f, interval = c(0, 1e3), a = 2)
#$root
#[1] 0.3485097
#
#$f.root
#[1] -0.0001305644
#
#$iter
#[1] 12
#
#$init.it
#[1] NA
#
#$estim.prec
#[1] 6.103516e-05
Well, I guess I must like doing things the hard way. I just rearranged your function to find its inverse:
funC <- function(y) (((3.137499)/(y - 0.8042851) - 1)^(-1/3.285016)) * 0.4039609
So if I want to know when funB(x) == 3.7
I can do:
funC(3.7)
#> [1] 0.860193
and sure enough
funB(0.860193)
#> [1] 3.7
or indeed
funB(funC(1))
#> [1] 1
And as others have pointed out, x doesn't have a real value at funB(x) == 0.2
as you can see in this plot:
curve(funC, 0, 4)
Now, if you really want to know the complex root where funB(x) == 0.2
then you can modify funC
like so:
funC <- function(y) (((3.137499)/(as.complex(y) - 0.8042851) - 1)^(-1/3.285016)) * 0.4039609
So now:
funC(0.2)
#> [1] 0.1336917+0.1894797i
And therefore the answer to your question is 0.1336917 +/- 0.1894797i
funB(complex(real = 0.133691691, imaginary = 0.1894797))
[1] 0.1999996+0i
Close enough.
funB <- function(x) (0.8042851 + ((3.9417843-0.8042851)/(1+((x/0.4039609)^(-3.285016)))))
# call the function with desired input
funB(0.2)
...and the output:
> funB(0.2)
[1] 1.087758
>
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.