2
$\begingroup$

Here I have one simple system solvable with NDSolve. I don't know why ParametricPlot3D doesn't present trajectory in space. I have solutions for x[t], y[t] and z[t]

  ss = NDSolve[{x''[t] == -1^2*((1 + 1) x[t])/
  Abs[(x[t]^2 + y[t]^2 + z[t]^2)]^(3/2), 
 y''[t] == -1^2*((1 + 1) y[t])/Abs[(x[t]^2 + y[t]^2 + z[t]^2)]^(3/
  2), z''[t] == -1^2*((1 + 1) z[t])/
  Abs[(x[t]^2 + y[t]^2 + z[t]^2)]^(3/2), x'[0] == 0, y'[0] == 0, 
z'[0] == 0, x[0] == 1, y[0] == 10, z[0] == 1}, {x, y, z}, {t, 0, 
1.2}];

 ParametricPlot3D[{Evaluate[x[t] /. ss], Evaluate[y[t] /. ss], 
 Evaluate[z[t] /. ss]}, {t, 0, 1.2}]

Plot[Evaluate[x[t] /. ss], {t, 0, 1.2}, PlotRange -> All]
Plot[Evaluate[y[t] /. ss], {t, 0, 1.2}, PlotRange -> All]
Plot[Evaluate[z[t] /. ss], {t, 0, 1.2}, PlotRange -> All]
$\endgroup$
1
  • $\begingroup$ You need to use ss = First@NDSolve[..] or x[t] /. First[ss] etc. Or Evaluate[{x[t], y[t], z[t]} /. ss]. $\endgroup$
    – Michael E2
    Commented Mar 16, 2013 at 0:42

1 Answer 1

5
$\begingroup$

You made (at least) two mistakes in your ParametricPlot3D call. First let me give you a solution. When you have Mathematica version 9, the probably easiest method is to use NDSolveValue which spares you the extraction of the solution from rules:

sol = NDSolveValue[{x''[
      t] == -1^2*((1 + 1) x[t])/Abs[(x[t]^2 + y[t]^2 + z[t]^2)]^(3/2),
     y''[t] == -1^2*((1 + 1) y[t])/
       Abs[(x[t]^2 + y[t]^2 + z[t]^2)]^(3/2), 
    z''[t] == -1^2*((1 + 1) z[t])/
       Abs[(x[t]^2 + y[t]^2 + z[t]^2)]^(3/2), x'[0] == 0, y'[0] == 0, 
    z'[0] == 0, x[0] == 1, y[0] == 10, z[0] == 1}, {x, y, z}, {t, 0, 
    1.2}];

ParametricPlot3D[Through[sol[t]], {t, 0, 1.2}]

Please look at sol to see that you get a list of pure functions. Through is very handy here, because it transforms an expression {x,y,z}[t] into {x[t],y[t],z[t]}.

When you want to stick with your NDSolve call, than you have to use your solution ss in the following way

ParametricPlot3D[Evaluate[{x[t], y[t], z[t]} /. ss], {t, 0, 1.2}]

Let me explain your two mistakes. First, although the above works, please check the output of NDSolve to see, that you get a list of a list as result. You should get rid of one level by using First as suggested by Michael in his comment.

The second issue is quite interesting and maybe not as easy to understand. Your call looked like

ParametricPlot3D[{Evaluate[x[t] /. ss],...},..]

You used Evaluate with good intention, but it has no effect if it is not the Head of the argument. The head of your argument here is List. Let's make a very small example function

Attributes[f] = {HoldAll};
f[x_] := ToString[Unevaluated[x]]

f does not evaluate its argument and it prints it in unevaluated form. Therefore, f[1+1] results in "1+1", although usual functions would first evaluated the argument to 2. This is exactly the same behavior that ParametricPlot3D has. Now you want to evaluate the 1+1 before printing it and you try

f[Evaluate[1 + 1]]

(* "2" *)

and get 2 as expected. The very important thing is, that this only works as long Evaluate appears as head of the argument. You can check this by trying

f[{1 + 1, Evaluate[1 + 1]}]

(* {1 + 1, Evaluate[1 + 1]} *)

or by reading more about the main evaluation loop of Mathematica.

Conclusion is: You were absolutely right to use Evaluate to evaluated the argument because ParametricPlot3D holds its arguments but Evaluate needs to appear as head of the argument.

$\endgroup$
1
  • $\begingroup$ Thank you very much for full and helpful answer $\endgroup$
    – Pipe
    Commented Mar 16, 2013 at 10:26

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.