Replicate: Difference between revisions

Jump to navigation Jump to search
6,041 bytes added ,  15:04, 13 March 2020
→‎External Links: NARS2000 documentation
(Created page with "{{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...")
 
(→‎External Links: NARS2000 documentation)
(12 intermediate revisions by the same user 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 checking the object to the left of a slash and treating the slash as Replicate if it is an array and as Reduce if it is a [[function]].
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.


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 57: Line 57:
== History ==
== History ==


Compress was described in [[A Programming Language]], which used the notation <math>/</math> and <math>//</math> for it. It was included in [[APL\360]] changing the doubled slash to a barred slash <source lang=apl inline>⌿</source>, and continued to be included in APLs essentially unchanged until 1980.
Compress was described in [[A Programming Language]], where it was written with the symbols <math>/</math> and <math>/\!\!/</math>. In [[Iverson notation]] compression was particularly important because [[Take]] and [[Drop]] could be performed only by compression with a [[prefix]] or [[suffix]] vector. It was included in [[APL\360]], which changed the doubled slash to a barred slash <source lang=apl inline>⌿</source>, and allowed a [[specified axis]] and [[singleton extension]] on both sides (very briefly, singleton extension was allowed only for the right argument<ref>Falkoff, A.D., and K.E. Iverson, "[http://keiapl.org/archive/APL360_UsersMan_Aug1968.pdf APL\360 User's Manual]". IBM, August 1968.</ref>). The APL\360 definition continued to be included in APLs unchanged until 1980.


In 1980, [[Bob Bernecky]] introduced the extension Replicate to [[SHARP APL]]: he allowed an operand (since SHARP's Replicate is an operator) consisting of non-negative integers rather than just [[Boolean]]s to indicate the number of times to copy.<ref>[[Bob Bernecky|Bernecky, Bob]]. SATN-34: Replication. [[IPSA]]. 1980-08-15.</ref> This extension was quickly implemented in [[NARS]], along with further extensions: a similar change to [[Expand]], and the extension allowing negative integers to indicate [[fill elements]]. Both extensions were quickly adopted by the APL community, and were included in new languages such as [[Dyalog APL]] and [[APL2]], and later the [[ISO/IEC 13751:2001]] standard.
In 1980, [[Bob Bernecky]] introduced the extension Replicate to [[SHARP APL]]: he allowed an operand (since SHARP's Replicate is an operator) consisting of non-negative integers rather than just [[Boolean]]s to indicate the number of times to copy.<ref>[[Bob Bernecky|Bernecky, Bob]]. SATN-34: Replication. [[IPSA]]. 1980-08-15.</ref> This extension was rapidly and widely adopted, starting with [[NARS]] in 1981, and is now a feature of the [[ISO/IEC 13751:2001]] standard.
 
Two extensions to allow negative numbers in the left argument have been introduced, in each case specifying that the negative of a number indicates that many [[fill element]]s should appear in the result. In 1981 [[NARS]] specified that these fill elements replace the corresponding right argument element, so that the lengths of the left and right arguments are always equal, and extended [[Expand]] similarly. [[APL2]], in 1984, made the opposite choice, so that the length of the right argument along the specified axis is equal to the number of non-negative elements on the left. [[APL2]] also loosened the [[conformability]] requirements further than simply allowing [[singleton extension]]: it allowed a right argument with length 1 along the replication axis to be extended. [[Dyalog APL]], created before APL2, adopted the [[NARS]] definition for negative elements but added APL2 conformability extension in [[Dyalog APL 13.1|version 13.1]]. Later [[APLX]] took advantage of the fact that the two negative number extensions can be distinguished by the length of the left argument, and implemented every NARS and APL2 extension.
 
[[A+]] and [[J]] modified Replicate to fit [[leading axis theory]]. Rather than allow Replicate to operate on any axis they have only one Replicate function (in A+, <source lang=apl inline>/</source>; in J, <source lang=j inline>#</source>) which works on the first axis—it copies [[major cell]]s rather than elements. Both languages rejected the [[NARS]] extension to negative left arguments, but J introduced its own system to add [[fill element]]s by allowing [[complex number]]s in the left argument, and removed the [[Expand]] function entirely. [[Arthur Whitney]] went on to make a more radical change in [[K]], removing Replicate entirely in favor of [[Where]].
 
== Extension support ==
 
Here ">1" refers to the [[SHARP APL]] extension to non-negative integers, while "<0" refers to extension to negative integers in either NARS or APL2 style.
{| class=wikitable
!rowspan=2| Language
!rowspan=2| Type
!rowspan=2 style="min-width:6em"| >1
!colspan=2| <0
!rowspan=2| Conformability<br/>extension
!rowspan=2| Axis<br/>specification
!rowspan=2| Notes
|-
! NARS !! APL2
|-
| [[APL\360]]                                        || Ambiguous || {{No}}  ||colspan=2 {{No}}    || {{Maybe|Single}}    || {{Yes}} ||
|-
| [[SHARP APL]]                                      || Operator  || {{Yes}} ||colspan=2 {{No}}    || {{No|Scalar}}      || {{Yes}} ||
|-
| [[NARS]]                                            || Function  || {{Yes}} || {{Yes}} || {{No}}  || {{Maybe|Single}}    || {{Yes}} ||
|-
| [[Dyalog APL]]                                     || Function  || {{Yes}} || {{Yes}} || {{No}}  || {{Yes|APL2 (13.1)}} || {{Yes}} ||
|-
| [[APL2]]                                           || Operator  || {{Yes}} || {{No}}  || {{Yes}} || {{Yes|APL2}}        || {{Yes}} ||
|-
| [[A+]] (<source lang=apl inline>/</source>)        || Function  || {{Yes}} ||colspan=2 {{No}}    || {{Maybe|Single}}    || {{No}}  ||
|-
| [[J]] (<source lang=j inline>#</source>)            || Function  || {{Yes}} ||colspan=2 {{No}}    || {{No|Scalar}}      || {{No}}  || Complex left argument allowed
|-
| [[ISO/IEC 13751:2001]]                             || Function  || {{Yes}} ||colspan=2 {{No}}    || {{No|Scalar}}      || {{Yes}} ||
|-
| [[APLX]]                                            || Function  || {{Yes}} || {{Yes}} || {{Yes}} || {{Yes|APL2}}        || {{Yes}} ||
|-
| [[NARS2000]]                                        || Function  || {{Yes}} || {{Yes}} || {{No}}  || {{Maybe|Single}}    || {{Yes}} ||
|-
| [[ngn/apl]]                                        || Ambiguous || {{Yes}} || {{Yes}} || {{No}}  || {{Yes|APL2}}        || {{Yes}} || Implemented as an operator
|-
| [[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
|}
 
In each language without axis specification, there is only one form of Replicate, which always applies to the first axis or [[major cell]]s—the last-axis form is discarded.
 
== Outside of APL ==
 
While Replicate is rarely used in non-array programming languages, Compress is sometimes seen. Usually the same functionality is provided by the higher-order function [[wikipedia:filter (higher-order function)|filter]], which an APLer might define as the [[monadic operator]] <source lang=apl inline>filter←{(⍺⍺¨ ⍵) / ⍵}</source> on a [[vector]] argument.
 
While filter is similar to Compress, some extensions to the [[wikipedia:x86|x86]] instruction set are exactly equivalent to Compress on particular data types. In [[wikipedia:BMI2|BMI2]], the PEXT and PDEP instructions (parallel bit extract and deposit) are identical to Compress and [[Expand]] on the bits of a register argument. Indeed, [[Dyalog APL]] uses these instructions to implement those primitives (see [[Dyalog APL#Instruction set usage]]). The [[wikipedia:AVX-512|AVX-512]] instructions VPCOMPRESSQ and VPEXPANDQ (and variations) are not only equivalent to Compress and Expand using a mask register for the [[Boolean]] argument and a vector register for the other argument, but are named after the APL functions. These instructions allow compression of 4-byte and 8-byte elements, and with AVX-512_VBMI2 support was added for 1-byte and 2-byte elements as well.


== External Links ==
== External Links ==
Line 70: Line 123:


* [http://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Replicate.htm Dyalog]
* [http://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Replicate.htm Dyalog]
* [http://wiki.nars2000.org/index.php/Symbol_Slash NARS2000]
* [http://microapl.com/apl_help/ch_020_020_840.htm APLX]
* [http://microapl.com/apl_help/ch_020_020_840.htm APLX]
* J [https://www.jsoftware.com/help/dictionary/d400.htm Dictionary], [https://code.jsoftware.com/wiki/Vocabulary/number#dyadic NuVoc]
* J [https://www.jsoftware.com/help/dictionary/d400.htm Dictionary], [https://code.jsoftware.com/wiki/Vocabulary/number#dyadic NuVoc]
=== Other ===
* [[Marshall Lochbaum]] [https://www.dyalog.com/blog/2018/06/expanding-bits-in-shrinking-time/ "Expanding Bits in Shrinking Time"]: On implementing Replicate of a [[Boolean]] array by a [[scalar]].


== References ==
== References ==

Navigation menu