# StreamPlot No Longer Works With Piecewise Function?

Bug introduced in 7.0 and persisting through 13.2

I was trying to plot a phase portrait (StreamPlot) using a piecewise (Piecewise) defined function as

  f[x_] := Piecewise[{{2 x - 3, x > 1}, {-x, -1 <= x <= 1}, {2 x + 3, x < -1}}]

StreamPlot[{y - f[x], -x}, {x, -5, 5}, {y, -5, 5}]


It does not produce a plot and gives: Part::partw: Part 1 of {} does not exist.

I am using Version: 11.0.1.0, Windows, 64-bit.

I found this previous post, How I can make the StreamPlot of this differential equation?. The following worked in some previous version of Mathematica (but same problem as I see above with copy-and-paste).

  StreamPlot[{1, Piecewise[{{0.4 p (1 - p/30), 0 < t <= 5},
{0.4 p (1 - p/30) - 0.25 p, t >= 5}}]}, {t, 0, 10}, {p, -5, 5}]


Did something break and there is a bug? Any way around it (maybe I should try defining it using unit step functions and seeing if that resolves the matter)?

• Doesn't work as far back as 10.1 in my testing. The error message is suspiciously unhelpful, I'd think it's a bug. I would report it to [email protected] if I were you.
– ktm
Dec 13, 2016 at 1:46
• The same error in 7.0.1 on Win7x64. Dec 13, 2016 at 11:06
• I wonder how the previous example ever worked based on the feedback from the two comments above. Regardless, i suppose it is a bug now. Thank you all!
– Moo
Dec 13, 2016 at 13:04

It does seem to be a bug. As a temporary workaround, you can re-express your function in terms of either UnitStep[] or Boole[], like so:

f[x_] = Dot @@ MapAt[Boole, InternalFromPiecewise[
Piecewise[{{2 x - 3, x > 1}, {-x, -1 <= x <= 1}, {2 x + 3, x < -1}}]], 1]

StreamPlot[{y - f[x], -x}, {x, -5, 5}, {y, -5, 5}] Note the use of the undocumented function InternalFromPiecewise[] for decomposing the Piecewise[] object.

• I'd be interested in understanding how this works or other insights Dec 13, 2016 at 9:13
• Which part, the conversion? If you look at the output of InternalFromPiecewise[Piecewise[{{2 x - 3, x > 1}, {-x, -1 <= x <= 1}, {2 x + 3, x < -1}}], it merely splits the Piecewise[] object into its component pieces and conditions. Dec 13, 2016 at 11:04
• I mean insight into why my initial answer fails. I am a little sick and going to bed so will look tomorrow. Dec 13, 2016 at 11:09
• You could also use f[x_] = SimplifyPWToUnitStep[Piecewise[{{2 x - 3, x > 1}, {-x, -1 <= x <= 1}, {2 x + 3, x < -1}}]]. Dec 13, 2016 at 22:47

A workaround:

g[x_] := -Boole[Abs[x] < 1] x + Boole[Abs[x] > 1] (2 x - 3 Sign[x])


Now,

StreamPlot[{y - g[x], -x}, {x, -5, 5}, {y, -5, 5}]


yields an incorrect plot! Using Graphics:

Graphics[Catenate@
Arrow[{{i, j}, {i, j} + 0.2 Normalize[{j - g[i], -i}]}]}, {i, -5,
5, 0.4}, {j, -5, 5, 0.4}]] • Very odd, the expression is correct, but the phase portrait appears not to be. Regardless, this approach works - I retyped $g(x)$ and got the correct phase portrait, +1. Thanks.
– Moo
Dec 13, 2016 at 8:36
• @Moo please fee free to correct my code Dec 13, 2016 at 8:37
• The $g(x)$ you typed is spot on. It gave the wrong phase portrait the first time, but now gives the correct one. The phase portrait should look like the one above. Just very odd behavior from Mathematica at times - I am not sure why and I lose faith in it as I have to triple check results. regards
– Moo
Dec 13, 2016 at 8:40
• @Moo, but then, you should always double or triple-check numbers/results you get from software anyway. Dec 13, 2016 at 12:48
• @J.M.: I think the issue is here that the correct $g(x)$ produced an incorrect plot and that is what we are trying to understand. I re-entered it and it produced the correct results. There are no error messages when it produces the incorrect plot and this is the question for this result. Thanks for your answers!
– Moo
Dec 13, 2016 at 13:25