3
$\begingroup$

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.

$\endgroup$
1
  • 1
    $\begingroup$ You can splice together multiple InterpolatingFunction objects into a single one using the technique in this answer $\endgroup$
    – Carl Woll
    Commented Jun 10, 2022 at 21:50

1 Answer 1

4
$\begingroup$

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 :)

$\endgroup$
1
  • 5
    $\begingroup$ 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}] $\endgroup$ Commented Jun 10, 2022 at 20:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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