5

I have written a function f[Ne,t,T], that gives back a list of results when evaluated with numeric values of the variables Ne, t and T.

Now I want to make a ParametricPlot of the first element of the resulting list against another function g[t,T] for different values of the parameter T. So I try it for example like this:

TList={0,1,2};
ParametricPlot[ Table[ {Part[f[5,t,T],1] , g[t,T]} , {T,TList}] ,{t,0,10}]

Since I didn't use Evaluate inside ParametricPlot, all the curves have the same color. But if I do us Evaluate inside ParametricPlot, for example like this:

TList={0,1,2};
ParametricPlot[ Evaluate@Table[ {Part[f[5,t,T],1] , g[t,T]} , {T,TList}] ,{t,0,10}]

then Part is acting too early, and f[5,t,T] is evaluated to 5 (which is of course the first part of the expression f[5,t,T]), but that's clearly not that what I want. I want the Table command to be evaluated, so that ParametricPlot can "see" the different curves, but I want the first part of f[Ne,t,T] to be taken after the function f[5,t,T] is evaluated for the actual value of t. So what can I do?

Brett Champion
  • 20,779
  • 2
  • 64
  • 121
user5373
  • 53
  • 3
  • What is the definition of f and g? – rm -rf Jan 11 '13 at 22:58
  • The function f is a call to a Fortran program via MathLink and g is a complicated function i setted up in a pacage so i cant give the definitions here... But the point is, that f needs to be evaluated Before Part 1 is taken... – user5373 Jan 11 '13 at 23:18
  • @user5373 You could provide arbitrary placeholder functions, just so people have somthing to test it with. I used f[Ne_?NumericQ,t_?NumericQ,T_?NumericQ]:={Ne t T,0} and g[t_,T_]:=t Sin[T] testing my solution. – jVincent Jan 12 '13 at 00:01

2 Answers2

3

A quick way around this is to use an Upvalue for f to indicate that you actually want to wait with the evaluation of Part until it doesn't have the head f anymore. I do this here by switching to hPart which I define such that it will evaluate back to Part for anything except expressions with head f:

 f /: Part[a_f, n_] := hPart[a, n]
 hPart[a : Except[_f], n_] := Part[a, n]

That way Part[f[2,3,a],3] evaluates to hPart[f[2,3,a],3] and when a takes a numerical value and f evaluates, hPart evaluates and gets the right part.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
jVincent
  • 14,766
  • 1
  • 42
  • 74
1

This is an extension to jVincent's answer.

Using UpValues is not necessary. You can also define your own function to use in place of Part.

f[x_, y_?NumericQ, z_?NumericQ] := {x Cos[y - z], x + y + z}

g[y_, z_] := Sin[y + z] - z

TList = {0, 1, 2};

part[x : Except[_f], spec__] := Part[x, spec]

ParametricPlot[
  {part[f[5, t, #], 1], g[t, #]} & /@ TList,
  {t, 0, 10},
  Evaluated -> True
]

Mathematica graphics

Note that I use Evaluated -> True because it correctly localizes t.

If the output of your functions is always a list this function could be generally defined:

part[x_List, spec__] := Part[x, spec]
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371