From 7c24de80e86c8a7eba9ae3eb4adc64bb93977e33 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Thu, 1 Jul 2021 19:34:17 -0400 Subject: Finish Scan documentation --- doc/scan.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'doc/scan.md') diff --git a/doc/scan.md b/doc/scan.md index ab4b6669..c4e3a3ad 100644 --- a/doc/scan.md +++ b/doc/scan.md @@ -50,7 +50,7 @@ BQN's Scan is ordered differently from Scan in APL. Both include one result for Scan also differs from Fold or Insert in that it never depends on `𝔽`'s identity element, because scanning over an empty array simply returns that array. -## Examples +## Lists The best-known use of Scan is the [prefix sum](https://en.wikipedia.org/wiki/Prefix_sum) of a list, in which each element of the result is the sum of that element and all the ones before it. With a [shift](shift.md) this can be modified to sum the previous elements only. @@ -92,7 +92,7 @@ A more complicated boolean scan, which depends on the left-to-right ordering, is {Β¬<`'\'=𝕩}⊸/ "ab\\\rs\\\\" -### Reverse scan +## Reverse scan We've discussed how the scan moves forward along `𝕩`, so that each time `𝔽` takes an old result as `𝕨` and a new value as `𝕩`. This means that results correspond to prefixes and go left to right on each one. Since the most important scans have associative, commutative operands, the left-to-right ordering often doesn't make a difference. But sometimes a suffix rather than prefix scan is wanted. For these cases, Scan Under [Reverse](reverse.md) (`` `⌾⌽ ``) does the trick. @@ -109,10 +109,22 @@ The new value is still the right argument to `𝔽`, even though with the revers {"("βˆΎπ•¨βˆΎ")𝔽"βˆΎπ•©}˜`⌾⌽ "a"β€Ώ"b"β€Ώ"c"β€Ώ"d" -### Higher ranks +## Higher ranks -Scan moves along the [leading axis](leading.md) of `𝕩`. Results are produced in index order. +Scan moves along the [leading axis](leading.md) of `𝕩`: vertically, for a table. To apply a scan to later axes, use `˘` or `βŽ‰`. Since a scan returns an array with the same shape as its argument, this can't cause an error from differing result cell shapes, unlike Fold or Insert. ⊒ a ← Β―2β€Ώ0.25β€Ώ'a'β€Ώβˆž ∾ 3β€Ώ4β₯ŠΒ―1β€Ώ0β€Ώ1 +` a + +If `𝕨` is given, it must have the same shape as a major cell of `𝕩` (this is why `𝕨` needs to be enclosed when `𝕩` is a list: in general it's an array). Then the first result cell is found by applying `𝔽` to elements of `𝕨` and `βŠπ•©`, and the computation continues as in the one-argument case for remaining cells. + + 3β€Ώ2β€Ώ1β€Ώ0 +` a + +Results are produced in index order. This means that instead of moving along each column in turn, a scan produces the first result cell one element at a time, then the next, and so on. Something like a breadth-first as opposed to depth-first ordering. + +## Definition + +Scan admits a simple recursive definition. `𝕩` is an array of rank one or more and `𝕨`, if given, is an atom or array with shape `1↓≒𝕩`. The result ``z←𝕨𝔽`𝕩`` is an array with the same shape as `𝕩`. If it has length at least one, `⊏z` is `βŠπ•©` if `𝕨` isn't given and `π•¨π”½Β¨βŠπ•©` if it is. For `0≀i`, `(i+1)⊏z` is `(i⊏z)𝔽¨(i+1)βŠπ•©`. + +The ordering of `𝔽` application is the natural one for this definition: cells are computed in turn, and each instance of `𝔽¨` goes in index order. -- cgit v1.2.3