8
$\begingroup$

As has been mentioned before, Piecewise causes the Mathematica Kernel to fail to during a NDSolve calculation. How can I write the function below without using Piecewise?

s[t_] := Piecewise[{{1, t < 300.}, {0, 300. <= t < 1500.}, {1, t <= 3600}}];
Plot[s[t], {t, 0., 4000.}]
$\endgroup$
3
  • 1
    $\begingroup$ More often than not Piecewise causes NDSolve to succeed in my experience. $\endgroup$
    – Michael E2
    Apr 23 '16 at 19:33
  • $\begingroup$ I think Piecewise is the most straightforward method to use. But it is a little frustrating that he kernel crashes so often. Is there any precedent that the cause of the failures is related to the use of reals in the function definition for the independent variable t? $\endgroup$
    – tarhawk
    Apr 24 '16 at 20:24
  • $\begingroup$ Yes, I think the use of approximate reals can make the analysis of the discontinuities computationally harder. Rounding error from transformations might slightly perturb quantities that ought to match up, for instance; x^0.5 is very different from x^(1/2), and so on. When someone here posts a problem with NDSolve[sys,...] and it seems related to this issue, I usually try it with NDSolve[Rationalize[sys, 0],...], if nothing else seems more likely. $\endgroup$
    – Michael E2
    Apr 24 '16 at 20:34
11
$\begingroup$

You can use the functions Simplify`PWToUnitStep and Simplify`SimplifyUnitStep to convert a Piecewise function to one using UnitStep:

s[t_] := Piecewise[{{1, t < 300.}, {0, 300. <= t < 1500.}, {1, t <= 3600}}];
s2[t_] := Simplify`SimplifyUnitStep[Simplify`PWToUnitStep[s@t]];
s2[t]

1 - UnitStep[-300. + t] + UnitStep[3600 - t, -1500. + t]

To use HeavisideTheta instead of UnitStep:

s2[t] /. UnitStep -> HeavisideTheta

1 - HeavisideTheta[-300. + t] + HeavisideTheta[3600 - t, -1500. + t]

Row[Plot[#, {t, 0., 4000.}, PlotStyle -> Thick, ImageSize -> 300] & /@ {s[t], s2[t]}]

Mathematica graphics

$\endgroup$
8
  • $\begingroup$ +1 @kglr, This is great. Is there a quick way to see other simplify subroutines in the Front-End? $\endgroup$
    – Rashid
    Apr 23 '16 at 18:56
  • $\begingroup$ @RashidZia, thanks for the vote. Perhaps ?? Simplify`*? $\endgroup$
    – kglr
    Apr 23 '16 at 19:03
  • $\begingroup$ @ kglr, thanks again. I got it to work with ?"Simplify`*" BTW there is also a Simplify`PWToHeavisideTheta function. $\endgroup$
    – Rashid
    Apr 23 '16 at 19:11
  • $\begingroup$ @RashidZia, I don't see a PWToHeavisideTheta function in Version 9. $\endgroup$
    – kglr
    Apr 23 '16 at 19:18
  • 1
    $\begingroup$ I encountered an annoying issue with Simplify`PWToUnitStep: if the original Piecewise expression has an Indeterminate branch (even at a single point), the whole result becomes Indeterminate. The workaround I use is to replace Indeterminate with HeavisideTheta[0] before calling Simplify`PWToUnitStep. $\endgroup$ Jun 25 '21 at 17:23
6
$\begingroup$

Two alternatives (depending on application) would be UnitStep and HeavisideTheta. For example,

sU[t_] := UnitStep[300 - t] + UnitStep[t - 1500, 3600 - t]
sH[t_] := HeavisideTheta[300 - t] + HeavisideTheta[t - 1500, 3600 - t]

For differential equations, I would use HeavisideTheta.

$\endgroup$

Your Answer

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

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