# Set Similarity

> NumKong for Rust

Packed-binary metrics work on packed words instead of boolean slices.
That is the right model once the workload is "semantic hash" rather than "array of booleans".

```rust
use numkong::{Dot, Hamming, Jaccard, u1x8};

let a = [u1x8(0b10101010), u1x8(0b11110000)];
let b = [u1x8(0b10101110), u1x8(0b11000000)];
let hamming = u1x8::hamming(&a, &b).unwrap();
let jaccard = u1x8::jaccard(&a, &b).unwrap();
let overlap = u1x8::dot(&a, &b).unwrap(); // set bits in common
```

`Dot` on `u1x8` is the intersection count Jaccard normalises, so a ranking pass can skip the division.

Integer set Jaccard works on sorted arrays of integer identifiers.

```rust
let set_a = [1_u32, 3, 5, 7, 9];
let set_b = [3_u32, 5, 8, 9, 10];
let jaccard_sets = u32::jaccard(&set_a, &set_b).unwrap();
assert!(jaccard_sets > 0.0 && jaccard_sets < 1.0); // |A ∩ B| / |A ∪ B|
```

`use numkong::BinarySimilarity;`

`use numkong::Hamming;`

`use numkong::Jaccard;`

## BinarySimilarity

[`BinarySimilarity`](#BinarySimilarity) bundles binary distance metrics: Hamming and Jaccard.

```rust
pub trait BinarySimilarity: Hamming + Jaccard
```

Implementors: - `impl<Scalar: [Hamming](#Hamming) + [Jaccard](#Jaccard)> [BinarySimilarity](#BinarySimilarity) for Scalar`

## Hamming

Computes the __Hamming distance__ between two binary vectors.

```rust
pub trait Hamming: StorageElement
```

Counts differing bits for [`u1x8`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#u1x8), or differing bytes for `u8`.

Range: [0, n]. Fails with [`Error::ShapeMismatch`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#ShapeMismatch) if lengths differ, or
[`Error::KernelFailed`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#KernelFailed) carrying the kernel's status.

Implemented for: [`u1x8`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#u1x8), `u8`.

Implementors: - `impl [Hamming](#Hamming) for [u1x8](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#u1x8)`
- `impl [Hamming](#Hamming) for u8`

## Output

Result type of the Hamming distance.

```rust
type Output;
```

## hamming

Computes the Hamming distance between two equally long slices.

```rust
fn hamming(a: &[Self], b: &[Self]) -> Result<Self::Output, Error>
```

## Jaccard

Computes the __Jaccard distance__ between two sets represented as bit/integer vectors.

```rust
pub trait Jaccard: StorageElement
```

d = 1 − |A ∩ B| / |A ∪ B|

Range: [0, 1]. Fails with [`Error::ShapeMismatch`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#ShapeMismatch) if lengths differ, or
[`Error::KernelFailed`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#KernelFailed) carrying the kernel's status.

Implemented for: [`u1x8`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#u1x8), `u16`, `u32`.

Implementors: - `impl [Jaccard](#Jaccard) for [u1x8](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#u1x8)`
- `impl [Jaccard](#Jaccard) for u16`
- `impl [Jaccard](#Jaccard) for u32`

## Output

Result type of the Jaccard distance.

```rust
type Output;
```

## jaccard

Computes the Jaccard distance between two equally long slices.

```rust
fn jaccard(a: &[Self], b: &[Self]) -> Result<Self::Output, Error>
```

