# SIMD, parallel, and sparse math

> Use Alice runtime numerical kernels, explicit parallel helpers, and sparse storage.

Canonical: https://alice-lang.org/documentation/library/numerics/

[Documentation index](https://alice-lang.org/documentation/llms.txt) · [Complete book](https://alice-lang.org/llms-full.txt)

## Start with ordinary arrays

Simple numeric pipelines can already lower to fused, vectorized loops. Begin with readable code and inspect the result before selecting an explicit runtime kernel.

```alice
xs = [1.0, 2.0, 3.0, 4.0]
val scale = 2.0
puts xs.map { |x| x * scale }.select { |x| x > 4.0 }.sum
```

Expected output:

```text
14
```

[Edit and run in the Alice playground](https://playground.alice-lang.org/#code=u.eHMgPSBbMS4wLCAyLjAsIDMuMCwgNC4wXQp2YWwgc2NhbGUgPSAyLjAKcHV0cyB4cy5tYXAgeyB8eHwgeCAqIHNjYWxlIH0uc2VsZWN0IHsgfHh8IHggPiA0LjAgfS5zdW0)

The example is small enough to understand by hand: the scaled values are 2, 4, 6, and 8; keeping values above 4 leaves 6 and 8, whose sum is 14.

## SIMD kernels

`Simd` supplies `Sum`, `Dot`, `Add`, `Multiply`, `Scale`, `Min`, and `Max`. Numeric kernels use `System.Numerics.Vector(T)` where available, with scalar handling for remainders. Their .NET signatures use arrays or spans as appropriate; buffers participating in element-wise operations must have matching lengths.

Use output buffers when an operation writes a result, and avoid overlapping inputs and outputs unless the operation's contract permits it. SIMD width and hardware support vary by host.

## AMath

| Kernel                           | Meaning                                             |
| -------------------------------- | --------------------------------------------------- |
| `AMath.Clamp`                    | Bound a numeric value                               |
| `AMath.Lerp`                     | Interpolate between floating-point values           |
| `AMath.Mean`                     | Arithmetic mean; empty input throws                 |
| `AMath.Variance`                 | Population variance                                 |
| `AMath.Norm`                     | Euclidean norm of a double span                     |
| `AMath.Axpy`                     | Update `y += alpha * x`                             |
| `AMath.MatMul(a, b, c, n, k, m)` | Row-major matrix product `C[n×m] = A[n×k] × B[k×m]` |

`MatMul` requires buffer lengths `n*k`, `k*m`, and `n*m`, respectively. Incorrect dimensions are rejected. Its implementation uses blocked work and parallelism for sufficiently large inputs. Select floating-point types for a mean or variance when integer truncation would be wrong.

## Explicit parallel helpers

`Par.For`, `Par.Map`, and `Par.Sum` expose parallel work. They still need safe bodies: no unsynchronized captured mutations. For many algorithms, the ordinary iterator form is clearer and lets the compiler choose an eligible optimized path. See [race safety](https://alice-lang.org/documentation/concurrency/race-safety.md).

## Matrix multiplication

```alice
a = [1.0, 2.0, 3.0, 4.0]
b = [5.0, 6.0, 7.0, 8.0]
c = Array(Float64).new(4)
AMath.MatMul(a, b, c, 2, 2, 2)
puts c.join(",")
```

Expected output:

```text
19,22,43,50
```

[Edit and run in the Alice playground](https://playground.alice-lang.org/#code=u.YSA9IFsxLjAsIDIuMCwgMy4wLCA0LjBdCmIgPSBbNS4wLCA2LjAsIDcuMCwgOC4wXQpjID0gQXJyYXkoRmxvYXQ2NCkubmV3KDQpCkFNYXRoLk1hdE11bChhLCBiLCBjLCAyLCAyLCAyKQpwdXRzIGMuam9pbigiLCIp)

The buffers hold two 2×2 matrices in row-major order. The output is `[19, 22, 43, 50]`. `c` is supplied by the caller and overwritten with the product, so it can be reused for later operations when the inputs and output do not overlap.

## Sparse data

`CsrMatrix(T)` stores compressed sparse rows and `SparseVector(T)` stores sparse vector data. These are useful when most entries are zero and dense storage would waste space.

| Type/member                                       | Contract                                                                         |
| ------------------------------------------------- | -------------------------------------------------------------------------------- |
| `CsrMatrix(T).FromDense(matrix)`                  | Build from a CLR rectangular two-dimensional array.                              |
| `CsrMatrix(T).FromTriplets(rows, cols, entries)`  | Build from `(row, column, value)` entries; sort, sum duplicates, and drop zeros. |
| `matrix.Rows`, `Columns`, `NonZeros`              | Logical dimensions and stored nonzero count.                                     |
| `matrix[row, col]`                                | Read an entry; absent stored entries are zero.                                   |
| `matrix.Multiply(x, y, parallel)`                 | Write `A*x` into `y`; `x` length must be Columns, `y` length Rows.               |
| `RowPointers`, `ColumnIndices`, `Values`          | Read-only CSR views with zero-based indices.                                     |
| `SparseVector(T).FromDense(values)`               | Build a sparse vector from a dense span.                                         |
| `vector.Length`, `NonZeros`, `Indices`, `Values`  | Logical length and read-only sparse views.                                       |
| `vector.Dot(dense)` or `vector.Dot(other_sparse)` | Dot product; logical lengths must match.                                         |

Triplet coordinates outside the dimensions are rejected. `Multiply` uses a serial path for smaller matrices even when parallel work is requested. Avoid overlapping input/output buffers during multiplication.

The runtime source is the detailed API contract for these specialized types: [Simd](https://github.com/alicelanguage/alice/blob/main/src/Alice.Runtime/Simd/Simd.cs), [AMath](https://github.com/alicelanguage/alice/blob/main/src/Alice.Runtime/Math/AMath.cs), and [sparse kernels](https://github.com/alicelanguage/alice/tree/main/src/Alice.Runtime/Sparse).

For column-oriented simulation records, see [SoA storage](https://alice-lang.org/documentation/language/records.md#structure-of-arrays-records).

## Continue reading

- Previous: [Console, files, JSON, and environment](https://alice-lang.org/documentation/library/io.md)
- Next: [Tasks, spawn, and async](https://alice-lang.org/documentation/concurrency/tasks.md)
