lacuna.sparse#

class lacuna.sparse.COO(row, col, data, shape, dtype=<class 'numpy.float64'>, check=True)[source]#

Bases: SparseArray

Coordinate (COO) sparse matrix.

Parameters:
  • row (array_like of int64) – Row indices for nonzero entries, length nnz.

  • col (array_like of int64) – Column indices for nonzero entries, length nnz.

  • data (array_like of float64) – Nonzero values, length nnz.

  • shape (tuple of int) – Matrix shape (nrows, ncols).

  • dtype (numpy.dtype, optional) – Value dtype, defaults to np.float64.

  • check (bool, optional) – If True, validate invariants in the native layer (may be slower).

row, col, data

Storage arrays for indices and values.

Type:

numpy.ndarray

shape#

Matrix dimensions.

Type:

tuple[int, int]

dtype#

Value dtype.

Type:

numpy.dtype

nnz#

Number of stored elements (with duplicates allowed).

Type:

int

Notes

Backed by Rust kernels through lacuna._core.Coo64; operations release the GIL.

Examples

Construct a small COO and run basic ops:

>>> import numpy as np
>>> from lacuna.sparse import COO
>>> row = np.array([0, 1, 1])
>>> col = np.array([0, 0, 2])
>>> val = np.array([1.0, 2.0, 3.0])
>>> a = COO(row, col, val, shape=(2, 3))
>>> a.nnz
3
>>> (a @ np.array([1.0, 0.0, 1.0])).tolist()  # SpMV
[1.0, 3.0]
>>> a.sum()
6.0
property T#
eliminate_zeros()[source]#

Remove explicit zeros. Returns a new COO.

classmethod from_arrays(row, col, data, shape, check=True)[source]#

Construct from index/value arrays.

Parameters:
  • row (array_like) – Coordinate indices and values.

  • col (array_like) – Coordinate indices and values.

  • data (array_like) – Coordinate indices and values.

  • shape (tuple[int, int]) – Matrix shape.

  • check (bool, optional) – Validate invariants in the native layer.

property nnz#

Number of stored values (including duplicates).

prune(eps)[source]#

Drop entries with abs(value) <= eps.

Returns a new COO.

sum(axis=None)[source]#

Sum of entries.

Parameters:

axis ({None, 0, 1}, optional) – None for global sum; 0 for column sums; 1 for row sums.

toarray()[source]#

Convert to a dense NumPy ndarray of shape (nrows, ncols).

class lacuna.sparse.COOND(shape, indices, data, dtype=<class 'numpy.float64'>, check=True)[source]#

Bases: SparseArray

N-dimensional sparse array in COO format.

Parameters:
  • shape (tuple[int, ...]) – Overall tensor shape of length ndim.

  • indices (array_like of int64, shape (nnz * ndim,) or (nnz, ndim)) – Concatenated per-nnz indices or a 2D array; values must be within bounds of shape. Duplicates are allowed (aggregated by ops).

  • data (array_like of float64, shape (nnz,)) – Nonzero values.

  • dtype (numpy.dtype, optional) – Value dtype, defaults to np.float64.

  • check (bool, optional) – If True, validate invariants in the native layer where applicable.

shape#

Tensor dimensions.

Type:

tuple[int, …]

ndim#

Number of dimensions (len(shape)).

Type:

int

indices#

Flattened indices of length nnz * ndim.

Type:

numpy.ndarray (int64)

data#

Nonzero values of length nnz.

Type:

numpy.ndarray (float64)

nnz#

Number of stored elements.

Type:

int

Notes

Backed by Rust ND-COO kernels via lacuna._core. Operations release the GIL. Key operations include sum, mean, axis reductions/permutations, reshape, broadcasting Hadamard multiply, and unfolding to CSR/CSC.

Examples

Construct a small 3D tensor and run basic ops:

>>> import numpy as np
>>> from lacuna.sparse import COOND
>>> shape = (2, 3, 4)
>>> # 2 nonzeros at positions (0,1,2) and (1,2,3)
>>> idx = np.array([
...     0, 1, 2,
...     1, 2, 3,
... ], dtype=np.int64)
>>> val = np.array([1.0, 3.0])
>>> a = COOND(shape, idx, val)
>>> a.nnz
2
>>> a.sum()
4.0
>>> a.reduce_sum_axes([2]).shape  # sum over last axis
(2, 3)
>>> a.permute_axes([2, 1, 0]).shape
(4, 3, 2)
>>> b = a.reshape((3, 2, 4))
>>> (a.hadamard_broadcast(b)).nnz
2
>>> a.mode_unfold_to_csr(axis=0).shape
(2, 12)
axes_unfold_to_csc(row_axes)[source]#

