# Integrating a piecewise function with symbolic pieces

Suppose I want to compute the antiderivative of this simple function: $$f(t)=\begin{cases} 1 & \text{if 0\le t\le t_1,} \\ -1 & \text{if t_1\le t\le t_2}, \\ 0 & \text{otherwise,} \end{cases}$$ where $t\in\mathbb R$ and $0\le t_1\le t_2$. I expect the integral to be defined piecewise with four cases: $$\int_0^t f(s)\,\mathrm ds = \begin{cases} 0 & \text{if t\le0,} \\ t & \text{if 0\le t\le t_1,} \\ t_1 - t & \text{if t_1\le t\le t_2,} \\ t_1 - t_2 & \text{if t_2\le t.} \end{cases}$$

Instead, Mathematica gives me something extremely complicated:

f[t_] := Piecewise[{{1, 0 <= t <= t1}, {-1, t1 <= t <= t2}, {0, True}}]
Integrate[f[s], {s, 0, t}, Assumptions -> t ∈ Reals && 0 <= t1 <= t2]

Piecewise[{{-t, t - t2 < 0 && t > 0 && t - t1 > 0 && t1 <= 0},
{t, (t - t1 < 0 && t - t2 > 0 && t > 0 && t1 > 0) ||
(t - t1 < 0 && t - t2 < 0 && t > 0 && t1 > 0) ||
(t - t1 < 0 && t - t2 > 0 && t > 0 && t2 <= 0)},
{t1, (t - t1 == 0 && t1 - t2 > 0 && t > 0 && t1 > 0) ||
(t - t1 == 0 && t1 - t2 < 0 && t > 0 && t1 > 0) ||
(t - t1 == 0 && t1 - t2 > 0 && t - t2 > 0 && t > 0 && t2 <= 0) ||
(t - t1 == 0 && t1 - t2 < 0 && t - t2 > 0 && t > 0 && t2 <= 0) ||
(t - t1 >= 0 && t1 - t2 > 0 && t - t2 > 0 && t > 0 && t1 > 0) ||
(t - t1 > 0 && t1 - t2 == 0 && t - t2 == 0 && t > 0 && t1 > 0)},
{-t + 2*t1, (t - t1 > 0 && t - t2 < 0 && t1 - t2 > 0 && t > 0 &&
t1 > 0) || (t - t1 > 0 && t - t2 < 0 && t1 - t2 < 0 && t > 0 &&
t1 > 0)}, {2*t1 - t2, (t - t1 > 0 && t - t2 == 0 && t1 - t2 > 0 &&
t > 0 && t1 > 0) || (t - t1 > 0 && t - t2 >= 0 && t1 - t2 < 0 &&
t > 0 && t1 > 0)}, {-t2, (t - t2 == 0 && t > 0 && t - t1 > 0 &&
t1 <= 0) || (t - t2 >= 0 && t > 0 && t - t1 > 0 && t1 <= 0 &&
t2 > 0)}, {t2, (t - t1 == 0 && t1 - t2 == 0 && t > 0 && t1 > 0) ||
(t - t1 == 0 && t1 - t2 == 0 && t > 0 && t - t2 > 0 && t2 <= 0) ||
(t - t1 >= 0 && t1 - t2 == 0 && t > 0 && t1 > 0 && t - t2 > 0) ||
(t - t1 < 0 && t > 0 && t1 > 0 && t - t2 == 0)}}, 0]


Running FullSimplify with the same assumptions simplifies the conditions, but does not reduce the number of cases. This is a problem because the actual function I am interested in has many more cases, and the number of cases in its computed antiderivative seems to be growing exponentially instead of linearly. (For example, try adding another case {1, t2 <= t <= t3} to the definition of f.)

How can I work around this?

Update: The strategy in my answer "works" for the function $$g(t)=\begin{cases} 1 & \text{if 0\le t\le t_1,} \\ -1 & \text{if t_2\le t\le t_3,} \\ 1 & \text{if t_4\le t\le t_5,} \\ 0 & \text{otherwise,} \end{cases}$$

g[t_] := Piecewise[{{1, 0 <= t <= t1}, {-1, t2 <= t <= t3}, {1, t4 <= t <= t5}}, 0]


giving a piecewise-defined solution with seven cases, but the computation takes an inordinately long time (nearly 90 seconds on my machine). @mikado's suggested alternate style for defining the function makes it even slower. So for me the question is still open.

