3
$\begingroup$

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?

$\endgroup$
4
$\begingroup$

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 the 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}}
$\endgroup$
3
$\begingroup$

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]}}
$\endgroup$
3
$\begingroup$
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]}}

$\endgroup$
2
$\begingroup$

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]}} *)
$\endgroup$
  • 2
    $\begingroup$ @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. $\endgroup$ – Mike Honeychurch Oct 12 '13 at 6:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.