Search code examples
rminnumerical-integrationintegral

Integrating over a min() function gives different result than the function inside


Shouldn't these two results be the same? Why are they not?

integrate(\(x) {x * min(-x+10, 10)},lower = 0, upper = 10)$value
> [1] 1.085709

integrate(\(x) {x * (-x+10)},lower = 0, upper = 10)$value
> [1] 166.6667

Keep in mind that from x values 0 to 10 we should never expect to get a value of y = -x + 10 that is higher than 10, so the min(-x+10, 10) will always return (-x+10) as long as we are between 0 and 10. So the two integrals should be identical.

Why are they not?


Solution

  • The problem is that min returns one value only, it's not vectorized.

    f <- \(x) {x * min(-x+10, 10)}
    g <- \(x) {x * (-x + 10)}
    
    f <- Vectorize(f, "x")
    g <- Vectorize(g, "x")
    
    # curve(f, from = 0, to = 10)
    # # this overplots perfectly
    # curve(g, from = 0, to = 10, add = TRUE, col = "red")
    
    integrate(f, lower = 0, upper = 10)$value
    #> [1] 166.6667
    integrate(g, lower = 0, upper = 10)$value
    #> [1] 166.6667
    

    Created on 2023-08-21 with reprex v2.0.2


    Edit

    If you don't want to assign twice to the same names, the first to create the function, the second to vectorize it, use the new pipe operator.

    f <- (\(x) {x * min(-x+10, 10)}) |> Vectorize()
    g <- (\(x) {x * (-x + 10)}) |> Vectorize()
    

    Created on 2023-08-21 with reprex v2.0.2