P.S. This is probably a duplicate of the previous question "Piecewise functions Integration with symbol", but that one does not have any answers.

• Are the $t_k$ in the extended case always in (strictly) increasing order? – J. M.'s discontentment Jul 28 '17 at 9:56
• @J.M.: Yes, they are. – user484 Jul 28 '17 at 14:54

Ten minutes after posting the question, I found that using 0 < t1 < t2 && t != t1 != t2 instead of 0 <= t1 <= t2 gets rid of all the extraneous cases.

f[t_] := Piecewise[{{1, 0 <= t <= t1}, {-1, t1 <= t <= t2}, {0, True}}]
Assuming[t ∈ Reals && 0 < t1 < t2 && t != t1 != t2, Integrate[f[s], {s, 0, t}]]

Piecewise[{{t, (t - t1 < 0 && t - t2 > 0 && t > 0) ||
(t - t1 < 0 && t - t2 < 0 && t > 0)},
{-t + 2*t1, (t - t1 > 0 && t - t2 < 0 && t1 - t2 > 0 && t > 0 &&
t1 > 0) || (t - t1 > 0 && t - t2 < 0 && t1 - t2 < 0 && t > 0 &&
t1 > 0)}, {2*t1 - t2, (t - t1 > 0 && t - t2 == 0 && t1 - t2 > 0 &&
t > 0 && t1 > 0) || (t - t1 > 0 && t - t2 >= 0 && t1 - t2 < 0 &&
t > 0 && t1 > 0)}}, 0]


Adding a FullSimplify finishes the job, giving the desired result (and revealing an error in the formula in my question):

Piecewise[{{t, t < t1 && t > 0}, {-t + 2*t1, t < t2 && t > t1},
{2*t1 - t2, t >= t2}}, 0]


I've tested it with a few more cases and it always seems to work.

Update: It becomes unreasonably slow when there are too many pieces, though. See the new test case I added to the question.

• Beat me to it!! – mikado Jul 24 '17 at 20:20
• I think you commented on my question on Math.SE, but then deleted the comment. Now I lost the blog post you linked to :-( – Szabolcs Feb 8 '18 at 14:11

Note that in Piecewise the conditions are evaluated sequentially. Bearing this in mind, we can avoid (at least in this case) introducing a dependency on the (assumed fixed) relationship between t1 and t2. For example,

g[t_] := Piecewise[{{0, t < 0}, {1, 0 <= t <= t1}, {-1, t <= t2}, {0,
True}}]

Assuming[0 < t1 < t2 && t ∈ Reals,
FullSimplify[Integrate[g[s], {s, 0, t}]]]
(* Piecewise[{{t, t < t1 && t > 0}, {t1, t > 0 && t == t1},
{-t + 2 t1, t > t1 && t < t2}, {2 t1 - t2, t >= t2}}] *)

• I found a harder test case where the computation becomes extremely slow. Do you have any ideas about how to avoid this? – user484 Jul 24 '17 at 22:13
• Can you write your expression as the sum of simple piecewise parts? In this case, I think everything should scalar proportional to the number of parts. – mikado Jul 24 '17 at 22:19
• That makes sense. I'll give it a try the next time I have some free time... – user484 Jul 25 '17 at 0:18

It seems that preprocessing with the undocumented function SimplifyPWToUnitStep[] helps a bit. Of course, you still need to manually include the assumption that the $t_k$ compose a strictly increasing sequence:

g[t_] = SimplifyPWToUnitStep[Piecewise[{{1, 0 <= t <= t1}, {-1, t2 <= t <= t3},
{1, t4 <= t <= t5}}, 0]]

int = Assuming[t ∈ Reals && 0 < t1 < t2 < t3 < t4 < t5, Integrate[g[s], {s, 0, t}]];

Assuming[t ∈ Reals && 0 < t1 < t2 < t3 < t4 < t5, FullSimplify[PiecewiseExpand[int]]]
ConditionalExpression[Piecewise[{{-t + t1 + t2, t <= t3},
{t1 + t2 - t3, t > t3 && t <= t4},
{t + t1 + t2 - t3 - t4, t > t4 && t <= t5}},
t1 + t2 - t3 - t4 + t5], t > t2]


A manual check of validity would still be necessary here, which I have omitted.