Search code examples
rsequenceintegral

How to calculate an integral with a change parameter and record every result as a sequence in R?


I have an integral with a change parameter (y) as follows.

y <- seq(1,2,0.01)
integrand_1 <- function(t){
  
  A1 <- 30*(y*30^(1/2)-t)^2
  A2 <- (dnorm(t+30^(1/2))+dnorm(t-30^(1/2)))
  
  return(pchisq(A1, 30)*A2)
}
W <- integrate( f = integrand_1, 
                   lower = 0, 
                   upper = y*30^(1/2)
)

W <- W$value
W

However, the integral cannot allow a sequence parameter to import it.

How can I obtain the outcomes with the sequence parameter and make the outcomes be a sequence (W)?

Many thanks to anyone who can provide a solution.


Solution

  • To make it work, we need to make a couple of small changes to your code.

    1. We know that integrate's first argument has to be numeric. In your example: t. However, we also have y, which has to be passed to the function as well. So our new function is:
    integrand <- function(t, y) {
      a1 <- 30 * (y * 30 ^ (1 / 2) - t) ^ 2
      a2 <- (dnorm(t + 30 ^ (1 / 2)) + dnorm(t - 30 ^ (1 / 2)))
      
      pchisq(a1, 30) * a2
    }
    

    Since we cannot pass a vector along to integrate, but still need to evaluate it for all values of y, I wrap it in a lapply() expression, which will return a list with the value of the integral for each value of Y.

    # Let's call the vector of Y values capital Y and elements of this lower-case y
    Y <- seq(1, 2, 0.01)
    
    # Use the lapply to evaluate the integral for each y
    W_list <- lapply(Y, function(y) {
      integrate(
        f = integrand, 
        lower = 0, 
        upper = y * 30 ^ (1 / 2),
        y = y # NOTE: This is where I pass the additional y argument to integrand inside integrate
      )
    })
    

    Lastly, we extract the values and combine them into a vector

    W <- do.call(c, lapply(W_list, function(w) w$value))
    

    W is now the same length as Y and contains values:

    [1] 0.1626543 0.1763727 0.1908012 0.2059319 0.2217521
    [6] 0.2382447