I have a function which I would like to integrate for x
between -Inf
and Inf
. I'm using the function integrate
in R. However, I do get an error saying Non-finite function value
.
random_walk_func<-function(t,A,sigma,y,x){
a1 = (2*A/(sigma))*exp((4*A*(y-x+(4*A*t)))/(sigma))
b1 = erfc((y-x+(8*A*t))/(2*sqrt(sigma*t)))
return(a1 * b1)
}
integrate(random_walk_func, lower = -Inf , upper = Inf, t,A,sigma,y)$value
Error in integrate(random_walk_func, lower = -Inf, upper = Inf, :
non-finite function value
It appears that this is most likely due to the fact that for x
values towards -Inf
, a1
becomes Inf
whereas b1
is 0
. Thus, when a1
and b1
are multiplied, the result is NaN
.
Any suggestion on how to solve this kind of numerical issues?
There are a couple of things to point out here. Firstly, your function needs to have as its first argument the variable over which you want to integrate, so you need to rewrite your function as:
random_walk_func<-function(x, t, A, sigma, y)
{
a1 <- (2*A/(sigma))*exp((4*A*(y-x+(4*A*t)))/(sigma))
b1 <- erfc((y-x+(8*A*t))/(2*sqrt(sigma*t)))
a1 * b1
}
Secondly, remember that this is numeric rather than symbolic integration, so you need to have values for all the other parameters you are passing to your function. I have no idea what you want these to be, so let's set them all to 1:
t <- A <- sigma <- y <- 1
Thirdly, it's a good idea to look at what you're integrating if your are getting infinity errors. If there are infinite values among the evaluated points, then you will get an error rather than a numeric result:
x <- seq(-10, 10, 0.01)
plot(x, random_walk_func(x, t, A, sigma, y), type = "l")
We can see that we will get an excellent approximation of the integral if we choose limits of -10 and 10:
integrate(random_walk_func, lower = -10 , upper = 10,
t = t, A = A, sigma = sigma, y = y)$value
#> [1] 1
However, ultimately the reason why you are getting the error is that a1
gets monstrously large very quickly the further from the central peak that we go, and b1
becomes infintesimal. Even though their product is nearly zero, the intermediate calculations are beyond R's numerical tolerance, which is what breaks the calculation. Once a1
exceed about 10^308, R will call it Inf
and a1 * b1
is therefore also Inf
.
The way round this is to calculate a1
and b1
as logs, then return their exponentiated sum. So if you do:
random_walk_func <- function(x, t, A, sigma, y)
{
a1 = log(2 * A / sigma) + 4 * A * (y - x + (4 * A * t)) / sigma
b1 = log(erfc((y - x + 8 * A * t) / (2 * sqrt(sigma * t))))
exp(a1 + b1)
}
Then you get:
integrate(random_walk_func, lower = -Inf, upper = Inf,
t = t, A = A, sigma = sigma, y = y)$value
#> [1] 1