# 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. – R. M. Feb 3 '12 at 5:31

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! :) – R. M. 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
@AlbertRetey, agree completely. That something can be done does not mean it should. These "reflection" capabilities are indeed ugly, error prone and not without side effects. IMO, they should be limited to specialized use in packages, not general Mathematica code. – kkm Jan 21 '15 at 18:48
I don't remember what I was thinking when making that comment, but I think I wasn't really meaning to make that comment to your answer but rather to the question. What you suggest is IMHO the best alternative. The problems I described are to expected whenever one needs to make use of ToExpression and ToString and I am quite sure that I meant to put that comment somewhere else. In your approach I only see a potential performance penalty when accessing DownValues and SubValues to find all known definitions, but that might not be a problem at all if you don't have too many... – Albert Retey Jan 22 '15 at 20:36

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