# Using variables in function names

I want to make a list of plots and my functions are named C1, C2... Cn.

The command I wish to execute is:

Table[Plot[Cn[t], {t, 0, 1}], {n, 1,6}]]


which obviously doesn't work. How is the equivalent of the above done in Mathematica?

EDIT: Thanks for the answers. Here is what it looks like:

-

You can also use ToExpression to join the index n to your base function name, C, as in the following example:

C1 = Sin[x];
C2 = Cos[x];
C3 = Tan[x];
Table[Plot[Evaluate[ToExpression["C" <> ToString@i]], {x, -π, π}], {i, 3}]


-
That evaluates ToExpression and ToString for each point in the plot. (Which is not the biggest performance hit ever, but still...) –  Brett Champion Feb 2 '12 at 22:32
The performance is not a problem for now, since I only have a couple of graphs I want to use, only as a visual aid. Thanks! –  CHM Feb 3 '12 at 0:26
@CHM Brett's right. I've edited my answer to add an Evaluate, so please note it. –  rm -rf Feb 3 '12 at 5:31

How about something like:

Plot[#, {t, 0, 1}] & /@
(ToExpression /@
Table["C" <> ToString[n] <> "[t]", {n, 1, 4}])


Edit With a form closer to your original code:

Table[Plot[ToExpression["C" <> ToString[n] <> "[t]"], {t, 0, 1}],
{n, 1, 4}]


For example, with:

C1[t_] := t
C2[t_] := t^2
C3[t_] := t^3
C4[t_] := t^4


Using either of the two solutions here gives:

-
oooh! Beat you by 13 seconds! :) –  rm -rf Feb 2 '12 at 21:16
Blast! And I thought I had this one in the bag! But mine has a shiny Map version, too. –  Eli Lansey Feb 2 '12 at 21:17
How is the Map version shinier? Is it performance-wise? –  CHM Feb 3 '12 at 0:30
I meant shiny in terms of "fancy-looking," but in retrospect, it is faster. Reason being, as @BrettChampion noted in @RM's solution, when the ToExpression command is included in the Plot function, it's evaluated at each plot point. In the Map scenario it's evaluated once, and then the function is evaluated. I tested on my home computer and the Table method is around 3 times slower than the Map method. –  Eli Lansey Feb 3 '12 at 0:37

You could define your functions like this:

Subscript[s, 1][t_] = Sin[t];
Subscript[s, 2][t_] = Cos[t];


And then plot using:

Plot[Evaluate[Table[Subscript[s, n][x], {n, 2}]], {x, -Pi, Pi}]


Just overlooked: This will create one Plot with all plots in it. The way your code snippet is written it looks as if you try to get each graph in its own plot in which case you have to use

Table[Plot[Subscript[s, n][x], {x, -Pi, Pi}], {n, 2}]

-
I hadn't thought about using a single Plot for all the functions. Might help me. Will check :) –  CHM Feb 3 '12 at 0:28

Alternatively, you may define indexed family of functions like c[1],...,c[n]. Indices do not have to be contiguous, as you can get them all from the symbol definition. So if you define

c[1] = Sin;
c[2] = Cos;
c[3][x_] := Cos[x]^2;


you can do the plotting by iterating the index

Table[Plot[c[i][x], {x, -Pi, Pi}], {i, 3}]


You can also iterate over all defined indices in a general way:

Plot[c[#][x], {x, -Pi, Pi}] & /@
Union[SubValues[c][[All, 1, 1, 0, 1]],
DownValues[c][[All, 1, 1, 1]]]


You may also define a function to help with such an iteration, to hide the ugliness of index scavenging:

AllFunIndices[sym_Symbol] :=
Union[SubValues[sym][[All, 1, 1, 0, 1]],
DownValues[sym][[All, 1, 1, 1]]];
SetAttributes[AllFunIndices, HoldAll]


and then the plotting code over indices becomes much more transparent

Plot[c[#][x], {x, -Pi, Pi}] & /@ AllFunIndices[c]

-
I wondered that no one else was actually giving the very important tip to not use those variable names in the first place, there are several drawbacks in doing so: It will always lead to complicated constructs with ToExpression that are cryptic, inefficient and will pose even larger problems with namespaces when e.g. used in a package or when given away i any form (notebooks and CDF-files will warn about unsave code, demonstrations site will not accept). And that's just what immediately crosses my mind... –  Albert Retey Feb 4 '12 at 17:02

This is the perfect time to use With to handle the creation of the variable name. For instance,

C1[t_] := Tanh[t];
C2[t_] := Sinh[t];
C3[t_] := Cosh[t];
GraphicsRow@Table[
With[{f = ToExpression["C" <> ToString[i]]},
Plot[f[t], {t, -1, 1}]],
{i, 3}]


gives

By using With to create the function name outside of Plot it is only executed once, not for every point.

-
Fun. It is nice to see different answers to the same question, it helps get a feel of how Mathematica can handle the problem. –  CHM Feb 3 '12 at 3:07
Nice use of With. That solves the speed issue. I imagine Table and Map probably have nearly the same efficiency using this approach, then. –  Eli Lansey Feb 3 '12 at 14:17
@EliLansey that's an interesting question. I've often found Table to be the slow point of any code I write, but I have not noticed the same thing with Map. I'll have to look at that. –  rcollyer Feb 3 '12 at 14:21
@rcollyer I've noticed that too, so I've become the "Map everything" lunatic in our lab. Then, one of my coworkers was doing some calculation with a Table and I suggested Map to speed it up, and it actually was much slower. So, when I'm writing code that I need to be fast, I obsessively check which one will be faster. Wish I knew why, though... Maybe I'll ask a question. –  Eli Lansey Feb 3 '12 at 14:26
@EliLansey most functional languages employ the idea of immutability, i.e. a variables value cannot be changed. So, Map has to produce a new list the same size as the old list while leaving the old one intact. I think, if it is slow, that's the reason: list construction can be fairly slow on mma. That's why Table can have truly awful performance. –  rcollyer Feb 3 '12 at 14:42