Rank (operator): Difference between revisions

Jump to navigation Jump to search
135 bytes added ,  20:56, 10 September 2022
m
Text replacement - "<source" to "<syntaxhighlight"
m (Use the right name)
m (Text replacement - "<source" to "<syntaxhighlight")
Line 5: Line 5:
== Rank specification ==
== Rank specification ==
The right operand specifies the [[rank]] of subarrays to which the left operand function is applied as follows:
The right operand specifies the [[rank]] of subarrays to which the left operand function is applied as follows:
For left argument <source lang=apl inline>⍺</source> and right argument <source lang=apl inline>⍵</source>,
For left argument <syntaxhighlight lang=apl inline>⍺</source> and right argument <syntaxhighlight lang=apl inline>⍵</source>,
<source lang=apl>
<syntaxhighlight lang=apl>
   ⍤    c  ⍝ Rank-c cells of ⍵ (monadic) or both arguments (dyadic)
   ⍤    c  ⍝ Rank-c cells of ⍵ (monadic) or both arguments (dyadic)
   ⍤  b c  ⍝ Rank-b cells of ⍺ and rank-c cells of ⍵ (dyadic)
   ⍤  b c  ⍝ Rank-b cells of ⍺ and rank-c cells of ⍵ (dyadic)
Line 14: Line 14:
A non-negative right operand specifies the number of ''final'' axes to which the function applies. A negative right operand specifies ''complementary'' rank, i.e. the number of leading axes to be ''excluded''. Negative rank can also be thought of as rank specification ''relative to'' the overall rank of the argument array.
A non-negative right operand specifies the number of ''final'' axes to which the function applies. A negative right operand specifies ''complementary'' rank, i.e. the number of leading axes to be ''excluded''. Negative rank can also be thought of as rank specification ''relative to'' the overall rank of the argument array.


Since a rank specification greater than the rank of the argument array means to apply the function to the whole array, <source lang=apl inline>99</source>, <source lang=apl inline>(⌊/⍬)</source> or <source lang=apl inline>∞</source>, depending on the implementation, is "rank infinity" and always specifies the whole argument array.
Since a rank specification greater than the rank of the argument array means to apply the function to the whole array, <syntaxhighlight lang=apl inline>99</source>, <syntaxhighlight lang=apl inline>(⌊/⍬)</source> or <syntaxhighlight lang=apl inline>∞</source>, depending on the implementation, is "rank infinity" and always specifies the whole argument array.


== Examples ==
== Examples ==
Reverse order of rows in matrices of a 3D array:
Reverse order of rows in matrices of a 3D array:
<source lang=apl>
<syntaxhighlight lang=apl>
       ⊖⍤2⊢3 2 4⍴⎕A
       ⊖⍤2⊢3 2 4⍴⎕A
EFGH
EFGH
Line 31: Line 31:


Laminate scalars from arrays of differing ranks:
Laminate scalars from arrays of differing ranks:
<source lang=apl>
<syntaxhighlight lang=apl>
       'ABCD',⍤0⍤1⊢2 4⍴⍳8
       'ABCD',⍤0⍤1⊢2 4⍴⍳8
A 1
A 1
Line 45: Line 45:


Flat outer product:
Flat outer product:
<source lang=apl>
<syntaxhighlight lang=apl>
       -⍤1⍤1 99⍨3 2⍴6 7 1 1 2 4  ⍝ ↑∘.-⍨↓
       -⍤1⍤1 99⍨3 2⍴6 7 1 1 2 4  ⍝ ↑∘.-⍨↓
  0  0
  0  0
Line 64: Line 64:


== Rank vs Axis ==
== Rank vs Axis ==
Due to its ability to apply functions to specified subarrays, rank is frequently contrasted with [https://aplwiki.com/wiki/Function_axis bracket-axis]. It provides nearly all of the functionality of the anomalous axis operator (<source lang=apl inline>f[a]</source>) without its draw-backs.<ref name="intro2rank">[[Robert Bernecky]]. [https://doi.org/10.1145/55626.55632 An introduction to function rank] at [[APL88]]. ACM SIGAPL APL Quote Quad, 18(2), pp.39-43. 1987.</ref>
Due to its ability to apply functions to specified subarrays, rank is frequently contrasted with [https://aplwiki.com/wiki/Function_axis bracket-axis]. It provides nearly all of the functionality of the anomalous axis operator (<syntaxhighlight lang=apl inline>f[a]</source>) without its draw-backs.<ref name="intro2rank">[[Robert Bernecky]]. [https://doi.org/10.1145/55626.55632 An introduction to function rank] at [[APL88]]. ACM SIGAPL APL Quote Quad, 18(2), pp.39-43. 1987.</ref>


One of these draw-backs is that bracket-axis is specified ad hoc for each of the specific primitives on which it applies. Rank benefits from consistent behaviour when applied to any function, including [[user-defined functions]]. The ad hoc nature of bracket-axis definitions means that a generalised axis operator which works on any function, but behaves just as bracket-axis on those particular primitives, is impossible to formulate.
One of these draw-backs is that bracket-axis is specified ad hoc for each of the specific primitives on which it applies. Rank benefits from consistent behaviour when applied to any function, including [[user-defined functions]]. The ad hoc nature of bracket-axis definitions means that a generalised axis operator which works on any function, but behaves just as bracket-axis on those particular primitives, is impossible to formulate.
Line 72: Line 72:
===Sum along axis===
===Sum along axis===
Rank k-cells are defined for k trailing axes, whereas axes are numbered from most major (first axis i.e. axis number 1) to least major (last axis). This leads to a simple and symmetrical relationship.
Rank k-cells are defined for k trailing axes, whereas axes are numbered from most major (first axis i.e. axis number 1) to least major (last axis). This leads to a simple and symmetrical relationship.
<source lang=apl>
<syntaxhighlight lang=apl>
+/[1+⍺-⍨≢⍴⍵] ≡ +⌿⍤⍺            ⍝ For scalar ⍺
+/[1+⍺-⍨≢⍴⍵] ≡ +⌿⍤⍺            ⍝ For scalar ⍺
+/[⍺]        ≡ +⌿⍤(1+⍺-⍨≢⍴⍵)  ⍝ For scalar ⍺
+/[⍺]        ≡ +⌿⍤(1+⍺-⍨≢⍴⍵)  ⍝ For scalar ⍺
Line 79: Line 79:
===Enclose axes===
===Enclose axes===
Enclose-with-axis is equivalent to transposing desired axes to the end of the array's shape and enclosing subarrays of a rank matching the number of axes.
Enclose-with-axis is equivalent to transposing desired axes to the end of the array's shape and enclosing subarrays of a rank matching the number of axes.
<source lang=apl>
<syntaxhighlight lang=apl>
EncloseAxes←{
EncloseAxes←{
     axes←⍳≢⍴⍵
     axes←⍳≢⍴⍵
Line 92: Line 92:


Merging trailing axes is trivial.
Merging trailing axes is trivial.
<source lang=apl>
<syntaxhighlight lang=apl>
,[(-⍺)↑⍴⍵] ≡ ,⍤⍺
,[(-⍺)↑⍴⍵] ≡ ,⍤⍺
</source>
</source>


Merging leading axes is more involved, but can be expressed in one line.
Merging leading axes is more involved, but can be expressed in one line.
<source lang=apl>
<syntaxhighlight lang=apl>
,[⍳⍺] ←→ {(1⌽⍳≢⍴z)⍉z←,⍤⍺((-⍺)⌽⍳≢⍴⍵)⍉⍵}
,[⍳⍺] ←→ {(1⌽⍳≢⍴z)⍉z←,⍤⍺((-⍺)⌽⍳≢⍴⍵)⍉⍵}
</source>
</source>


The general treatment benefits from being expanded.
The general treatment benefits from being expanded.
<source lang=apl>
<syntaxhighlight lang=apl>
MergeAxes←{
MergeAxes←{
     axes←⍳≢⍴⍵
     axes←⍳≢⍴⍵

Navigation menu