Unfold by grouping selected axes as CSC rows (the rest become columns).

axes_unfold_to_csr(row_axes)[source]#

Unfold by grouping selected axes as CSR rows and the rest as columns.

Parameters:

row_axes (array_like of int) – Axes that form the row index in the unfolded matrix.

Returns:

A CSR matrix.

Return type:

CSR

classmethod from_arrays(shape, indices, data, check=True)[source]#

Construct COOND from raw arrays.

Parameters:
  • shape (tuple[int, ...]) – Tensor shape.

  • indices (array_like of int64) – Flattened or 2D indices (nnz x ndim).

  • data (array_like of float64) – Nonzero values.

  • check (bool, optional) – Validate invariants via native layer when possible.

hadamard_broadcast(other)[source]#

Elementwise product with broadcasting against another COOND.

Parameters:

other (COOND) – Right-hand operand.

Returns:

Result of broadcasting Hadamard multiplication.

Return type:

COOND

mean()[source]#

Mean of all entries (sum / total elements implied by shape).

mode_unfold_to_csc(axis)[source]#

Unfold along a single mode into a 2D CSC matrix.

Parameters:

axis (int) – Mode (axis) to place along the columns; remaining modes are flattened as rows.

Returns:

A CSC matrix of shape (prod(shape[~axis]), shape[axis]).

Return type:

CSC

mode_unfold_to_csr(axis)[source]#

Unfold along a single mode into a 2D CSR matrix.

Parameters:

axis (int) – Mode (axis) to place along the rows; remaining modes are flattened as columns.

Returns:

A CSR matrix of shape (shape[axis], prod(shape[~axis])).

Return type:

CSR

property nnz#

Number of stored values.

permute_axes(perm)[source]#

Permute axes by the given permutation.

Parameters:

perm (array_like of int) – A permutation of range(ndim).

Returns:

Tensor with permuted axes.

Return type:

COOND

reduce_mean_axes(axes)[source]#

Mean over specified axes.

Parameters:

axes (array_like of int) – Axes to average over.

Returns:

A new tensor with the given axes averaged out.

Return type:

COOND

reduce_sum_axes(axes)[source]#

Sum over specified axes.

Parameters:

axes (array_like of int) – Axes to reduce. Order-insensitive, must be valid axes of shape.

Returns:

A new tensor with the given axes summed out.

Return type:

COOND

reshape(new_shape)[source]#

Return a new tensor with the same data but a different shape.

Parameters:

new_shape (tuple[int, ...]) – Target shape; must be compatible with shape.

sum()[source]#

Sum of all entries.

Returns:

Total sum of nonzero values.

Return type:

float

class lacuna.sparse.CSC(indptr, indices, data, shape, dtype=<class 'numpy.float64'>, check=True)[source]#

Bases: SparseMatrix

Compressed Sparse Column (CSC) matrix.

Parameters:
  • indptr (array_like of int64, shape (ncols + 1,)) – Column pointer array.

  • indices (array_like of int64, shape (nnz,)) – Row indices of nonzero values.

  • data (array_like of float64, shape (nnz,)) – Nonzero values.

  • shape (tuple of int) – Matrix shape (nrows, ncols).

  • dtype (numpy.dtype, optional) – Value dtype, defaults to np.float64.

  • check (bool, optional) – If True, validate invariants in the native layer (may be slower).

indptr, indices, data

Storage arrays for CSC structure and values.

Type:

numpy.ndarray

shape#

Matrix dimensions.

Type:

tuple[int, int]

dtype#

Value dtype.

Type:

numpy.dtype

nnz#

Number of stored elements.

Type:

int

Notes

Backed by Rust kernels through lacuna._core.Csc64; operations release the GIL.

Examples

Construct a small CSC and run basic ops:

>>> import numpy as np
>>> from lacuna.sparse import CSC
>>> indptr = np.array([0, 1, 2, 3])
>>> indices = np.array([0, 1, 1])
>>> data = np.array([1.0, 2.0, 3.0])
>>> a = CSC(indptr, indices, data, shape=(2, 3))
>>> a.nnz
3
>>> (a @ np.array([1.0, 0.0, 1.0])).tolist()  # SpMV
[1.0, 3.0]
>>> a.sum()
6.0
property T#
eliminate_zeros()[source]#

