20

Fold is an extension of Nest for 2 arguments. How does one extend this concept to multiple arguments. Here is a trivial example:

FoldList[#1 (1 + #2) &, 1000, {.01, .02, .03}]

Say I want do something like:

FoldList[#1(1+#2)-#3&,1000,{.01,.02,.03},{100,200,300}] 

where 100,200,300 are the values for #3. I know Fold doesn't work this way. I'm looking for an approach that will work like this... ((1000*(1.01)-100)*1.02-200)*1.03-300).

Is there a way to extend Fold to more than 2 arguments? or is there a better approach for solving problems like this?

RobK
  • 417
  • 2
  • 7

2 Answers2

23

Yes, there is. Group your extra arguments in a list, and address them by their positions in the function under Fold. For your particular example:

FoldList[#1 (1 + First@#2) - Last@#2 &, 1000, Transpose@{{.01, .02, .03}, {100, 200, 300}}]

(* {1000, 910., 728.2, 450.046} *)
Leonid Shifrin
  • 114,335
  • 15
  • 329
  • 420
15

To achieve the specific syntax you requested we can use something like this:

multiFoldList[f_, start_, args__List] :=
  FoldList[f @@ Prepend[#2, #] &, start, {args}\[Transpose]]

Example:

multiFoldList[#1 (1 + #2) - #3 &, 1000, {.01, .02, .03}, {100, 200, 300}]
{1000, 910., 728.2, 450.046}

Here is another formulation which tests slightly faster and may be easier to read:

multiFoldList[f_, start_, args__List] :=
  Module[{ff},
    ff[x_, {y__}] := f[x, y];
    FoldList[ff, start, {args}\[Transpose]]
  ]
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371