Victor Nielsen
Victor Nielsen

Reputation: 493

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?

Upvotes: 2

Views: 111

Answers (2)

Victor Nielsen
Victor Nielsen

Reputation: 493

@RuiBarradas' answer works, but I found a way to mitigate the issue using pmin:

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

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

If anyone for some reason experiences other problems with min() not being vectorized, this might solve it.

Upvotes: 0

Rui Barradas
Rui Barradas

Reputation: 76641

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

Upvotes: 3

Related Questions