# How to build a list of functions

Having said that I'm no expert, I have some problems in generating a list of functions inside a loop. The functions in the list should depend on the elements of a parameters list, that are read in sequence. The stripped down examples here below should show what I mean. First I tried this (rather naively)

parameters = {a, 3, 6, E, 2}; p = 1;
While[p <= 5, funclist[[p]][x_] := parameters[[p]] x^p; p++]


Naturally it doesn't work. After some other trials I arrived at this possible solution

parameters = {a, 3, 6, E, 2}; p = 1;
While[p <= 5, With[{p = p}, funclist[p, x_] := parameters[[p]] x^p]; p++]


But in this case the output is not actually a list but rather a sort of indexed function that cannot be manipulated as a list could be.

What I'd like to get is a list of functions that, for example can be used in the following ways:

in: funclist
out: {a x, 3 x^2...}


and also

in: funclist[[2]][4]
out: 48


or also

Plot[funclist[[2]],{x,-1,5}]


Is it possible?

The question contains conflicting requirements. On the one hand, it wants funclist to behave like a list of functions so that we can write funclist[[2]][4] and get a value. On the other hand, it wants funclist to act like a list of expressions in x so that we can write Plot[funclist[[2]], {x, -1, 5}]. The two requirements are incompatible: we will need to choose between them.

Functions

If we wish funclist to behave like a list of functions, we can do this:

parameters = {a, 3, 6, E, 2};

