This is the Non-Linear Equation in "mu" which I want to solve numerically using R. All of the paired (x, y) are known. So the only variable is "mu"
Now, I have written the function in R. Then, I am trying to get the root by using "rootSolve" package. But it is giving an error.
This is my code of the function:
f = function(k){
sum(((2*exp(-x) - 1)*(2*exp(-y)- 1))/
(1 + k*(2*exp(-x) - 1)*(2*exp(-y)- 1)))
}
This is the error after running "uniroot.all" from the "rootSolve" package:
> library(rootSolve)
> uniroot.all(f, interval = c(-1, 1))
numeric(0)
Warning message:
In k * (2 * exp(-x) - 1) :
longer object length is not a multiple of shorter object length
Also, I am searching my root in the interval (-1, 1).
Can someone please help? I think, my way of defining the function is wrong. Hence this error is coming.
Can anyone confirm that my way of defining the function in the picture is correct or not?
Thank you in advance!
The way I have defined my function (chances are high that the way is wrong) and given my data (x, y)
, I have f(-1) < f(1) and also f(-1) * f(1) < 0
. These conditions are satisfied.
I cannot run curve function in R
. e.g., curve(f, from = -1, to = 1)
But, if I plot Vectorize(f)
, then the curve
function works.
Can anyone please help me in correcting the way of defining the function?
Thank you very much!
It seems that uniroot.all
wants a vectorized function. I have tried to use it and get the same error as you do. I can't find anything in the documentation of uniroot.all
about this.
I have tried package nleqslv
and can get a solution.
I have rewritten your function as follows (I think you made some errors in setting up the equation):
f <- function(k){
A <- 2*exp(-x)-1
B <- 2*exp(-y)-1
sum((A*B)/(1+k*A*B))
}
and run the function with these data
set.seed(13)
x <- runif(10)*10
y <- runif(10)*5
and the solved your function as follows:
library(nleqslv)
nleqslv(0,f)
with the following output:
$x
[1] 1.42992
$fvec
[1] 2.300633e-09
$termcd
[1] 1
$message
[1] "Function criterion near zero"
$scalex
[1] 1
$nfcnt
[1] 7
$njcnt
[1] 1
$iter
[1] 7
This solves with a Secant method. If you want to try other methods you can use testnslv
to explore.
** Addition **
Function uniroot.all
will work in my example as long as you do:
fvec <- Vectorize(f)
and change the interval to c(-1,1.7)
.