Pure Elixir vector packing/unpacking for dense and sparse vector types.
Converts between Elixir lists and native-endian binary representations used by zvec. Supports fp16, fp32, fp64, int4, int8, int16, binary32, and binary64 dense vector types, as well as sparse_fp16 and sparse_fp32 sparse vector types.
Dense Example
iex> vector = Zvex.Vector.from_list([1.0, 2.0, 3.0], :fp32)
iex> Zvex.Vector.to_list(vector)
[1.0, 2.0, 3.0]
iex> Zvex.Vector.dimension(vector)
3Sparse Example
iex> vector = Zvex.Vector.from_sparse([0, 5, 10], [1.0, 2.5, -3.0], :sparse_fp32)
iex> Zvex.Vector.to_sparse(vector)
{[0, 5, 10], [1.0, 2.5, -3.0]}
iex> Zvex.Vector.sparse?(vector)
true
Summary
Types
Shorthand alias used in from_list/2, from_binary/2, and from_sparse/3.
Full vector type atom as stored in the struct and in document fields.
Functions
Returns the number of elements (dimension) in a dense vector.
Wraps a pre-packed binary as a dense vector of the given type.
Packs a list of numbers into a dense vector binary.
Creates a sparse vector from index and value lists.
Returns the number of non-zero elements in a sparse vector.
Returns true if the vector is a sparse type.
Unpacks a dense vector back to a list of numbers.
Unpacks a sparse vector back to {indices, values}.
Types
@type shorthand() ::
:fp16
| :fp32
| :fp64
| :int4
| :int8
| :int16
| :binary32
| :binary64
| :sparse_fp16
| :sparse_fp32
Shorthand alias used in from_list/2, from_binary/2, and from_sparse/3.
Each shorthand maps to a full type (e.g. :fp32 -> :vector_fp32,
:sparse_fp32 -> :sparse_vector_fp32).
@type type() ::
:vector_fp16
| :vector_fp32
| :vector_fp64
| :vector_int4
| :vector_int8
| :vector_int16
| :vector_binary32
| :vector_binary64
| :sparse_vector_fp16
| :sparse_vector_fp32
Full vector type atom as stored in the struct and in document fields.
Functions
@spec dimension(t()) :: non_neg_integer() | nil
Returns the number of elements (dimension) in a dense vector.
Returns nil for sparse vectors, since sparse vectors don't have a fixed
dimension. Use nnz/1 to get the number of non-zero entries instead.
Wraps a pre-packed binary as a dense vector of the given type.
No validation is performed on the binary contents — it is assumed to already be in the correct native-endian format for the given type.
Packs a list of numbers into a dense vector binary.
The type is a shorthand atom (e.g. :fp32, :int8). Sparse shorthands
are not accepted — use from_sparse/3 instead.
Examples
iex> vec = Zvex.Vector.from_list([1.0, 2.0, 3.0], :fp32)
iex> Zvex.Vector.dimension(vec)
3
@spec from_sparse([non_neg_integer()], [number()], type() | shorthand()) :: t()
Creates a sparse vector from index and value lists.
The type must be either :sparse_fp32 or :sparse_fp16.
Indices must be non-negative, sorted in ascending order, with no duplicates.
The indices and values lists must have the same length.
The binary layout is [nnz::uint64-little][indices::uint32-little * nnz][values::type * nnz].
@spec nnz(t()) :: non_neg_integer()
Returns the number of non-zero elements in a sparse vector.
Raises ArgumentError for dense vectors.
Returns true if the vector is a sparse type.
Unpacks a dense vector back to a list of numbers.
For fp16 vectors, special IEEE 754 values may appear as :infinity,
:neg_infinity, or :nan. Sparse vectors are not supported — use
to_sparse/1 instead.
@spec to_sparse(t()) :: {[non_neg_integer()], [number()]}
Unpacks a sparse vector back to {indices, values}.
Raises ArgumentError if the vector is not a sparse type.