Wolfram · Linear Algebra

Linear Algebra

Needs["USearch`"] 3.0.0-rc.1 · 4c3e5023

§ Sparse Multiplication

DenseMultiply[receiver, left, arena] runs on the inner metric and answers <|"Offsets"->…, "Keys"->…, "Scores"->…, "Required"->…|>. Row i of the left matrix owns pairs offsets[[i]] + 1 through offsets[[i + 1]], in traversal order, and "Required" counts the pairs scored. "Wanted"->n keeps at most that many pairs per left row, zero keeping every pair the walk scored. Any other metric fails as config-mismatch.

Pass an ordered list of column keys to get a Wolfram SparseArray:

products = DenseMultiply[index, left, {42, 41}, arena];
products . right

Column 1 names key 42 & column 2 names key 41, including full-width UUID keys. Each stored product is a dot product against a quantized indexed vector; unvisited entries are zero, so this approximates a dense product rather than multiplying arbitrary sparse inputs exactly. Column keys must be unique & cover every returned key; repeated keys within a product row are refused because they cannot identify distinct matrix columns. "Wanted" truncates traversal order, rather than selecting the largest products. The original three-argument form keeps the offsets & keys, which identify the computed entries even when a computed score is zero.

§ Late Interaction

DenseMaxsim[receiver, queries, rowsPerQuery, wanted, arena] scores multi-row queries late-interaction style, answering <|"Offsets"->…, "Keys"->…, "Scores"->…, "Required"->…|> as DenseMultiply does. Query i owns keys offsets[[i]] + 1 through offsets[[i + 1]], largest summed maxima first, and "Required" counts the keys scored before wanted cut any. wanted keeps at most that many keys per query, zero keeping every key a query scored. The token rows of every query are laid end to end, so their number divides by rowsPerQuery.

§ Folded Attention

Prepare values once in the index’s quantization, then reuse them across attention calls:

values = DenseValues[index, {41, 42}, NumericArray[valueRows, "Real32"]];
attention = DenseAttend[index, queryRows, values, arena,
    "HeadCount"->2, "ExpansionFactor"->64, "ScoreScale"->0.1];
attention["Outputs"]
attention["Carry"]

DenseValues stores sorted 128-bit keys & quantized rows in kernel-owned NumericArray buffers. Values have the same width as the indexed keys, with one value row per unique key; every key the walk scores needs a value. Native worker threads look up those immutable rows directly, without entering the evaluator. This cache serves RAM & NVMe attention; device value lookup is not exposed here.

DenseAttend folds every scored key-value pair into online softmax, including candidates rejected by the nearest-neighbor candidates. It requires the inner metric, as DenseMultiply does. "HeadCount" consecutive query rows share one key-value head & graph walk; it must divide the number of query rows. Zero means one head. "ScoreScale"->0. derives the usual inverse square root of the dimension. The answer contains "Outputs", one real row per query head, & "Carry", one {maximumLogit, partition} row per head. The partition is the sum of exponentials relative to that maximum, over the scored subset. Native folding accumulates in f32; the binding exports real tensors as f64. Outputs & carry are copied before the Arena is reused.

API

Functions

DenseMaxsimDenseMaxsim[receiver, queries, rowsPerQuery, wanted, arena] scores queries of rowsPerQuery rows against multi-row entries: every query row takes its best match within a key, and those maxima sum to the key's score, keeping up to wanted keys per query.
USearch.wl:42 ↗
DenseMaxsim[receiver, queries, rowsPerQuery, wanted, arena, OptionsPattern[]]

"ExpansionFactor" sets the breadth of the candidates the walk explores, 0 deriving it.

Parameters

"ExpansionFactor"Default: 0
DenseMultiplyDenseMultiply[receiver, left, arena] approximates the sparse product of the rows of left with the indexed vectors, answering every pair the walk scored as "Offsets", "Keys" and "Scores"; DenseMultiply[receiver, left, columnKeys, arena] lays the same products out as a SparseArray with one column per key of columnKeys.
USearch.wl:48 ↗
DenseMultiply[receiver, left, arena, OptionsPattern[]]
DenseMultiply[receiver, left, columnKeys, arena, OptionsPattern[]]

DenseMultiply[receiver, left, columnKeys, arena] lays the same products out as a SparseArray with one column per key of columnKeys. "Wanted" bounds the pairs kept per row, the first ones its walk scored, 0 keeping every pair, and "ExpansionFactor" sets the breadth of the candidates, which widens the pattern, 0 deriving it.

"Wanted" bounds the pairs kept per row, the first ones its walk scored, 0 keeping every pair, and "ExpansionFactor" sets the breadth of the candidates, which widens the pattern, 0 deriving it.

Parameters

"Wanted"Default: 0
"ExpansionFactor"Default: 0
DenseAttendDenseAttend[receiver, queries, values, arena] folds softmax attention of the query heads over every key their graph walks score, reading each key's row from values, a DenseValues.
USearch.wl:50 ↗
DenseAttend[receiver, queries, values, arena, OptionsPattern[]]

"HeadCount" is how many query heads share one walk per token, dividing the query count; "ExpansionFactor" sets the breadth of the candidates the walk explores, 0 deriving it; and "ScoreScale" is the logit scale, conventionally the inverse square root of the head dimensionality, 0. deriving it from the index's geometry.

Parameters

"HeadCount"Default: 1
"ExpansionFactor"Default: 0
"ScoreScale"Default: 0.