Is it possible to use the NestList command with two functions, one at every even step and apply the other at every odd step. If this is possible could someone share an example ?
Update:
I think that the cleanest way is to use ComposeList
(as suggested by kglr),
but with PadRight
to generate {f,g,f,g,f,...}
sequence:
ComposeList[PadRight[{}, 5, {f, g}], x]
{x, f[x], g[f[x]], f[g[f[x]]], g[f[g[f[x]]]], f[g[f[g[f[x]]]]]}
It can be easily generalized to a larger number of functions:
ComposeList[PadRight[{}, 5, {f, g, h}], x]
{x, f[x], g[f[x]], h[g[f[x]]], f[h[g[f[x]]]], g[f[h[g[f[x]]]]]}
Original answer:
Here is one possibilty using FoldList
:
FoldList[If[OddQ[#2], f[#], g[#]]&, x, Range[4]]
{x, f[x], g[f[x]], f[g[f[x]]], g[f[g[f[x]]]]}
We can apply R.M's method from How to apply or map a list of functions to a list of data?
I'll show an example with three functions to demonstrate generality; two work just as well.
fns = {f, g, h};
NestList[Last[fns = RotateLeft[fns]][#] &, x, 5]
{x, f[x], g[f[x]], h[g[f[x]]], f[h[g[f[x]]]], g[f[h[g[f[x]]]]]}
-
$\begingroup$ @MrWizard, same style solution:
tmp = h; NestList[(tmp = tmp /. {f -> g, g -> h, h -> f})[#] &, x, 5]
$\endgroup$ – garej May 30 '17 at 14:44
Update: Another variation on ComposeList
:
ComposeList[PadRight[##, "Periodic"], x] &[{f, g}, 5]
{x, f[x], g[f[x]], f[g[f[x]]], g[f[g[f[x]]]], f[g[f[g[f[x]]]]]}
ComposeList[PadRight[##, "Periodic"], x] &[{f, g, h}, 5]
{x, f[x], g[f[x]], h[g[f[x]]], f[h[g[f[x]]]], g[f[h[g[f[x]]]]]}
Similarly, on FoldList
:
FoldList[#2@# &, x, PadRight[##, "Periodic"]] &[{f, g, h}, 5]
{x, f[x], g[f[x]], h[g[f[x]]], f[h[g[f[x]]]], g[f[h[g[f[x]]]]]}
And a variation on @WReach's approach:
foo = {{f, g }[[#2]]@#, 3 - #2} & @@ # &;
NestList[foo, {x, 1}, 5][[All, 1]]
{x, f[x], g[f[x]], f[g[f[x]]], g[f[g[f[x]]]], f[g[f[g[f[x]]]]]}
Original post:
Using NestList
i = 1; NestList[{f1, f2}[[Mod[i++, 2, 1]]][#] &, x, 5]
{x, f1[x], f2[f1[x]], f1[f2[f1[x]]], f2[f1[f2[f1[x]]]], f1[f2[f1[f2[f1[x]]]]]}
We get the same result using ComposeList
:
ComposeList[{f1, f2}[[Mod[Range[5], 2, 1]]], x]
or FoldList
in alternative ways:
FoldList[{f1, f2}[[Mod[#2, 2, 1]]][#] &, x, Range@5]
FoldList[#2@# &, x, {f1, f2}[[Mod[Range[5], 2, 1]]]]
FoldList[#2[#1] &, x, Riffle[Table[f, 3], g]]
(* {x, f[x], g[f[x]], f[g[f[x]]], g[f[g[f[x]]]], f[g[f[g[f[x]]]]]} *)
Here's my take using a counter:
Block[{i = 1}, NestList[Unevaluated[{f, g}[[ Mod[i++, 2, 1] ]] ], x, 5]]
{x, f[x], g[f[x]], f[g[f[x]]], g[f[g[f[x]]]], f[g[f[g[f[x]]]]]}
A golfier variation of the same (but vulnerable to existing definitions of f[g]
):
Block[{i = 0}, NestList[Unevaluated[f[g][[i++~Mod~2]]], x, 5]]
In:
nest[f_, g_, x_, n_] /; EvenQ[n] := Nest[g@*f, x, n/2]
nest[f_, g_, x_, n_] /; OddQ[n] := f@Nest[g@*f, x, (n - 1)/2]
nestlist[f_, g_, x_, n_] := Table[nest[f, g, x, i], {i, 0, n}]
nestlist[f, g, x, 5]
Out:
{x, f[x], g[f[x]], f[g[f[x]]], g[f[g[f[x]]]], f[g[f[g[f[x]]]]]}
-
$\begingroup$ This solution works but not exactly like
NestList
. BecauseNestList
calculatesf[x]
only once, and then uses that value in the next iterations, while this solution will recalculatef[x]
on each step. This can be important iff
has side effects i.e.f[x_] := (Print["Calculating f[", x, "]"]; ff[x])
. $\endgroup$ – Shadowray May 28 '17 at 9:42 -
$\begingroup$ @Shadowray Thanks! It's a surprise. I didn't know NestList calculate f[x] only once. And I assumed that f and g are purely functional functions. I made too many assumptions in this case. $\endgroup$ – UnchartedWorks May 28 '17 at 9:59
NetList
is not really the right choice for this, but you can use Nest
with Sow
and Reap
the intermediate results. E.g.,
ClearAll[f, g]
Last@Last@Reap@Nest[Sow@f[Sow@g[#]] &, x0, 3]
Nest[If[Head@# === g, f, g]@# &, x, 6]
This is a bad solution. Now I changed it.
f[g_, f_, n_] :=
Module[{g1, f1},
NestList[If[Head@# === g1, f1, g1]@# &, x, n] /. {g1 -> g, f1 -> f}]
To avoid recalculating f[x] at each step:
f[g_, f_, n_] :=
NestList[If[Head@# === Hold[g], Hold[f], Hold[g]]@ReleaseHold@# &, x, n + 1][[2 ;;, 1]]
-
$\begingroup$ @Shadowray Thank you for pointing out my mistake $\endgroup$ – wul May 28 '17 at 17:55
-
$\begingroup$ No problem. Note that your new solution has the same specifics as the one by UnchartedWorks. I.e. it will recalculate f[x] at each step. $\endgroup$ – Shadowray May 28 '17 at 18:11
-
$\begingroup$ @Shadowray Thank you again. I have changed my answer. $\endgroup$ – wul May 29 '17 at 4:48