Outer Product

, or Table is a monadic operator, which will produce a dyadic function when applied with a dyadic function. Outer product applies the operand function on each element of the left array with each element of the right array. It can be described as a shortcut for constructing nested for loops, and as a generalization of the Cartesian product to operations other than catenation.

Syntax
Outer Product differs from all other monadic operators, which are written as a single glyph, with the operand on the left. For historical reasons, the outer product operator is a bi-glyph denoted as, and its operand appears on the right. This special notation is derived from the  notation of inner product: The result of an inner product is an array with rank two less than the sum of the argument ranks. The result of an outer product, on the other hand, is always an array of rank equal to the sum of the argument ranks. This follows from the fact that the reduction operation, which collapses two dimensions in an inner product, is not used in the outer product. The notation for outer product reflects this by canonically using a small circle as the first symbol. Thus, the ordinary outer product is written as. This syntactical inconsistency is resolved in J and BQN, where the outer product operator, called Table, and denoted  and   respectively, has the usual operator syntax.

Model
Outer Product can be modeled as.

Applications
Outer product is useful for solving problems that intuitively require a polynomial time algorithm. This may also indicate that such an algorithm is not the fastest solution.

For example, suppose we want to find duplicated elements in an non-nested array. Intuitively speaking, the easiest way to solve this problem is to compare each element of the array with all other elements, which is exactly what an outer product does. Using similar techniques, we can define a function that generates prime numbers by using an outer product of Residue. Here there are faster solutions such as the Sieve of Eratosthenes.

Differences between dialects
J's Table differs from APL's Outer Product by enabling Cartesian pairing between cells of ranks other than 0, and between cells of different rank for the left vs. right arguments, without needing to first enclose the relevant cells. It is defined as, where   is the left rank of operand   (  denotes infinity in J). The results of the individual applications of u are collectively framed by the catenation of the frames of the left and right arguments relative to their lu- and ru-cells respectively, where lu and ru are the dyadic ranks of the operand u. Unlike APL's Outer Product, J's Table does not use an implicit Each, so the results of the individual applications of its operand are not boxed (unless the given operand itself does so).

In APL this behavior can be accomplished by enclosing the relevant cells of each argument before applying the outer product operation (or by successive applications of Rank, e.g. ). Conversely, the behavior of APL's Outer Product can be accomplished in terms of J's Table by adding the Each modifier, as in   or , depending on whether the given operand is a scalar function.

The Cartesian pairing behavior of J's Table results from each  cell-pairing being processed by , which applies its own ranks to divide up the right argument into cells.

However, it does not allow for creating a Cartesian pairing involving cells of the left argument specified with negative left rank (except trivially, in cases in which Table's application has no effect, e.g. ). This is because negative assigned rank in J is encoded as infinite rank; in J's terminology, negative rank is "internal rank" only.

Documentation

 * Dyalog
 * APLX
 * J Dictionary, NuVoc
 * BQN