diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2021-07-15 23:17:35 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2021-07-15 23:17:35 -0400 |
| commit | b4dc8e155b3f10891d15143bb57b690d0456fc14 (patch) | |
| tree | 63aa11aefbf2660fdfa6819badb59d30a8f45a0f /doc | |
| parent | cc62bbae0f4e2eb6b20f04e31b2f222ee26ac670 (diff) | |
Take and Drop documentation
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/README.md | 1 | ||||
| -rw-r--r-- | doc/primitive.md | 4 | ||||
| -rw-r--r-- | doc/take.md | 87 |
3 files changed, 90 insertions, 2 deletions
diff --git a/doc/README.md b/doc/README.md index fc8e7000..19d261ad 100644 --- a/doc/README.md +++ b/doc/README.md @@ -54,6 +54,7 @@ Primitives: - [Self-search functions](selfcmp.md) (`⊐⊒∊⍷`) - [Shift functions](shift.md) (`»«`) - [Solo, Couple, and Merge](couple.md) (`≍>`) +- [Take and Drop](take.md) (`↑`) - [Transpose](transpose.md) (`⍉`) - [Windows](windows.md) (`↕`) diff --git a/doc/primitive.md b/doc/primitive.md index b768be37..1852da20 100644 --- a/doc/primitive.md +++ b/doc/primitive.md @@ -39,8 +39,8 @@ Functions that have significant differences from APL functions are marked with a | `⥊` | [Deshape](reshape.md) | [Reshape](reshape.md)* | `∾` | [Join](join.md)* | [Join to](join.md) | `≍` | [Solo](couple.md)* | [Couple](couple.md)* -| `↑` | [Prefixes](prefixes.md)* | [Take](https://aplwiki.com/wiki/Take) -| `↓` | [Suffixes](prefixes.md)* | [Drop](https://aplwiki.com/wiki/Drop) +| `↑` | [Prefixes](prefixes.md)* | [Take](take.md) +| `↓` | [Suffixes](prefixes.md)* | [Drop](take.md) | `↕` | [Range](range.md) | [Windows](windows.md)* | `»` | [Nudge](shift.md)* | [Shift Before](shift.md)* | `«` | [Nudge Back](shift.md)* | [Shift After](shift.md)* diff --git a/doc/take.md b/doc/take.md index 1cc0b833..8a8d6423 100644 --- a/doc/take.md +++ b/doc/take.md @@ -41,3 +41,90 @@ dim ← ⟨2+≠tx,1.96⟩ ⋄ sh ← ¯1.8‿¯0.5 lg Ge Line wm ≍˜⊸≍ ¯0.3‿1.2+ty ⟩ --> + +The basic idea of Take (`↑`) is to get the first few elements of a list, while Drop (`↓`) removes those and returns the rest. Then they are extended in like a billion ways. + +- `𝕩` can be an atom, or array of any rank (the result will be an array). +- `𝕨` can be negative to take or drop from the end instead of the beginning. +- For Take, if `𝕨` is larger than the length of `𝕩`, then fills are added. +- `𝕨` can have multiple numbers corresponding to leading axes of `𝕩`. +- `𝕨` is allowed to be longer than the rank of `𝕩`; `𝕩` will be extended to fit. + +These extensions can be combined as well, so there are a lot of possibilities. A good picture to have in mind is cutting out a corner of the array `𝕩`. This is because the result `𝕨↑𝕩` or `𝕨↓𝕩` always aligns with one side of `𝕩` along each axis, so it aligns with the corner where those sides meet. + +The result `d↓𝕩` is always the same as `t↑𝕩` for some other argument `t`, but computing `t` wouldn't be too convenient. The reverse isn't true: only Take can insert fills, so results that include them can't come from Drop. + +## One axis + +Let's start with a natural number `𝕨`. Take gives the first `𝕨` major cells of `𝕩` (or elements of a list), while Drop gives all but the first `𝕨`. + + 4 ↑ "take and drop" + 4 ↓ "take and drop" + + 1 ↓ >"maj"‿"orc"‿"ell" + +If `𝕨` is too large it's usually not a problem. For Take, fill elements are added to the end to bring `𝕩` up to the required length—although this *will* fail if `𝕩` has no fill element. For Drop, the result is an empty array. + + ↕6 + + 10 ↑ ↕6 + + 10 ↓ ↕6 + + ≢ 5 ↓ ↕3‿9‿2 + +If `𝕩` is an atom or unit array, it's converted to a list first. For Take this is useful to make an array of mostly fills; for Drop it's pretty much useless. + + 10 ↑ 9 + + 3 ↓ <"element" + +### Negative argument + +If `𝕨` is negative then wraps around the other side to take or drop from the end of `𝕩`. It's a lot like negative indices in [Select](select.md) (`⊏`), but while negative indices are asymmetric—`0` is the first entry but `¯1` is the last—this case is symmetric. It's because the place to cut is always *before* the index `𝕨`, cancelling out the negative index asymmetry. + + 3 ↑ "abcdeEDCBA" + + ¯3 ↑ "abcdeEDCBA" # Last three + + ¯3 ↓ "abcdeEDCBA" # All but the last three + +What about `0`? It behaves like it's both positive *and* negative. For Take, the first 0 and last 0 cells are indistinguishable, because they're both empty. For Drop, if you remove 0 cells it doesn't matter whether you start at the front or the back, because you're not going to do anything either way. + + 0 ↑ 4‿3‿2 # Nothing + + 0 ↓ 4‿3‿2 # Everything + +If `|𝕨` is too large, then Take will insert fills at the beginning to keep the result aligned with `𝕩` at the end. Drop returns an empty array as in the positive case. So unlike [Rotate](reverse.md) (`⌽`), which is completely cyclical, Take and Drop work cyclically only around 0. + + ¯6 ↑ "xy" + +## Multiple axes + +In the general case `𝕨` is a list of integers. They're matched with the leading axes of `𝕩`, so that each affects one axis independently from the others. + + ⊢ m ← (10×↕5) +⌜ ↕7 + + ¯4‿2 ↑ m # Last four rows; first two columns + + ¯4‿2 ↓ m + +Now Take and Drop taken together don't include the whole array. Take includes the elements that are selected on *every* axis, while Drop excludes the ones selected on *any* axis. They are opposite corners that meet at some point in the middle of the array (here, at the spot between `2` and `11`). + +Any integer values at all can be used, in any combination. Here one axis is shortened and the other's padded with fills. The result of Take has shape `|𝕨`, maybe plus some trailing axes from `𝕩`. Of course, if that's too big for your available memory, your BQN implementation probably can't compute it for you! + + 3‿¯12 ↑ m + + ≢ 9‿¯4 ↑ ↕7‿6‿5 # Trailing shape example + +If the rank of `𝕩` is *smaller* than the length of `𝕨`, then length-1 axes are added to the beginning until it's equal. Mostly this will be used with Take when `𝕩` is a unit, producing an array that contains `𝕩` and a lot of fills. + + 3‿4 ↑ <1‿1 + +This property also enables a nice little trick with Drop. If `𝕨` is a list of zeros, Drop won't do anything—except extend the rank of `𝕩`. So `(r⥊0)↓a`, or `r ⥊⟜0⊸↓ a`, ensures `a` is an array with rank at least `r` but doesn't change any of the elements. As a special case, `⟨⟩↓v` [Encloses](enclose.md) an atom argument but otherwise has no effect. + + ≢ (3⥊0) ↓ 3 + + ≢ (3⥊0) ↓ ↕3 + + ≢ (3⥊0) ↓ ↕5‿4‿3‿2 |
