Depth (operator): Difference between revisions
m (Text replacement - "</source>" to "</syntaxhighlight>") |
(→Publications: Benkard paper that uses a depth operator) |
||
(8 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
:''This article is about the operator. See [[Depth]] for the number associated with every array and the function which returns this number.'' | :''This article is about the operator. See [[Depth]] for the number associated with every array and the function which returns this number.'' | ||
{{Built-in|Depth|⍥}} is a [[primitive operator|primitive]] [[dyadic operator]] which applies its left [[operand]] function to sub- | {{Built-in|Depth|⍥}} is a [[primitive operator|primitive]] [[dyadic operator]] which applies its left [[operand]] function to [[sub-array]]s of its arguments specified by its right operand array. It appears in [[Extended Dyalog APL]], [[dzaima/APL]], [[J]] (as <syntaxhighlight lang=j inline>L:</syntaxhighlight>), and [[BQN]] (as <code>⚇</code>). | ||
== Introduction == | == Introduction == | ||
The Depth operator is a generalisation of the [[Each]] operator (as <code>¨</code>). While Each switches application from being directly on array arguments, to be on their elements, Depth allows exact specification of the depth level of each argument that the function is applied to. | The Depth operator is a generalisation of the [[Each]] operator (as <code>¨</code>). While Each switches application from being directly on array arguments, to be on their elements, Depth allows exact specification of the depth level of each argument that the function is applied to. | ||
Depth is closely related to [[Rank (operator)|Rank]] (<syntaxhighlight lang=apl inline>⍤</syntaxhighlight>), but while Rank specifies the [[rank]] of the final arguments of | Depth is closely related to [[Rank (operator)|Rank]] (<syntaxhighlight lang=apl inline>⍤</syntaxhighlight>), but while Rank specifies the [[rank]] of the final arguments of the left operand function, Depth specifies the [[depth]] of the final arguments of the left operand function. | ||
For all arguments, when applied with a non-negative right depth specification (the right operand), and also with negative depth specification even when the arguments are ragged (of non-uniform depth), <syntaxhighlight lang=apl inline>f⍥p⊢Y</syntaxhighlight> is equivalent to <syntaxhighlight lang=apl inline>f¨¨</syntaxhighlight>…<syntaxhighlight lang=apl inline>¨¨Y</syntaxhighlight> and <syntaxhighlight lang=apl inline>X f⍥p⊢Y</syntaxhighlight> is equivalent to <syntaxhighlight lang=apl inline>(⊂⊂</syntaxhighlight>…<syntaxhighlight lang=apl inline>⊂⊂X)f¨¨</syntaxhighlight>…<syntaxhighlight lang=apl inline>¨¨⊂⊂</syntaxhighlight>…<syntaxhighlight lang=apl inline>⊂⊂Y</syntaxhighlight> where "<code>xx</code>…<code>xx</code>" indicates some number of repetitions of the function or operator <code>x</code>. | For all arguments, when applied with a non-negative right depth specification (the right operand), and also with negative depth specification even when the arguments are ragged (of non-uniform depth), <syntaxhighlight lang=apl inline>f⍥p⊢Y</syntaxhighlight> is equivalent to <syntaxhighlight lang=apl inline>f¨¨</syntaxhighlight>…<syntaxhighlight lang=apl inline>¨¨Y</syntaxhighlight> and <syntaxhighlight lang=apl inline>X f⍥p⊢Y</syntaxhighlight> is equivalent to <syntaxhighlight lang=apl inline>(⊂⊂</syntaxhighlight>…<syntaxhighlight lang=apl inline>⊂⊂X)f¨¨</syntaxhighlight>…<syntaxhighlight lang=apl inline>¨¨⊂⊂</syntaxhighlight>…<syntaxhighlight lang=apl inline>⊂⊂Y</syntaxhighlight> where "<code>xx</code>…<code>xx</code>" indicates some number of repetitions of the function or operator <code>x</code>. | ||
== Depth specification == | == Depth specification == | ||
The right operand specifies the [[depth]] of sub- | The right operand specifies the [[depth]] of sub-arrays to which the left operand function is applied as follows: | ||
For left argument <syntaxhighlight lang=apl inline>⍺</syntaxhighlight> and right argument <syntaxhighlight lang=apl inline>⍵</syntaxhighlight>, | For left argument <syntaxhighlight lang=apl inline>⍺</syntaxhighlight> and right argument <syntaxhighlight lang=apl inline>⍵</syntaxhighlight>, | ||
<syntaxhighlight lang=apl> | <syntaxhighlight lang=apl> | ||
⍥ c ⍝ Depth-c sub-arrays of ⍵ (monadic) or both arguments (dyadic) | |||
⍥ b c ⍝ Depth-b sub-arrays of ⍺ and depth-c sub-arrays of ⍵ (dyadic) | |||
⍥a b c ⍝ Depth-a sub-arrays of ⍵ (monadic), depth-b sub-arrays of ⍺ and depth-c sub-arrays of ⍵ (dyadic) | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 44: | Line 44: | ||
└──────────┴───┘ | └──────────┴───┘ | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Con[[catenate]] a constant prefix to each element: | Con[[catenate]] a constant prefix to each element: | ||
Line 56: | Line 55: | ||
Pair up the elements on the left with each element of each element on the right. | Pair up the elements on the left with each element of each element on the right. | ||
<syntaxhighlight lang=apl> | <syntaxhighlight lang=apl> | ||
'xy', | 'xy',⍥¯1⍥¯1⊢('ab' 'cd')('AB' 'CD') ⍝ equivalent to (⊂'xy'),¨¨('ab' 'cd')('AB' 'CD') | ||
┌─────────┬─────────┐ | ┌─────────┬─────────┐ | ||
│┌───┬───┐│┌───┬───┐│ | │┌───┬───┐│┌───┬───┐│ | ||
Line 70: | Line 69: | ||
=== Publications === | === Publications === | ||
* [[dfns workspace]]: [https://dfns.dyalog.com/n_Depth.htm Depth] | * [https://github.com/abrudz/primitives/blob/main/depth.aplo APL model] | ||
* [[dfns workspace]]: [https://dfns.dyalog.com/n_Depth.htm Depth] (this model does not correspond to the final design) | |||
* [https://doi.org/10.1145/28315.28345 Replicate each, anyone?] by J. Philip Benkard at [[APL87]] | |||
{{APL built-ins}}[[Category:Primitive operators]] | {{APL built-ins}}[[Category:Primitive operators]] |
Latest revision as of 22:22, 7 February 2024
- This article is about the operator. See Depth for the number associated with every array and the function which returns this number.
⍥
|
Depth (⍥
) is a primitive dyadic operator which applies its left operand function to sub-arrays of its arguments specified by its right operand array. It appears in Extended Dyalog APL, dzaima/APL, J (as L:
), and BQN (as ⚇
).
Introduction
The Depth operator is a generalisation of the Each operator (as ¨
). While Each switches application from being directly on array arguments, to be on their elements, Depth allows exact specification of the depth level of each argument that the function is applied to.
Depth is closely related to Rank (⍤
), but while Rank specifies the rank of the final arguments of the left operand function, Depth specifies the depth of the final arguments of the left operand function.
For all arguments, when applied with a non-negative right depth specification (the right operand), and also with negative depth specification even when the arguments are ragged (of non-uniform depth), f⍥p⊢Y
is equivalent to f¨¨
…¨¨Y
and X f⍥p⊢Y
is equivalent to (⊂⊂
…⊂⊂X)f¨¨
…¨¨⊂⊂
…⊂⊂Y
where "xx
…xx
" indicates some number of repetitions of the function or operator x
.
Depth specification
The right operand specifies the depth of sub-arrays to which the left operand function is applied as follows:
For left argument ⍺
and right argument ⍵
,
⍥ c ⍝ Depth-c sub-arrays of ⍵ (monadic) or both arguments (dyadic) ⍥ b c ⍝ Depth-b sub-arrays of ⍺ and depth-c sub-arrays of ⍵ (dyadic) ⍥a b c ⍝ Depth-a sub-arrays of ⍵ (monadic), depth-b sub-arrays of ⍺ and depth-c sub-arrays of ⍵ (dyadic)
A non-negative right operand specifies the depth of the final arguments to which the function applies. Therefore, application with a depth specification of 0
causes the function to be called only on simple scalars, thus implementing pervasion for any given function.
A negative right operand specifies complementary depth, i.e. the number of levels to descend into before applying the operand. Negative depth can also be thought of as depth specification relative to the overall depth of the argument array. Thus, a depth specification of ¯1
is equivalent to application with Each and in general, a depth specification of -k
is equivalent to application with k
Eaches.
Since a depth specification greater than the depth of the argument array means to apply the function to the whole array, (⌊/⍬)
or ∞
, depending on the implementation, is "depth infinity" and always specifies the whole argument array. However, in practice, any large number, for example 9, is sufficient for most uses.
Examples
Reverse each element in a ragged depth-3D array (note that all member vectors are reversed, despite that their individual structures vary):
⌽⍥¯1⊢('abc' 'cdef') 'ghi' ⍝ equivalent to ⌽¨('abc' 'cdef') 'ghi' ┌──────────┬───┐ │┌────┬───┐│ihg│ ││cdef│abc││ │ │└────┴───┘│ │ └──────────┴───┘
Reverse each simple vector in a ragged depth-3D array (note that each simple vector is reversed, even though the amount of penetration, into the entire array, varies):
⌽⍥1⊢('abc' 'cdef') 'ghi' ┌──────────┬───┐ │┌───┬────┐│ihg│ ││cba│fedc││ │ │└───┴────┘│ │ └──────────┴───┘
Concatenate a constant prefix to each element:
'; ',⍥1⊢'abc' 'cdef' 'ghi' ⍝ equivalent to (⊂'; '),¨'abc' 'cdef' 'ghi' ┌─────┬──────┬─────┐ │; abc│; cdef│; ghi│ └─────┴──────┴─────┘
Pair up the elements on the left with each element of each element on the right.
'xy',⍥¯1⍥¯1⊢('ab' 'cd')('AB' 'CD') ⍝ equivalent to (⊂'xy'),¨¨('ab' 'cd')('AB' 'CD') ┌─────────┬─────────┐ │┌───┬───┐│┌───┬───┐│ ││xab│ycd│││xAB│yCD││ │└───┴───┘│└───┴───┘│ └─────────┴─────────┘
External links
Documentation
- J Dictionary, NuVoc (as
L:
) - BQN (as
⚇
)
Publications
- APL model
- dfns workspace: Depth (this model does not correspond to the final design)
- Replicate each, anyone? by J. Philip Benkard at APL87