Struct Storage
pub struct Storage(/* private fields */);Expand description
Storage backend for tensor data.
Public callers interact with this opaque wrapper through constructors and high-level query/materialization methods.
§Examples
use tensor4all_tensorbackend::Storage;
// Dense 2x3 matrix stored column-major: [[1,2,3],[4,5,6]]
let data = vec![1.0_f64, 4.0, 2.0, 5.0, 3.0, 6.0];
let s = Storage::from_dense_col_major(data, &[2, 3]).unwrap();
assert!(s.is_f64());
assert!(!s.is_complex());
// Diagonal storage: 2x2 identity-like diagonal
let diag = Storage::new_diag(vec![1.0_f64, 2.0]);
assert!(diag.is_f64());Implementations§
§impl Storage
impl Storage
pub fn from_dense_col_major<T>(
data: Vec<T>,
logical_dims: &[usize],
) -> Result<Storage, Error>where
T: StorageScalar,
pub fn from_dense_col_major<T>(
data: Vec<T>,
logical_dims: &[usize],
) -> Result<Storage, Error>where
T: StorageScalar,
Create dense storage from column-major logical values (generic over scalar type).
The scalar type is inferred from the data argument.
§Examples
use tensor4all_tensorbackend::Storage;
// 2x2 matrix, column-major: [[1,3],[2,4]]
let s = Storage::from_dense_col_major(vec![1.0_f64, 2.0, 3.0, 4.0], &[2, 2]).unwrap();
assert!(s.is_f64());
assert!(s.is_dense());
assert_eq!(s.len(), 4);pub fn from_diag_col_major<T>(
diag_data: Vec<T>,
logical_rank: usize,
) -> Result<Storage, Error>where
T: StorageScalar,
pub fn from_diag_col_major<T>(
diag_data: Vec<T>,
logical_rank: usize,
) -> Result<Storage, Error>where
T: StorageScalar,
Create diagonal storage from column-major diagonal payload values (generic over scalar type).
pub fn new_dense<T>(size: usize) -> Storagewhere
T: StorageScalar + Default,
pub fn new_dense<T>(size: usize) -> Storagewhere
T: StorageScalar + Default,
Create a new 1D zero-initialized dense storage (generic over scalar type).
pub fn new_diag<T>(diag_data: Vec<T>) -> Storagewhere
T: StorageScalar,
pub fn new_diag<T>(diag_data: Vec<T>) -> Storagewhere
T: StorageScalar,
Create a new diagonal storage with the given diagonal data (generic over scalar type).
§Examples
use tensor4all_tensorbackend::Storage;
let s = Storage::new_diag(vec![1.0_f64, 2.0, 3.0]);
assert!(s.is_diag());
assert!(s.is_f64());pub fn new_structured<T>(
data: Vec<T>,
payload_dims: Vec<usize>,
strides: Vec<isize>,
axis_classes: Vec<usize>,
) -> Result<Storage, Error>where
T: StorageScalar,
pub fn new_structured<T>(
data: Vec<T>,
payload_dims: Vec<usize>,
strides: Vec<isize>,
axis_classes: Vec<usize>,
) -> Result<Storage, Error>where
T: StorageScalar,
Create a new structured storage (generic over scalar type).
pub fn from_dense_f64_col_major(
data: Vec<f64>,
logical_dims: &[usize],
) -> Result<Storage, Error>
pub fn from_dense_f64_col_major( data: Vec<f64>, logical_dims: &[usize], ) -> Result<Storage, Error>
Create dense f64 storage from column-major logical values.
pub fn from_dense_c64_col_major(
data: Vec<Complex<f64>>,
logical_dims: &[usize],
) -> Result<Storage, Error>
pub fn from_dense_c64_col_major( data: Vec<Complex<f64>>, logical_dims: &[usize], ) -> Result<Storage, Error>
Create dense Complex64 storage from column-major logical values.
pub fn from_diag_f64_col_major(
diag_data: Vec<f64>,
logical_rank: usize,
) -> Result<Storage, Error>
pub fn from_diag_f64_col_major( diag_data: Vec<f64>, logical_rank: usize, ) -> Result<Storage, Error>
Create diagonal f64 storage from column-major diagonal payload values.
pub fn from_diag_c64_col_major(
diag_data: Vec<Complex<f64>>,
logical_rank: usize,
) -> Result<Storage, Error>
pub fn from_diag_c64_col_major( diag_data: Vec<Complex<f64>>, logical_rank: usize, ) -> Result<Storage, Error>
Create diagonal Complex64 storage from column-major diagonal payload values.
pub fn is_complex(&self) -> bool
pub fn is_complex(&self) -> bool
Check if this storage uses complex scalar type.
This is an alias for is_c64().
pub fn sum<T>(&self) -> Twhere
T: SumFromStorage,
pub fn sum<T>(&self) -> Twhere
T: SumFromStorage,
Sum all elements, converting to type T.
§Example
use tensor4all_tensorbackend::Storage;
let s = Storage::from_dense_col_major(vec![1.0, 2.0, 3.0], &[3]).unwrap();
assert_eq!(s.sum::<f64>(), 6.0);pub fn max_abs(&self) -> f64
pub fn max_abs(&self) -> f64
Maximum absolute value over all stored elements.
For real storage this is max(|x|), and for complex storage this is
max(norm(z)).
pub fn to_dense_f64_col_major_vec(
&self,
logical_dims: &[usize],
) -> Result<Vec<f64>, String>
pub fn to_dense_f64_col_major_vec( &self, logical_dims: &[usize], ) -> Result<Vec<f64>, String>
Materialize dense logical values as a column-major f64 buffer.
pub fn to_dense_c64_col_major_vec(
&self,
logical_dims: &[usize],
) -> Result<Vec<Complex<f64>>, String>
pub fn to_dense_c64_col_major_vec( &self, logical_dims: &[usize], ) -> Result<Vec<Complex<f64>>, String>
Materialize dense logical values as a column-major Complex64 buffer.
pub fn to_dense_storage(&self, dims: &[usize]) -> Storage
pub fn to_dense_storage(&self, dims: &[usize]) -> Storage
Convert this storage to dense storage. For Diag storage, creates a Dense storage with diagonal elements set and off-diagonal elements as zero. For Dense storage, returns a copy (clone).
pub fn permute_storage(&self, _dims: &[usize], perm: &[usize]) -> Storage
pub fn permute_storage(&self, _dims: &[usize], perm: &[usize]) -> Storage
Permute the storage data according to the given permutation.
pub fn extract_real_part(&self) -> Storage
pub fn extract_real_part(&self) -> Storage
Extract real part from Complex64 storage as f64 storage. For f64 storage, returns a copy (clone).
pub fn extract_imag_part(&self, _dims: &[usize]) -> Storage
pub fn extract_imag_part(&self, _dims: &[usize]) -> Storage
Extract imaginary part from Complex64 storage as f64 storage. For f64 storage, returns zero storage (will be resized appropriately).
pub fn to_complex_storage(&self) -> Storage
pub fn to_complex_storage(&self) -> Storage
Convert f64 storage to Complex64 storage (real part only, imaginary part is zero). For Complex64 storage, returns a clone.
pub fn conj(&self) -> Storage
pub fn conj(&self) -> Storage
Complex conjugate of all elements.
For real (f64) storage, returns a clone (conjugate of real is identity). For complex (Complex64) storage, conjugates each element.
This is inspired by the conj operation in ITensorMPS.jl.
§Example
use tensor4all_tensorbackend::Storage;
use num_complex::Complex64;
let data = vec![Complex64::new(1.0, 2.0), Complex64::new(3.0, -4.0)];
let storage = Storage::from_dense_col_major(data, &[2]).unwrap();
let conj_storage = storage.conj();
// conj(1+2i) = 1-2i, conj(3-4i) = 3+4ipub fn combine_to_complex(
real_storage: &Storage,
imag_storage: &Storage,
) -> Storage
pub fn combine_to_complex( real_storage: &Storage, imag_storage: &Storage, ) -> Storage
Combine two f64 storages into Complex64 storage. real_storage becomes the real part, imag_storage becomes the imaginary part. Formula: real + i * imag
pub fn try_add(&self, other: &Storage) -> Result<Storage, String>
pub fn try_add(&self, other: &Storage) -> Result<Storage, String>
Add two storages element-wise, returning Result on error instead of panicking.
Both storages must have the same type and length.
§Errors
Returns an error if:
- Storage types don’t match
- Storage lengths don’t match
pub fn try_sub(&self, other: &Storage) -> Result<Storage, String>
pub fn try_sub(&self, other: &Storage) -> Result<Storage, String>
Try to subtract two storages element-wise.
Returns an error if the storages have different types or lengths.
Trait Implementations§
§impl Add<&Storage> for &Storage
Add two storages element-wise.
Both storages must have the same type and length.
impl Add<&Storage> for &Storage
Add two storages element-wise. Both storages must have the same type and length.
§Panics
Panics if storage types don’t match or lengths differ.
§Note
Prefer using Storage::try_add which returns a Result instead of panicking.
This trait implementation is kept for convenience but may panic on invalid inputs.
§impl Mul<Scalar> for &Storage
Multiply storage by a scalar (AnyScalar).
May promote f64 storage to Complex64 when scalar is complex.
impl Mul<Scalar> for &Storage
Multiply storage by a scalar (AnyScalar). May promote f64 storage to Complex64 when scalar is complex.
Auto Trait Implementations§
impl Freeze for Storage
impl RefUnwindSafe for Storage
impl Send for Storage
impl Sync for Storage
impl Unpin for Storage
impl UnwindSafe for Storage
Blanket Implementations§
§impl<Rhs, Lhs, Output> AddByRef<Rhs> for Lhs
impl<Rhs, Lhs, Output> AddByRef<Rhs> for Lhs
type Output = Output
fn add_by_ref(&self, rhs: &Rhs) -> <Lhs as AddByRef<Rhs>>::Output
§impl<Rhs, Lhs, Output> AddByRef<Rhs> for Lhs
impl<Rhs, Lhs, Output> AddByRef<Rhs> for Lhs
type Output = Output
fn add_by_ref(&self, rhs: &Rhs) -> <Lhs as AddByRef<Rhs>>::Output
§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