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
Related
I've a function as follows:
V <- seq(50, 350, by = 1)
> VK
Voltage^0 Voltage^1 Voltage^2 Voltage^3
-1.014021e+01 9.319875e-02 -2.738749e-04 2.923875e-07
> plot(x = V, exp(exp(sapply(0:3, function(x) V^x) %*% VK)), type = "l"); grid()
Now I would like to do an inverse regression upon this certain function. I've seen Solving for the inverse of a function in R :
inverse = function (f, lower = -100, upper = 100) {
function (y) uniroot((function (x) f(x) - y), lower = lower, upper = upper)1
}
square_inverse = inverse(function (x) x^2, 0.1, 100)
square_inverse(4)
and I'm trying to adjust it to my purposes as follows:
certain_function <- function(x=V) { exp(exp(sapply(0:3, function(x) V^x) %*% VK)) }
inverse = function (f, lower = 50, upper = 350) {
function (y) uniroot((function (x) f(x) - y), lower = lower, upper = upper)[1]
}
inverse_regression = inverse(certain_function, 50, 350)
inverse_regression(2)
Unfortunately this yields:
Error in uniroot((function(x) f(x) - y), lower = lower, upper = upper) :
f() values at end points not of opposite sign In addition: Warning messages:
1: In if (is.na(f.lower)) stop("f.lower = f(lower) is NA") :
the condition has length > 1 and only the first element will be used
2: In if (is.na(f.upper)) stop("f.upper = f(upper) is NA") :
the condition has length > 1 and only the first element will be used
As far as I understood: The error means that there are more roots than only one (uniroot can only handle one root) but there shouldn't be more than one root since it's a strictly monotonically increasing function.
The warnings I do not understand..
edit: I'm trying to get behind it.. I removed both exponentials which yields the following plot:
and this still generates the following error:
> inverse_regression(0.1)
Error in uniroot((function(x) f(x) - y), lower = lower, upper = upper) :
f() values at end points not of opposite sign In addition: Warning messages:
1: In if (is.na(f.lower)) stop("f.lower = f(lower) is NA") :
the condition has length > 1 and only the first element will be used
2: In if (is.na(f.upper)) stop("f.upper = f(upper) is NA") :
the condition has length > 1 and only the first element will be used
Why is this? Obviously the curve has opposite signs at both end points.. I guess end points mean the points left and right to the root?
Probably the inverse regression did not work due to the definition of "certain_function". This is a matrix-vector product and the result is a vector again. Therefore I transformed this to a regular function function(x) exp(exp(sum(x^0*VK[1],x^1*VK[2],x^2*VK[3],x^3*VK[4])) and now it is working.
Hence, one should be aware of the bounds each time in general.
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 )
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.
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")
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.