3

I have multiple functions from two different NDSolves that I would piece together. Here is a working minimal example:

ClearAll["Global`*"];

sol = First@NDSolve[ {x'[t] == 0.5 x[t] - 0.5 y[t] + 0.5 z[t], x[0] == 0, y'[t] == 0.5 x[t] - 0.5 y[t] - 0.5 z[t], y[0] == 1, z'[t] == -0.5 x[t] - 0.5 y[t] + 0.5 z[t], z[0] == 2}, {x, y, z},{t, 0, 5}]

initx = x[5] /. sol; inity = y[5] /. sol; initz = z[5] /. sol;

solcont = First@NDSolve[ {x'[t] == x[t] - y[t] + z[t], x[5] == initx, y'[t] == x[t] - y[t] - z[t], y[5] == inity, z'[t] == -x[t] - y[t] + z[t], z[5] == initz}, {x, y, z},{t, 5, 10}]

As expected, sol and solcont return lists of interpolating function rules which can then be combined using Piecewise:

xsol[t_] := Piecewise[{{x[t] /. sol, t <= 5}}, x[t] /. solcont]
ysol[t_] := Piecewise[{{y[t] /. sol, t <= 5}}, y[t] /. solcont];
zsol[t_] := Piecewise[{{z[t] /. sol, t <= 5}}, z[t] /. solcont];

Plot[xsol[t], {t, 0, 10}, PlotRange -> All]

or

{xsol[t_], ysol[t_], zsol[t_]} := 
  {Piecewise[{{x[t] /. sol, t <= 5}}, x[t] /. solcont], 
   Piecewise[{{y[t] /. sol, t <= 5}}, y[t] /. solcont], 
   Piecewise[{{z[t] /. sol, t <= 5}}, z[t] /. solcont]};

My question is, is there a way I could apply Piecewise all at once, since the solutions "switch" at the same time? I am working with quite a few DEs and I'm looking to streamline.

After much searching, it seems I'm trying to generalize this post: Create List of Functions using Piecewise but with an extra function.

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574

1 Answers1

4

Hooray, I figured it out! Only took 5 hours of struggling for this...

{xsol[t_], ysol[t_], zsol[t_]} =
  MapThread[
   Piecewise[{{#1, t <= 5}}, #2] &,
   {{x[t] /. sol, y[t] /. sol, z[t] /. sol}, {x[t] /. solcont, 
     y[t] /. solcont, z[t] /. solcont}}
   ];

Overall a good learning experience :)

  • 5
    Depending on your needs, NDSolveValue[] can be more convenient: sol = NDSolveValue[(* stuff *)]; {initx, inity, initz} = Through[sol[5]]; solcont = NDSolveValue[(* stuff *)]; {xsol[t_], ysol[t_], zsol[t_]} = MapThread[Piecewise[{{#1[t], t <= 5}}, #2[t]] &, {sol, solcont}] – J. M.'s missing motivation Jun 10 '22 at 20:33