From e4fb816e77a852230490817bb53aa6f9ceb3725e Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Tue, 5 Jan 2021 22:18:10 -0500 Subject: Add Reshape and Transpose to restructuring primitive commentary --- docs/spec/primitive.html | 2 ++ spec/primitive.md | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/docs/spec/primitive.html b/docs/spec/primitive.html index ab11aa76..c8db181e 100644 --- a/docs/spec/primitive.html +++ b/docs/spec/primitive.html @@ -117,3 +117,5 @@

Enclose (<) forms a unit array that contains its argument.

Merge (>) combines the outer axes of an array of arrays with inner axes: it requires that all elements of its argument have the same shape, and creates an array such that (i∾j)āŠ‘>š•© is iāŠ‘jāŠ‘š•©. It also accepts atom elements of š•©, converting them to unit arrays, or an atom argument, which is returned unchanged. Solo and Couple (ā‰) turn one or two arguments into major cells of the result and can be defined easily in terms of Merge.

Join To (∾) combines its two arguments along an existing initial axis, unless both arguments are units, in which case it creates an axis and is identical to Couple (ā‰). The arguments must differ in rank by at most 1, and the result rank is equal to the maximum of 1 and the higher argument rank. Each argument with rank less than the result, and each major cell of an argument with rank equal to it, becomes a major cell of the result, with cells from the left argument placed before those from the right. Join (∾) generalizes the equal-rank subset of this behavior to an array of values instead of just two. The argument must be an array (unlike Merge), and its elements must all the same rank, which is at least the argument rank. Atom elements are treated as unit arrays. Then "outer" argument axes are matched up with leading "inner" element axes, and elements are joined along these axes. In order to allow this, the length of an element along a particular axis must depend only on the position along the corresponding axis in the argument. An empty argument to Join is return unchanged, as though the element rank is equal to the argument rank.

+

Deshape (ℊ) differs from the provided function (which returns the element list of an array) only in that it accepts an atom, returning a one-element list containing it. Reshape (ℊ) is extended in numerous ways. It accepts any list of natural numbers (including as a unit array or atom) for the left argument and any right argument; š•© is deshaped first so that it is treated as a list of elements. These elements are repeated cyclically to fill the result array in ravel order. If š•© is empty but the result is not, then the result consists of fill elements for š•©. Furthermore, at most one element of š•Ø can be a "length code": one of the primitives āˆ˜āŒŠāŒ½ā†‘. In this case, a target length is computed from the number of elements in š•© divided by the product of the other elements of š•Ø (which must not be zero). If the target length is an integer then it is used directly for the length code. Otherwise, an error is given if the length code is ∘, and the target length is rounded down if the code is ⌊ and up if it's ⌽ or ↑. With code ⌽, elements are repeated cyclically as usual, but with code ↑, the extra elements after each argument element is used are fill values for š•©.

+

Transpose (ā‰) reorders axes of its argument to place the first axis last; if the argument has one or fewer axes then it's returned unchanged. Reorder Axes (ā‰) requires the left argument to be a list or unit of natural numbers, with length at most the rank of the right argument. This list is extended to match the right argument rank exactly by repeatedly appending the least unused natural number (for example, given 1‿3‿0‿0, 2 is appended). After extension, it specifies a result axis for each axis of the right argument. There must be no gaps in the list: that is, with the result rank equal to one plus the greatest value present, every result axis must appear at least once. Now each argument axis is "sent to" the specified result axis: in terms of indices, iāŠ‘š•Øā‰š•© is (š•ØāŠi)āŠ‘š•© if š•Ø is complete. If multiple argument axes correspond to the same result axis, then a diagonal is taken, and it's as long as the shortest of those argument axes. While Transpose does not enclose an atom right argument, Reorder Axes does, so that its result is always an array.

diff --git a/spec/primitive.md b/spec/primitive.md index ba5fae9b..b2d9b6ff 100644 --- a/spec/primitive.md +++ b/spec/primitive.md @@ -140,3 +140,7 @@ Modifiers for iteration are defined in layers 1, 2, and 4. Two 2-modifiers, `āš‡ **Merge** (`>`) combines the outer axes of an array of arrays with inner axes: it requires that all elements of its argument have the same shape, and creates an array such that `(i∾j)āŠ‘>š•©` is `iāŠ‘jāŠ‘š•©`. It also accepts atom elements of `š•©`, converting them to unit arrays, or an atom argument, which is returned unchanged. **Solo** and **Couple** (`ā‰`) turn one or two arguments into major cells of the result and can be defined easily in terms of Merge. **Join To** (`∾`) combines its two arguments along an existing initial axis, unless both arguments are units, in which case it creates an axis and is identical to Couple (`ā‰`). The arguments must differ in rank by at most 1, and the result rank is equal to the maximum of 1 and the higher argument rank. Each argument with rank less than the result, and each major cell of an argument with rank equal to it, becomes a major cell of the result, with cells from the left argument placed before those from the right. **Join** (`∾`) generalizes the equal-rank subset of this behavior to an array of values instead of just two. The argument must be an array (unlike Merge), and its elements must all the same rank, which is at least the argument rank. Atom elements are treated as unit arrays. Then "outer" argument axes are matched up with leading "inner" element axes, and elements are joined along these axes. In order to allow this, the length of an element along a particular axis must depend only on the position along the corresponding axis in the argument. An empty argument to Join is return unchanged, as though the element rank is equal to the argument rank. + +**Deshape** (`ℊ`) differs from the provided function (which returns the element list of an array) only in that it accepts an atom, returning a one-element list containing it. **Reshape** (`ℊ`) is extended in numerous ways. It accepts any list of natural numbers (including as a unit array or atom) for the left argument and any right argument; `š•©` is deshaped first so that it is treated as a list of elements. These elements are repeated cyclically to fill the result array in ravel order. If `š•©` is empty but the result is not, then the result consists of fill elements for `š•©`. Furthermore, at most one element of `š•Ø` can be a "length code": one of the primitives `āˆ˜āŒŠāŒ½ā†‘`. In this case, a target length is computed from the number of elements in `š•©` divided by the product of the other elements of `š•Ø` (which must not be zero). If the target length is an integer then it is used directly for the length code. Otherwise, an error is given if the length code is `∘`, and the target length is rounded down if the code is `⌊` and up if it's `⌽` or `↑`. With code `⌽`, elements are repeated cyclically as usual, but with code `↑`, the extra elements after each argument element is used are fill values for `š•©`. + +**Transpose** (`ā‰`) reorders axes of its argument to place the first axis last; if the argument has one or fewer axes then it's returned unchanged. **Reorder Axes** (`ā‰`) requires the left argument to be a list or unit of natural numbers, with length at most the rank of the right argument. This list is extended to match the right argument rank exactly by repeatedly appending the least unused natural number (for example, given `1‿3‿0‿0`, `2` is appended). After extension, it specifies a result axis for each axis of the right argument. There must be no gaps in the list: that is, with the result rank equal to one plus the greatest value present, every result axis must appear at least once. Now each argument axis is "sent to" the specified result axis: in terms of indices, `iāŠ‘š•Øā‰š•©` is `(š•ØāŠi)āŠ‘š•©` if `š•Ø` is complete. If multiple argument axes correspond to the same result axis, then a diagonal is taken, and it's as long as the shortest of those argument axes. While Transpose does not enclose an atom right argument, Reorder Axes does, so that its result is always an array. -- cgit v1.2.3