| """ |
| Sparse Tensor — Lightweight ndarray wrapper with brain-inspired sparsity. |
| |
| The brain is lazy and sparse: ~1-5% of neurons fire at any moment. |
| This module provides sparse operations that model this biological constraint. |
| Sparsity enables "common sense" — knowing ~60% is enough, then filling gaps. |
| |
| Author: Algorembrant, Rembrant Oyangoren Albeos (2026) |
| """ |
|
|
| import numpy as np |
| from typing import Optional, Tuple, Union |
|
|
|
|
| class SparseTensor: |
| """ |
| A sparse tensor wrapper over NumPy arrays that enforces biological sparsity. |
| |
| Key biological properties: |
| - Top-k sparsification (winner-take-all inhibition) |
| - Threshold activation (firing threshold) |
| - Lazy computation (only compute when needed) |
| - Efficient sparse dot products |
| """ |
|
|
| def __init__(self, data: np.ndarray, sparsity_mask: Optional[np.ndarray] = None): |
| """ |
| Args: |
| data: Dense NumPy array (the raw signal) |
| sparsity_mask: Boolean mask of active units (True = active/firing) |
| """ |
| self._data = np.asarray(data, dtype=np.float64) |
| if sparsity_mask is not None: |
| self._mask = np.asarray(sparsity_mask, dtype=bool) |
| assert self._mask.shape == self._data.shape, \ |
| f"Mask shape {self._mask.shape} != data shape {self._data.shape}" |
| else: |
| |
| self._mask = np.ones(self._data.shape, dtype=bool) |
|
|
| @property |
| def data(self) -> np.ndarray: |
| """Raw underlying data (masked values are zeroed).""" |
| return self._data * self._mask |
|
|
| @property |
| def dense(self) -> np.ndarray: |
| """Full dense representation (unmasked).""" |
| return self._data |
|
|
| @property |
| def mask(self) -> np.ndarray: |
| """Boolean sparsity mask: True where units are active.""" |
| return self._mask |
|
|
| @property |
| def shape(self) -> Tuple[int, ...]: |
| return self._data.shape |
|
|
| @property |
| def sparsity(self) -> float: |
| """Fraction of zeros (inactive units). 0.0 = fully dense, 1.0 = fully sparse.""" |
| return 1.0 - (np.sum(self._mask) / self._mask.size) |
|
|
| @property |
| def num_active(self) -> int: |
| """Number of active (non-zero) units.""" |
| return int(np.sum(self._mask)) |
|
|
| |
|
|
| def threshold(self, theta: float) -> 'SparseTensor': |
| """ |
| Threshold activation — only units above theta fire. |
| Models neuronal firing threshold / activation threshold. |
| |
| Args: |
| theta: Firing threshold |
| Returns: |
| New SparseTensor with sub-threshold units masked out |
| """ |
| new_mask = self._mask & (np.abs(self._data) >= theta) |
| return SparseTensor(self._data, new_mask) |
|
|
| def top_k(self, k: int, axis: Optional[int] = None) -> 'SparseTensor': |
| """ |
| Top-k sparsification — winner-take-all competitive inhibition. |
| Only the k strongest activations survive. This is how lateral inhibition |
| in cortex creates sparse population codes. |
| |
| Args: |
| k: Number of top activations to keep |
| axis: Axis along which to apply top-k (None = global) |
| Returns: |
| New SparseTensor with only top-k values active |
| """ |
| if axis is None: |
| flat = np.abs(self._data).ravel() |
| if k >= flat.size: |
| return SparseTensor(self._data.copy(), self._mask.copy()) |
| |
| threshold_val = np.partition(flat, -k)[-k] |
| new_mask = self._mask & (np.abs(self._data) >= threshold_val) |
| |
| active_count = np.sum(new_mask) |
| if active_count > k: |
| active_indices = np.argwhere(new_mask.ravel()).ravel() |
| active_vals = np.abs(self._data.ravel()[active_indices]) |
| |
| sorted_order = np.argsort(-active_vals) |
| kill = active_indices[sorted_order[k:]] |
| flat_mask = new_mask.ravel().copy() |
| flat_mask[kill] = False |
| new_mask = flat_mask.reshape(self._data.shape) |
| return SparseTensor(self._data, new_mask) |
| else: |
| |
| new_mask = np.zeros_like(self._mask) |
| nd = self._data.ndim |
| slices = [slice(None)] * nd |
| for i in range(self._data.shape[axis]): |
| slices[axis] = i |
| sl = tuple(slices) |
| vals = np.abs(self._data[sl]) |
| flat = vals.ravel() |
| actual_k = min(k, flat.size) |
| if actual_k == flat.size: |
| new_mask[sl] = self._mask[sl] |
| else: |
| thresh = np.partition(flat, -actual_k)[-actual_k] |
| new_mask[sl] = self._mask[sl] & (vals >= thresh) |
| return SparseTensor(self._data, new_mask) |
|
|
| def sparsify(self, target_sparsity: float) -> 'SparseTensor': |
| """ |
| Achieve a target sparsity level (fraction of zeros). |
| Brain typically has 95-99% sparsity in any population code. |
| |
| Args: |
| target_sparsity: Desired fraction of inactive units (0.0 to 1.0) |
| Returns: |
| New SparseTensor with approximately target_sparsity inactive |
| """ |
| k = max(1, round((1.0 - target_sparsity) * self._data.size)) |
| return self.top_k(k) |
|
|
| |
|
|
| def relu(self) -> 'SparseTensor': |
| """Half-wave rectification — models neuronal firing rate (no negative rates).""" |
| new_data = np.maximum(self._data, 0.0) |
| new_mask = self._mask & (new_data > 0.0) |
| return SparseTensor(new_data, new_mask) |
|
|
| def sigmoid(self, gain: float = 1.0) -> 'SparseTensor': |
| """Sigmoidal activation — saturating firing rate.""" |
| new_data = 1.0 / (1.0 + np.exp(-gain * self._data)) |
| return SparseTensor(new_data, self._mask) |
|
|
| def softmax(self, axis: int = -1) -> 'SparseTensor': |
| """Softmax normalization — competitive normalization across a population.""" |
| shifted = self._data - np.max(self._data, axis=axis, keepdims=True) |
| exp_vals = np.exp(shifted) * self._mask |
| sums = np.sum(exp_vals, axis=axis, keepdims=True) |
| sums = np.where(sums == 0, 1.0, sums) |
| new_data = exp_vals / sums |
| return SparseTensor(new_data, self._mask) |
|
|
| def divisive_normalization(self, sigma: float = 1.0, axis: int = -1) -> 'SparseTensor': |
| """ |
| Divisive normalization — the canonical neural computation. |
| r_i = r_i^n / (sigma^n + sum(r_j^n)) |
| Models gain control in visual cortex. |
| """ |
| n = 2.0 |
| powered = np.abs(self.data) ** n |
| pool = np.sum(powered, axis=axis, keepdims=True) |
| normalized = powered / (sigma ** n + pool) |
| |
| signs = np.sign(self._data) |
| new_data = signs * (normalized ** (1.0 / n)) |
| return SparseTensor(new_data, self._mask) |
|
|
| |
|
|
| def dot(self, other: Union['SparseTensor', np.ndarray]) -> 'SparseTensor': |
| """ |
| Sparse dot product — only active units contribute. |
| Efficient because inactive synapses don't transmit. |
| """ |
| if isinstance(other, SparseTensor): |
| result = np.dot(self.data, other.data) |
| else: |
| result = np.dot(self.data, np.asarray(other, dtype=np.float64)) |
| return SparseTensor(result) |
|
|
| def outer(self, other: 'SparseTensor') -> 'SparseTensor': |
| """Outer product — used for Hebbian learning (pre × post).""" |
| result = np.outer(self.data.ravel(), other.data.ravel()) |
| return SparseTensor(result) |
|
|
| |
|
|
| def __add__(self, other: Union['SparseTensor', np.ndarray, float]) -> 'SparseTensor': |
| if isinstance(other, SparseTensor): |
| return SparseTensor(self._data + other._data, self._mask | other._mask) |
| return SparseTensor(self._data + np.float64(other), self._mask) |
|
|
| def __sub__(self, other: Union['SparseTensor', np.ndarray, float]) -> 'SparseTensor': |
| if isinstance(other, SparseTensor): |
| return SparseTensor(self._data - other._data, self._mask | other._mask) |
| return SparseTensor(self._data - np.float64(other), self._mask) |
|
|
| def __mul__(self, other: Union['SparseTensor', np.ndarray, float]) -> 'SparseTensor': |
| if isinstance(other, SparseTensor): |
| return SparseTensor(self._data * other._data, self._mask & other._mask) |
| return SparseTensor(self._data * np.float64(other), self._mask) |
|
|
| def __neg__(self) -> 'SparseTensor': |
| return SparseTensor(-self._data, self._mask.copy()) |
|
|
| def __repr__(self) -> str: |
| return (f"SparseTensor(shape={self.shape}, " |
| f"active={self.num_active}/{self._data.size}, " |
| f"sparsity={self.sparsity:.1%})") |
|
|
| |
|
|
| def copy(self) -> 'SparseTensor': |
| return SparseTensor(self._data.copy(), self._mask.copy()) |
|
|
| def reshape(self, *shape) -> 'SparseTensor': |
| return SparseTensor(self._data.reshape(*shape), self._mask.reshape(*shape)) |
|
|
| def flatten(self) -> 'SparseTensor': |
| return SparseTensor(self._data.ravel(), self._mask.ravel()) |
|
|
| @staticmethod |
| def from_dense(data: np.ndarray, threshold: float = 0.0) -> 'SparseTensor': |
| """Create from dense array, automatically masking near-zero values.""" |
| mask = np.abs(data) > threshold |
| return SparseTensor(data, mask) |
|
|
| @staticmethod |
| def zeros(shape: Tuple[int, ...]) -> 'SparseTensor': |
| return SparseTensor(np.zeros(shape), np.zeros(shape, dtype=bool)) |
|
|
| @staticmethod |
| def ones(shape: Tuple[int, ...]) -> 'SparseTensor': |
| return SparseTensor(np.ones(shape)) |
|
|
| @staticmethod |
| def random(shape: Tuple[int, ...], sparsity: float = 0.95) -> 'SparseTensor': |
| """Random sparse tensor — models spontaneous neural activity.""" |
| data = np.random.randn(*shape) |
| mask = np.random.random(shape) > sparsity |
| return SparseTensor(data, mask) |
|
|