Unique: Difference between revisions

Jump to navigation Jump to search
23 bytes added ,  17:38, 2 October 2023
Rip out the (wrong) model for unique.
m (→‎History: Make Operators and Functions a page link instead of a reference)
(Rip out the (wrong) model for unique.)
Line 72: Line 72:
== APL model ==
== APL model ==


For [[Vector|vectors]] the following implementation based on [[Union]] can be used. It repeatedly adds cells of the argument to an accumulated unique vector <syntaxhighlight lang=apl inline>u</syntaxhighlight>, using Union so that duplicate cells are never added.
An APL model suggested by Kamila Szewczyk begins with an implementation for vector (rank 1) and scalar (rank 0) arrays as follows:
 
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
VecUnique ← {
v ← {1/⊃∪/⊂¨⍵}
    u ← 0↑⍵
    u ⊣ {u∪←⍵}⍤¯1 ⊢1/
}
</syntaxhighlight>
</syntaxhighlight>
{{Works in|[[Dyalog APL]]}}
{{Works in|[[Dyalog APL]]}}
The accumulation above resembles a [[reduction]]—in fact, it is a reverse [[insertion]]. The following implementation written with Reduce works for [[simple]] vectors in [[Nested array model|nested]] APLs because reduction is equivalent to insertion followed by [[Enclose]] on such vectors:
 
It is extended to arbitrary rank inputs as follows:
 
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
VecUnique ← {⊃∪⍨/⌽⍵}
m ← {0∊⍴⍵:⍵⍴⍨≠∘0@⎕io⊢⍴⍵ ⋄ ↑1/⊃∪/⊂¨⊂⍤¯1⊢⍵}
</syntaxhighlight>
</syntaxhighlight>
{{Works in|[[Dyalog APL]],[[ngn/apl]]}}
{{Works in|[[Dyalog APL]]}}
It can be modified to obtain a full model for Unique by enclosing enough times, and converting scalars to vectors with [[Replicate]] at the end:
 
The guard checks for a zero element in a shape because the general model does not handle the case where the leading axis has shape of zero. While a zero element in the shape in any other place is handled by the general model, the special case is faster and less complex hence preferred. If modelling the primitive via Union is not desirable due to how similar these two primitives are, it is possible to replace this particular usage of union (not in the general case!) as follows:
 
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
Unique ← {1/↑↑⌽∪/⌽⊂∘⊂⍤¯1⊢⍵}
m ← {0∊⍴⍵:⍵ ⋄ ↑1/⊃(⊣,⊢⊢⍤/⍨(∧/∘.≢⍨))/⊂¨⊂⍤¯1⊢⍵}
</syntaxhighlight>
</syntaxhighlight>
{{Works in|[[Dyalog APL]]}}
{{Works in|[[Dyalog APL]]}}


While the model <syntaxhighlight lang=apl inline>{((⍳≢⍵)=(⍵⍳⍵))⌿⍵}</syntaxhighlight>, based on [[Nub Sieve]], is often described as an implementation of Unique, it does not correctly handle [[tolerant comparison]].<ref>Hui, Roger. [https://dyalog.tv/Dyalog17/?v=fPWky9IOG40 Tolerant Unique]. [[Dyalog '17]].</ref> A correct implementation of Nub Sieve could be used to implement Unique, but writing such an implementation is no easier than implementing Unique directly.
While the model <syntaxhighlight lang=apl inline>{((⍳≢⍵)=(⍵⍳⍵))⌿⍵}</syntaxhighlight> for vector arguments, based on [[Nub Sieve]], is often described as an implementation of Unique, it does not correctly handle [[tolerant comparison]].<ref>Hui, Roger. [https://dyalog.tv/Dyalog17/?v=fPWky9IOG40 Tolerant Unique]. [[Dyalog '17]].</ref> A correct implementation of Nub Sieve could be used to implement Unique, but writing such an implementation is no easier than implementing Unique directly.


== Properties ==
== Properties ==

Navigation menu