pub struct TensorData<St, L>{ /* private fields */ }Expand description
Joined storage + layout bundle.
Construction goes through new, which asserts
storage.flat_len() == layout.storage_extent(). The bound
St: StorageFor<L> enforces flavor compatibility at the type
level (only DenseStorage ⇔ DenseLayout,
BlockSparseStorage ⇔ BlockSparseLayout).
Implementations§
Source§impl<T, S: Sector> TensorData<BlockSparseStorage<T>, BlockSparseLayout<S>>
impl<T, S: Sector> TensorData<BlockSparseStorage<T>, BlockSparseLayout<S>>
Sourcepub fn zeros(indices: Vec<QNIndex<S>>, flux: S, order: MemoryOrder) -> Self
pub fn zeros(indices: Vec<QNIndex<S>>, flux: S, order: MemoryOrder) -> Self
Construct a zero-filled BlockSparseTensorData with all
flux-allowed blocks.
Cross-crate: the user-facing constructor is
BlockSparseTensor::zeros,
which pins memory order to the active backend. Direct callers
(notably ariadnetor-linalg BSp kernel output-construction sites)
that need an explicit order go through this helper or build
TensorData::new(storage, layout) directly.
Sourcepub fn from_block_fn<F>(
indices: Vec<QNIndex<S>>,
flux: S,
order: MemoryOrder,
f: F,
) -> Self
pub fn from_block_fn<F>( indices: Vec<QNIndex<S>>, flux: S, order: MemoryOrder, f: F, ) -> Self
Construct by populating each flux-allowed block from a closure.
The closure receives the block coordinate and its dense block
shape (one entry per leg) and must return the block’s flat data
in the layout’s memory order. Forbidden blocks are not
queried. Block coordinates are visited in the layout’s
lexicographic enumeration order.
Cross-crate: the user-facing constructor is
BlockSparseTensor::from_block_fn,
which pins memory order to the active backend.
§Panics
Panics if the closure returns a Vec<T> whose length differs
from product(block_shape) (the per-block element count).
Sourcepub fn random<R: Rng>(
indices: Vec<QNIndex<S>>,
flux: S,
order: MemoryOrder,
rng: &mut R,
) -> Selfwhere
StandardUniform: Distribution<T>,
pub fn random<R: Rng>(
indices: Vec<QNIndex<S>>,
flux: S,
order: MemoryOrder,
rng: &mut R,
) -> Selfwhere
StandardUniform: Distribution<T>,
Construct with all flux-allowed blocks filled with random values from the standard distribution.
Cross-crate: the user-facing constructor is
BlockSparseTensor::random,
which pins memory order to the active backend.
Sourcepub fn block_data(&self, coord: &BlockCoord) -> Option<&[T]>
pub fn block_data(&self, coord: &BlockCoord) -> Option<&[T]>
Data slice for a block identified by coordinate.
Returns None if the block is not stored (zero by symmetry).
Sourcepub fn shape(&self) -> &[usize]
pub fn shape(&self) -> &[usize]
Logical shape (total dimension per leg). Forwards to the layout.
Sourcepub fn num_blocks(&self) -> usize
pub fn num_blocks(&self) -> usize
Number of stored (non-zero) blocks. Forwards to the layout.
Sourcepub fn block_metas(&self) -> &[BlockMeta]
pub fn block_metas(&self) -> &[BlockMeta]
Block metadata (sorted by coordinate). Forwards to the layout.
Sourcepub fn is_allowed_block(&self, coord: &BlockCoord) -> bool
pub fn is_allowed_block(&self, coord: &BlockCoord) -> bool
Check whether a block coordinate satisfies the flux conservation law. Forwards to the layout.
Sourcepub fn order(&self) -> MemoryOrder
pub fn order(&self) -> MemoryOrder
Memory order the paired storage is laid out in. Forwards to the layout.
Sourcepub fn block_data_mut(&mut self, coord: &BlockCoord) -> Option<&mut [T]>where
T: Clone,
pub fn block_data_mut(&mut self, coord: &BlockCoord) -> Option<&mut [T]>where
T: Clone,
Mutable data slice for a block identified by coordinate (triggers CoW on the storage half if shared).
Source§impl<T, S: Sector> TensorData<BlockSparseStorage<T>, BlockSparseLayout<S>>where
T: Scalar,
impl<T, S: Sector> TensorData<BlockSparseStorage<T>, BlockSparseLayout<S>>where
T: Scalar,
Sourcepub fn dagger(&self) -> Self
pub fn dagger(&self) -> Self
Hermitian adjoint: element-wise conjugation of the data, flip of every QNIndex direction (Out↔In), and dualization of the flux.
Block coordinates and packed offsets are preserved
(BlockSparseLayout::dagger_layout reuses them). Involution:
x.dagger().dagger() == x.
Sourcepub fn conj(&self) -> Self
pub fn conj(&self) -> Self
Element-wise complex conjugate. Layout (including directions
and flux) is preserved; use dagger when the
adjoint structure is required for inner products.
Sourcepub fn stored_len(&self) -> usize
pub fn stored_len(&self) -> usize
Total number of stored elements across all blocks. Forwards to the storage half.
Sourcepub fn norm_frobenius(&self) -> T::Real
pub fn norm_frobenius(&self) -> T::Real
Frobenius norm: √(Σ |element|²). Forwards to the storage half.
Sourcepub fn norm(&self) -> T::Real
pub fn norm(&self) -> T::Real
Frobenius norm (alias for norm_frobenius).
Sourcepub fn normalize(&mut self) -> T::Real
pub fn normalize(&mut self) -> T::Real
Normalize to unit Frobenius norm in place. Returns the norm before normalization. Panics if the tensor has zero norm.
Sourcepub fn normalized(&self) -> (Self, T::Real)
pub fn normalized(&self) -> (Self, T::Real)
Normalize and return a new tensor (out-of-place). Returns
(normalized_tensor, original_norm). Panics if the tensor has
zero norm.
Source§impl<T, S: Sector> TensorData<BlockSparseStorage<T>, BlockSparseLayout<S>>where
T: Clone,
impl<T, S: Sector> TensorData<BlockSparseStorage<T>, BlockSparseLayout<S>>where
T: Clone,
Source§impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Clone,
impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Clone,
Sourcepub fn get(&self, indices: &[usize]) -> T
pub fn get(&self, indices: &[usize]) -> T
Get element at multi-dimensional indices.
The flat index is computed using self.order().
§Panics
Panics if indices are out of bounds.
Sourcepub fn set(&mut self, indices: &[usize], value: T)
pub fn set(&mut self, indices: &[usize], value: T)
Set element at multi-dimensional indices (triggers CoW on the storage half if shared).
The flat index is computed using self.order().
§Panics
Panics if indices are out of bounds.
Sourcepub fn data_mut(&mut self) -> &mut [T]
pub fn data_mut(&mut self) -> &mut [T]
Mutable reference to the underlying contiguous data buffer (triggers CoW on the storage half if shared).
Sourcepub fn fill(&mut self, value: T)
pub fn fill(&mut self, value: T)
Fill every element with a constant value (triggers CoW if shared). Forwards to the storage half.
Source§impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Clone,
impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Clone,
Sourcepub fn zeros_in_order(shape: Vec<usize>, order: MemoryOrder) -> Selfwhere
T: Zero,
pub fn zeros_in_order(shape: Vec<usize>, order: MemoryOrder) -> Selfwhere
T: Zero,
Zero-filled tensor in the requested memory order.
Sourcepub fn ones_in_order(shape: Vec<usize>, order: MemoryOrder) -> Self
pub fn ones_in_order(shape: Vec<usize>, order: MemoryOrder) -> Self
Ones-filled tensor in the requested memory order.
Sourcepub fn filled_in_order(shape: Vec<usize>, value: T, order: MemoryOrder) -> Self
pub fn filled_in_order(shape: Vec<usize>, value: T, order: MemoryOrder) -> Self
Tensor filled with value in the requested memory order.
Sourcepub fn eye_in_order(n: usize, order: MemoryOrder) -> Self
pub fn eye_in_order(n: usize, order: MemoryOrder) -> Self
n × n identity matrix in the requested memory order.
The identity matrix is symmetric, so the flat buffer is the
same under either memory order; only the layout’s order()
differs.
Sourcepub fn random_in_order<R: Rng>(
shape: Vec<usize>,
order: MemoryOrder,
rng: &mut R,
) -> Selfwhere
StandardUniform: Distribution<T>,
pub fn random_in_order<R: Rng>(
shape: Vec<usize>,
order: MemoryOrder,
rng: &mut R,
) -> Selfwhere
StandardUniform: Distribution<T>,
Random-filled tensor (standard distribution) in the requested
memory order. Random values are layout-invariant; only the
layout’s order() tag matters for downstream interpretation.
Source§impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Clone,
impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Clone,
Sourcepub fn concatenate(tensors: &[&DenseTensorData<T>], axis: usize) -> Self
pub fn concatenate(tensors: &[&DenseTensorData<T>], axis: usize) -> Self
Concatenate tensors along an existing axis.
All tensors must have the same rank, the same order(), and
matching sizes on all axes except axis. The output preserves
the shared order().
Sourcepub fn stack(tensors: &[&DenseTensorData<T>], axis: usize) -> Self
pub fn stack(tensors: &[&DenseTensorData<T>], axis: usize) -> Self
Stack tensors along a new axis.
All tensors must have the same shape and the same order().
The output preserves the shared order().
Source§impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Clone,
impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Clone,
Sourcepub fn reshape(&self, new_shape: Vec<usize>) -> Self
pub fn reshape(&self, new_shape: Vec<usize>) -> Self
Reshape the tensor to a new shape (zero-copy: shares the underlying storage Arc).
The flat data is not rearranged — only the layout’s shape
changes. The output preserves self.order(). Reshape semantics
depend on the order: adjacent-axis fusion is zero-copy under
both row-major and column-major for contiguous tensors, but
non-adjacent fusion produces a different logical mapping under
each order.
§Panics
Panics if the new shape has a different total number of elements.
Sourcepub fn map<U, F>(&self, f: F) -> DenseTensorData<U>
pub fn map<U, F>(&self, f: F) -> DenseTensorData<U>
Apply a function to each element.
Iterates flat data directly. The result preserves
self.order().
Sourcepub fn map_with_index<U, F>(&self, f: F) -> DenseTensorData<U>
pub fn map_with_index<U, F>(&self, f: F) -> DenseTensorData<U>
Apply a function with multi-dimensional coordinates to each element.
Iterates coordinates in self.order() while reading storage
linearly, so the coordinate-to-value mapping always matches
the storage’s layout. The output preserves self.order().
Source§impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Clone,
impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Clone,
Sourcepub fn add_all(
tensors: &[&DenseTensorData<T>],
) -> Result<DenseTensorData<T>, TensorError>
pub fn add_all( tensors: &[&DenseTensorData<T>], ) -> Result<DenseTensorData<T>, TensorError>
Add all tensors (coefficients all = 1).
Sourcepub fn linear_combine(
tensors: &[&DenseTensorData<T>],
coefs: &[T],
) -> Result<DenseTensorData<T>, TensorError>
pub fn linear_combine( tensors: &[&DenseTensorData<T>], coefs: &[T], ) -> Result<DenseTensorData<T>, TensorError>
Linear combination: Σ coefs[i] * tensors[i].
All input tensors must share the same order(); the result
preserves that order.
§Errors
Returns an error if tensors have different shapes, different orders, the list is empty, or tensors and coefficients have different lengths.
Source§impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Scalar,
impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Scalar,
Sourcepub fn to_complex(&self) -> DenseTensorData<T::Complex>
pub fn to_complex(&self) -> DenseTensorData<T::Complex>
Convert each element to its complex representation.
Sourcepub fn real(&self) -> DenseTensorData<T::Real>
pub fn real(&self) -> DenseTensorData<T::Real>
Extract the real part of each element.
Sourcepub fn imag(&self) -> DenseTensorData<T::Real>
pub fn imag(&self) -> DenseTensorData<T::Real>
Extract the imaginary part of each element.
Sourcepub fn norm_frobenius(&self) -> T::Real
pub fn norm_frobenius(&self) -> T::Real
Compute Frobenius norm: √(Σ |element|²).
Sourcepub fn norm(&self) -> T::Real
pub fn norm(&self) -> T::Real
Compute Frobenius norm (alias for norm_frobenius).
Sourcepub fn normalize(&mut self) -> T::Real
pub fn normalize(&mut self) -> T::Real
Normalize to unit Frobenius norm (in-place).
Returns the norm before normalization. Panics if the tensor has zero norm.
Sourcepub fn normalized(&self) -> (Self, T::Real)
pub fn normalized(&self) -> (Self, T::Real)
Normalize and return a new tensor (out-of-place).
Returns (normalized_tensor, original_norm). Panics if the
tensor has zero norm.
Source§impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Clone,
impl<T> TensorData<DenseStorage<T>, DenseLayout>where
T: Clone,
Sourcepub fn slice(&self, ranges: &[(usize, usize)]) -> Self
pub fn slice(&self, ranges: &[(usize, usize)]) -> Self
Extract a sub-tensor by specifying a (start, end) range for
each axis (exclusive end).
The flat-data interpretation follows self.order(), and the
output preserves the same order.
§Panics
Panics if ranges length doesn’t match rank, or any range is
out of bounds.
Sourcepub fn expand(&self, padding: &[(usize, usize)]) -> Selfwhere
T: Zero,
pub fn expand(&self, padding: &[(usize, usize)]) -> Selfwhere
T: Zero,
Expand tensor by adding zero-padding at the boundaries.
The flat-data interpretation follows self.order(), and the
output preserves the same order.
Sourcepub fn replace_slice(&mut self, sub: &Self, begin: &[usize])
pub fn replace_slice(&mut self, sub: &Self, begin: &[usize])
Write a sub-tensor into this tensor starting at the given position (triggers CoW on the storage half if shared).
The flat-data interpretation follows self.order().
§Panics
Panics if sub.rank() or begin.len() does not match
self.rank(), or any sub-tensor extent exceeds the
destination’s bounds. Also panics if sub.order() differs from
self.order() at rank ≥ 2.
Source§impl<T> TensorData<DenseStorage<T>, DenseLayout>
impl<T> TensorData<DenseStorage<T>, DenseLayout>
Sourcepub fn from_raw_parts(
data: Vec<T>,
shape: Vec<usize>,
order: MemoryOrder,
) -> Selfwhere
T: Clone,
pub fn from_raw_parts(
data: Vec<T>,
shape: Vec<usize>,
order: MemoryOrder,
) -> Selfwhere
T: Clone,
Construct from flat data, shape, and the memory order the data is laid out in.
§Panics
Panics if data.len() does not equal shape.iter().product().
Sourcepub fn order(&self) -> MemoryOrder
pub fn order(&self) -> MemoryOrder
Memory order the flat data is laid out in.
Source§impl<St, L> TensorData<St, L>
impl<St, L> TensorData<St, L>
Sourcepub fn new(storage: St, layout: L) -> Self
pub fn new(storage: St, layout: L) -> Self
Construct from a Storage half and a paired TensorLayout
half. Asserts the storage-layout boundary: the storage’s flat
length must match the layout’s expected storage extent.
Sourcepub fn into_parts(self) -> (St, L)
pub fn into_parts(self) -> (St, L)
Consume and return both halves.
Trait Implementations§
Source§impl<St, L> Clone for TensorData<St, L>
impl<St, L> Clone for TensorData<St, L>
Auto Trait Implementations§
impl<St, L> Freeze for TensorData<St, L>
impl<St, L> RefUnwindSafe for TensorData<St, L>where
St: RefUnwindSafe,
L: RefUnwindSafe,
impl<St, L> Send for TensorData<St, L>
impl<St, L> Sync for TensorData<St, L>
impl<St, L> Unpin for TensorData<St, L>
impl<St, L> UnsafeUnpin for TensorData<St, L>where
St: UnsafeUnpin,
L: UnsafeUnpin,
impl<St, L> UnwindSafe for TensorData<St, L>where
St: UnwindSafe,
L: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more