Non-finite function value with integrate() R although solution exists - r

I would like to calculate the following integral in R:
print(integrate(function(x){((1.-x)^2)/(abs(1.-x))^(1/3)},lower = 0, upper = 1.6, abs.tol = 1E-7)$value)
And I get this error:
Error in integrate(function(x) { : non-finite function value
However, when I integrate up to 1.600001 or 1.599999, it works and yields 0.4710365 and 0.4710357.
But there is nothing special with this function at the point 1.6... So it should be some strange numerical problem in R.
Any ideas?

In line with #Bhas's answer, I would go for the following solution:
> f <- function(x){ifelse(x!=1,((1.-x)^2)/(abs(1.-x))^(1/3),0)} # Set f(1)=0 since it is the limit of 'f' at 1.
> integrate(f,lower=0,upper=1.6,abs.tol=1E-7)
0.4710361 with absolute error < 2.2e-08
'ifelse' avoids problems related to a vectorized 'x'

If you write your function like this
f <- function(x) {
r <- ((1.-x)^2)/(abs(1.-x))^(1/3)
cat("x=",x,"\n")
cat("r=",r,"\n")
r
}
you can get some idea of what's happening.
Try this
z <- integrate(f,lower = 0, upper = 1.6, abs.tol = 1E-7,subdivisions=50)
z
And you will see that integrate passes a value of 1 to functionf.
And dividing by 0 (from 1-x)) gives a NaN. This seems to be an artifact of integrate.
With the limits you specified you are jumping over a point where the function is undefined.
You can avoid that by doing
z1 <- integrate(f,lower = 0, upper = 1, abs.tol = 1E-7)
z1
z2 <- integrate(f,lower = 1, upper = 1.6, abs.tol = 1E-7)
z2
z1$value+z2$value
which gives a result of
[1] 0.4710361
I wouldn't know how to get around this other than by what you did or what I tried.

Related

Uniroot log(x) solution

I would like to find the root of log(x) = x2 − 2 using uniroot in R
f <- function(x) (log(x)+2-x^2)
uniroot(f, lower=0, upper=100000000)$root
But this shows the error
Error in uniroot(f, lower = 0, upper = 1e+08) : f() values at end
points not of opposite sign
uniroot requires an interval where the function has opposite signs at the two endpoints (since it uses a variation of the bisection method). It isn't a bad idea to do a quick plot when you don't know about just where to look:
f <- function(x) (log(x)+2-x^2)
x <- seq(0.0,4,0.01)
y <- f(x)
plot(x,y,ylim = c(-1,1),type = "l")
abline(h=0)
This yields:
From this you can see that there are two roots, one between 0 and 1, and one between 1 and 2:
uniroot(f,interval = c(0,1))$root #returns 0.1379346
uniroot(f,interval = c(1,2))$root #returns 1.564445

integrate with a vecor or list as upper limit R

I want to use integrate and calculate for different upper limits. I tried to put a vector and a list into the upper limit parameter:
ul <- as.list(seq(0.001,1,0.001))
integrand <- function(x) {1/((x+1)*sqrt(x))}
test <- integrate(integrand, lower = 0, upper = ul)$val
Error:
Error in is.finite(upper) : default method not implemented for type 'list'
I tried it with a for loop:
ul <- seq(0.001,1,0.001)
for (i in ul){
test = NULL
test <- rbind(test, integrate(integrand, lower = 0, upper = S[i])$val[i])
}
error: Error in if (is.finite(lower) && is.finite(upper)) { : missing value where TRUE/FALSE needed
I could change the upper limit manually and then save the result with rbind in a data frame, but this would need to much time:
test <-data.frame(test = integrate(integrand, lower = 0, upper = 0.001)$val)
test <- data.frame(rbind(test, integrate(integrand, lower = 0, upper = 0.002)$val))
and so on.
I guess I should use lappy to solve my problem, but I'm not familiar to using it. How could I solve my problem?
sapply(ul, function(x) integrate(integrand, lower = 0 , upper = x)$value )

integrate from 0 to a variable in r

I would like to plot y against z, where y=(1+z)int_0^z((0.3(1+z')^3+0.7)^-1/2)dz',
where int_0^z just means integrate from 0 to z.
I figured I should first integrate from 0 to z, and then use the integral result to plug into the equation. Here is my code:
integrand <- function(z1) {(0.3*(1+z1)^3+0.7)^-1/2}
integral<-integrate(integrand, lower = 0, upper = z)
but this error appears:
Error: object 'any_number' not found
Error in integrate(integrand, lower = 0, upper = z) :
object 'z' not found"
How do I define z here?
Thanks,
Jade
I'll give it a try.
integrand <- function(z1) {(0.3*(1+z1)^3+0.7)^-1/2}
We need to make integral a function of z, ensure that it only returns the value of the integral, and that it is vectorized in z:
integral <- Vectorize(function(z) integrate(integrand, lower = 0, upper = z)$value)
Now we can test it:
integral(1:2)
#[1] 0.3056435 0.4037815
And plot:
curve(integral, 0, 10, xname = "z")

non-finite function value integrate R

I encountered a problem when i was trying to use the integrate function in R.
non-finite function value
i continuous getting this error message when i call the integrate function with some data. I tried to restrict the target function in range of (-1,1)
and it integrate on a finite interval(-1,1). i couldn't find any explanation for this error. has anyone encountered this kind of situation before? many thanks
function reference link as below
http://stat.ethz.ch/R-manual/R-devel/library/stats/html/integrate.html
following is the code
f<-function(p,c,n,k,a,b){
Ans=p^(a-1)*(1-p)^(b-1)*(c*p)^(k)*(1-c*p)^(n-k)
if (is.finite(Ans)[1]){
return(Ans)
}
else if (abs(Ans)>1) {
return(1)
}
else {
return(0)
}
}
intFun<-function(c,n,k,a,b){
return(integrate(f,lower=0,upper=1,c=c,n=n,k=k,a=a,b=b,abs.tol =100)$value)
}
At a guess, your problem is that you have missing or NaN input values, which are considered non-finite. That means that this error can be generated not only by infinite values:
integrate(function(x) 1 / x, lower = -1, upper = 1)
## Error in integrate(function(x) 1/x, lower = -1, upper = 1) :
## non-finite function value
but by missing ones too:
integrate(function(x) ifelse(x == 0, NA, x), lower = -1, upper = 1)
## Error in integrate(function(x) ifelse(x == 0, NA, x), lower = -1, upper = 1) :
## non-finite function value

Integrating beta-function-like function over compact support [0,alpha], alpha < 1

I would like to integrate a following function named betalog
g <- function(x,a,b){
if (a < 0 | b < 0) stop()
temp <- (a-1)*log(x) + (b-1)*log(1-x)
return( exp(temp) )
}
betalog<- function(x,a,b)
{
temp <- g(x=x,a=a,b=b)* log(x/(1-x))
return( temp )
}
The function g is integrand of the beta function. In theory, betalog should be integrable over any [0,alpha] interval if 0 < alpha < 1, and a > 0, b >0.
However, I cannot numerically integrate betalog with very small a:
a <- 0.00001
b <- 1
alpha <- 0.5
integrate(betalog,a=a,b=b,lower=0,upper=alpha,subdivisions=1000000L)
Error in integrate(betalog, a = a, b = b, lower = 0, upper = alpha, subdivisions =
1000000L) :
non-finite function value
In fact, I cannot even compute the incomplete beta function using R integrate function when a is very small:
integrate(g,a=a,b=b,lower=0,upper=alpha,subdivisions=1000000L)
Error in integrate(g, a = a, b = b, lower = 0, upper = alpha, subdivisions = 1000000L) :
roundoff error is detected in the extrapolation table
Can anyone gives me tip to integrate such incomplete beta-like function in R?
> betalog(0, a, b)
[1] -Inf
Your function is singular at the lower bound. Recall that to compute an improper integral you must replace the singular bounds with dummy variables and take the limit from the correct side towards that bound. In particular,
> integrate(betalog,a=a,b=b,lower=0.000001,upper=alpha,subdivisions=10000000L)
-94.60292 with absolute error < 0.00014
> integrate(betalog,a=a,b=b,lower=.Machine$double.xmin * 1000,upper=alpha,subdivisions=10000
-244894.7 with absolute error < 10
> integrate(betalog,a=a,b=b,lower=.Machine$double.xmin,upper=alpha,subdivisions=10000000L)
Error in integrate(betalog, a = a, b = b, lower = .Machine$double.xmin, :
non-finite function value
I suspect that your integral diverges, but this might be tricky since even state-of-the-art symbolic algebra systems can't prove that:
http://www.wolframalpha.com/input/?i=Integral%28x%5E%280.00001+-1%29+ln%28x%2F%281-x%29%29%2C+x%2C0%2C+0.5%29
Whatever the case, R is not the correct tool for this problem.

Resources