Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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]
share|improve this question
    
You need to use ss = First@NDSolve[..] or x[t] /. First[ss] etc. Or Evaluate[{x[t], y[t], z[t]} /. ss]. –  Michael E2 Mar 16 '13 at 0:42

1 Answer 1

up vote 6 down vote accepted

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.

share|improve this answer
    
Thank you very much for full and helpful answer –  Pipe Mar 16 '13 at 10:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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