integrate from 0 to a variable in r - 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")

Related

Plotting incomplete elliptic integral of 1st kind

I wanted to set a small dataframe in order to plot myself some points of the incomplete elliptic integral of 1st kind for different values of amplitude phi and modulus k. The function to integrate is 1/sqrt(1 - (k*sin(x))^2) between 0 and phi.Here is the code I imagined:
v.phi <- seq(0, 2*pi, 1)
n.phi <- length(v.phi)
v.k <- seq(-1, +1, 0.5)
n.k <- length(v.k)
k <- rep(v.k, each = n.phi, times = 1)
phi <- rep(v.phi, each = 1, times = n.k)
df <- data.frame(k, phi)
func <- function(x, k) 1/sqrt(1 - (k*sin(x))^2)
df$area <- integrate(func,lower=0, upper=df$phi, k=df$k)
But this generates errors and I am obviously mistaking in constructing the new variable df$area... Could someone put me in the right way?
You can use mapply:
df$area <- mapply(function(phi,k){
integrate(func, lower=0, upper=phi, k=k)$value
}, df$phi, df$k)
However that generates an error because there are some values of k equal to 1 or -1, while the allowed values are -1 < k < 1. You can't evaluate this integral for k = +/- 1.
Note that there's a better way to evaluate this integral: the incomplete elliptic function of the first kind is implemented in the gsl package:
> integrate(func, lower=0, upper=6, k=0.5)$value
[1] 6.458877
> gsl::ellint_F(6, 0.5)
[1] 6.458877
As I said, this function is not defined for k=-1 or k=1:
> gsl::ellint_F(6, 1)
[1] NaN
> gsl::ellint_F(6, -1)
[1] NaN
> integrate(func, lower=0, upper=6, k=1)
Error in integrate(func, lower = 0, upper = 6, k = 1) :
non-finite function value

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 )

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

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.

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