pub trait TensorLike: TensorIndex {
Show 22 methods
// Required methods
fn factorize(
&self,
left_inds: &[<Self as TensorIndex>::Index],
options: &FactorizeOptions,
) -> Result<FactorizeResult<Self>, FactorizeError>;
fn conj(&self) -> Self;
fn direct_sum(
&self,
other: &Self,
pairs: &[(<Self as TensorIndex>::Index, <Self as TensorIndex>::Index)],
) -> Result<DirectSumResult<Self>>;
fn outer_product(&self, other: &Self) -> Result<Self>;
fn norm_squared(&self) -> f64;
fn permuteinds(
&self,
new_order: &[<Self as TensorIndex>::Index],
) -> Result<Self>;
fn contract(tensors: &[&Self], allowed: AllowedPairs<'_>) -> Result<Self>;
fn contract_connected(
tensors: &[&Self],
allowed: AllowedPairs<'_>,
) -> Result<Self>;
fn axpby(&self, a: AnyScalar, other: &Self, b: AnyScalar) -> Result<Self>;
fn scale(&self, scalar: AnyScalar) -> Result<Self>;
fn inner_product(&self, other: &Self) -> Result<AnyScalar>;
fn maxabs(&self) -> f64;
fn diagonal(
input_index: &<Self as TensorIndex>::Index,
output_index: &<Self as TensorIndex>::Index,
) -> Result<Self>;
fn scalar_one() -> Result<Self>;
fn ones(indices: &[<Self as TensorIndex>::Index]) -> Result<Self>;
fn onehot(
index_vals: &[(<Self as TensorIndex>::Index, usize)],
) -> Result<Self>;
// Provided methods
fn norm(&self) -> f64 { ... }
fn sub(&self, other: &Self) -> Result<Self> { ... }
fn neg(&self) -> Result<Self> { ... }
fn isapprox(&self, other: &Self, atol: f64, rtol: f64) -> bool { ... }
fn validate(&self) -> Result<()> { ... }
fn delta(
input_indices: &[<Self as TensorIndex>::Index],
output_indices: &[<Self as TensorIndex>::Index],
) -> Result<Self> { ... }
}Expand description
Trait for tensor-like objects that expose external indices and support contraction.
This trait is fully generic (monomorphic), meaning it does not support
trait objects (dyn TensorLike). For heterogeneous tensor collections,
use an enum wrapper instead.
§Design Principles
- Minimal interface: Only external indices and automatic contraction
- Fully generic: Uses associated type for
Index, returnsSelf - Stable ordering:
external_indices()returns indices in deterministic order - No trait objects: Requires
Sized, cannot usedyn TensorLike
§Example
use tensor4all_core::{TensorLike, AllowedPairs};
fn contract_pair<T: TensorLike>(a: &T, b: &T) -> Result<T> {
T::contract(&[a, b], AllowedPairs::All)
}§Heterogeneous Collections
For mixing different tensor types, define an enum:
enum TensorNetwork {
Dense(TensorDynLen),
MPS(MatrixProductState),
}§Supertrait
TensorLike extends TensorIndex, which provides:
external_indices()- Get all external indicesnum_external_indices()- Count external indicesreplaceind()/replaceinds()- Replace indices
This separation allows tensor networks (like TreeTN) to implement
index operations without implementing contraction/factorization.
Required Methods§
Sourcefn 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>
Factorize this tensor into left and right factors.
This function dispatches to the appropriate algorithm based on options.alg:
SVD: Singular Value DecompositionQR: QR decompositionLU: Rank-revealing LU decompositionCI: Cross Interpolation
The canonical option controls which factor is “canonical”:
Canonical::Left: Left factor is orthogonal (SVD/QR) or unit-diagonal (LU/CI)Canonical::Right: Right factor is orthogonal (SVD) or unit-diagonal (LU/CI)
§Arguments
left_inds- Indices to place on the left sideoptions- Factorization options
§Returns
A FactorizeResult containing the left and right factors, bond index,
singular values (for SVD), and rank.
§Errors
Returns FactorizeError if:
- The storage type is not supported (only DenseF64 and DenseC64)
- QR is used with
Canonical::Right - The underlying algorithm fails
Sourcefn conj(&self) -> Self
fn conj(&self) -> Self
Tensor conjugate operation.
This is a generalized conjugate operation that depends on the tensor type:
- For dense tensors (TensorDynLen): element-wise complex conjugate
- For symmetric tensors: tensor conjugate considering symmetry sectors
This operation is essential for computing inner products and overlaps in tensor network algorithms like fitting.
§Returns
A new tensor representing the tensor conjugate.
Sourcefn 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>>
Direct sum of two tensors along specified index pairs.
For tensors A and B with indices to be summed specified as pairs, creates a new tensor C where each paired index has dimension = dim_A + dim_B. Non-paired indices must match exactly between A and B (same ID).
§Arguments
other- Second tensorpairs- Pairs of (self_index, other_index) to be summed. Each pair creates a new index in the result with dimension = dim(self_index) + dim(other_index).
§Returns
A DirectSumResult containing the result tensor and new indices created
for the summed dimensions (one per pair).
§Example
// A has indices [i, j] with dims [2, 3]
// B has indices [i, k] with dims [2, 4]
// If we pair (j, k), result has indices [i, m] with dims [2, 7]
// where m is a new index with dim = 3 + 4 = 7
let result = a.direct_sum(&b, &[(j, k)])?;Sourcefn outer_product(&self, other: &Self) -> Result<Self>
fn outer_product(&self, other: &Self) -> Result<Self>
Outer product (tensor product) of two tensors.
Computes the tensor product of self and other, resulting in a tensor
with all indices from both tensors. No indices are contracted.
§Arguments
other- The other tensor to compute outer product with
§Returns
A new tensor representing the outer product.
§Errors
Returns an error if the tensors have common indices (by ID).
Use tensordot for contraction when indices overlap.
Sourcefn norm_squared(&self) -> f64
fn norm_squared(&self) -> f64
Compute the squared Frobenius norm of the tensor.
The squared Frobenius norm is defined as the sum of squared absolute values
of all tensor elements: ||T||_F^2 = sum_i |T_i|^2.
This is used for computing norms in tensor network algorithms, convergence checks, and normalization.
§Returns
The squared Frobenius norm as a non-negative f64.
Sourcefn permuteinds(
&self,
new_order: &[<Self as TensorIndex>::Index],
) -> Result<Self>
fn permuteinds( &self, new_order: &[<Self as TensorIndex>::Index], ) -> Result<Self>
Permute tensor indices to match the specified order.
This reorders the tensor’s axes to match the order specified by new_order.
The indices in new_order are matched by ID with the tensor’s current indices.
§Arguments
new_order- The desired order of indices (matched by ID)
§Returns
A new tensor with permuted indices.
§Errors
Returns an error if:
- The number of indices doesn’t match
- An index ID in
new_orderis not found in the tensor
Sourcefn contract(tensors: &[&Self], allowed: AllowedPairs<'_>) -> Result<Self>
fn contract(tensors: &[&Self], allowed: AllowedPairs<'_>) -> Result<Self>
Contract multiple tensors over their contractable indices.
This method contracts 2 or more tensors. Pairs of indices that satisfy
is_contractable() (same ID, same dimension, compatible ConjState)
are contracted based on the allowed parameter.
Handles disconnected tensor graphs automatically by:
- Finding connected components based on contractable indices
- Contracting each connected component separately
- Combining results using outer product
§Arguments
tensors- Slice of tensor references to contract (must have length >= 1)allowed- Specifies which tensor pairs can have their indices contracted:AllowedPairs::All: Contract all contractable index pairs (default behavior)AllowedPairs::Specified(&[(i, j)]): Only contract indices between specified tensor pairs
§Returns
A new tensor representing the contracted result. If tensors form disconnected components, they are combined via outer product.
§Behavior by N
- N=0: Error
- N=1: Clone of input
- N>=2: Contract connected components, combine with outer product
§Errors
Returns an error if:
- No tensors are provided
AllowedPairs::Specifiedcontains a pair with no contractable indices
§Example
// Contract all contractable pairs
let result = T::contract(&[&a, &b, &c], AllowedPairs::All)?;
// Only contract between tensor pairs (0,1) and (1,2)
let result = T::contract(&[&a, &b, &c], AllowedPairs::Specified(&[(0, 1), (1, 2)]))?;Sourcefn contract_connected(
tensors: &[&Self],
allowed: AllowedPairs<'_>,
) -> Result<Self>
fn contract_connected( tensors: &[&Self], allowed: AllowedPairs<'_>, ) -> Result<Self>
Contract multiple tensors that must form a connected graph.
This is the core contraction method that requires all tensors to be
connected through contractable indices. Use Self::contract if you want
automatic handling of disconnected components via outer product.
§Arguments
tensors- Slice of tensor references to contract (must form a connected graph)allowed- Specifies which tensor pairs can have their indices contracted
§Returns
A new tensor representing the contracted result.
§Errors
Returns an error if:
- No tensors are provided
- The tensors form a disconnected graph
§Example
// All tensors must be connected through contractable indices
let result = T::contract_connected(&[&a, &b, &c], AllowedPairs::All)?;Sourcefn axpby(&self, a: AnyScalar, other: &Self, b: AnyScalar) -> Result<Self>
fn axpby(&self, a: AnyScalar, other: &Self, b: AnyScalar) -> Result<Self>
Compute a linear combination: a * self + b * other.
This is the fundamental vector space operation.
Sourcefn inner_product(&self, other: &Self) -> Result<AnyScalar>
fn inner_product(&self, other: &Self) -> Result<AnyScalar>
Inner product (dot product) of two tensors.
Computes ⟨self, other⟩ = Σ conj(self)_i * other_i.
Sourcefn 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>
Create a diagonal (Kronecker delta) tensor for a single index pair.
Creates a 2D tensor T[i, o] where T[i, o] = δ_{i,o} (1 if i==o, 0 otherwise).
§Arguments
input_index- Input indexoutput_index- Output index (must have same dimension as input)
§Returns
A 2D tensor with shape [dim, dim] representing the identity matrix.
§Errors
Returns an error if dimensions don’t match.
§Example
For dimension 2:
diagonal(i, o) = [[1, 0], [0, 1]]Sourcefn scalar_one() -> Result<Self>
fn scalar_one() -> Result<Self>
Create a scalar tensor with value 1.0.
This is used as the identity element for outer products.
Sourcefn ones(indices: &[<Self as TensorIndex>::Index]) -> Result<Self>
fn ones(indices: &[<Self as TensorIndex>::Index]) -> Result<Self>
Provided Methods§
Sourcefn sub(&self, other: &Self) -> Result<Self>
fn sub(&self, other: &Self) -> Result<Self>
Element-wise subtraction: self - other.
Indices are automatically permuted to match self’s order via axpby.
Sourcefn isapprox(&self, other: &Self, atol: f64, rtol: f64) -> bool
fn isapprox(&self, other: &Self, atol: f64, rtol: f64) -> bool
Approximate equality check (Julia isapprox semantics).
Returns true if ||self - other|| <= max(atol, rtol * max(||self||, ||other||)).
Sourcefn validate(&self) -> Result<()>
fn validate(&self) -> Result<()>
Validate structural consistency of this tensor.
The default implementation does nothing (always succeeds).
Types with internal structure (e.g., [BlockTensor]) can override
this to check invariants such as index sharing between blocks.
Sourcefn 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>
Create a delta (identity) tensor as outer product of diagonals.
For paired indices (i1, o1), (i2, o2), ..., creates a tensor where:
T[i1, o1, i2, o2, ...] = δ_{i1,o1} × δ_{i2,o2} × ...
This is computed as the outer product of individual diagonal tensors.
§Arguments
input_indices- Input indicesoutput_indices- Output indices (must have same length and matching dimensions)
§Returns
A tensor representing the identity operator on the given index space.
§Errors
Returns an error if:
- Number of input and output indices don’t match
- Dimensions of paired indices don’t match
§Example
For a single index pair with dimension 2:
delta([i], [o]) = [[1, 0], [0, 1]]Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.