If PDL-like threading syntax is adopted, this is trivial.  In PDL:
    $a = pdl(1,2);
    $b = pdl(3,4);
    $c = $a->(*1) * $b;
    print $c;
yields the output:
     [3 4]
     [6 8]
The '(*1)' inserts a dummy dimension into $a, making it a 1x2-array rather than a 2-array. Then
the threading engine makes the appropriate outer product.

I strongly encourage the use of threading syntax (see the very nice PDL::NiceSlice module) rather than a specific outer-product operator: threading syntax turns out to be the answer to a rather large collection of problems.

On Oct 28, 2005, at 12:21 AM, Darren Duncan wrote:

Not sure if this matter was resolved on a previous discussion, but here goes ...

I would like to have a simple way to combine 2 array where every element of each array is combined with every element of the other array; this can also chain or scale to handle any number of arrays. For now lets name it 'cross', since it behaves similarly to the set operation that SQL calls a cross-join.

What I'm not yet sure about is whether this would be better as something resembling the zip() operator or a hyper-operator.

One thing I would like to be able to do is this:

  @baz = cross([1,2],[3,4]); # yields ([1,3],[1,4],[2,3],[2,4])

And alternately, this:

  for cross([1,2],[3,4]) -> $foo,$bar { ... } # loop has 4 iterations

More examples:

  cross() # yields ()
  cross([],[1]) # yields ()
  cross([1,2]) # yields ([1],[2])
  cross([1,2],[3]); # yields ([1,3],[2,3])
  cross([1],[2],[3]) # yields ([1,2,3])
  cross([1],[2],[3,4]) # yields ([1,2,3],[1,2,4])

The order of the output elements is determined by the order of the input elements.

If one were to be able to use this as a simple joining mechanism, then each combination would have to be returned as an array, so that 'map' or 'grep' etc would work properly. For example:

  @A = ('red shirt', 'white shirt');
  @B = ('blue pants', 'black pants');

  @C = map { "going with $_[0] and $_[1] today" } cross(@A,@B);

On the other hand, perhaps something I actually want is something like the hyper-operation but with appropriately different syntax:

  ['a','b'] >>~<< ['c','d']

But that it returns ['ac','ad','bc','bd'] rather than ['ac','bd'].

So is there a similarly terse way to do combinations already, and if not then would you consider it commonly used enough to add?

-- Darren Duncan

Reply via email to