Swift · Set Similarity

Set Similarity

import NumKong 8.0.0-rc.1 · b1f866ab

Binary metrics work on packed words instead of boolean slices. That is the right model once the workload is “semantic hash” or “binary embedding” rather than “array of booleans”. U1x8 packs 8 bits into one byte.

import NumKong

// Each U1x8 holds 8 bits. Two elements = 16 bits total.
let a: [U1x8] = [U1x8(bitPattern: 0b10101010), U1x8(bitPattern: 0b11110000)]
let b: [U1x8] = [U1x8(bitPattern: 0b10101110), U1x8(bitPattern: 0b11000000)]

let hamming = a.hamming(b) // UInt32: count of differing bits
let jaccard = a.jaccard(b) // Float32: Jaccard distance in [0, 1]

print(hamming as Any, jaccard as Any)

Hamming returns UInt32 — the count of differing bits across all packed words. Jaccard returns Float32 — the set-theoretic distance computed on bit populations.

§ Set Distance Kernels

Set distance kernels operate on U1x8 matrices where each row is a packed binary vector. The same packed and symmetric shapes available for dense metrics exist here.

import NumKong

// Eight binary vectors, each 16 bits wide (2 x U1x8 per row)
let rows = 8
let columns = 2
var rawBits = [U1x8](repeating: U1x8(bitPattern: 0b10101010), count: rows * columns)

let t = try rawBits.withUnsafeMutableBufferPointer { buf -> Tensor<U1x8> in
    let data = Array(buf)
    return try Tensor<U1x8>.fromArray(data, rows: rows, columns: columns)
}

let packed = try PackedMatrix<U1x8>(packing: t.view())

// Cross-matrix Hamming distances: shape [8, 8]
let hammings = try t.hammingsPacked(packed)  // Tensor<UInt32>

// Symmetric all-pairs Jaccard distances: shape [8, 8]
let jaccards = try t.jaccardsSymmetric()     // Tensor<Float32>

assert(hammings.rows == rows && hammings.columns == rows)
assert(jaccards.rows == rows && jaccards.columns == rows)

Free-function forms are also available:

try hammingsPacked(view, packed, &span)
try jaccardsPacked(view, packed, &span)
try hammingsSymmetric(view, &span, rowsBegin: 0, rowsEnd: rows)
try jaccardsSymmetric(view, &span, rowsBegin: 0, rowsEnd: rows)

API

ProtocolNumKongHammingA type that can compute SIMD-accelerated Hamming distances over bit sets.2
Scalar.swift:810 ↗
protocol NumKongHamming

Conforming types

HammingOutputThe type the Hamming distance is returned in.
Scalar.swift:812 ↗
associatedtype HammingOutput
hammingComputes the Hamming distance between two bit sets.
Scalar.swift:820 ↗
static func hamming<A, B>(
    _ a: A,
    _ b: B
) -> HammingOutput? where Self == A.Element, A : Sequence, B : Sequence, A.Element == B.Element

Parameters

aThe first bit set.
bThe second bit set, as long as a.

Returns

The number of differing bits, or nil if the sequences are empty, differ in length, or the kernel reports an error.
ProtocolNumKongJaccardA type that can compute SIMD-accelerated Jaccard distances over bit sets.2
Scalar.swift:825 ↗
protocol NumKongJaccard

Conforming types

JaccardOutputThe type the Jaccard distance is returned in.
Scalar.swift:827 ↗
associatedtype JaccardOutput
jaccardComputes the Jaccard distance between two bit sets.
Scalar.swift:835 ↗
static func jaccard<A, B>(
    _ a: A,
    _ b: B
) -> JaccardOutput? where Self == A.Element, A : Sequence, B : Sequence, A.Element == B.Element

Parameters

aThe first bit set.
bThe second bit set, as long as a.

Returns

The Jaccard distance, or nil if the sequences are empty, differ in length, or the kernel reports an error.