6
$\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$
  • 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
9
$\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$
  • $\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
  • $\begingroup$ I am using Version 10.4 and this is what I see $\endgroup$ – Rashid Apr 23 '16 at 19:22
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.