# How to combine multiple functions into a single function, indexed bya new argument

I have a system of expressions (matrices) which correspond to increasing orders of precision in a theory. These expressions are quite complex (require about 40+ lines of code to produce) and are not of equal size (the dimension increases monotonically with the order in the theory). For this reason, I have resigned myself to not creating a single cell which produces all orders.

f1[x_, y_] = {{x, y}, {x y, x + y}}
f2[x_, y_] = {{x, y, 0}, {0, x + y, 0}, {1, x - y, x y}}


and I would like to produce a new function

g[(*something*),x_,y_]


such that

g[1,x_,y_] = f1[x_,y_]
g[2,x_,y_] = f2[x_,y_]


Can this be accomplished?

Is there a way to form a conditional on the arguments of a function? Something like

g[j_,x_,y_]=If[j==1,f1[x_,y_],f2[x_,y_]]


This doesn't work, of course, because the first argument isn't actually assigned to j. I guess I'm more surprised it doesn't work to just define g[1,x_,y_] and g[2,x_,y_] individually as above, but it doesn't work.

• You can do g[i_Integer, x_, y_] := Symbol["f" <> ToString@i][x, y]. This question is often asked here...
– rm -rf
Commented Mar 7, 2014 at 22:18
• I apologize for the repeat question. Commented Mar 7, 2014 at 22:24
• No worries :) There's no harm in accidentally asking the same question... if my comment helped you, feel free to just delete the question. Also, if you're only switching between some finite number of such functions, take a look at Switch.
– rm -rf
Commented Mar 7, 2014 at 22:27

Another approach is to define your f's in a manner more conducive to easy manipulations down the road. For instance,

f[1, x_, y_] := {{x, y}, {x y, x + y}};
f[2, x_, y_] := {{x, y, 0}, {0, x + y, 0}, {1, x - y, x y}};
g[i_, x_, y_] := f[i, x, y];


allows a simple definition of g. Of course, in this case, you don't even need the g at all.

Your syntax is not quite right, which is why your attempt did not work. Pattern objects should not be on the right-hand-side of the definition. Correcting that alone solves the problem:

f1[x_, y_] = {{x, y}, {x y, x + y}};
f2[x_, y_] = {{x, y, 0}, {0, x + y, 0}, {1, x - y, x y}};

g[1, x_, y_] = f1[x, y];
g[2, x_, y_] = f2[x, y];


Test:

g[2, a, b]

{{a, b, 0}, {0, a + b, 0}, {1, a - b, a b}}


You should also familiarize yourself with the difference between Set and SetDelayed. The latter is most often what you want as it is "safest" since it avoids possibly premature evaluation.

In addition this syntax, and the one which bill s showed, here is another option:

h[1][x_, y_] := {{x, y}, {x y, x + y}};
h[2][x_, y_] := {{x, y, 0}, {0, x + y, 0}, {1, x - y, x y}};


This has the advantage of allowing you to use the expression h[1] as you would f1, in e.g. Apply:

h[1] @@@ {{a, b}, {c, d}}

{{{a, b}, {a b, a + b}}, {{c, d}, {c d, c + d}}}


See Define parameterized function for more examples of and information regarding this syntax.

g[1, x_, y_] := f1[x, y]
g[2, x_, y_] := f2[x, y]


It works.