MathGroup Archive 1997

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Threading objects of unequal length

  • To: mathgroup at
  • Subject: [mg8163] Re: [mg8112] Threading objects of unequal length
  • From: Olivier Gerard <jacquesg at>
  • Date: Sat, 16 Aug 1997 11:51:07 -0400
  • Sender: owner-wri-mathgroup at

C. Woll wrote
> Hi group,
> I'm interested in adding variable length List. For example, I would like
> to do something like
> {a,b}+{c,d,e}+{f}
> to return
> {a+c+f,b+d,e}
> Of course, Plus doesn't work, since you can't thread objects of unequal
> length.
>  [ more follows...]

For the specific task of Plus, which is very easy to
handle because there is a neutral element (namely 0),
you can do something like that:

PaddedPlus[ jk__List ] :=
Module[{mlotl}, mlotl=Max[Map[Length, List[jk]]];
Plus@@Map[Join[#1,Array[0&,mlotl-Length[#1]]]&, List[jk]] ]


PaddedPlus[ {a,b}, {c,d,e,f},{g,h,i}]

{a + c + g, b + d + h, e + i, f}

This is only a rough interpretation, mostly valable for
sets of lists irregular only at the first level. For more
nested cases, one should be a bit more cautious and imaginative.
Also, the reason why Thread does not do something like this
is that many behaviors are possible in this situation.
(By the way, my code is easy modifiable to the case were
you want the lists to be justified to the right instead of the
left or even to a few differents kind of centering).

> So what is a good way of defining a function to do this? To be specific, I
> would like a function g which accepts multiple arguments, and when given
> an input like
> g[{a,b}, {c,d,e}, {f}]
> returns
> {h[a,c,f],h[b,d],h[e]}
> where in my particular application, I want h to be Plus. However, it would
> be nice to have the function work for arbitrary heads.
> I could do something like padding each of the arguments with some dummy
> variable so that everything has the same length, then threading, then
> removing the dummy variable, but that seems very cumbersome. Can anyone
> think of a better way?
> Thanks for any comments.
> Carl Woll
> Physics Dept
> U of Washington

A good way in my opinion would be to have a very powerful syntax
for a generalization of Transpose and a neutral element for being
in a list or for list ap/pre-pending.
I have been proposing that many times to WRI. Anyone listening ?

Here is an easy implementation of the idea you mention, restricted
to your original purpose and you can see it is not so cumbersome:

(* Code *)
TestEltQ[NotAnElt] = False;
TestEltQ[__] = True;

SetAttributes[PaddedThread, HoldAll]
PaddedThread[ hd_Symbol[jk__List] ] :=
Module[{mlotl=Max[Map[Length, List[jk]]]},
Map[ hd@@Select[#1,TestEltQ]&,
Transpose[Map[Join[#1,Array[NotAnElt&,mlotl-Length[#1]]]&, List[jk]]] ]

(* Example *)
PaddedThread[ FTGT[{a,b}, {c,d,e,f},{g,h,i}] ]

{FTGT[a, c, g], FTGT[b, d, h], FTGT[e, i], FTGT[f]}

This 'version' of Thread has not all the features of the original
but it would not be difficult to make it so. We can imagine an
option with values Left, Right for the kind of padding and a few other things.

Another way of doing what you want to do is to play with indices
of elements in the lists. It is often inefficient in Mathematica
compared to List programming. I would be very interested if someone
has another idea.

Of course, the ideas I alluded to have broader uses and could
be a significant addition to Mathematica programming language
but to be implemented both generally and efficiently they require
more code and intermediate functions to help users master their power.

Hope this helps,

Olivier Gerard

Mathematica Developper

  • Prev by Date: Re: Strange result in MMa 3.0
  • Next by Date: Re: ListPlot with little plus signs instead?
  • Previous by thread: Re: Threading objects of unequal length
  • Next by thread: Re: Threading objects of unequal length