# Linear Algebra

> USearch for Rust

### Sparse Multiplication

`multiply`, `maxsim` and `attend` treat the index as a sparse operand rather than as a kNN store, and each folds its arithmetic into the graph walk instead of materializing a match list.
All three need logits rather than distances, so they run on an inner-product index alone.

`multiply` is a sparse matrix product: every left row is walked against the index, and every pair the walk scored lands in an arena as one ragged run, in traversal order.
`wanted` keeps the first pairs of each row, where zero keeps every pair, and `required` counts how many there were.
The run's Apache Arrow offsets land in the arena beside the keys and products.

```rust
let mut arena = Arena::new_in(&executor)?;
let products = index.on(&executor).multiply(&rows(&left, 768)?, 32, &mut arena)?;
for row in products.iter()? {
    println!("{} pairs", row.keys.len());
}
```

### Late Interaction

`maxsim` is late interaction - every query row takes its best match within a key, and those maxima sum to that key's score.
A document is one key holding its token rows, which is what a `values_per_key` above one exists for, and the wanted count is over documents rather than rows.
Each query lands its best documents, largest score first, in the same ragged `DenseProducts` run `multiply` returns, and a `wanted` of zero keeps every document the query scored.

```rust
let documents = index.on(&executor).maxsim(&rows(&tokens, 768)?, tokens_per_query, 10, &mut arena)?;
for query in documents.iter()? {
    println!("best {:?} of {} documents", query.keys.first(), query.keys.len());
}
```

### Attention

`attend` is Flash Attention folded into the walk: every key it scores folds into each head's running maximum, partition and weighted value sum, with no top-k cut, and the outputs land in an arena already divided by the partition, as rows of the queries' own scalar type.
The index stores no values, so a `ValueLookup` closure resolves every scored key to its value row, as wide as the keys, stored in the index's own quantization, and borrowed from storage outliving the call.
A `None` row, or rows of another scalar type or width than the library reads, refuses the call with `Status::ShapeMismatch`.
It runs on the executor's threads together, hence `Sync`, and a panic inside it refuses the call.
A VRAM walk resolves values on the device, where no Rust closure runs, so an arena from a VRAM executor is refused with `Status::Device`.
With a `head_count` of 8, row `t * 8 + h` of the queries is head `h` of token `t`, and the heads of one token share its walk.
A `carry` of one `DenseSoftmaxState` per query row, lent by you, folds this branch into another over the same queries, such as a recent window kept out of the index.
`score_scale` is conventionally the inverse square root of the head width, and zero derives it from the frozen geometry.

```rust
let value_lookup: &ValueLookup<bf16> = &|key| cache.get(&key).map(Vec::as_slice);
let mut carry = vec![DenseSoftmaxState::default(); queries_count];
let context = index.on(&executor).attend(&rows(&queries, 128)?, value_lookup, DenseAttendConfig {
    carry: Some(&mut carry),
    ..DenseAttendConfig::from(8)
}, &mut arena)?;
println!("{:?}", context.view()?.shape());
```

`use usearch::DenseAttendConfig;`

`use usearch::DenseMaxsimConfig;`

`use usearch::DenseMultiplyConfig;`

`use usearch::DenseProducts;`

`use usearch::DenseSoftmaxState;`

`use usearch::*;`

## ValueLookup

An attention's value lookup, run on the executor's threads together: it resolves one key to its value row, stored in the index's own quantization and borrowed from storage outliving the call, and `None` refuses the call, as a panic does before it resurfaces once the call is final.

```rust
pub type ValueLookup<'lookup, Value> = dyn Fn(Key) -> Option<&'lookup [Value]> + Sync + 'lookup;
```

## DenseAttendConfig

The heads, carry and knobs of an attention's walk; see [`DenseVerbs::attend`](https://www.unum.cloud/docs/usearch/rust/metrics.md#attend).

```rust
pub struct DenseAttendConfig<'config>
```

