viva_math/matrix_dense
Dense matrix backed by BitArray (binary row-major).
Counterpart to viva_math/matrix.MatN. Where MatN stores rows as
nested List(Float), DenseMat keeps a single contiguous binary
buffer with one IEEE-754 little-endian double per element. This:
- Saves memory: 8 bytes/element vs ~24 bytes/element for cons-cell lists on 64-bit BEAM.
- Speeds up indexed access: O(1) random read of any cell via
byte_offset = (row · cols + col) · 8. - Avoids list reversal:
transposeandmatmulrebuild a binary instead of allocating thousands of cons cells.
Scope
Suitable for matrices up to a few thousand rows × cols. For tensor-scale
work (batched GEMM, GPU acceleration) defer to viva_tensor. This
module is the middle ground between the trivially-correct MatN and
the heavy viva_tensor.
Limitations
- Float-only (
Float↔ 64-bit IEEE 754 little-endian). - Sequential algorithms (no parallelism, no SIMD).
- Conversion to/from
MatNavailable for interop.
Types
Row-major dense matrix backed by a BitArray of 64-bit little-endian
floats (8 bytes per cell). Shape invariant: byte_size(data) = rows·cols·8.
Opaque to prevent direct construction with a data blob whose size does
not match the declared shape. Use zeros, identity, or from_list to
build a DenseMat and the rows, cols, byte_size accessors to query
its shape.
pub opaque type DenseMat
Values
pub fn add(a: DenseMat, b: DenseMat) -> Result(DenseMat, Nil)
Element-wise add. Errors on shape mismatch.
pub fn byte_size(m: DenseMat) -> Int
Number of bytes consumed by the data buffer. Useful for benchmarking.
pub fn from_list(
rows: Int,
cols: Int,
values: List(Float),
) -> Result(DenseMat, Nil)
Build from row-major list of values. Errors if shape doesn’t match.
pub fn get(m: DenseMat, row: Int, col: Int) -> Result(Float, Nil)
Random-access read in O(1). Errors on out-of-bounds.
pub fn hadamard(
a: DenseMat,
b: DenseMat,
) -> Result(DenseMat, Nil)
Element-wise Hadamard product.
pub fn mul(a: DenseMat, b: DenseMat) -> Result(DenseMat, Nil)
Matrix product A · B. Errors on shape mismatch.
Naïve triple-loop O(n³). For larger matrices defer to viva_tensor which
dispatches to BLAS / cuBLAS.
pub fn row(m: DenseMat, row_idx: Int) -> Result(List(Float), Nil)
Get an entire row as a list.
pub fn to_rows(m: DenseMat) -> List(List(Float))
Convert to nested-list representation for interop with MatN.