distances

Distances is a high performance Nim library for calculating distances.

Pure Nim score 15/100 · tests present · no docs generated

Summary

Latest Version Unknown
License Apache-2.0 License
CI Status Failing
Downloads 0
Last Indexed 2026-07-21 05:24

Installation

nimble install distances
choosenim install distances
git clone https://github.com/ayman-albaz/distances

OS Compatibility

Platform Linux macOS Windows FreeBSD OpenBSD NetBSD Android iOS WASM Embedded
distances - - - - - - -

Source

Repository https://github.com/ayman-albaz/distances
Homepage https://github.com/ayman-albaz/distances
Registry Source nimble_official

README

Linux Build Status (Github Actions) License

Distances

Distances is a high performance Nim library for calculating distances.

This library is designed to allow users to calculate common distance metrics using pure Nim sequences.

Supported Distance Metrics

Current supported distance metrics include:

Distance Command Normalized Variant
Hamming hammingDistance(x1, x2) normalizedHammingDistance(x1, x2)
Euclidean euclideanDistance(x1, x2) normalizedEuclideanDistance(x1, x2)
Squared Euclidean squaredEuclideanDistance(x1, x2) normalizedSquaredEuclideanDistance(x1, x2)
City Block cityblockDistance(x1, x2) normalizedCityblockDistance(x1, x2)
Total Variation totalVariationDistance(x1, x2) normalizedTotalVariationDistance(x1, x2)
Jaccard jaccardDistance(x1, x2)
Cosine cosineDistance(x1, x2)
KL Divergence klDivergenceDistance(x1, x2)

Normalized Distances

For metrics that support it, a normalized variant divides the raw distance by the vector length (n). This scales the result to the range [0, 1] (or similar, depending on the metric). The normalized variants are provided as separate functions (e.g., normalizedEuclideanDistance).

Edge Cases

  • Cosine distance returns NaN if either input vector has zero magnitude, since cosine similarity is undefined in that case.
  • KL divergence returns NaN if any element is negative (invalid probability distribution) and Inf if x1[k] > 0 while x2[k] == 0.
  • Jaccard distance returns 0.0 when both inputs contain only zeros (convention for empty sets).
  • All distances return 0.0 for empty arrays of equal length.

Examples

Calculating Cosine Distance

Note: All computations are done row-wise.

import sequtils
import distances

let
    num_rows = 100
    num_cols = 100
    input_seq_int = newSeq[int](num_cols)
    input_seq_seq_int = newSeqWith(num_rows, newSeq[int](num_cols))

# 1D distance
echo cosineDistance(input_seq_int, input_seq_int)

# 2D distance (Pairwise)
echo pairwise(input_seq_seq_int, cosineDistance)

Normalization

Use the dedicated normalized functions when you need length-normalized results:

import distances

discard normalizedEuclideanDistance(@[0.0, 0.0], @[3.0, 4.0])
discard pairwise(@[@[0.0, 0.0], @[3.0, 4.0]], normalizedEuclideanDistance)

Symmetry

The pairwise proc computes only the lower-left triangle (including the diagonal) to save time. To obtain a full symmetric matrix, use symmetrize with the SymmetrizeDir enum.

import distances

discard symmetrize(X, sdLowerToUpper)  # Copy lower triangle to upper triangle
discard symmetrize(X, sdUpperToLower)  # Copy upper triangle to lower triangle

Working with arrays and other sequences

All 1D distance functions accept openArray[T], so they work with seq, array, and string slices interchangeably:

let a = [1, 2, 3]
let b = [1, 3, 3]
echo hammingDistance(a, b)  # Works with arrays too

Performance

To get optimal performance, compile with --d:release or --d:danger: - --d:release -> ~100x pairwise speedup - --d:danger -> ~120x pairwise speedup

TODO

  • Add more distance metrics
  • Add support for distance metrics with more than 2 arguments

Performance, feature, and documentation PR's are always welcome.

Contact

I can be reached at aymanalbaz98@gmail.com