# Integrate over Piecewise function efficiently

I have this Piecewise function:

Piecewise[{(t - #[[1]])^2, #[[1]] <= t && t < #[[2]]} & /@
Partition[Sort[Join[{0}, RandomReal[{0, 10}, 20], {10}]], 2, 1], 0]


I would like to Plot the integral of this function. But when I do it like this:

Plot[{Evaluate@Integrate[pieces, {t, 0, x}]}, {x, 0,
10}, Filling -> Bottom, PlotRange -> All]


it takes 114 seconds to evaluate on a very capable computer.

• It seems to help if you give Integrate the assumption Assumptions -> {0 < x < 10} – Simon Woods Jul 26 '15 at 12:08

Note that Piecewise functions are a special case in Integrate if the integral is in the form of an indefinite integral. (One can add a constant as needed to adjust for a different starting point, but in the OP's example, it is unnecessary.) This evaluates relatively quickly:

foo = Piecewise[{(t - #[[1]])^2, #[[1]] <= t && t < #[[2]]} & /@
Partition[Sort[Join[{0}, RandomReal[{0, 10}, 20], {10}]], 2, 1],
0];

AbsoluteTiming[
ifoo = Integrate[foo, t];
Plot[ifoo, {t, 0, 10}]
]


The problem with the OP's code is that

 Evaluate@Integrate[pieces, {t, 0, x}]


is wrapped in a List and does not evaluate. But fixing that still leaves the major problem, which is that

Integrate[foo, {t, 0, x}]


does not evaluate until x is numeric. In fact, trying to evaluate the above gives a hint similar to what Simon Woods suggested in a comment:

Integrate::pwrl: Unable to prove that integration limits {0,x} are real. Adding assumptions may help. >>

First thing I would note is that you should Integrate the function analytically before plotting it. To do so you should add your assumptions like already commented by other users (note that it is important to use set (=) instead of set delayed(:=) to do the integration only once):

f[t_] = Piecewise[{(t - #[[1]])^2, #[[1]] <= t && t < #[[2]]} & /@
Partition[Sort[Join[{0}, RandomReal[{0, 10}, 20], {10}]], 2, 1], 0]

F[x_] = Assuming[x \[Element] Reals && 0 < x <= 10,
Integrate[f[t], {t, 0, x}]]


Then you can plot the function in a matter of a fraction of a second:

Plot[F[x], {x, 0, 10}, Filling -> Bottom,
PlotRange -> All] // AbsoluteTiming


Note that of course the main culprit in terms of computation time is to integrate f analytically, but this only hast to be done once. My general suggestion is to always do the pre computation first and the plotting afterwards. Here is the timing for the integration:

F[x_] = Assuming[x \[Element] Reals && 0 < x <= 10,
Integrate[f[t], {t, 0, x}]]; // AbsoluteTiming


{10.3487, Null}

• @MichaelE2: Added the information. – Wizard Jul 26 '15 at 14:42

Essentially the same as Simon Woods's comment:

SeedRandom[1]

data = Partition[Sort[Join[{0}, RandomReal[{0, 10}, 20], {10}]], 2, 1];


You don't need the And with the inequality

f[t_] = Piecewise[{(t - #[[1]])^2, #[[1]] <= t < #[[2]]} & /@ data];


You need to add an assumption to the Integrate for it to evaluate

Plot[Evaluate@Assuming[x >= 0, Integrate[f[t], {t, 0, x}]], {x, 0, 10},
Filling -> Bottom, PlotRange -> All] // Timing