Replicate: Difference between revisions

Jump to navigation Jump to search
3,870 bytes added ,  10:09, 4 May 2020
m
(→‎Extension support: Combine NARS and NARS2000)
(11 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Built-ins|Replicate|/|⌿}}, or '''Copy''' (<source lang=j inline>#</source>) in [[J]], is a [[dyadic function]] or [[monadic operator]] that copies each [[element]] of the right [[argument]] a given number of times, ordering the copies along a specified [[axis]]. Typically <source lang=apl inline>/</source> is called Replicate while <source lang=apl inline>⌿</source> is called "Replicate First" or an equivalent. Replicate is a widely-accepted extension of the function '''Compress''', which requires the number of copies to be [[Boolean]]: each element is either retained (1 copy) or discarded (0 copies). Replicate with a Boolean left argument or [[operand]] may still be called "Compress".
{{Built-ins|Replicate|/|⌿}}, or '''Copy''' (<source lang=j inline>#</source>) in [[J]], is a [[dyadic function]] or [[monadic operator]] that copies each [[element]] of the right [[argument]] a given number of times, ordering the copies along a specified [[axis]]. Typically <source lang=apl inline>/</source> is called Replicate while <source lang=apl inline>⌿</source> is called "Replicate First" or an equivalent. Replicate is a widely-accepted extension of the function '''Compress''', which requires the number of copies to be [[Boolean]]: each element is either retained (1 copy) or discarded (0 copies). Replicate with a Boolean left argument or [[operand]] may still be called "Compress".


Replicate is usually associated with [[Expand]] (<source lang=apl inline>\</source>), and the two functions are related to [[Mask]] and [[Mesh]]. It is also closely related to the [[Indices]] function. It shares a [[glyph]] with [[Reduce]] even though Replicate is naturally a [[function]] and Reduce must be an [[operator]]. This incongruity is occasionally resolved by making Replicate an operator itself, and more often by [[function-operator overloading]] allowing both syntactic elements to coexist.
Replicate is usually associated with [[Expand]] (<source lang=apl inline>\</source>), and the two functions are related to [[Mask]] and [[Mesh]]. It is also closely related to the [[Indices]] function. It shares a [[glyph]] with [[Reduce]] even though Replicate is naturally a [[function]] and Reduce must be an [[operator]]. This incongruity is sometimes resolved by making Replicate an operator itself, and sometimes by [[function-operator overloading]] allowing both syntactic elements to coexist.


Outside of APL, [[wikipedia:filter (higher-order function)|filter]] typically provides the functionality of Compress, while Replicate has no common equivalent.
Outside of APL, [[wikipedia:filter (higher-order function)|filter]] typically provides the functionality of Compress, while Replicate has no common equivalent.
Line 26: Line 26:
8
8
</source>
</source>
A second extension introduced by [[NARS]] allows either positive or negative integers, where a negative number indicates that a [[fill element]] should be used instead of an element from the right argument. In this case the length of the result is the sum of the [[absolute value]] of the control array.
Replicate usually allows [[scalar extension]] of the left argument, which results in every element being copied a fixed number of times.
<source lang=apl>
      3 / 'replicate'
rrreeepppllliiicccaaattteee
</source>
 
=== Negative numbers ===
An extension introduced by [[NARS]] allows either positive or negative integers, where a negative number indicates that a [[fill element]] should be used instead of an element from the right argument. In this case the argument lengths must be equal (unless one side is a [[singleton]]). [[APL2]] defined a different extension: negative numbers do not correspond to any element of the right argument, but still indicate that many fills should be inserted. In the APL2 extension the length of the right argument is the number of non-negative elements in the left argument. In both extensions the length of the result is the sum of the [[absolute value]] of the control array.
<source lang=apl>
<source lang=apl>
       0 2 ¯3 1 / ⍳4
       0 2 ¯3 1 / ⍳4
2 2 0 0 0 4
2 2 0 0 0 4
</source>
</source>{{Works in|[[NARS2000]], [[Dyalog APL]], [[APLX]], [[ngn/apl]]}}
Replicate works along a particular axis, which can be specified in languages with [[function axis]] and otherwise is the first axis for <source lang=apl inline>⌿</source>, and the last axis for <source lang=apl inline>/</source> (except in [[A+]], which uses <source lang=apl inline>/</source> for the [[Leading axis theory|first-axis]] form and has no last-axis form).
<source lang=apl>
      0 2 ¯3 1 / ⍳3
2 2 0 0 0 3
</source>{{Works in|[[APL2]], [[APLX]], [[GNU APL]]}}
The extensions are the same when the right argument is subject to [[singleton extension]]. This extension was usually supported before any extension to negative numbers, but would not typically be useful because <source lang=apl inline>v/s</source> {{←→}} <source lang=apl inline>(+/v)/s</source> where <source lang=apl inline>v</source> is a non-negative integer vector and <source lang=apl inline>s</source> is a singleton.
<source lang=apl>
      1 ¯2 3 / 'a'
a  aaa
</source>{{Works in|[[NARS2000]], [[APL2]], [[Dyalog APL]], [[APLX]], [[ngn/apl]], [[GNU APL]]}}
 
=== High-rank arrays ===
Replicate works along a particular [[axis]], which can be specified in languages with [[function axis]] and otherwise is the first axis for <source lang=apl inline>⌿</source>, and the last axis for <source lang=apl inline>/</source> (except in [[A+]], which uses <source lang=apl inline>/</source> for the [[Leading axis theory|first-axis]] form and has no last-axis form).
<source lang=apl>
<source lang=apl>
       ⊢A ← 4 6⍴⎕A
       ⊢A ← 4 6⍴⎕A
Line 49: Line 67:
STUVWX
STUVWX
</source>
</source>
Replicate usually allows [[scalar extension]] of the left argument, which results in every element being copied a fixed number of times.
[[APL2]] further extends the [[singleton extension]] of the right argument, allowing it to have length 1 along the replication axis even if other axes have lengths not equal to 1.
<source lang=apl>
      1 ¯2 3 / ⍪'abc'
a  aaa
b  bbb
c  ccc
</source>{{Works in|[[APL2]], [[Dyalog APL]], [[APLX]], [[ngn/apl]], [[GNU APL]]}}
 
[[dzaima/APL]] expects arguments of <source lang=apl inline>⌿</source> to have matching shape, and replicates the [[ravel]] of both.
 
=== Operator or function? ===
 
The syntax <source lang=apl inline>a / b</source> is ambiguous: it may be an invocation of a [[dyadic function]] <source lang=apl inline>/</source> with left [[argument]] <source lang=apl inline>a</source> and right argument <source lang=apl inline>b</source>, or of a [[monadic operator]] with [[operand]] <source lang=apl inline>a</source> and right argument <source lang=apl inline>b</source>. In early APLs there was no way to resolve this ambiguity, but with the extension of [[operator]]s to allow arbitrary function operands instead of a specified set of [[primitive function]]s, the distinction becomes apparent: a function Replicate can be used as an [[operand]] while an operator Replicate cannot.
 
One test of Replicate's nature is to try Replicate [[Each]]<ref>Benkard, J. Philip. [https://dl.acm.org/doi/10.1145/384282.28345 "Replicate each, anyone?"]. [[APL87]].</ref> with an expression such as <source lang=apl inline>1 3 /¨ 'ab' 'cd'</source>. If Replicate is implemented as an operator, it will be applied to the operand <source lang=apl inline>1 3</source>, and Each will be applied to the resulting [[derived function]] <source lang=apl inline>1 3/</source>.
<source lang=apl>
      1 3 /¨ 'ab' 'cd' 
abbb  cddd
      (1 3/)¨ 'ab' 'cd'
abbb  cddd
</source>{{Works in|[[SHARP APL]] (with <source lang=apl inline>¨></source> in place of <source lang=apl inline>¨</source>), [[APL2]], [[APLX]]}}
If Replicate is a function, then Each will apply to Replicate only, and the resulting derived function will be invoked monadically.
<source lang=apl>
<source lang=apl>
       3 / 'replicate'
       1 3 /¨ 'ab' 'cd' 
rrreeepppllliiicccaaattteee
ab  cccddd
</source>
      1 3 (/¨) 'ab' 'cd'
ab  cccddd
</source>{{Works in|[[NARS2000]], [[Dyalog APL]], [[GNU APL]]}}
In early APLs such as [[APL\360]], applying an operator to Compress will always result in a [[SYNTAX ERROR]], because Compress is not an allowed operand of any operator. This is also the case in [[ngn/apl]]: although operators can apply to any function, Replicate cannot be used unless both arguments are immediately available. In both cases there is no way to determine whether Replicate "acts like a function" or "acts like an operator".


== History ==
== History ==
Line 95: Line 137:
| [[ISO/IEC 13751:2001]]                              || Function  || {{Yes}} ||colspan=2 {{No}}    || {{No|Scalar}}      || {{Yes}} ||
| [[ISO/IEC 13751:2001]]                              || Function  || {{Yes}} ||colspan=2 {{No}}    || {{No|Scalar}}      || {{Yes}} ||
|-
|-
| [[APLX]]                                            || Function || {{Yes}} || {{Yes}} || {{Yes}} || {{Yes|APL2}}        || {{Yes}} ||
| [[APLX]]                                            || Operator || {{Yes}} || {{Yes}} || {{Yes}} || {{Yes|APL2}}        || {{Yes}} ||
|-
|-
| [[ngn/apl]]                                        || Ambiguous || {{Yes}} || {{Yes}} || {{No}}  || {{Yes|APL2}}        || {{Yes}} || Implemented as an operator
| [[ngn/apl]]                                        || Ambiguous || {{Yes}} || {{Yes}} || {{No}}  || {{Yes|APL2}}        || {{Yes}} || Implemented as an operator
Line 101: Line 143:
| [[GNU APL]]                                        || Function  || {{Yes}} || {{No}}  || {{Yes}} || {{Yes|APL2}}        || {{Yes}} ||
| [[GNU APL]]                                        || Function  || {{Yes}} || {{No}}  || {{Yes}} || {{Yes|APL2}}        || {{Yes}} ||
|-
|-
| [[dzaima/APL]] (<source lang=apl inline>⌿</source>) || Function  || {{Yes}} || {{Yes}} || {{No}}  || {{None}}            || {{No}}  || Vector right argument only
| [[dzaima/APL]] (<source lang=apl inline>⌿</source>) || Function  || {{Yes}} || {{Yes}} || {{No}}  || {{None}}            || {{No}}  ||
|}
|}


Line 133: Line 175:
<references />
<references />


{{APL built-ins}}
{{APL built-ins}}[[Category:Primitive functions]][[Category:Functions with first- and last-axis forms]]

Navigation menu