Array ordering: Difference between revisions

From APL Wiki
Jump to navigation Jump to search
m (Missing First in comparison code)
(Extend with material from Total array ordering and more)
Line 1: Line 1:
'''Array ordering''' is the ordering of [[array]]s exposed by functions such as [[Grade]] and [[Interval Index]]. It may be more general than [[comparison]], for example by allowing [[character]]s to be compared to each other and to [[number]]s. However, not all arrays need to be comparable, meaning that functions that depend on array ordering can throw an [[error]]. Traditionally, ordering is defined only for [[simple]] arrays of the same [[shape]] and [[type]] (Grade of a simple array only requires this sort of comparison), and is determined by the ordering of the first unequal pair of [[element]]s in those arrays in [[ravel order]]. It may be extended to all arrays in various ways, making it a [[total array order]] (TAO).
'''Array ordering''' is the ordering of [[array]]s exposed by functions such as [[Grade]] and [[Interval Index]]. It may be more general than [[comparison]], for example by allowing [[character]]s to be compared to each other and to [[number]]s. However, not all arrays need to be comparable, meaning that functions that depend on array ordering can throw an [[error]]. Traditionally, ordering is defined only for [[simple]] arrays of the same [[shape]] and [[type]] (Grade of a simple array only requires this sort of comparison), and is determined by the ordering of the first unequal pair of [[element]]s in those arrays in [[ravel order]]. Various extensions to other domains have been defined, including an extension to numbers and characters in all shapes and combinations in [[Dyalog APL]] known as [[total array order]] (TAO).
 
== Examples ==


