6
$\begingroup$

Why do I get a smooth curve (that is obviously wrong) when I run this?

Plot[
 Evaluate[
  NDSolveValue[{x'[t] == -x[t], x[0] == 1}, {x[t]}, {t, 0, 1}, 
   StartingStepSize -> 1, Method -> {"FixedStep", Method -> "ExplicitEuler"}]],
 {t, 0, 1},
 PlotRange -> All]

Shouldn't I just get back a straight line connecting (0, 1) to (1, 0)?!

How do I make Mathematica just do a plain classic Forward Euler?! I don't want fancy smoothing...

$\endgroup$
5
$\begingroup$

You have to set MaxStepFraction, too, say, to 1.

Plot[
 Evaluate[
  NDSolveValue[{x'[t] == -x[t], x[0] == 1}, {x[t]}, {t, 0, 1}, 
   StartingStepSize -> 1, Method -> {"FixedStep", Method -> "ExplicitEuler"},
   MaxStepFraction -> 1]],
 {t, 0, 1},
 PlotRange -> All]

Mathematica graphics

It's not a straight line because the value of the derivatives are stored & used in the InterpolatingFunction solution. However, we can see there are only two points.

sol /. t -> "Grid"
(*  {{{0.}, {1.}}}  *)
$\endgroup$
  • $\begingroup$ +1 Ahhh! Is there any way to make it draw without smoothing then? It's so misleading the way it draws it... $\endgroup$ – Mehrdad Feb 15 '16 at 2:41
  • $\begingroup$ @Mehrdad Oops, made a mistake editing the comment. Try sol1 = Interpolation[Table[{t, sol}, {t, Flatten[sol /. t -> "Grid"]}], InterpolationOrder -> 1]. $\endgroup$ – Michael E2 Feb 15 '16 at 2:57
  • $\begingroup$ Awesome, got it! It ended up being sol = Evaluate[ NDSolveValue[{x'[t] == -x[t], x[0] == 1}, x[t], {t, 0, 1}, StartingStepSize -> 1, MaxStepFraction -> 1, Method -> {"FixedStep", Method -> "ExplicitEuler"}]]; sol = Interpolation[Table[{t, sol}, {t, Flatten[sol /. t -> "Grid"]}], InterpolationOrder -> 1][t]; Plot[sol, {t, 0, 1}, PlotRange -> All]. $\endgroup$ – Mehrdad Feb 15 '16 at 3:03
  • $\begingroup$ PS, this might be more painful but for future reference it might be nice to add how to do it if we're solving for multiple values (e.g. {x[t], x'[t]}). $\endgroup$ – Mehrdad Feb 15 '16 at 3:06
  • 1
    $\begingroup$ @mmal Yes, I tried that. InterpolationOrder -> 0 generates an error; everything else seems ignored. InterpolationOrder -> All is the only setting shown in the docs, and it seems to do something rather interesting (too long for a comment). $\endgroup$ – Michael E2 Feb 15 '16 at 21:21
2
$\begingroup$

I would suggest (as an alternative) the following

pointsAndValues[x_InterpolatingFunction] :=
  Transpose[{First[x["Coordinates"]], x["ValuesOnGrid"]}];

ListPlot[
  pointsAndValues@
    First@NDSolveValue[{x'[t] == -x[t], x[0] == 1}, {x}, {t, 0, 3}, 
      StartingStepSize -> 1, 
      Method -> {"FixedStep", Method -> "ExplicitEuler"}, 
      MaxStepFraction -> 1], Joined -> True, PlotMarkers -> Automatic]

And to check the convergence use e.g.

ListPlot[pointsAndValues@
  First@NDSolveValue[{x'[t] == -x[t], x[0] == 1}, {x}, {t, 0, 2}, 
    StartingStepSize -> 1/#, 
    Method -> {"FixedStep", Method -> "ExplicitEuler"}, 
    MaxStepFraction -> 1] & /@ {1, 2, 4, 16}, Joined -> True, 
 PlotMarkers -> Automatic]
$\endgroup$
0
$\begingroup$

Here's a more polished version of the currently accepted answer:

Reinterpolate[interpolation_, args___] := 
  Interpolation[
   Transpose[
    Append[Transpose[interpolation["Grid"]], 
     interpolation["ValuesOnGrid"]]], args];
ReinterpolateAll[expr_, args___] := 
  expr /. {InterpolatingFunction[params___] :> 
     Reinterpolate[InterpolatingFunction[params], args]};
sol = NDSolveValue[{x'[t] == -x[t], x[0] == 10}, x[t], {t, 0, 1}, 
   StartingStepSize -> 1/3, MaxStepFraction -> 1, 
   Method -> {"FixedStep", Method -> "ExplicitEuler"}];
Plot[Evaluate[ReinterpolateAll[sol, InterpolationOrder -> 1]], {t, 0, 1}, PlotRange -> All]
$\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.