I'd like to Fold over higher dimensional objects than lists. Semantically, the format would be something like FoldMulti[f, array, list]. As a precondition, Dimensions[array] == Length[list].

The motivating example is from the recent discussions about inverse of CoefficientList.

Let poly be some polynomial, and cl be the coefficient list e.g.

poly = a x^5 + (x + 2 y)^3 + x y z + 1;
vars = {x, y, z};
cl = CoefficientList[poly, vars];

In this example, array = cl is 3 dimensional, and poly has length 3. For each variable var in {x,y,z}, the function (#1 var + #2) & should be folded across cl, to recreate poly from the coefficient array cl.

The following code works:

   Function[{clinner, var}, Fold[(#1 var + #2) &, Reverse@clinner]],

% - poly // Expand
(* 0 *)

but the problem is that's just a horribly complex bit of code that calls Fold twice.

The following works and is pretty enough! But it uses a different idiom.

polyFromCL[cl_, {}] := cl
polyFromCL[cl_, vars_] :=
    Fold[(#1 First@vars + #2) &, Reverse@cl],

polyFromCL[cl, vars]
% - poly // Expand
(* 0 *)

Can something like MapThread or Outer be made to do this elegantly?

  • 2
    $\begingroup$ I'm not sure if I got the point, but why not Fold[FromDigits[Reverse[#1], #2] &, cl, {x, y, z}] like documentation suggests? $\endgroup$ – Kuba May 10 '15 at 15:41
  • 3
    $\begingroup$ What kind of output do you expect from this Tensor Fold ? For this multi-fold do you mean something like: Outer[Fold[f, #1, #2] &, {{o,p}, {q,r}, {s,t}},{{u,v}, {w,x}, {y,z}},1] Maybe TensorContract[#,{level}] and the Tensor functions could be helpful. $\endgroup$ – Histograms May 10 '15 at 16:40
  • $\begingroup$ @Kuba the example documentation is wrong, see the answers to the question on Unexpected behaviour using FromDigits. $\endgroup$ – djp May 10 '15 at 22:42
  • 1
    $\begingroup$ I do not understand why you feel that the first method is a "horribly complex bit of code" -- okay, it's not the embodiment of elegance, but really what's wrong with it? $\endgroup$ – Mr.Wizard May 10 '15 at 23:10
  • $\begingroup$ @Mr.Wizard Horribly complex might be exaggerating, but it's the sort of code that is much easier to write than read. I don't like defining two different functions in a single line of code! You would avoid using Table twice in a single line like that, I'm hoping to avoid using Fold twice in much the same way. $\endgroup$ – djp May 11 '15 at 0:35

This is fairly elegant way for dealing with your example, but I don't see how to generalize it a multi-dimensional Fold, what ever that might be.

p1 = a x^5 + (x + 2 y)^3 + x y z + 1;
vars = {x, y, z};
cl = CoefficientList[p1, vars];
p2 = Fold[FromDigits[Reverse[#1], #2] &, cl, vars];
p1 - p2 // Expand


BTW, I unashamedly stole this from the 2nd example given under CoefficientList > Examples > Properties & Relations


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