Can I combine two FoldList into one?

I want get something like this:

{{x, x}, {g[x, 1], f[x, 1]}, {g[g[x, 1], 2],
f[f[x, 1], 2]}, {g[g[g[x, 1], 2], 3], f[f[f[x, 1], 2], 3]}}

one way is Transpose@{FoldList[f, x, {1, 2, 3}], FoldList[g, x, {1, 2, 3}]}

Is it posibble only use FoldList once?

=================

=================

4 Answers
4

=================

I am going to argue for the superiority of the method you are already using, and suggest using an auxiliary function to simplify its application.

Fold and FoldList auto-compile, where possible, when the length of the third argument is greater than value defined in SystemOptions[“CompileOptions” -> “FoldCompileLength”]. Since it will be less likely for the combined form to compile (generally), for best performance I think you should not try to combine both functions into one.

I propose:

multiFoldList[fns_, start_, list_] := Transpose[FoldList[#, start, list] & /@ fns]

Usage and performance:

SeedRandom[1]
args = RandomReal[{-1, 1}, 3500000];

multiFoldList[{Plus, Times, #/2 + #2 &}, 0`, args] // Timing // First

0.53

Compared to a combined form of the same operation:

FoldList[{#[[1]] + #2, #[[2]] #2, #[[3]]/2 + #2} &, {0`, 0`, 0`}, args] // timeAvg

0.702

If you wish to provide for the possibility of different starting (“x”) values for each function you can use this form:

multiFoldList[fns_List, start_, list_] :=
FoldList[##, list] & @@@ Thread[{fns, start}] // Transpose

Allowing:

multiFoldList[{Plus, Times, #/2 + #2 &}, {1`, 2`, 3`}, {10`, 11`, 12`, 13`, 14`}]

{{1., 2., 3.}, {11., 20., 11.5}, {22., 220., 16.75}, {34., 2640., 20.375},
{47., 34320., 23.1875}, {61., 480480., 25.5938}}

Or a shared starting value as before:

multiFoldList[{Plus, Times, #/2 + #2 &}, 2.5, Range[2, 7]]

{{2.5, 2.5, 2.5}, {4.5, 5., 3.25}, {7.5, 15., 4.625}, {11.5, 60., 6.3125},
{16.5, 300., 8.15625}, {22.5, 1800., 10.0781}, {29.5, 12600., 12.0391}}

Here’s another way using Rules and Pure Functions:

{#, # /. f -> g} & /@ FoldList[f, x, {1, 2, 3}]

Gives:

{{x, x}, {f[x,1], g[x,1]}, {f[f[x,1], 2], g[g[x,1], 2]}, {f[f[f[x,1], 2], 3], g[g[g[x, 1], 2], 3]}}

Here’s a way to write it with just a single FoldList:

FoldList[{f[#[[1]], #2], g[#[[2]], #2]} &, {x, x}, {1, 2, 3}]
(* {{x, x}, {f[x, 1], g[x, 1]}, {f[f[x, 1], 2],
g[g[x, 1], 2]}, {f[f[f[x, 1], 2], 3], g[g[g[x, 1], 2], 3]}} *)

2

 

@expression what do you expect if you multiply True by an integer! Additionally you are introducing a function that returns one part but using it in a way that requires the output to have two parts. …And so on. Some effort is needed on your part to understand answers provided.
– Mike Honeychurch
Oct 12 ’13 at 6:09

Thread[FoldList[#, x, {1, 2, 3}] & /@ {f, g}]

{{x, x}, {f[x,1], g[x,1]}, {f[f[x,1], 2], g[g[x,1], 2]}, {f[f[f[x,1], 2], 3], g[g[g[x, 1], 2], 3]}}