Previous sessions established a basic conception of indexing an array. Namely, an index encodes a reference to an element in an array according to the position of the element along each of its dimensions. Always a vector, each element of an index falls in the range [0, d) where d is the corresponding element in the array's shape. As previously noted, an index corresponds 1-to-1 to a natural number which corresponds to the same element in the ravel of the indexed array. This gives the following equivalence precisely describing this correspondence:
A[⍳⍴A] ←→ (,A)[⍳⍴,A]
This correspondence demonstrates a deep and powerful connection between vectors of numbers and their scalar equivalents. Mappings like those between indices and natural numbers arise so often that two primitive functions describe this sort of mapping programmatically. The function decode, written
⊥, when given a shape on the left and an index on the right, gives the corresponding ravel index. The following equivalency gives a formal description of this behavior:
I⌷A ←→ ((⍴A)⊥I)⌷,A
The inverse operation, encoding (
⊤), when given a shape on the left and a ravel index on the right, gives the corresponding element in an array of the specified shape. Said formally:
I⌷,A ←→ ((⍴A)⊤I)⌷A
Since encoding and decoding give the inverse of the other, the following hold:
I ←→ S⊤S⊥I I ←→ S⊥S⊤I
Encode and decode allow any program to seamlessly move from ravel index to normal index, but they serve many more roles than this. The reader should take some time to consider the many other uses for encode and decode that may exist.
Please support my work via GitTip.