# Vocabulary/eq

 = y Self-Classify

Rank Infinity -- operates on x and y as a whole -- WHY IS THIS IMPORTANT? The use of =y is deprecated because its result is too large.

The essential action, that of assigning the items of y to classes of identical items,
can be performed by (i.~ y), giving a result of length (#y),
compared with =y whose result has size proportional to (*:#y).

A Boolean table relating a given vector to its Nub (~.).

```   z=: 'abracadabra'
~.z	NB. Nub z
abrcd
=z
1 0 0 1 0 1 0 1 0 0 1
0 1 0 0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0
```

The table compares unique items of y against all items of y. Each row of the table has the comparisons for a single unique item; each column has the comparisons for a single item. The unique items are calculated by ~. y and appear in order of their first appearance in y.

Tabulated, we see the equalities clearer:

```   (~. 'abracadabra') (('=' ; [: }: 1j1 # ]) ,: ,.@[ ; ":@(=/)) 'abracadabra'
+-+---------------------+
|=|a b r a c a d a b r a|
+-+---------------------+
|a|1 0 0 1 0 1 0 1 0 0 1|
|b|0 1 0 0 0 0 0 0 1 0 0|
|r|0 0 1 0 0 0 0 0 0 1 0|
|c|0 0 0 0 1 0 0 0 0 0 0|
|d|0 0 0 0 0 0 1 0 0 0 0|
+-+---------------------+
```

### Common uses

Count the occurrences of each distinct letter in a string.

```   +/"1 =z   NB. sum the rows of: =z
5 2 2 1 1
```

1. = y uses tolerant comparison. Use =!.0 for exact comparison.

2. Comparing Self-Classify with Table (/) we see that =z is the "equal-table" of z with repeated rows deleted (i.e. the Nub).

The equivalence is imperfect, because = y compares items of y, while x = y works on atoms.

```   ~. z=/z   NB. Nub of: z =/ z.   Also equal to (~.z) =/ z
1 0 0 1 0 1 0 1 0 0 1
0 1 0 0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0
```

 x = y Equal

Rank 0 0 -- operates on individual atoms of x and y, producing a result of the same shape -- WHY IS THIS IMPORTANT?

The Boolean result of comparing x and y atom by atom.

```   ]z=: i.5
0 1 2 3 4
3 = z
0 0 0 1 0
z = z
1 1 1 1 1
z = |.z
0 0 1 0 0
```

Equal works for boxed atoms too:

```   z=: 'alpha' ; 'bravo' ; 'charlie'
z = |.z
0 1 0
z = <'bravo'
0 1 0
```

Equal (x=y) has rank 0. It compares corresponding atoms and gives a result 0 (not-equal) or 1 (equal) for each pair of atoms.

If y is an atom, not a list, it behaves like a list having the same shape as x. And vice-versa. x and y may have different rank only if they agree.

If you want to compare two entire nouns for equality, use Match (-:), as in (x-:y). Because, unlike (=), no error results if the shapes of x and y differ.

only tests the first atom in the Boolean (list) condition: b.

Thus:

```if. 'chalk' = 'cheez' do.
```

will test true, because

```   'chalk' = 'cheez'
1 1 0 0 0
```

only the first atom of the result is inspected.

### Common uses

1. Make a conditional phrase in a verb definition (explicit definition)

``` if. LF={:z  do. }:z end.   NB. drop trailing LF if it's there
```

2. Make a Boolean list (b) to work with a given string (z)

```   z =: 'alpha bravo charlie'
] b =: z=' '
0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0
-.b   NB. not-b
1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1

(-.b) # z
alphabravocharlie

] i =: I.b
5 11
] good_name =: '_' i } z
alpha_bravo_charlie
```

### Related Primitives

Larger Than (x > y), Larger Or Equal (x >: y), Less Than (x < y), Less Or Equal (x <: y), Not-Equal (x ~: y), Match (x -: y)

1. (=) uses tolerant comparison, which means that inexact numeric types (floating-point and complex) are considered equal if they are "close enough". By default the comparison tolerance is (2^_44), which means that two numbers are considered equal if the magnitude of the difference is no more than (2^_44) times the larger argument magnitude. To require exact comparison, use (=!.0) to temporarily set the comparison tolerance to 0.

2. The arguments x and y can be of any type. No error results if the types are different. Atoms of different types always give 0 (not-equal). Atoms of the same type give 1 if equal, 0 otherwise.

3. Boxed atoms are compared by opening (unboxing) them and comparing their contents. Two boxed atoms are equal only if the shapes of the contents are the same and their corresponding elements are equal. If the corresponding elements are themselves boxed, these are compared in exactly the same way. And so on, down to any level of boxing. Numeric comparisons are tolerant whatever the level of boxing.

```   ]a =: ;: 'a'   NB. One word, one letter
+-+
|a|
+-+
]b =: <'a'    NB. one word, one letter
+-+
|a|
+-+
a = b    NB. But not the same!  Why not?  a voyage of discovery...
0
\$a   NB. a is a LIST of boxed words
1
\$b   NB. b is an atom

\$,b   NB. We could make b into a list
1
a = ,b   NB. but it's still not the same!
0
\$>a   NB. opened a is a TABLE!! Why?
1 1
{. a     NB. Take just one atom (the only atom) of a
+-+
|a|
+-+
\$ {. a   NB. OK, that's an atom.  Its shape is empty

\$ > {. a   NB. The contents are a list (of length 1).  That's why when we opened a
NB. it had 2 axes: one from a itself and one from the contents
1
\$>b    NB. b is an atom containing an atom, so opened it's still an atom

a = <,'a'   NB. a is equal to a boxed list
1
\$ a = ,'a'   NB. but note: the result of the comparison is a LIST
1
```

### Use These Combinations

Combinations using x = y that have exceptionally good performance include those shown in Searching and Matching Items: Fast List Operations (FLOs), as well as the following:

 What it does Type; Precisions; Ranks Syntax Variants; Restrictions Benefits; Bug Warnings Boolean reductions on infixes Boolean x +./\ y x positive *. = ~: in place of +. much faster than alternatives Mean on infixes integer and floating-point x (+/%#)\ y x positive *. = ~: in place of + much faster than alternatives Boolean reductions on partitions Boolean x +//. y = <. >. +. * *. ~: in place of + avoids building argument cells Boolean reductions along diagonals Boolean +.//. y *. = ~: < <: > >: in place of +. avoids building argument cells