ann_router.backends.exact module

Exact brute-force backend — the always-available reference implementation.

Pure numpy: no optional dependency, so ExactIndex is the one backend that is always usable and doubles as the ground truth the router’s recall tests score every approximate engine against. For a corpus under a few tens of thousands of vectors a vectorised full scan is already sub-millisecond and, being exact, has recall 1.0 by construction — which is exactly why the policy routes small problems here instead of paying an index-build cost for nothing.

Consumes: ann_router.base (the ANNIndex contract), numpy. Produces: ExactIndex.

Author: Warith Harchaoui <warith.harchaoui@deraison.ai>

class ann_router.backends.exact.ExactIndex(dim, metric='cosine', **kwargs)[source]

Bases: ANNIndex

Exact k-NN by full matrix multiplication over the stored corpus.

The corpus is kept as a contiguous float32 matrix; for cosine/inner-product metrics search is a single queries @ corpus.T followed by a top-k partition, and for L2 it is the standard ||q||^2 - 2 q·x + ||x||^2 expansion. All operations are exact, so this class defines “truth” for the recall benchmarks.

Parameters:
  • dim (int) – Embedding dimensionality.

  • metric ({"cosine", "l2", "ip"}, optional) – Distance metric. Defaults to "cosine".

  • kwargs (object)

Examples

>>> rng = np.random.default_rng(0)
>>> vecs = rng.standard_normal((100, 16)).astype(np.float32)
>>> idx = ExactIndex(dim=16).build(vecs)
>>> ids, dists = idx.search(vecs[:1], k=1)
>>> int(ids[0, 0])              # nearest neighbour of a point is itself
0
add(vectors)[source]

Append vectors with the next contiguous ids.

Parameters:

vectors (numpy.ndarray) – Shape (m, dim).

Return type:

None

Examples

>>> idx = ExactIndex(dim=4).build(np.ones((2, 4), dtype=np.float32))
>>> idx.add(np.ones((3, 4), dtype=np.float32))
>>> idx.size
5
add_with_ids(vectors, ids)[source]

Append vectors with explicit ids.

Parameters:
  • vectors (numpy.ndarray) – Shape (m, dim).

  • ids (numpy.ndarray) – Shape (m,).

Return type:

None

Examples

>>> idx = ExactIndex(dim=4).build(np.ones((2, 4), dtype=np.float32))
>>> idx.add_with_ids(np.zeros((1, 4), dtype=np.float32), np.array([99]))
>>> idx.size
3
build(vectors, ids=None)[source]

Store the initial corpus.

Parameters:
  • vectors (numpy.ndarray) – Shape (n, dim).

  • ids (numpy.ndarray, optional) – Shape (n,); defaults to range(n).

Returns:

self.

Return type:

ExactIndex

Examples

>>> idx = ExactIndex(dim=4).build(np.ones((5, 4), dtype=np.float32))
>>> idx.search(np.ones((1, 4), dtype=np.float32), k=3)[0].shape
(1, 3)
classmethod capabilities()[source]

Return the exact backend’s capability descriptor.

Returns:

Exact, mutable, in-memory, no GPU, no metadata filter.

Return type:

Capabilities

Examples

>>> ExactIndex.capabilities().approximate
False
classmethod is_available()[source]

Return True — numpy is a core dependency, so exact always works.

Returns:

Always True.

Return type:

bool

Examples

>>> ExactIndex.is_available()
True
load(path)[source]

Load a corpus previously written by save().

Parameters:

path (str) – Source .npz path.

Returns:

self, populated from disk.

Return type:

ExactIndex

remove(ids)[source]

Delete vectors by id (true deletion — the rows are dropped).

Parameters:

ids (numpy.ndarray) – Ids to remove.

Return type:

None

Examples

>>> idx = ExactIndex(dim=4).build(np.ones((3, 4), dtype=np.float32))
>>> idx.remove(np.array([1]))
>>> idx.size
2
save(path)[source]

Persist the corpus and ids to a .npz file.

Parameters:

path (str) – Destination path (.npz appended by numpy if absent).

Return type:

None

Examples

>>> import tempfile, os
>>> idx = ExactIndex(dim=4).build(np.ones((3, 4), dtype=np.float32))
>>> p = os.path.join(tempfile.mkdtemp(), "exact.npz")
>>> idx.save(p); os.path.exists(p) or os.path.exists(p + ".npz")
True
search(queries, k)[source]

Return exact top-k neighbours per query.

Parameters:
  • queries (numpy.ndarray) – Shape (q, dim).

  • k (int) – Neighbours per query.

Returns:

  • ids (numpy.ndarray) – Shape (q, k) neighbour ids (-1 where fewer than k exist).

  • distances (numpy.ndarray) – Shape (q, k) distances (similarity for cosine/ip, euclidean^2 for l2).

Return type:

tuple[ndarray, ndarray]

Examples

>>> rng = np.random.default_rng(1)
>>> vecs = rng.standard_normal((50, 8)).astype(np.float32)
>>> ids, _ = ExactIndex(dim=8).build(vecs).search(vecs[:3], k=5)
>>> ids.shape
(3, 5)
property size: int

Number of vectors currently stored.

Examples

>>> ExactIndex(dim=4).build(np.ones((7, 4), dtype=np.float32)).size
7