diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-06-11 20:08:12 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-06-11 20:08:12 -0400 |
| commit | b6bcf214e638fd36ef7d76c9f573a84e6e016482 (patch) | |
| tree | a435e4f0afed7266b868798e51b792c4600fabe1 /doc/transpose.md | |
| parent | 383298b70274c5ac22eb2100aad7f6cd8eeca02d (diff) | |
Nothing but edits yet again
Diffstat (limited to 'doc/transpose.md')
| -rw-r--r-- | doc/transpose.md | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/doc/transpose.md b/doc/transpose.md index e11ab359..fdbfdeca 100644 --- a/doc/transpose.md +++ b/doc/transpose.md @@ -28,7 +28,7 @@ BQN's transpose takes the first axis of `π©` and moves it to the end. β’ β a23456 -In terms of the argument data as given by [Deshape](reshape.md#deshape) (`β₯`), this looks like a simple 2-dimensional transpose: one axis is exchanged with a compound axis made up of the other axes. Here we transpose a rank 3 matrix: +In terms of the index-ordered elements as given by [Deshape](reshape.md#deshape) (`β₯`), this looks like a simple 2-dimensional transpose: one axis is exchanged with a compound axis made up of the other axes. Here we transpose a rank 3 matrix: a322 β 3βΏ2βΏ2β₯β12 βββ a322 @@ -45,7 +45,7 @@ To exchange multiple axes, use the [Repeat](repeat.md) modifier. A negative powe In fact, we have `β’ββk a ββ kβ½β’a` for any whole number `k` and array `a`. -To move axes other than the first, use the Rank modifier in order to leave initial axes untouched. A rank of `k>0` transposes only the last `k` axes while a rank of `k<0` ignores the first `|k` axes. +To move axes other than the first, use the [Rank modifier](rank.md) in order to leave initial axes untouched. A rank of `k>0` transposes only the last `k` axes while a rank of `k<0` ignores the first `|k` axes. β’ ββ3 a23456 @@ -57,7 +57,7 @@ Using these forms (and the [Rank](shape.md) function), we can state BQN's genera a MP b ββ ββ(1-=a) (βb) MP (ββΌa) -Certainly not as concise as APL's version, but not a horror either. BQN's rule is actually more parsimonious in that it only performs the axis exchanges necessary for the computation: it moves the two axes that will be paired with the matrix product into place before the product, and directly exchanges all axes afterwards. Each of these steps is equivalent in terms of data movement to a matrix transpose, the simplest nontrivial transpose to perform. Also remember that for two-dimensional matrices both kinds of transposition are the same, so that APL's simpler rule `MP β‘ MPβΎβΛ` holds in BQN. +Certainly not as concise as APL's version, but not a horror either. BQN's rule is actually more parsimonious in that it only performs the axis exchanges necessary for the computation: it moves the two axes that will be paired with the matrix product into place before the product, and directly exchanges all axes afterwards. Each of these steps is equivalent in terms of data movement to a matrix transpose, the simplest nontrivial transpose to perform. Also remember that for two-dimensional matrices both kinds of transposition are the same, so that APL's simpler rule `MP β‘ MPβΎβΛ` holds in BQN on rank 2. Axis permutations of the types we've shown generate the complete permutation group on any number of axes, so you could produce any transposition you want with the right sequence of monadic transpositions with Rank. However, this can be unintuitive and tedious. What if you want to transpose the first three axes, leaving the rest alone? With monadic Transpose you have to send some axes to the end, then bring them back to the beginning. For example [following four or five failed tries]: @@ -67,7 +67,7 @@ In a case like this the dyadic version of `β`, called Reorder Axes, is much ea ## Reorder Axes -Transpose also allows a left argument that specifies a permutation of `π©`'s axes. For each index `pβiβπ¨` in the left argument, axis `i` of `π©` is used for axis `p` of the result. Multiple argument axes can be sent to the same result axis, in which case that axis goes along a diagonal of `π©`, and the result will have a lower rank than `π©`. +Transpose also allows a left argument that specifies a permutation of `π©`'s axes. For each index `pβiβπ¨` in the left argument, axis `i` of `π©` is used for axis `p` of the result. Multiple argument axes can be sent to the same result axis, in which case that axis goes along a diagonal of `π©`, and the result will have a lower rank than `π©` (see the next section). β’ 1βΏ3βΏ2βΏ0βΏ4 β a23456 @@ -87,12 +87,25 @@ In particular, the case with only one axis specified is interesting. Here, the f Finally, it's worth noting that, as monadic Transpose moves the first axis to the end, it's equivalent to Reorder Axes with a "default" left argument: `(=-1Λ)βΈβ`. +### Taking diagonals + +When `π¨` contains an axis index more than once, the corresponding axes of `π©` will *all* be sent to that axis of the result. This isn't a special case: it follows the same rule that `iβπ¨βπ©` is `(π¨βi)βπ©`. Only the result shape has to be adjusted for this case: the length along a result axis is the minimum of all the axes of `π©` that go into it, because any indices outside this range will be out of bounds along at least one axis. + +A bit abstract. This rule is almost always used simply as `0βΏ0βπ©` to get the main diagonal of a matrix. + + β’ a β 3βΏ5β₯'a'+β15 + + 0βΏ0 β a + + β¨2β©β0βΏ0βa # Single index into result + β¨2,2β©βa # is like a doubled index into a + ## Definitions Here we define the two valences of Transpose more precisely. -An atom right argument to either valence of Transpose is always enclosed to get an array before doing anything else. +An atom right argument to Transpose or Reorder Axes is always [enclosed](enclose.md) to get an array before doing anything else. -Monadic transpose is identical to `(=-1Λ)βΈβ`, except that if `π©` is a unit it is returned unchanged (after enclosing, if it's an atom) rather than giving an error. +Monadic Transpose is identical to `(=-1Λ)βΈβ`, except that if `π©` is a unit it's returned unchanged (after enclosing, if it's an atom) rather than giving an error. -In Reorder Axes, `π¨` is a number or numeric array of rank 1 or less, and `π¨β€ββ β’π©`. Define the result rank `rβ(=π©)-+´¬βπ¨` to be the right argument rank minus the number of duplicate entries in the left argument. We require `β§Β΄π¨<r`. Bring `π¨` to full length by appending the missing indices: `π¨βΎβ©π¨(Β¬ββΛ/β’)βr`. Now the result shape is defined to be `β´¨π¨ββ’π©`. Element `iβz` of the result `z` is element `(π¨βi)βπ©` of the argument. +In Reorder Axes, `π¨` is a number or numeric array of rank 1 or less, and `π¨β€ββ β’π©`. Define the result rank `rβ(=π©)-+´¬βπ¨` to be the rank of `π©` minus the number of duplicate entries in `π¨`. We require `β§Β΄π¨<r`. Bring `π¨` to full length by appending the missing indices: `π¨βΎβ©π¨(Β¬ββΛ/β’)βr`. Now the result shape is defined to be `β´¨π¨ββ’π©`. Element `iβz` of the result `z` is element `(π¨βi)βπ©` of the argument. |
