pub struct BlockTensor<T: TensorLike> { /* private fields */ }Expand description
A collection of tensors organized in a block structure.
Each block is a tensor of type T implementing TensorLike.
The flattened block list is ordered row-by-row:
(0, 0), (0, 1), ..., (1, 0), (1, 1), ....
§Type Parameters
T- The tensor type for each block, must implementTensorLike
Implementations§
Source§impl<T: TensorLike> BlockTensor<T>
impl<T: TensorLike> BlockTensor<T>
Sourcepub fn try_new(blocks: Vec<T>, shape: (usize, usize)) -> Result<Self>
pub fn try_new(blocks: Vec<T>, shape: (usize, usize)) -> Result<Self>
Create a new block tensor with validation.
§Arguments
blocks- Vector of blocks flattened row-by-rowshape- Block structure as (rows, cols)
§Errors
Returns an error if rows * cols != blocks.len().
§Examples
use tensor4all_core::block_tensor::BlockTensor;
use tensor4all_core::{DynIndex, TensorDynLen};
let i = DynIndex::new_dyn(2);
let t1 = TensorDynLen::from_dense(vec![i.clone()], vec![1.0, 2.0]).unwrap();
let t2 = TensorDynLen::from_dense(vec![i.clone()], vec![3.0, 4.0]).unwrap();
let bt = BlockTensor::try_new(vec![t1, t2], (2, 1)).unwrap();
assert_eq!(bt.shape(), (2, 1));
// Wrong number of blocks returns an error
let t3 = TensorDynLen::from_dense(vec![i], vec![5.0, 6.0]).unwrap();
assert!(BlockTensor::try_new(vec![t3], (2, 1)).is_err());Sourcepub fn new(blocks: Vec<T>, shape: (usize, usize)) -> Self
pub fn new(blocks: Vec<T>, shape: (usize, usize)) -> Self
Create a new block tensor.
§Arguments
blocks- Vector of blocks flattened row-by-rowshape- Block structure as (rows, cols)
§Panics
Panics if rows * cols != blocks.len().
§Examples
use tensor4all_core::block_tensor::BlockTensor;
use tensor4all_core::{DynIndex, TensorDynLen};
let i = DynIndex::new_dyn(2);
let t = TensorDynLen::from_dense(vec![i], vec![1.0, 2.0]).unwrap();
let bt = BlockTensor::new(vec![t], (1, 1));
assert_eq!(bt.shape(), (1, 1));Sourcepub fn shape(&self) -> (usize, usize)
pub fn shape(&self) -> (usize, usize)
Get the block structure (rows, cols).
§Examples
use tensor4all_core::block_tensor::BlockTensor;
use tensor4all_core::{DynIndex, TensorDynLen};
let i = DynIndex::new_dyn(2);
let blocks: Vec<TensorDynLen> = (0..6)
.map(|_| TensorDynLen::from_dense(vec![i.clone()], vec![0.0, 0.0]).unwrap())
.collect();
let bt = BlockTensor::new(blocks, (2, 3));
assert_eq!(bt.shape(), (2, 3));Sourcepub fn num_blocks(&self) -> usize
pub fn num_blocks(&self) -> usize
Get the total number of blocks.
Sourcepub fn get(&self, row: usize, col: usize) -> &T
pub fn get(&self, row: usize, col: usize) -> &T
Get a reference to the block at (row, col).
§Panics
Panics if the indices are out of bounds.
§Examples
use tensor4all_core::block_tensor::BlockTensor;
use tensor4all_core::{DynIndex, TensorDynLen};
let i = DynIndex::new_dyn(2);
let t1 = TensorDynLen::from_dense(vec![i.clone()], vec![1.0, 2.0]).unwrap();
let t2 = TensorDynLen::from_dense(vec![i], vec![3.0, 4.0]).unwrap();
let bt = BlockTensor::new(vec![t1, t2], (2, 1));
assert_eq!(bt.get(0, 0).dims(), vec![2]);
assert_eq!(bt.get(1, 0).dims(), vec![2]);Sourcepub fn get_mut(&mut self, row: usize, col: usize) -> &mut T
pub fn get_mut(&mut self, row: usize, col: usize) -> &mut T
Get a mutable reference to the block at (row, col).
§Panics
Panics if the indices are out of bounds.
§Examples
use tensor4all_core::block_tensor::BlockTensor;
use tensor4all_core::{DynIndex, TensorDynLen};
let i = DynIndex::new_dyn(2);
let t = TensorDynLen::from_dense(vec![i.clone()], vec![1.0, 2.0]).unwrap();
let mut bt = BlockTensor::new(vec![t], (1, 1));
let block = bt.get_mut(0, 0);
assert_eq!(block.dims(), vec![2]);Sourcepub fn blocks(&self) -> &[T]
pub fn blocks(&self) -> &[T]
Get all blocks as a slice.
§Examples
use tensor4all_core::block_tensor::BlockTensor;
use tensor4all_core::{DynIndex, TensorDynLen};
let i = DynIndex::new_dyn(2);
let t1 = TensorDynLen::from_dense(vec![i.clone()], vec![1.0, 2.0]).unwrap();
let t2 = TensorDynLen::from_dense(vec![i], vec![3.0, 4.0]).unwrap();
let bt = BlockTensor::new(vec![t1, t2], (1, 2));
assert_eq!(bt.blocks().len(), 2);Sourcepub fn blocks_mut(&mut self) -> &mut [T]
pub fn blocks_mut(&mut self) -> &mut [T]
Get all blocks as a mutable slice.
§Examples
use tensor4all_core::block_tensor::BlockTensor;
use tensor4all_core::{DynIndex, TensorDynLen};
let i = DynIndex::new_dyn(2);
let t = TensorDynLen::from_dense(vec![i], vec![1.0, 2.0]).unwrap();
let mut bt = BlockTensor::new(vec![t], (1, 1));
assert_eq!(bt.blocks_mut().len(), 1);Sourcepub fn into_blocks(self) -> Vec<T>
pub fn into_blocks(self) -> Vec<T>
Consume self and return the blocks.
§Examples
use tensor4all_core::block_tensor::BlockTensor;
use tensor4all_core::{DynIndex, TensorDynLen};
let i = DynIndex::new_dyn(2);
let t = TensorDynLen::from_dense(vec![i], vec![1.0, 2.0]).unwrap();
let bt = BlockTensor::new(vec![t], (1, 1));
let blocks = bt.into_blocks();
assert_eq!(blocks.len(), 1);
assert_eq!(blocks[0].dims(), vec![2]);Sourcepub fn validate_indices(&self) -> Result<()>
pub fn validate_indices(&self) -> Result<()>
Validate that blocks share external indices consistently.
For column vectors (cols=1), no index sharing is required between blocks. Different rows can have independent physical indices (the operator determines their relationship).
For matrices (rows x cols), checks that:
- All blocks have the same number of external indices.
- Blocks in the same row share some common index IDs (output indices).
- Blocks in the same column share some common index IDs (input indices).
§Examples
use tensor4all_core::block_tensor::BlockTensor;
use tensor4all_core::{DynIndex, TensorDynLen};
// Column vector: always valid regardless of index sharing
let i = DynIndex::new_dyn(2);
let j = DynIndex::new_dyn(2);
let t1 = TensorDynLen::from_dense(vec![i], vec![1.0, 2.0]).unwrap();
let t2 = TensorDynLen::from_dense(vec![j], vec![3.0, 4.0]).unwrap();
let bt = BlockTensor::new(vec![t1, t2], (2, 1));
assert!(bt.validate_indices().is_ok());Trait Implementations§
Source§impl<T: Clone + TensorLike> Clone for BlockTensor<T>
impl<T: Clone + TensorLike> Clone for BlockTensor<T>
Source§fn clone(&self) -> BlockTensor<T>
fn clone(&self) -> BlockTensor<T>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<T: Debug + TensorLike> Debug for BlockTensor<T>
impl<T: Debug + TensorLike> Debug for BlockTensor<T>
Source§impl<T: TensorLike> TensorIndex for BlockTensor<T>
impl<T: TensorLike> TensorIndex for BlockTensor<T>
Source§type Index = <T as TensorIndex>::Index
type Index = <T as TensorIndex>::Index
Source§fn external_indices(&self) -> Vec<Self::Index>
fn external_indices(&self) -> Vec<Self::Index>
Source§fn replaceind(
&self,
old_index: &Self::Index,
new_index: &Self::Index,
) -> Result<Self>
fn replaceind( &self, old_index: &Self::Index, new_index: &Self::Index, ) -> Result<Self>
Source§fn replaceinds(
&self,
old_indices: &[Self::Index],
new_indices: &[Self::Index],
) -> Result<Self>
fn replaceinds( &self, old_indices: &[Self::Index], new_indices: &[Self::Index], ) -> Result<Self>
Source§fn num_external_indices(&self) -> usize
fn num_external_indices(&self) -> usize
Source§impl<T: TensorLike> TensorLike for BlockTensor<T>
impl<T: TensorLike> TensorLike for BlockTensor<T>
Source§fn norm_squared(&self) -> f64
fn norm_squared(&self) -> f64
Source§fn axpby(&self, a: AnyScalar, other: &Self, b: AnyScalar) -> Result<Self>
fn axpby(&self, a: AnyScalar, other: &Self, b: AnyScalar) -> Result<Self>
a * self + b * other. Read moreSource§fn inner_product(&self, other: &Self) -> Result<AnyScalar>
fn inner_product(&self, other: &Self) -> Result<AnyScalar>
Source§fn factorize(
&self,
_left_inds: &[<Self as TensorIndex>::Index],
_options: &FactorizeOptions,
) -> Result<FactorizeResult<Self>, FactorizeError>
fn factorize( &self, _left_inds: &[<Self as TensorIndex>::Index], _options: &FactorizeOptions, ) -> Result<FactorizeResult<Self>, FactorizeError>
Source§fn factorize_full_rank(
&self,
_left_inds: &[<Self as TensorIndex>::Index],
_alg: FactorizeAlg,
_canonical: Canonical,
) -> Result<FactorizeResult<Self>, FactorizeError>
fn factorize_full_rank( &self, _left_inds: &[<Self as TensorIndex>::Index], _alg: FactorizeAlg, _canonical: Canonical, ) -> Result<FactorizeResult<Self>, FactorizeError>
Source§fn direct_sum(
&self,
_other: &Self,
_pairs: &[(<Self as TensorIndex>::Index, <Self as TensorIndex>::Index)],
) -> Result<DirectSumResult<Self>>
fn direct_sum( &self, _other: &Self, _pairs: &[(<Self as TensorIndex>::Index, <Self as TensorIndex>::Index)], ) -> Result<DirectSumResult<Self>>
Source§fn outer_product(&self, _other: &Self) -> Result<Self>
fn outer_product(&self, _other: &Self) -> Result<Self>
Source§fn permuteinds(
&self,
_new_order: &[<Self as TensorIndex>::Index],
) -> Result<Self>
fn permuteinds( &self, _new_order: &[<Self as TensorIndex>::Index], ) -> Result<Self>
Source§fn fuse_indices(
&self,
old_indices: &[Self::Index],
new_index: Self::Index,
order: LinearizationOrder,
) -> Result<Self>
fn fuse_indices( &self, old_indices: &[Self::Index], new_index: Self::Index, order: LinearizationOrder, ) -> Result<Self>
Source§fn contract(_tensors: &[&Self], _allowed: AllowedPairs<'_>) -> Result<Self>
fn contract(_tensors: &[&Self], _allowed: AllowedPairs<'_>) -> Result<Self>
Source§fn contract_connected(
_tensors: &[&Self],
_allowed: AllowedPairs<'_>,
) -> Result<Self>
fn contract_connected( _tensors: &[&Self], _allowed: AllowedPairs<'_>, ) -> Result<Self>
Source§fn diagonal(
_input_index: &<Self as TensorIndex>::Index,
_output_index: &<Self as TensorIndex>::Index,
) -> Result<Self>
fn diagonal( _input_index: &<Self as TensorIndex>::Index, _output_index: &<Self as TensorIndex>::Index, ) -> Result<Self>
Source§fn scalar_one() -> Result<Self>
fn scalar_one() -> Result<Self>
Source§fn ones(_indices: &[<Self as TensorIndex>::Index]) -> Result<Self>
fn ones(_indices: &[<Self as TensorIndex>::Index]) -> Result<Self>
Source§fn onehot(_index_vals: &[(<Self as TensorIndex>::Index, usize)]) -> Result<Self>
fn onehot(_index_vals: &[(<Self as TensorIndex>::Index, usize)]) -> Result<Self>
Source§fn isapprox(&self, other: &Self, atol: f64, rtol: f64) -> bool
fn isapprox(&self, other: &Self, atol: f64, rtol: f64) -> bool
isapprox semantics). Read moreSource§fn delta(
input_indices: &[<Self as TensorIndex>::Index],
output_indices: &[<Self as TensorIndex>::Index],
) -> Result<Self>
fn delta( input_indices: &[<Self as TensorIndex>::Index], output_indices: &[<Self as TensorIndex>::Index], ) -> Result<Self>
Auto Trait Implementations§
impl<T> Freeze for BlockTensor<T>
impl<T> RefUnwindSafe for BlockTensor<T>where
T: RefUnwindSafe,
impl<T> Send for BlockTensor<T>
impl<T> Sync for BlockTensor<T>
impl<T> Unpin for BlockTensor<T>where
T: Unpin,
impl<T> UnsafeUnpin for BlockTensor<T>
impl<T> UnwindSafe for BlockTensor<T>where
T: UnwindSafe,
Blanket Implementations§
§impl<U> As for U
impl<U> As for U
§fn as_<T>(self) -> Twhere
T: CastFrom<U>,
fn as_<T>(self) -> Twhere
T: CastFrom<U>,
self to type T. The semantics of numeric casting with the as operator are followed, so <T as As>::as_::<U> can be used in the same way as T as U for numeric conversions. Read moreSource§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,
§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> Twhere
Self: Distribution<T>,
§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> Twhere
Self: Distribution<T>,
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