While two characters can't be compared directly in most APL implementations, their array ordering can be observed with Grade:
While two characters can't be compared directly in most APL implementations, their array ordering can be observed with Grade:
Line 12: Line 14:
</syntaxhighlight>
</syntaxhighlight>
Grade reverses the order of these elements, showing that <syntaxhighlight lang=apl inline>'a'</syntaxhighlight> comes before <syntaxhighlight lang=apl inline>'b'</syntaxhighlight> in the array ordering. In general, <syntaxhighlight lang=apl inline>1=⊃⍋X Y</syntaxhighlight> tests whether array <syntaxhighlight lang=apl inline>X</syntaxhighlight> precedes or [[match]]es <syntaxhighlight lang=apl inline>Y</syntaxhighlight>. However, <syntaxhighlight lang=apl inline>⍋X Y</syntaxhighlight> doesn't distinguish between these two cases, so for complete information about the ordering, these arrays must also be graded in the opposite order.
Grade reverses the order of these elements, showing that <syntaxhighlight lang=apl inline>'a'</syntaxhighlight> comes before <syntaxhighlight lang=apl inline>'b'</syntaxhighlight> in the array ordering. In general, <syntaxhighlight lang=apl inline>1=⊃⍋X Y</syntaxhighlight> tests whether array <syntaxhighlight lang=apl inline>X</syntaxhighlight> precedes or [[match]]es <syntaxhighlight lang=apl inline>Y</syntaxhighlight>. However, <syntaxhighlight lang=apl inline>⍋X Y</syntaxhighlight> doesn't distinguish between these two cases, so for complete information about the ordering, these arrays must also be graded in the opposite order.
The concept of an ordering distinct from [[comparison function]]s was introduced by [[SHARP APL]] in 1980: "The domain of the [[grade]] functions (<syntaxhighlight lang=apl inline>⍋</syntaxhighlight> and <syntaxhighlight lang=apl inline>⍒</syntaxhighlight>), previously restricted to numeric [[vector]]s, has been extended to all numeric arrays of [[rank]] greater than 0".<ref>Peter Wooster. "Extended Upgrade and Downgrade". SATN-35. 1980-09-15.</ref> For the [[major cell]]s of such an array, which may have any shape but all share the same one, SHARP defines a "lexical" ordering where the first pair of differing elements in [[ravel order]] decides how the cells compare. This definition has been widely adopted but is extended to arrays of differing shape, and non-numeric types and [[complex number]]s (which were added later to SHARP but not supported in Grade), in different ways by various dialects.
== Differing shapes ==
Ordering of arrays with different shapes can arise in Grade on non-[[simple]] arrays, either because they're [[nested]] or when the ordering is extended to [[box]]es. [[Interval Index]] (assuming [[major cell search]]) may also allow arguments with differing cell shapes.
[[GNU APL]] and [[NARS2000]] implement a [[wikipedia:shortlex order|shortlex order]]-like ordering, comparing first [[rank]], then [[shape]], then [[type]], and finally [[element]] values in [[ravel order]]. By comparing elements only in the case of matching shapes, there's no question of how indices in differently-shaped arrays might correspond to each other.
[[Dyalog APL]]'s [[total array ordering]], introduced with [[Dyalog APL 17.0|version 17.0]] in 2018, begins by comparing elements instead, in order to conform with [[wikipedia:lexicographic order|lexicographic order]] as used in dictionaries. Two elements may be compared only if they have matching [[Index#element_index|indices]], ignoring leading zeros to allow a correspondence even if the arrays differ in rank. An element
[[J]], which defined its ordering early on in 1996 (release 3.01), uses a mix of strategies. It first compares array types, then ranks, then elements after padding with fills (according to documentation; however, as of version 9.5 there are various differences from this definition when values equal or less than the fill are used).<ref>[[Roger Hui|Hui, R.]]. [https://code.jsoftware.com/wiki/Essays/The_TAO_of_J The TAO of J].</ref>
== Scalar types ==
Array ordering may also support [[simple scalar]]s that aren't valid arguments to [[comparison functions]], such as [[character]]s. Some languages, including [[GNU APL]], [[TinyAPL]], [[BQN]], and [[Uiua]], extend comparisons to non-numeric values, although they may retain some difference between comparison and array ordering of scalars.
[[Dyalog APL]] extended Grade to apply to simple character arrays in 1982.<ref>Hui, R. and [[Morten Kromberg|M. Kromberg]]. [https://dl.acm.org/doi/abs/10.1145/3386319 ''APL since 1978'']. ACM HOPL IV. 2020-06.</ref> This extension had not been implemented by SHARP, as [[dyadic Grade]] was used instead. With total array ordering Dyalog extended further to allow comparisons between characters and numbers, as well as the special value <syntaxhighlight lang=apl inline>⎕null</syntaxhighlight>. Other simple scalars (namely [[namespace]]s, [[object]]s, and [[object representation]]s) were excluded, because ordering them was considered "contentious but of little incremental benefit."<ref name=bfh>[[Adám Brudzewsky|Brudzewsky, A.]], [[Jay Foad|J. Foad]], and R. Hui. [https://www.jsoftware.com/papers/TAOaxioms.htm TAO Axioms]. 2018-02-02.</ref> However, the [[dfns workspace]] includes an APL model which is truly total, though it differs from the native implementation in ordering characters before numbers instead of the opposite.<ref>[[Dfns workspace]]. [http://dfns.dyalog.com/n_le.htm <syntaxhighlight lang=apl inline>le</syntaxhighlight>] ― Total array ordering (TAO) comparison.</ref>
=== Complex numbers ===
[[Complex number]]s were added to [[SHARP APL]] in 1981 but not supported in comparison functions or Grade, "Because the complex numbers are not ordered".<ref>[[Eugene McDonnell]]. [https://www.jsoftware.com/papers/satn40.htm Complex Numbers]. SATN-40. 1981-06-20.</ref> That is, complex numbers and other extensions of the reals don't belong to any [[wikipedia:ordered field|ordered field]]: any ordering that remains the same after adding a constant could not be compatible with multiplication in the sense that the product of any two numbers greater than zero is greater than zero. [[NARS2000]] doesn't order complex numbers, quaternions, and octonions for the same reason.
Languages including [[J]], [[Dyalog APL]], and [[GNU APL]] order complex numbers by real part and then imaginary part, producing an ordering that's compatible with the one on reals even if some error is added to the complex part (which is common in complex calculations where the final value is real, due to the high sensitivity of floating-point components around 0). Regarding the fact that this design doesn't conform to a mathematical ordered field, Dyalog's designers remark: "A TAO does not (and can not) claim to order the complex numbers and preserve arithmetic properties".<ref name=bfh/>


== Documentation ==
== Documentation ==


* [https://help.dyalog.com/latest/#Language/Primitive%20Functions/Grade%20Up%20Monadic.htm Dyalog APL]
* [https://help.dyalog.com/latest/#Language/Primitive%20Functions/Grade%20Up%20Monadic.htm Dyalog APL]
* [https://www.gnu.org/software/apl/apl.html#Section-2_002e4 GNU APL]
* [https://beta.tinyapl.rubenverg.com/docs/info/ordering TinyAPL]
* [https://code.jsoftware.com/wiki/Vocabulary/slashco#Details J]
* [https://code.jsoftware.com/wiki/Vocabulary/slashco#Details J]
* [https://mlochbaum.github.io/BQN/doc/order.html#array-ordering BQN]
* [https://mlochbaum.github.io/BQN/doc/order.html#array-ordering BQN]
== References ==
<references/>
{{APL features}}[[Category:Array relationships]]
{{APL features}}[[Category:Array relationships]]

Revision as of 15:22, 17 October 2024

Array ordering is the ordering of arrays exposed by functions such as Grade and Interval Index. It may be more general than comparison, for example by allowing characters to be compared to each other and to numbers. However, not all arrays need to be comparable, meaning that functions that depend on array ordering can throw an error. Traditionally, ordering is defined only for simple arrays of the same shape and type (Grade of a simple array only requires this sort of comparison), and is determined by the ordering of the first unequal pair of elements in those arrays in ravel order. Various extensions to other domains have been defined, including an extension to numbers and characters in all shapes and combinations in Dyalog APL known as total array order (TAO).

Examples

While two characters can't be compared directly in most APL implementations, their array ordering can be observed with Grade:

      'b'>'a'
DOMAIN ERROR
      'b'>'a'
         ∧

      ⍋ 'ba'
2 1

Grade reverses the order of these elements, showing that 'a' comes before 'b' in the array ordering. In general, 1=⊃⍋X Y tests whether array X precedes or matches Y. However, ⍋X Y doesn't distinguish between these two cases, so for complete information about the ordering, these arrays must also be graded in the opposite order.

The concept of an ordering distinct from comparison functions was introduced by SHARP APL in 1980: "The domain of the grade functions ( and ), previously restricted to numeric vectors, has been extended to all numeric arrays of rank greater than 0".[1] For the major cells of such an array, which may have any shape but all share the same one, SHARP defines a "lexical" ordering where the first pair of differing elements in ravel order decides how the cells compare. This definition has been widely adopted but is extended to arrays of differing shape, and non-numeric types and complex numbers (which were added later to SHARP but not supported in Grade), in different ways by various dialects.

Differing shapes

Ordering of arrays with different shapes can arise in Grade on non-simple arrays, either because they're nested or when the ordering is extended to boxes. Interval Index (assuming major cell search) may also allow arguments with differing cell shapes.

GNU APL and NARS2000 implement a shortlex order-like ordering, comparing first rank, then shape, then type, and finally element values in ravel order. By comparing elements only in the case of matching shapes, there's no question of how indices in differently-shaped arrays might correspond to each other.

Dyalog APL's total array ordering, introduced with version 17.0 in 2018, begins by comparing elements instead, in order to conform with lexicographic order as used in dictionaries. Two elements may be compared only if they have matching indices, ignoring leading zeros to allow a correspondence even if the arrays differ in rank. An element

J, which defined its ordering early on in 1996 (release 3.01), uses a mix of strategies. It first compares array types, then ranks, then elements after padding with fills (according to documentation; however, as of version 9.5 there are various differences from this definition when values equal or less than the fill are used).[2]

Scalar types

Array ordering may also support simple scalars that aren't valid arguments to comparison functions, such as characters. Some languages, including GNU APL, TinyAPL, BQN, and Uiua, extend comparisons to non-numeric values, although they may retain some difference between comparison and array ordering of scalars.

Dyalog APL extended Grade to apply to simple character arrays in 1982.[3] This extension had not been implemented by SHARP, as dyadic Grade was used instead. With total array ordering Dyalog extended further to allow comparisons between characters and numbers, as well as the special value ⎕null. Other simple scalars (namely namespaces, objects, and object representations) were excluded, because ordering them was considered "contentious but of little incremental benefit."[4] However, the dfns workspace includes an APL model which is truly total, though it differs from the native implementation in ordering characters before numbers instead of the opposite.[5]

Complex numbers

Complex numbers were added to SHARP APL in 1981 but not supported in comparison functions or Grade, "Because the complex numbers are not ordered".[6] That is, complex numbers and other extensions of the reals don't belong to any ordered field: any ordering that remains the same after adding a constant could not be compatible with multiplication in the sense that the product of any two numbers greater than zero is greater than zero. NARS2000 doesn't order complex numbers, quaternions, and octonions for the same reason.

Languages including J, Dyalog APL, and GNU APL order complex numbers by real part and then imaginary part, producing an ordering that's compatible with the one on reals even if some error is added to the complex part (which is common in complex calculations where the final value is real, due to the high sensitivity of floating-point components around 0). Regarding the fact that this design doesn't conform to a mathematical ordered field, Dyalog's designers remark: "A TAO does not (and can not) claim to order the complex numbers and preserve arithmetic properties".[4]

Documentation

References

  1. Peter Wooster. "Extended Upgrade and Downgrade". SATN-35. 1980-09-15.
  2. Hui, R.. The TAO of J.
  3. Hui, R. and M. Kromberg. APL since 1978. ACM HOPL IV. 2020-06.
  4. 4.0 4.1 Brudzewsky, A., J. Foad, and R. Hui. TAO Axioms. 2018-02-02.
  5. Dfns workspace. le ― Total array ordering (TAO) comparison.
  6. Eugene McDonnell. Complex Numbers. SATN-40. 1981-06-20.
APL features [edit]
Built-ins Primitives (functions, operators) ∙ Quad name
Array model ShapeRankDepthBoundIndex (Indexing) ∙ AxisRavelRavel orderElementScalarVectorMatrixSimple scalarSimple arrayNested arrayCellMajor cellSubarrayEmpty arrayPrototype
Data types Number (Boolean, Complex number) ∙ Character (String) ∙ BoxNamespaceFunction array
Concepts and paradigms Conformability (Scalar extension, Leading axis agreement) ∙ Scalar function (Pervasion) ∙ Identity elementComplex floorArray ordering (Total) ∙ Tacit programming (Function composition, Close composition) ∙ GlyphLeading axis theoryMajor cell searchFirst-class function
Errors LIMIT ERRORRANK ERRORSYNTAX ERRORDOMAIN ERRORLENGTH ERRORINDEX ERRORVALUE ERROREVOLUTION ERROR