Empty array: Difference between revisions
Jump to navigation
Jump to search
m (Kinds of array category) |
m (Text replacement - "<source" to "<syntaxhighlight") |
||
Line 1: | Line 1: | ||
In the APL [[array model]], an '''empty''' array is one with a [[bound]] of zero, that is, an array with no [[element]]s. While a nested list model has only one empty list, APL has many different empty arrays. These arrays are distinguished by their [[shape]] and [[prototype]]. | In the APL [[array model]], an '''empty''' array is one with a [[bound]] of zero, that is, an array with no [[element]]s. While a nested list model has only one empty list, APL has many different empty arrays. These arrays are distinguished by their [[shape]] and [[prototype]]. | ||
Examples of empty arrays are the empty [[numeric]] array [[Zilde]] (< | Examples of empty arrays are the empty [[numeric]] array [[Zilde]] (<syntaxhighlight lang=apl inline>⍬</source>) and the empty [[character]] array <syntaxhighlight lang=apl inline>''</source>. These arrays have different prototypes, and do not [[match]] in most APLs. | ||
== Empty array shape == | == Empty array shape == | ||
Line 8: | Line 8: | ||
The primary exception is when using the [[Rank operator]] on an array with no [[cell]]s of the specified rank. Because the shape of each result cell might be determined by values in an argument cell, the appropriate shape may be impossible to determine. | The primary exception is when using the [[Rank operator]] on an array with no [[cell]]s of the specified rank. Because the shape of each result cell might be determined by values in an argument cell, the appropriate shape may be impossible to determine. | ||
< | <syntaxhighlight lang=apl> | ||
⍴ ⍳⍤0 ⊢2⍴3 | ⍴ ⍳⍤0 ⊢2⍴3 | ||
2 3 | 2 3 | ||
Line 17: | Line 17: | ||
</source> | </source> | ||
{{Works in|[[Dyalog APL]], [[NARS2000]]}} | {{Works in|[[Dyalog APL]], [[NARS2000]]}} | ||
The example above shows how an arithmetic rule can fail when using Rank with an empty array. For any positive integer < | The example above shows how an arithmetic rule can fail when using Rank with an empty array. For any positive integer <syntaxhighlight lang=apl inline>n</source>, it's clear that <syntaxhighlight lang=apl inline>(n,3) ≡ ⍴ ⍳⍤0 ⊢n⍴3</source> because each result cell is the array <syntaxhighlight lang=apl inline>⍳3</source>. However, the empty array <syntaxhighlight lang=apl inline>0⍴3</source> is indistinguishable from any other empty numeric array because it has shape <syntaxhighlight lang=apl inline>,0</source> and prototype <syntaxhighlight lang=apl inline>0</source>. This means Rank cannot determine the appropriate result shape. The Rank operator still attempts to find a sensible result shape: it executes the operand on a prototype cell obtained by reshaping the argument to the argument cell shape (here, the prototype cell is a scalar <syntaxhighlight lang=apl inline>0</source>), and uses the resulting shape to determine the shape of its final result. In this case, this succeeds in finding the appropriate result rank but not the desired shape. | ||
If Rank is implemented by [[split]]ting the argument(s) into cells, applying the operand with [[Each]], and [[mix]]ing, then the above problem actually becomes an issue of empty array prototypes: the result of Split is empty, and calling Each on an empty array uses prototypes to determine prototypes, an unreliable operation. | If Rank is implemented by [[split]]ting the argument(s) into cells, applying the operand with [[Each]], and [[mix]]ing, then the above problem actually becomes an issue of empty array prototypes: the result of Split is empty, and calling Each on an empty array uses prototypes to determine prototypes, an unreliable operation. | ||
Line 28: | Line 28: | ||
Consider the following identities for [[Catenate]] on [[vector]]s, one of which is empty. | Consider the following identities for [[Catenate]] on [[vector]]s, one of which is empty. | ||
< | <syntaxhighlight lang=apl> | ||
a ≡ ⍬,a | a ≡ ⍬,a | ||
b ≡ b,'' | b ≡ b,'' | ||
</source> | </source> | ||
These identities always hold when < | These identities always hold when <syntaxhighlight lang=apl inline>a</source> and <syntaxhighlight lang=apl inline>b</source> are non-empty, because the result is non-empty and its elements are entirely determined by the non-empty argument. However, if we consider the catenation | ||
< | <syntaxhighlight lang=apl> | ||
⍬,'' | ⍬,'' | ||
</source> | </source> | ||
then the first identity tells us that the result should be < | then the first identity tells us that the result should be <syntaxhighlight lang=apl inline>''</source> while the second gives a result of <syntaxhighlight lang=apl inline>⍬</source>. These two arrays do not match, so one of the identities must be wrong! In fact, the choice of which prototype to use for the result is a source of incompatibility among APLs. In [[Dyalog APL]] it has even been changed in the past. At one point the right argument's prototype was used; now we can inspect the [[first]] element of <syntaxhighlight lang=apl inline>⍬,''</source> to see that the left argument's prototype is used. | ||
< | <syntaxhighlight lang=apl> | ||
⊃⍬,'' | ⊃⍬,'' | ||
0 | 0 | ||
Line 45: | Line 45: | ||
== Reduction over a length-0 axis == | == Reduction over a length-0 axis == | ||
If a [[Reduce|reduction]] (using one of < | If a [[Reduce|reduction]] (using one of <syntaxhighlight lang=apl inline>/</source>, <syntaxhighlight lang=apl inline>⌿</source>, <syntaxhighlight lang=apl inline>\</source>, or <syntaxhighlight lang=apl inline>⍀</source>) is performed over an axis of length 0, the resulting array is filled with [[identity element]]s. For example, the sum of an empty list is <syntaxhighlight lang=apl inline>0</source> because the identity element for [[addition]] is <syntaxhighlight lang=apl inline>0</source>: | ||
< | <syntaxhighlight lang=apl> | ||
+/0⍴0 | +/0⍴0 | ||
0 | 0 |