Skip to main content

ariadnetor_tensor/block_sparse/
mod.rs

1//! Block-sparse tensor storage for abelian symmetries.
2//!
3//! Provides [`BlockSparseTensorData<T, S>`] — the joined storage +
4//! layout bundle for tensors whose blocks are constrained by an
5//! abelian conservation law (flux). Only blocks satisfying the
6//! conservation law are allocated; the packed flat buffer lives on
7//! [`BlockSparseStorage<T>`] and the per-leg sector indices /
8//! allowed-block metadata live on [`BlockSparseLayout<S>`].
9//!
10//! # Key types
11//!
12//! - [`Direction`] — leg direction (Out/In) for flux computation
13//! - [`QNIndex<S>`] — quantum-number index mapping sectors to block dimensions
14//! - [`BlockCoord`] — N-dimensional block coordinate
15//! - [`BlockMeta`] — per-block metadata (coordinate, offset, size)
16//! - [`BlockSparseStorage<T>`] / [`BlockSparseLayout<S>`] /
17//!   [`BlockSparseTensorData<T, S>`] — the storage / layout / joined
18//!   bundle
19
20use crate::sector::Sector;
21
22mod layout;
23mod qn_index;
24mod storage;
25mod tensor_data;
26
27pub use layout::BlockSparseLayout;
28pub use qn_index::QNIndex;
29pub use storage::BlockSparseStorage;
30pub use tensor_data::BlockSparseTensorData;
31
32// ---------------------------------------------------------------------------
33// Direction
34// ---------------------------------------------------------------------------
35
36/// Leg direction for flux computation (see each variant).
37#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
38pub enum Direction {
39    /// Ket / row index: the sector contributes as-is to the flux.
40    Out,
41    /// Bra / column index: the sector contributes via `dual()` to the flux.
42    In,
43}
44
45impl Direction {
46    /// Apply direction to a sector: identity for `Out`, `dual()` for `In`.
47    pub fn apply<S: Sector>(&self, sector: &S) -> S {
48        match self {
49            Direction::Out => sector.clone(),
50            Direction::In => sector.dual(),
51        }
52    }
53}
54
55// ---------------------------------------------------------------------------
56// BlockCoord
57// ---------------------------------------------------------------------------
58
59/// N-dimensional block coordinate.
60///
61/// Each element is an index into the corresponding `QNIndex.blocks`.
62/// `Ord` is derived (lexicographic) to define a deterministic sort order
63/// for `Vec<BlockMeta>`.
64#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
65pub struct BlockCoord(pub Vec<usize>);
66
67// ---------------------------------------------------------------------------
68// BlockMeta
69// ---------------------------------------------------------------------------
70
71/// Metadata for a single block within a block-sparse tensor.
72#[derive(Clone, Debug)]
73pub struct BlockMeta {
74    /// Block coordinate (index into each leg's QNIndex).
75    pub coord: BlockCoord,
76    /// Element offset into the flat data buffer.
77    pub offset: usize,
78    /// Number of elements in this block.
79    pub size: usize,
80}
81
82#[cfg(test)]
83mod tests;