6
$\begingroup$

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.

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

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.

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

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}}] *)
| improve this answer | |
$\endgroup$
  • $\begingroup$ I found a harder test case where the computation becomes extremely slow. Do you have any ideas about how to avoid this? $\endgroup$ – user484 Jul 24 '17 at 22:13
  • $\begingroup$ 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. $\endgroup$ – mikado Jul 24 '17 at 22:19
  • $\begingroup$ That makes sense. I'll give it a try the next time I have some free time... $\endgroup$ – user484 Jul 25 '17 at 0:18
0
$\begingroup$

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

g[t_] = Simplify`PWToUnitStep[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.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy