120
edits
No edit summary |
No edit summary |
||
(2 intermediate revisions by one other user not shown) | |||
Line 62: | Line 62: | ||
== History == | == History == | ||
The rank operator was invented by Arthur Whitney in 1982 and first implemented in [[SHARP APL]] in 1983. It has been described as "a microcosm of APL history"<ref name="hopl4">[https://dl.acm.org/doi/pdf/10.1145/3386319 Hui, R.K. and Kromberg, M.J., 2020. APL Since 1978. Proceedings of the ACM on Programming Languages.]</ref>, its evolution a progression from [[scalar extension]], which has been in APL since its inception, through [[leading axis theory]] to a construct which is a generalisation of scalar extension, [[inner product|inner (matrix) product]], [[outer product]], maplist in LISP, map in modern functional programming languages and the broadcast facility in NumPy. | The rank operator was invented by Arthur Whitney in 1982 and first implemented in [[SHARP APL]] in 1983. It has been described as "a microcosm of APL history"<ref name="hopl4">[https://dl.acm.org/doi/pdf/10.1145/3386319 Hui, R.K. and Kromberg, M.J., 2020. APL Since 1978. Proceedings of the ACM on Programming Languages.]</ref>, its evolution a progression from [[scalar extension]], which has been in APL since its inception, through [[leading axis theory]] to a construct which is a generalisation of scalar extension, [[inner product|inner (matrix) product]], [[outer product]], maplist in LISP, map in modern functional programming languages and the broadcast facility in NumPy. | ||
== 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">Bernecky, R., 1987. An introduction to function rank. ACM SIGAPL APL Quote Quad, 18(2), pp.39-43.</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. | |||
Here we show some bracket-axis constructs and their equivalent expressions which use rank but do not use bracket-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. | |||
<source lang=apl> | |||
+/[1+⍺-⍨≢⍴⍵] ≡ +⌿⍤⍺ ⍝ For scalar ⍺ | |||
+/[⍺] ≡ +⌿⍤(1+⍺-⍨≢⍴⍵) ⍝ For scalar ⍺ | |||
</source> | |||
===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. | |||
<source lang=apl> | |||
EncloseAxes←{ | |||
axes←⍳≢⍴⍵ | |||
move←⍋(axes~⍺),⍺ | |||
⊂⍤(≢⍺)⊢move⍉⍺ | |||
} | |||
⊂[⍺] ≡ ⍺∘EncloseAxes | |||
</source> | |||
===Merge axes=== | |||
Ravel-with-axis allows data to be merged along specified ''consecutive'' axes. The requirement that axes be consecutive is so that the data can remain in its original relative order. | |||
Merging trailing axes is trivial. | |||
<source lang=apl> | |||
,[(-⍺)↑⍴⍵] ≡ ⊂⍤⍺ | |||
</source> | |||
Merging leading axes is more involved, but can be expressed in one line. | |||
<source lang=apl> | |||
,[⍳⍺] ←→ {(1⌽⍳≢⍴z)⍉z←,⍤⍺((-⍺)⌽⍳≢⍴⍵)⍉⍵} | |||
</source> | |||
The general treatment benefits from being expanded. | |||
<source lang=apl> | |||
MergeAxes←{ | |||
axes←⍳≢⍴⍵ | |||
move←⍋(axes~⍺),⍺ | |||
merged←,⍤(≢⍺)⊢move⍉⍵ | |||
restore←((⍳≢⍴merged)~⊃⍺),⊃⍺ | |||
restored⍉merged | |||
} | |||
,[⍺] ←→ ⍺∘MergeAxes ⍝ for ∧/1=¯2-/⍺ | |||
</source> | |||
== External links == | == External links == | ||
Line 71: | Line 122: | ||
* [https://aplcart.info/pub/?q=the%20rank%20operator# APLCart/Pub] | * [https://aplcart.info/pub/?q=the%20rank%20operator# APLCart/Pub] | ||
==References== | |||
<references/> | |||
{{APL built-ins}}[[Category:Primitive operators]] | {{APL built-ins}}[[Category:Primitive operators]] |