Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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]

enter image description here

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.

share|improve this question
1  
It seems to help if you give Integrate the assumption Assumptions -> {0 < x < 10} –  Simon Woods Jul 26 at 12:08

3 Answers 3

up vote 4 down vote accepted

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}]
 ]

Mathematica graphics

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. >>

share|improve this answer

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]

(*integrate analytically with additional assumptions*)
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

enter image description here

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}

share|improve this answer
    
@MichaelE2: Added the information. –  Wizard Jul 26 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

enter image description here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.