Remove explicit zeros. Returns a new CSC.

classmethod from_arrays(indptr, indices, data, shape, check=True)[source]#

Construct from CSC arrays.

Parameters:
  • indptr (array_like) – CSC structure and values.

  • indices (array_like) – CSC structure and values.

  • data (array_like) – CSC structure and values.

  • shape (tuple[int, int]) – Matrix shape.

  • check (bool, optional) – Validate invariants in the native layer.

multiply(other)[source]#

Hadamard (elementwise) product with another CSC.

property nnz#

Number of stored values.

prune(eps)[source]#

Drop entries with abs(value) <= eps. Returns a new CSC.

sum(axis=None)[source]#

Sum of entries.

Parameters:

axis ({None, 0, 1}, optional) – None for global sum; 0 for column sums; 1 for row sums.

toarray()[source]#

Convert to a dense NumPy ndarray of shape (nrows, ncols).

class lacuna.sparse.CSR(indptr, indices, data, shape, dtype=<class 'numpy.float64'>, check=True)[source]#

Bases: SparseMatrix

Compressed Sparse Row (CSR) matrix.

Parameters:
  • indptr (array-like of int64, shape (n_rows + 1,)) – Row pointer array. Must be non-decreasing, start at 0, end at nnz.

  • indices (array-like of int64, shape (nnz,)) – Column indices for each non-zero. Must be strictly increasing within each row.

  • data (array-like of float64, shape (nnz,)) – Non-zero values.

  • shape (tuple[int, int]) – Matrix shape (n_rows, n_cols).

  • dtype (numpy.dtype, optional (default: np.float64)) – Data dtype (v0.1 supports float64 only).

  • check (bool, optional (default: True)) – When True, validate structural invariants using the Rust core.

Notes

The constructor may raise if the structure is invalid when check=True.

Examples

Construct a small CSR and run basic ops:

>>> import numpy as np
>>> from lacuna.sparse import CSR
>>> indptr = np.array([0, 2, 3])  # 2 rows, 3 nnz
>>> indices = np.array([0, 2, 1])
>>> data = np.array([1.0, 3.0, 2.0])
>>> a = CSR(indptr, indices, data, shape=(2, 3))
>>> a.nnz
3
>>> (a @ np.array([1.0, 0.0, 1.0])).tolist()  # SpMV
[4.0, 2.0]
>>> a.sum()
6.0
property T#

Transpose of the matrix (CSR).

Returns:

Transposed matrix as a new CSR instance.

Return type:

CSR

Raises:

RuntimeError – If the native core is not available.

astype(dtype)[source]#

Return a copy converted to the given dtype.

Parameters:

dtype (numpy.dtype or str) – Target dtype. v0.1 supports float64 only.

Returns:

A new CSR with data cast to the requested dtype.

Return type:

CSR

Raises:

NotImplementedError – If dtype is not float64 in v0.1.

eliminate_zeros()[source]#

Remove exact zeros from the matrix structure.

Returns:

New CSR with all zero entries removed.

Return type:

CSR

Raises:

RuntimeError – If the native core is not available.

classmethod from_arrays(indptr, indices, data, shape, check=True)[source]#

Construct a CSR from raw arrays.

Parameters:
  • indptr – See CSR.__init__.

  • indices – See CSR.__init__.

  • data – See CSR.__init__.

  • shape – See CSR.__init__.

  • check – See CSR.__init__.

Returns:

New CSR instance.

Return type:

CSR

multiply(other)[source]#
property nnz#

Number of stored non-zero entries (int).

prune(eps)[source]#

Remove entries with absolute value <= eps.

Parameters:

eps (float) – Threshold for pruning.

Returns:

New CSR with pruned entries.

Return type:

CSR

Raises:

RuntimeError – If the native core is not available.

sum(axis=None)[source]#

Sum elements along the given axis using the Rust core.

Parameters:

axis ({None, 0, 1}, optional) – None for total sum (scalar), 0 for column sums (length = ncols), 1 for row sums (length = nrows).

Returns:

Scalar for total sum, 1D array for axis-specific sums.

Return type:

float or numpy.ndarray

Raises:
toarray()[source]#

Materialize the sparse matrix as a dense numpy.ndarray.

Returns:

Dense array of shape self.shape with the same dtype as data.

Return type:

numpy.ndarray