Storage

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

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,

Create diagonal storage from column-major diagonal payload values (generic over scalar type).

pub fn new_dense<T>(size: usize) -> Storage

Create a new 1D zero-initialized dense storage (generic over scalar type).

pub fn new_diag<T>(diag_data: Vec<T>) -> Storage
where 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,

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>

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>

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>

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>

Create diagonal Complex64 storage from column-major diagonal payload values.

pub fn is_dense(&self) -> bool

Check if this storage is logically dense.

pub fn is_diag(&self) -> bool

Check if this storage is a Diag storage type.

pub fn is_f64(&self) -> bool

Check if this storage uses f64 scalar type.

pub fn is_c64(&self) -> bool

Check if this storage uses Complex64 scalar type.

pub fn is_complex(&self) -> bool

Check if this storage uses complex scalar type.

This is an alias for is_c64().

pub fn len(&self) -> usize

Get the length of the storage (number of elements).

pub fn is_empty(&self) -> bool

Check if the storage is empty.

pub fn sum<T>(&self) -> T
where 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

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>

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>

Materialize dense logical values as a column-major Complex64 buffer.

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

Permute the storage data according to the given permutation.

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

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

Convert f64 storage to Complex64 storage (real part only, imaginary part is zero). For Complex64 storage, returns a clone.

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+4i

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>

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>

Try to subtract two storages element-wise.

Returns an error if the storages have different types or lengths.

pub fn scale(&self, scalar: &Scalar) -> Storage

Scale storage by a scalar value.

If the scalar is complex but the storage is real, the storage is promoted to complex.

pub fn axpby( &self, a: &Scalar, other: &Storage, b: &Scalar, ) -> Result<Storage, String>

Compute linear combination: a * self + b * other.

Returns an error if the storages have different types or lengths. If any scalar is complex, the result is promoted to complex.

Trait Implementations§

§

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.

§

type Output = Storage

The resulting type after applying the + operator.
§

fn add(self, rhs: &Storage) -> <&Storage as Add<&Storage>>::Output

Performs the + operation. Read more
§

impl Clone for Storage

§

fn clone(&self) -> Storage

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Storage

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Mul<Complex<f64>> for &Storage

Multiply storage by a scalar (Complex64).

§

type Output = Storage

The resulting type after applying the * operator.
§

fn mul(self, scalar: Complex<f64>) -> <&Storage as Mul<Complex<f64>>>::Output

Performs the * operation. Read more
§

impl Mul<Scalar> for &Storage

Multiply storage by a scalar (AnyScalar). May promote f64 storage to Complex64 when scalar is complex.

§

type Output = Storage

The resulting type after applying the * operator.
§

fn mul(self, scalar: Scalar) -> <&Storage as Mul<Scalar>>::Output

Performs the * operation. Read more
§

impl Mul<f64> for &Storage

Multiply storage by a scalar (f64). For Complex64 storage, multiplies each element by the scalar (treated as real).

§

type Output = Storage

The resulting type after applying the * operator.
§

fn mul(self, scalar: f64) -> <&Storage as Mul<f64>>::Output

Performs the * operation. Read more

Auto Trait Implementations§

Blanket Implementations§

§

impl<Rhs, Lhs, Output> AddByRef<Rhs> for Lhs
where &'a Lhs: for<'a> Add<&'a Rhs, Output = Output>,

§

type Output = Output

§

fn add_by_ref(&self, rhs: &Rhs) -> <Lhs as AddByRef<Rhs>>::Output

§

impl<Rhs, Lhs, Output> AddByRef<Rhs> for Lhs
where &'a Lhs: for<'a> Add<&'a Rhs, Output = Output>,

§

type Output = Output

§

fn add_by_ref(&self, rhs: &Rhs) -> <Lhs as AddByRef<Rhs>>::Output

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<U> As for U

§

fn as_<T>(self) -> T
where T: CastFrom<U>,

Casts 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 more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> ByRef<T> for T

§

fn by_ref(&self) -> &T

§

impl<T> ByRef<T> for T

§

fn by_ref(&self) -> &T

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> DistributionExt for T
where T: ?Sized,

§

fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> T
where Self: Distribution<T>,

§

impl<T> DistributionExt for T
where T: ?Sized,

§

fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> T
where Self: Distribution<T>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

§

impl<T> MaybeSend for T

§

impl<T> MaybeSendSync for T

§

impl<T> MaybeSync for T