# Obtaining all possible compositions of functions in mathematica

Suppose I have two functions $$f,g$$ given by

f[path1_] := Drop[FoldList[fr[#1, #2] &, 1, path1], 1]
g[path1_] := Drop[FoldList[fr[#1, #2] &, -1, path1], 1]


with

fr[z1_, z2_] := z /. FindRoot[f0[z] == z2, {z, z1}]

and f0[z_] := z^2 + c0

with c0=-1

taking as input a list list1 = Table[4E^(j*I*Pi/256), {j, 0, 512}].

Is there a way to write a function say x[n_] which gives all possible n-fold compositions of these two functions?

So x would give the list {f[f[list1]], f[g[list1]], g[f[list1]], g[g[list1]]}

Could I then build some labeling of these? Suppose I wanted each composition to be labelled by the string of functions that built it e.g. for the f[g[g[list1]]] it would be labelled by $$ggf$$. Could I somehow also have a function that takes as input x and gives the list {ff,fg,gf,gg} so as to keep track of the order of the output of x[n]?

I have been thinking about this for a while but it seems like a difficult code to write, although I do not have strong programming skills.

• #[list1] & /@ Composition @@@ Tuples[{f, g}, 2] Jun 3, 2020 at 13:58
• Your question does not indicate how you are using FindRoot. What is the definition of your fr? Jun 3, 2020 at 14:27
• Which then leads to the question, what is your definition of f0? Jun 3, 2020 at 14:36

Clear["Global*"]

c0 = -1;
f0[z_] := z^2 + c0;


Your use of FindRoot indicated a possible precision issue. Consequently, add a means of precision control. Also, since fr uses a numeric technique, restrict its arguments to numeric values.

fr[z1_?NumericQ, z2_?NumericQ,
wp_ : MachinePrecision] := Module[{
z1p = SetPrecision[z1, wp],
z2p = SetPrecision[z1, wp]},
z /. FindRoot[f0[z] == z2p, {z, z1p},
WorkingPrecision -> wp]]


Specify a WorkingPrecision in the definitions of f and g

f[path1_List] :=
Drop[FoldList[fr[#1, #2, 15] &, 1, path1], 1];
g[path1_List] :=
Drop[FoldList[fr[#1, #2, 15] &, -1, path1], 1];

x[n_Integer?Positive] := Module[
{t = Tuples[{f, g}, n]},
Transpose[{StringJoin @@@ (Map[ToString, #, {1}] & /@ t),
#[list1] & /@ Composition @@@ t}]];


Using an abbreviated list for this example

list1 = Table[4 E^(j*I*Pi/256), {j, 0, 7}];


Using N to abbreviate the output display

x // N

(* {{"ff", {1.41421, 1.55377, 1.59805, 1.61185, 1.61612, 1.61744, 1.61785,
1.61798}}, {"fg", {1.41421, 1.55377, 1.59805, 1.61185, 1.61612, 1.61744,
1.61785, 1.61798}}, {"gf", {-2.98023*10^-8, -1., -0.00012207, -0.999939, \
-0.00781262, -0.996086, -0.0625617, -0.968214}}, {"gg", {-2.98023*10^-8, -1., \
-0.00012207, -0.999939, -0.00781262, -0.996086, -0.0625617, -0.968214}}} *)

• Thanks for this, it's very helpful, but there is something which doesn't act as it should. When I tried the code there was the same precision error. I have code which works to produce the list of outputs expected but this does not match the above code. The output should give complex numbers for example, x1 = Map[ToComplex, ReIm[list1]]; x1[n_] := x1[n] = f[x[n - 1]] and similarly we can define a recursive function for g. This gives the correct output but I had issues iterating this correctly, previously and it resulted in precision errors. I'm not sure if there is some way to fix this.
– math
Jun 3, 2020 at 19:27
• I do not understand your comment. ToComplex is undefined. Your recursion is not recursive. Although perhaps you mean for x[n-1] to be x1[n-1]`. Please spend some time formulating questions. Jun 3, 2020 at 20:53