funclist = Function /@ (parameters # ^ Range@Length@parameters)

(* {a #1 &, 3 #1^2 &, 6 #1^3 &, E #1^4 &, 2 #1^5 &} *)


Then:

funclist[[2]][4]

(* 48 *)


But we must pass an explicit argument to one these functions in order to plot it:

Plot[funclist[[2]][x], {x, -1, 5}]


Expressions in x

Alternatively, we can have funclist contain a list of expressions in x:

funclist = parameters x ^ Range@Length@parameters

(* {a x, 3 x^2, 6 x^3, E x^4, 2 x^5} *)


But now we cannot invoke them like functions. To evaluate them, we need to replace x:

funclist[[2]] /. x -> 4

(* 48 *)


Plotting, on the other hand, does not require anything special:

Plot[funclist[[2]], {x, -1, 5}]


Earlier it was stated that we cannot have funclist behave both as a list of functions and as a list of expressions. This is not entirely true. If we are willing to damn the torpedoes and steam in anyway, it is possible to make it happen. This is not a serious proposal. It is simply a demonstration that the Wolfram language is very malleable, if we are determined enough.

We start by defining xfuns, which masquerades as an innocent list. In fact, it serves as a factory to produce these hybrid function/expression objects:

Format[xfuns[e___]] := {e}
xfuns[e___][[i_]] ^:= With[{a = {e}[[i]]}, xfun[a]]


Next we define xfun, a wrapper that implements the hybrid behaviour:

xfun[e_] /; MatchQ[Stack[], {___, Null, xfun, MatchQ}] := Function @@ {{x}, e}
xfun[x_] := x


This nasty piece of business looks up the call stack to see whether or not it is being applied to an argument. If it is, it returns a function. Otherwise it returns an expression.

Here it all is in action:

funclist = xfuns @@ (parameters x ^ Range@Length@parameters)

(* {a x, 3 x^2, 6 x^3, E x^4, 2 x^5} *)


funclist looks like a list of expressions in x. The individual elements resolve to expressions as well:

funclist[[2]]

(* 3 x^2 *)


Plot agrees:

Plot[funclist[[2]], {x, -1, 5}]


But... they can be used as functions too!

funclist[[2]][4]

(* 48 *)


Pure evil. I emphasize again: this is not a recommended practice. This is just for fun. Programming in this style means that expressions evaluate in unexpected ways, creating a fertile breeding ground in which bugs can thrive.

Because of what I consider serious overlap with later answers (either with the beginning of this answer, or the later part) I feel compelled to note that this answer covers two different methods.

Sure, it's possible. But not quite in the way you imagined.

Clear[a, x, p];
parameters = {a, 3, 6, E, 2};
funclist = MapIndexed[# x^(First@#2) &, parameters]


{a x, 3 x^2, 6 x^3, E x^4, 2 x^5}

This looks right, just like your list, but they aren't functions so you can't evaluate them the way you hoped to. Instead we have to do something like

With[{x = 4}, Evaluate@funclist[[2]]]


48

where Evaluate is needed because that rewrites the expression so that x appears explicitly. With will only replace symbols that appear explicitly in the expression in its body. This is also needed to plot any of the expressions because, again, x has appear explicitly:

Plot[Evaluate@funclist[[2]], {x, -1, 5}]


You can write a list of functions that will execute the way you want, but the list won't look the way it does in your example. You could do it like this:

funclist = MapIndexed[Function[{x}, # x^(First@#2)] &, parameters]

{Function[{x}, a x^First[{1}]], Function[{x}, 3 x^First[{2}]],
Function[{x}, 6 x^First[{3}]], Function[{x}, E x^First[{4}]],
Function[{x}, 2 x^First[{5}]]}

funclist[[2]][4]


48

And for the plot:

Plot[funclist[[2]][x], {x, -1, 5}]


EDIT: As seismatica pointed out to me, using Evaluate inside funclist makes the output better looking:

funclist = MapIndexed[Function[{x}, Evaluate[# x^(First@#2)]] &, parameters]


{Function[{x}, a x], Function[{x}, 3 x^2], Function[{x}, 6 x^3], Function[{x}, E x^4], Function[{x}, 2 x^5]}

• I was probably the first one to upvote your answer. Before you find further "overlaps": What's with Plot[Evaluate@funclist[[1]], {x, -1, 5}] ??? – eldo Sep 6 '14 at 21:36
• @eldo Thanks for the vote. That's what I need to make it work, isn't it? – C. E. Sep 6 '14 at 21:39

There is also a solution without the need for Evaluate.

parameters = {a, 3, 6, E, 2};
funclist = Table[p #^e & /. {p -> parameters[[n]], e -> n}, {n, 1, 5}];


The # and & are abbreviations for building pure functions. # stands for the varaible and & has to be put at the end of the expression to build a function.

Then you can use funclist like this:

funclist[[2]][4]
(* 48 *)


or

Plot[funclist[[2]][x], {x, 0, 1}]


Instead of creating a list of functions, I would simply use

func[p_][x_] := parameters[[p]] x^p


To avoid accidental modification of parameters, I might use

funcparametes = {...};
func[p_][x_] := funcparameters[[p]] x^p


Then you can use func[1] as a function, or if you really need them stored in a list, func /@ Range[5] gives you that.

Definitions of the form f[...][...]...[...] := ... (i.e. having more than one [...]) are called sub-value definitions.

• func[5][x] functions with me. But func /@ Range[5] doesn't. Please clarify. – eldo Sep 6 '14 at 21:49
para = {a, 3, 6, E, 2};

fun = Map[para[[#]] x^# &, Range @ 5]


{a x, 3 x^2, 6 x^3, E x^4, 2 x^5}

Plot[
Evaluate @ Map[fun[[#]] /. a -> 700 &, Range @ 5],
{x, 0, 10},
PlotStyle -> {Black, Red, Green, Blue, Orange},
PlotTheme -> "Detailed",
ImageSize -> 600]


I would suggest (to make easier) to do it like this:

 parameters = {a, 3, 6, E, 2};
funclist[x_]=# x^Range[Length[#]] &[parameters]
(*{a x, 3 x^2, 6 x^3, E x^4, 2 x^5}*)
funclist[4][[2]]
(*48*)
Plot[funclist[x][[2]],{x,-1,5}]
`