- `head_count` `usize`: The query heads sharing the index's key-value head, and with it one walk per token: row
`t · head_count + h` is head `h` of token `t`, so it must divide the rows; zero means one.
- `carry` `Option<&'config mut [DenseSoftmaxState]>`: Where the online-softmax state lands, one entry per query row, which folds this call into
another over the same queries by partial-softmax rescaling.
- `expansion_factor` `usize`: The breadth of the candidates; zero derives it. Wider candidates walk further, folding more of the
tail.
- `score_scale` `f32`: The logit scale, conventionally the inverse square root of the head dimensionality; zero
derives it from the index's frozen geometry.
- `progress` `Option<&'config mut ProgressCallback<'config>>`: Reports the queries resolved and stops wherever it says to.
- `progress_steps` `usize`: Reports the call makes at most, the last at completion; zero derives to ten.
- `stats` `Option<&'config mut DenseTraversalStats>`: Where the traversal telemetry lands, overwritten by the call.

Implements: `From<usize>`

## DenseMaxsimConfig

The documents a late-interaction search keeps and the knobs of its walk; see [`DenseVerbs::maxsim`](https://www.unum.cloud/docs/usearch/rust/metrics.md#maxsim).

```rust
pub struct DenseMaxsimConfig<'config>
```

- `wanted` `usize`: Documents kept per query, counted over keys rather than entries; zero keeps every key the
query scored.
- `expansion_factor` `usize`: The breadth of the candidates the walk explores; zero derives it from the geometry.
- `progress` `Option<&'config mut ProgressCallback<'config>>`: Reports the queries resolved and stops wherever it says to.
- `progress_steps` `usize`: Reports the call makes at most, the last at completion; zero derives to ten.
- `stats` `Option<&'config mut DenseTraversalStats>`: Where the traversal telemetry lands, overwritten by the call.

Implements: `From<usize>`

## DenseMultiplyConfig

The pairs a sparse product keeps and the knobs of its walk; see [`DenseVerbs::multiply`](https://www.unum.cloud/docs/usearch/rust/metrics.md#multiply).

```rust
pub struct DenseMultiplyConfig<'config>
```

- `wanted` `usize`: Keeps the first `wanted` pairs each row's walk scored; zero keeps every pair.
- `expansion_factor` `usize`: The breadth of the candidates, which widens the emitted pattern; zero derives it.
- `progress` `Option<&'config mut ProgressCallback<'config>>`: Reports the rows resolved and stops wherever it says to.
- `progress_steps` `usize`: Reports the call makes at most, the last at completion; zero derives to ten.
- `stats` `Option<&'config mut DenseTraversalStats>`: Where the traversal telemetry lands, overwritten by the call.

Implements: `From<usize>`

## DenseProducts

The ragged run [`DenseVerbs::multiply`](https://www.unum.cloud/docs/usearch/rust/metrics.md#multiply) or [`DenseVerbs::maxsim`](https://www.unum.cloud/docs/usearch/rust/metrics.md#maxsim) exported into the arena it borrows: per left row, every pair its walk scored, in traversal order, or per query, its kept keys, largest score first.

```rust
pub struct DenseProducts<'arena>
```

## queries

Left rows the call multiplied, or queries it scored.

```rust
pub fn queries(&self) -> usize
```

## required

Pairs the walks scored across every left row, or keys scored across every query, before the wanted bound cut any.

```rust
pub fn required(&self) -> usize
```

## query

The pairs of one left row, a key naming each indexed entry beside its product, or the keys of one query beside their summed maxima, refused with [`Status::InvalidArgument`](https://www.unum.cloud/docs/usearch/rust/errors.md#InvalidArgument) when [`query`](#query) is not below [`DenseProducts::queries`](#queries) and with [`Status::Device`](https://www.unum.cloud/docs/usearch/rust/errors.md#Device) over device memory.

```rust
pub fn query(&self, query: usize) -> Result<QueryMatches<'arena>>
```

## iter

Every query's pairs or keys, in query order, refused with [`Status::Device`](https://www.unum.cloud/docs/usearch/rust/errors.md#Device) over device memory.

```rust
pub fn iter(&self) -> Result<impl Iterator<Item = QueryMatches<'arena>>>
```

## DenseSoftmaxState

The online-softmax carry of one query row, which folds one attention call into another over the same queries.

```rust
pub struct DenseSoftmaxState
```

- `maximum_score` `f32`: The largest logit seen so far - the recurrence's `m`.
- `partition` `f32`: The sum of exponentials taken against that maximum - the recurrence's `l`.

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Debug`, `Default`

