6

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:

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

% - 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_] :=
  polyFromCL[
    Fold[(#1 First@vars + #2) &, Reverse@cl],
    Rest@vars
  ]

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

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

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
djp
  • 1,493
  • 14
  • 18
  • 2
    I'm not sure if I got the point, but why not Fold[FromDigits[Reverse[#1], #2] &, cl, {x, y, z}] like documentation suggests? – Kuba May 10 '15 at 15:41
  • 3
    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.

    – Histograms May 10 '15 at 16:40
  • @Kuba the example documentation is wrong, see the answers to the question on Unexpected behaviour using FromDigits. – djp May 10 '15 at 22:42
  • 1
    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? – Mr.Wizard May 10 '15 at 23:10
  • @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. – djp May 11 '15 at 00:35
  • @Histograms I don't know what the general form should be but I will think about it. I posed the question because I've bumped up against this problem a couple of times and always felt that I was missing a useful idiom. I hoped that someone would recognise the pattern and say "oh you need to know about cwyozeg" :) or similar. – djp May 11 '15 at 00:39
  • Could you provide a second example of a two-dimensional Fold operation? I have trouble separating this particular example from the generalized concept. – Mr.Wizard May 11 '15 at 04:22
  • I'll try. It was years ago. Got called in to work so it might be a couple of days. Thanks so far. – djp May 11 '15 at 05:05

1 Answers1

2

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

0

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

m_goldberg
  • 107,779
  • 16
  • 103
  • 257