Reference

TensorAlgebra.ConjBroadcastedType
ConjBroadcasted(parent)

Lazy conjugate node in the linear-combination broadcast fold, the LinearBroadcasted counterpart of ScaledBroadcasted/AddBroadcasted. Holds parent (any array-like operand or backend tensor, not necessarily an AbstractArray) and presents its axes conjugated (dualized); the op primitives absorb it by unwrapping to the parent and folding conj into their op (see the bipermutedimsopadd! method below). Produced internally by the conj lowering of a broadcast (linearbroadcasted(conj, a)), not a user-facing lazy-conjugate wrapper. Because it is not an AbstractArray, it works for non-array backends (e.g. a TensorMap) as well as dense arrays.

source
TensorAlgebra.LinearBroadcastedType
LinearBroadcasted

Abstract supertype for lazy linear broadcast expressions. Analogous to Base.Broadcast.Broadcasted but restricted to linear operations.

Materializes via the protocol: copy(lb) = copyto!(similar(lb), lb) copyto!(dest, lb) → add!(dest, lb, 1, 0)

source
TensorAlgebra.PermutedDimsType
PermutedDims(parent, perm)

Lazy permuted-dims wrapper storing parent and the permutation perm in fields (unlike Base.PermutedDimsArray, which encodes perm in a type parameter), so it constructs cheaply from a runtime permutation. Primarily for internal use to track permutations in linear broadcasting.

source
TensorAlgebra.allocate_projectMethod
allocate_project(raw, codomain_axes, domain_axes) -> dest

Allocate the destination that projecting raw onto codomain_axes/domain_axes fills. The generic method is similar_map(raw, codomain_axes, domain_axes). This is a backend customization point (with projectto! and is_projected): the allocation may depend on the data, since a symmetric backend derives the space of one trailing surplus axis in raw (an auxiliary leg appended as the last domain axis, e.g. a flux-canceling leg for a charge-shifting operator) before allocating.

source
TensorAlgebra.bipartitionMethod
bipartition(t::Tuple, length1::Val) -> (t1, t2)
bipartition(t::Tuple, group1::Tuple, group2::Tuple) -> (p1, p2)

Split a flat tuple into two groups, returned as a pair of tuples.

The first form splits t in order, taking the first length1 entries as t1 and the remaining entries as t2. The second form gathers the entries of t at the two index groups group1 and group2, returning p1 = t[group1...] and p2 = t[group2...].

source
TensorAlgebra.bipermMethod
biperm(t, t1, t2) -> (p1, p2)

Locate the groups t1 and t2 within t, returning the positions of t1 as p1 and the positions of t2 as p2. The groups t1 and t2 must partition t, so the concatenation (p1..., p2...) is a permutation of eachindex(t) and the pair (p1, p2) is a bipartitioned permutation (a "biperm") splitting t into a codomain p1 and a domain p2.

source
TensorAlgebra.bipermutedimsopadd!Method
bipermutedimsopadd!(dest, op, src, perm_codomain, perm_domain, α, β)

dest = β * dest + α * permutedims(op.(src), (perm_codomain..., perm_domain...)).

This is the primary overload point for downstream array types that want to implement op-aware bipartitioned permutation + accumulation (e.g., fuse conj into the copy, or use lazy wrappers like StridedView with op metadata).

The op is the conjugation flag expressed as a function — identity or conj, analogous to TensorOperations' boolean conjA/conjB. On graded axes conj dualizes; on dense axes it is a no-op. Transposition/permutation is carried by the perm arguments, not by op.

The default implementation flattens the bipartitioned permutation, applies op element-wise, permutes, then accumulates via broadcasting with Strided.jl optimization when possible.

source
TensorAlgebra.eig_fullFunction
eig_full(A, labels_A, labels_codomain, labels_domain; kwargs...) -> D, V
eig_full(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> D, V
eig_full(A, ndims_codomain::Val; kwargs...) -> D, V

Compute the eigenvalue decomposition of a generic N-dimensional array interpreted as a general (non-Hermitian) linear map from the domain to the codomain dimensions. The output eltype is always <:Complex. The partition is specified either via labels or directly through a bi-permutation.

See also MatrixAlgebraKit.eig_full!.

source
TensorAlgebra.eig_truncFunction
eig_trunc(A, labels_A, labels_codomain, labels_domain; trunc, kwargs...) -> D, V
eig_trunc(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; trunc, kwargs...) -> D, V
eig_trunc(A, ndims_codomain::Val; trunc, kwargs...) -> D, V

Truncated general eigenvalue decomposition, like eig_full but keeping only the eigenvalues selected by the trunc strategy.

See also MatrixAlgebraKit.eig_trunc!.

source
TensorAlgebra.eig_valsFunction
eig_vals(A, labels_A, labels_codomain, labels_domain; kwargs...) -> D
eig_vals(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> D
eig_vals(A, ndims_codomain::Val; kwargs...) -> D

Compute the eigenvalues of a generic N-dimensional array interpreted as a general (non-Hermitian) linear map from the domain to the codomain dimensions. The output is a vector of eigenvalues with <:Complex eltype.

See also MatrixAlgebraKit.eig_vals!.

source
TensorAlgebra.eigh_fullFunction
eigh_full(A, labels_A, labels_codomain, labels_domain; kwargs...) -> D, V
eigh_full(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> D, V
eigh_full(A, ndims_codomain::Val; kwargs...) -> D, V

Compute the eigenvalue decomposition of a generic N-dimensional array interpreted as a Hermitian linear map from the domain to the codomain dimensions. The partition is specified either via labels or directly through a bi-permutation.

See also MatrixAlgebraKit.eigh_full!.

source
TensorAlgebra.eigh_truncFunction
eigh_trunc(A, labels_A, labels_codomain, labels_domain; trunc, kwargs...) -> D, V
eigh_trunc(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; trunc, kwargs...) -> D, V
eigh_trunc(A, ndims_codomain::Val; trunc, kwargs...) -> D, V

Truncated Hermitian eigenvalue decomposition, like eigh_full but keeping only the eigenvalues selected by the trunc strategy.

See also MatrixAlgebraKit.eigh_trunc!.

source
TensorAlgebra.eigh_valsFunction
eigh_vals(A, labels_A, labels_codomain, labels_domain; kwargs...) -> D
eigh_vals(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> D
eigh_vals(A, ndims_codomain::Val; kwargs...) -> D

Compute the eigenvalues of a generic N-dimensional array interpreted as a Hermitian linear map from the domain to the codomain dimensions. The output is a vector of eigenvalues.

See also MatrixAlgebraKit.eigh_vals!.

source
TensorAlgebra.gram_eigh_fullFunction
gram_eigh_full(A, labels_A, labels_codomain, labels_domain; kwargs...) -> X
gram_eigh_full(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> X
gram_eigh_full(A, ndims_codomain::Val; kwargs...) -> X

Gram factorization of a generic N-dimensional array, interpreting it as a Hermitian positive semi-definite linear map from the domain to the codomain dimensions. Returns X such that A ≈ X * X' (contracted on the rank leg), i.e. the codomain axes of X match the codomain axes of A and X has a single trailing rank axis.

Keyword arguments

  • alg: forwarded to MatrixAlgebraKit.eigh_full.

  • atol::Real: absolute clamping threshold. Default 0.

  • rtol::Real: relative clamping threshold. Default eps(real(eltype(A)))^(3//4) when atol = 0, else 0.

Examples

julia> using TensorAlgebra: contract, gram_eigh_full

julia> B = randn(3, 2, 2);

julia> A = contract((:a, :b, :c, :d), conj(B), (:r, :a, :b), B, (:r, :c, :d));

julia> X = gram_eigh_full(A, (:a, :b, :c, :d), (:a, :b), (:c, :d));

julia> A ≈ contract((:a, :b, :c, :d), X, (:a, :b, :r), conj(X), (:c, :d, :r))
true

See also gram_eigh_full_with_pinv and MatrixAlgebra.gram_eigh_full.

source
TensorAlgebra.gram_eigh_full_with_pinvFunction
gram_eigh_full_with_pinv(A, labels_A, labels_codomain, labels_domain; kwargs...) -> X, Y
gram_eigh_full_with_pinv(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> X, Y
gram_eigh_full_with_pinv(A, ndims_codomain::Val; kwargs...) -> X, Y

Like gram_eigh_full, but additionally returns Y ≈ pinv(X) such that Y * X ≈ I on the rank subspace (a left inverse). The codomain axes of X match the codomain axes of A; Y has a leading rank axis followed by the codomain axes.

Keyword arguments

  • alg: forwarded to MatrixAlgebraKit.eigh_full.

  • atol::Real: absolute clamping threshold. Default 0.

  • rtol::Real: relative clamping threshold. Default eps(real(eltype(A)))^(3//4) when atol = 0, else 0.

Examples

julia> using LinearAlgebra: I

julia> using TensorAlgebra: contract, gram_eigh_full_with_pinv

julia> B = randn(8, 2, 2);

julia> A = contract((:a, :b, :c, :d), conj(B), (:r, :a, :b), B, (:r, :c, :d));

julia> X, Y = gram_eigh_full_with_pinv(A, (:a, :b, :c, :d), (:a, :b), (:c, :d));

julia> A ≈ contract((:a, :b, :c, :d), X, (:a, :b, :r), conj(X), (:c, :d, :r))
true

julia> contract((:r, :s), Y, (:r, :a, :b), X, (:a, :b, :s)) ≈ I
true

See also MatrixAlgebra.gram_eigh_full_with_pinv.

source
TensorAlgebra.invsqrth_safeFunction
invsqrth_safe(A, labels_A, labels_codomain, labels_domain; kwargs...) -> P
invsqrth_safe(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> P
invsqrth_safe(A, ndims_codomain::Val; kwargs...) -> P

Pseudo-inverse square root of a generic N-dimensional array, interpreting it as a Hermitian positive semi-definite linear map from the domain to the codomain dimensions. The result carries the same codomain and domain axes as A. Eigenvalues below tolerance are clamped to zero (Moore-Penrose convention). The input must be Hermitian: project with project_hermitian first if it is Hermitian only up to numerical noise.

Keyword arguments

  • alg: forwarded to MatrixAlgebraKit.eigh_full.

  • atol::Real: absolute clamping threshold. Default 0.

  • rtol::Real: relative clamping threshold. Default eps(real(eltype(A)))^(3//4) when atol = 0, else 0.

See also sqrth_safe, sqrth_invsqrth_safe, and MatrixAlgebra.invsqrth_safe.

source
TensorAlgebra.is_projectedMethod
is_projected(dest, src; kwargs...) -> Bool

Whether the projected dest still represents src within the isapprox tolerance, i.e. whether the projection that produced dest discarded only a negligible component of src. Keyword arguments are forwarded to isapprox.

Together with unchecked_project this is the backend customization point (project and tryproject derive from the two). The generic method reshapes src to size(dest) up to trailing length-1 axes (so a lower-rank src that omits them lines up) and compares against convert(Array, dest), so a backend whose arrays are not elementwise comparable to a dense array (opaque block storage, a TensorMap) only needs that conversion.

source
TensorAlgebra.label_typeMethod
label_type(::Type{L}) -> Type

The label type to use when deriving a contraction.

Deriving a contraction makes several passes comparing labels, so a label type that is costly to compare can map here to a cheaper integer type: the labels are matched to integers by equality pattern, the bookkeeping runs on the integers, and the derived labels are mapped back. The default is the identity label_type(::Type{L}) = L, so the bookkeeping runs on the labels as-is. A label type with expensive equality opts in by defining e.g.

TensorAlgebra.label_type(::Type{MyLabel}) = Int
source
TensorAlgebra.left_nullFunction
left_null(A, labels_A, labels_codomain, labels_domain; kwargs...) -> N
left_null(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> N
left_null(A, ndims_codomain::Val; kwargs...) -> N

Compute the left nullspace of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions. These can be specified either via their labels or directly through a bi-permutation. The output satisfies N' * A ≈ 0 and N' * N ≈ I.

Keyword arguments

  • atol::Real=0: absolute tolerance for the nullspace computation.
  • rtol::Real=0: relative tolerance for the nullspace computation.
  • kind::Symbol: specify the kind of decomposition used to compute the nullspace. The options are :qr, :qrpos and :svd. The former two require 0 == atol == rtol. The default is :qrpos if atol == rtol == 0, and :svd otherwise.
source
TensorAlgebra.left_orthFunction
left_orth(A, labels_A, labels_codomain, labels_domain; kwargs...) -> V, C
left_orth(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> V, C
left_orth(A, ndims_codomain::Val; kwargs...) -> V, C

Compute the left orthogonal decomposition of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions. These can be specified either via their labels or directly through a bi-permutation.

Keyword arguments

  • Keyword arguments are passed on directly to MatrixAlgebraKit.

See also MatrixAlgebraKit.left_orth!.

source
TensorAlgebra.left_polarFunction
left_polar(A, labels_A, labels_codomain, labels_domain; kwargs...) -> W, P
left_polar(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> W, P
left_polar(A, ndims_codomain::Val; kwargs...) -> W, P

Compute the left polar decomposition of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions. These can be specified either via their labels or directly through a bi-permutation.

Keyword arguments

  • Keyword arguments are passed on directly to MatrixAlgebraKit.

See also MatrixAlgebraKit.left_polar!.

source
TensorAlgebra.linearbroadcastedFunction
linearbroadcasted(f, args...)

Construct a LinearBroadcasted subtype from function f and arguments. Analogous to Base.Broadcast.broadcasted(f, args...).

Examples

linearbroadcasted(*, 2.0, a)   # ScaledBroadcasted(2.0, a)
linearbroadcasted(conj, a)     # ConjBroadcasted(a)
linearbroadcasted(+, a, b)     # AddBroadcasted(a, b)
source
TensorAlgebra.lq_compactFunction
lq_compact(A, labels_A, labels_codomain, labels_domain; kwargs...) -> L, Q
lq_compact(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> L, Q
lq_compact(A, ndims_codomain::Val; kwargs...) -> L, Q

Compute the compact LQ decomposition of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions, where L is square. The partition is specified either via labels or directly through a bi-permutation.

Keyword arguments

  • positive::Bool=false: specify if the diagonal of L should be positive, leading to a unique decomposition.
  • Other keywords are passed on directly to MatrixAlgebraKit.

See also MatrixAlgebraKit.lq_compact!.

source
TensorAlgebra.lq_fullFunction
lq_full(A, labels_A, labels_codomain, labels_domain; kwargs...) -> L, Q
lq_full(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> L, Q
lq_full(A, ndims_codomain::Val; kwargs...) -> L, Q

Compute the full LQ decomposition of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions, where Q is unitary. The partition is specified either via labels or directly through a bi-permutation.

Keyword arguments

  • positive::Bool=false: specify if the diagonal of L should be positive, leading to a unique decomposition.
  • Other keywords are passed on directly to MatrixAlgebraKit.

See also MatrixAlgebraKit.lq_full!.

source
TensorAlgebra.matricizeoppermMethod
matricizeopperm(op, a, perm_codomain, perm_domain)

Matricize a with element-wise operation op folded in. Returns a matrix representing op.(matricizeperm(a, perm_codomain, perm_domain)).

Has "maybe alias" semantics: the result may be a view/wrapper aliasing a or a fresh copy, depending on the fusion style and array type. The caller should treat the result as read-only.

source
TensorAlgebra.oneFunction
TensorAlgebra.one(A, labels_A, labels_codomain, labels_domain) -> Id
TensorAlgebra.one(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}) -> Id
TensorAlgebra.one(A, ndims_codomain::Val) -> Id

Construct the identity operator tensor whose shape mirrors A, interpreted as a linear map from the domain to the codomain dimensions. The codomain and domain partition is specified either via labels or directly through a bi-permutation; fused codomain and domain sizes must match. A is treated as a shape prototype and is not mutated.

Not exported, since exporting would clash with the implicit Base.one. Qualify as TensorAlgebra.one(A, ...).

See also MatrixAlgebraKit.one!.

Examples

julia> using LinearAlgebra: I

julia> using TensorAlgebra: TensorAlgebra, matricize

julia> A = randn(2, 3, 2, 3);

julia> Id = TensorAlgebra.one(A, (:a, :b, :c, :d), (:a, :b), (:c, :d));

julia> matricize(Id, Val(2)) ≈ I
true
source
TensorAlgebra.permuteddimsMethod
permuteddims(a, perm)

Lazy permutedims. For an AbstractArray this is a Base.PermutedDimsArray view; for any other operand it is a generic PermutedDims node. This is an extension hook: downstream types can overload it to return their own lazy permuted-dims type.

source
TensorAlgebra.permutedims!Method
permutedims!(dest, a, perm)
permutedims!(dest, a, perm_codomain, perm_domain)

In-place counterpart of permutedims: write the permuted a into dest. Both forms forward to bipermutedimsopadd! with α, β = true, false; the flat form passes an empty domain permutation.

source
TensorAlgebra.permutedimsMethod
permutedims(a, perm)
permutedims(a, perm_codomain, perm_domain)

Out-of-place permutation of a, mirroring TensorKit.permute. The single-permutation form reorders every dimension into perm, giving an all-codomain result. The two-permutation form additionally splits the dimensions into a codomain/domain bipartition, with perm_codomain selecting the codomain dimensions and perm_domain the domain ones.

Allocates the destination with similar_map and materializes it through permutedims!, so any operand implementing the permutedimsopadd! / bipermutedimsopadd! interface (a dense array, a graded array, a TensorMap) is permuted with no dedicated method. A dense operand ignores the bipartition and stores the result flat.

source
TensorAlgebra.permutedimsopMethod
permutedimsop(op, src, perm_codomain, perm_domain)

Non-mutating version of bipermutedimsopadd!: returns op.(permutedims(src, (perm_codomain..., perm_domain...))).

source
TensorAlgebra.permutedimsopadd!Method
permutedimsopadd!(dest, op, src, perm, α, β)

dest = β * dest + α * permutedims(op.(src), perm).

This is the single materialization primitive for LinearBroadcasted types. Downstream array types should implement bipermutedimsopadd! for the bipartitioned permutation version; this flat-permutation overload forwards to it with perm_domain = ().

source
TensorAlgebra.project!Method
project!(dest, src; kwargs...) -> dest

In-place checked projection: project src into the restricted space of dest via projectto! and verify with is_projected that only a negligible component was discarded, throwing an InexactError otherwise (keyword arguments are forwarded to the isapprox tolerance check). This is the checked sibling of the projectto! primitive, in the way copy! relates to copyto!; see project for the allocating form.

source
TensorAlgebra.projectMethod
project(raw, codomain_axes, domain_axes; kwargs...) -> dest
project(raw, axes; kwargs...) -> dest

Project raw into a symmetry-restricted array shaped as a map from domain_axes to codomain_axes, verifying that only a negligible component of raw is discarded and throwing an InexactError otherwise (keyword arguments are forwarded to the isapprox tolerance check; the default tolerances are subject to change in future versions). See tryproject for a nullable version and unchecked_project for the unchecked projection this derives from.

When raw has one axis more than the given axes account for, that trailing surplus axis is an auxiliary leg whose space a symmetric backend derives so the result is symmetry-allowed (e.g. a flux-canceling leg for a charge-shifting operator); the result's shape matches raw's shape. The derivation is backend-internal: a graded backend reads the sector, the TensorMap backend projects over the codomain ⊗ conj(domain) content. The two-argument form takes a flat list of axes and is equivalent to an empty domain.

source
TensorAlgebra.project_hermitianFunction
project_hermitian(A, labels_A, labels_codomain, labels_domain; kwargs...) -> H
project_hermitian(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> H
project_hermitian(A, ndims_codomain::Val; kwargs...) -> H

Hermitian part (M + M') / 2 of a generic N-dimensional array, interpreting it as a linear map M from the domain to the codomain dimensions. The result carries the same codomain and domain axes as A.

See also MatrixAlgebraKit.project_hermitian.

source
TensorAlgebra.projectto!Method
projectto!(dest, src) -> dest

Project src into the restricted space of dest without checking which components may have been projected out. The default reshapes src to size(dest) up to trailing length-1 axes (so a lower-rank src may omit them, e.g. an auxiliary flux-canceling leg a codomain/domain split introduces on a symmetric state) and copyto!s, throwing on a genuine shape mismatch rather than reinterpreting the data. A backend whose arrays are not copyto!-compatible with a dense array overloads this. This is the in-place fill primitive that unchecked_project allocates a destination for.

source
TensorAlgebra.qr_compactFunction
qr_compact(A, labels_A, labels_codomain, labels_domain; kwargs...) -> Q, R
qr_compact(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> Q, R
qr_compact(A, ndims_codomain::Val; kwargs...) -> Q, R

Compute the compact QR decomposition of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions, where R is square. The partition is specified either via labels or directly through a bi-permutation.

Keyword arguments

  • positive::Bool=false: specify if the diagonal of R should be positive, leading to a unique decomposition.
  • Other keywords are passed on directly to MatrixAlgebraKit.

See also MatrixAlgebraKit.qr_compact!.

source
TensorAlgebra.qr_fullFunction
qr_full(A, labels_A, labels_codomain, labels_domain; kwargs...) -> Q, R
qr_full(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> Q, R
qr_full(A, ndims_codomain::Val; kwargs...) -> Q, R

Compute the full QR decomposition of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions, where Q is unitary. The partition is specified either via labels or directly through a bi-permutation.

Keyword arguments

  • positive::Bool=false: specify if the diagonal of R should be positive, leading to a unique decomposition.
  • Other keywords are passed on directly to MatrixAlgebraKit.

See also MatrixAlgebraKit.qr_full!.

source
TensorAlgebra.randFunction
zeros([T,] axes) -> A
randn([rng,] [T,] axes) -> A
rand([rng,] [T,] axes) -> A

Axis-friendly counterparts of Base.zeros/Base.randn/Base.rand, taking the axes as a single tuple. Base.zeros already accepts axes, but Base.randn/Base.rand accept only integer dims, so these fill that gap for dense Base.OneTo axes and otherwise forward to Base (so a graded-axis backend that extends Base.randn/rand on its axis type is picked up). These are the flat (non-map) companions of zeros_map.

source
TensorAlgebra.rand_mapFunction
zeros_map([T,] codomain_axes, domain_axes) -> M
randn_map([rng,] [T,] codomain_axes, domain_axes) -> M
rand_map([rng,] [T,] codomain_axes, domain_axes) -> M

Construct an array shaped as a linear map from domain_axes to codomain_axes, filled with zeros (zeros_map), normally-distributed values (randn_map), or uniformly-distributed values (rand_map), with element type T (defaulting to Float64). These are the value-filling companions of similar_map: the domain axes are given un-dualized (codomain facing) and stored dual, so the default flattens to the axis-friendly zeros/randn/rand over (codomain_axes..., conj.(domain_axes)...) (conj dualizes a graded axis and is a no-op on a dense one). Backends with map-shaped storage (e.g. a TensorMap) overload these to build the codomain/domain directly.

source
TensorAlgebra.randnFunction
zeros([T,] axes) -> A
randn([rng,] [T,] axes) -> A
rand([rng,] [T,] axes) -> A

Axis-friendly counterparts of Base.zeros/Base.randn/Base.rand, taking the axes as a single tuple. Base.zeros already accepts axes, but Base.randn/Base.rand accept only integer dims, so these fill that gap for dense Base.OneTo axes and otherwise forward to Base (so a graded-axis backend that extends Base.randn/rand on its axis type is picked up). These are the flat (non-map) companions of zeros_map.

source
TensorAlgebra.randn_mapFunction
zeros_map([T,] codomain_axes, domain_axes) -> M
randn_map([rng,] [T,] codomain_axes, domain_axes) -> M
rand_map([rng,] [T,] codomain_axes, domain_axes) -> M

Construct an array shaped as a linear map from domain_axes to codomain_axes, filled with zeros (zeros_map), normally-distributed values (randn_map), or uniformly-distributed values (rand_map), with element type T (defaulting to Float64). These are the value-filling companions of similar_map: the domain axes are given un-dualized (codomain facing) and stored dual, so the default flattens to the axis-friendly zeros/randn/rand over (codomain_axes..., conj.(domain_axes)...) (conj dualizes a graded axis and is a no-op on a dense one). Backends with map-shaped storage (e.g. a TensorMap) overload these to build the codomain/domain directly.

source
TensorAlgebra.right_nullFunction
right_null(A, labels_A, labels_codomain, labels_domain; kwargs...) -> Nᴴ
right_null(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> Nᴴ
right_null(A, ndims_codomain::Val::Val; kwargs...) -> Nᴴ

Compute the right nullspace of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions. These can be specified either via their labels or directly through a bi-permutation. The output satisfies A * Nᴴ' ≈ 0 and Nᴴ * Nᴴ' ≈ I.

Keyword arguments

  • atol::Real=0: absolute tolerance for the nullspace computation.
  • rtol::Real=0: relative tolerance for the nullspace computation.
  • kind::Symbol: specify the kind of decomposition used to compute the nullspace. The options are :lq, :lqpos and :svd. The former two require 0 == atol == rtol. The default is :lqpos if atol == rtol == 0, and :svd otherwise.
source
TensorAlgebra.right_orthFunction
right_orth(A, labels_A, labels_codomain, labels_domain; kwargs...) -> C, V
right_orth(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> C, V
right_orth(A, ndims_codomain::Val; kwargs...) -> C, V

Compute the right orthogonal decomposition of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions. These can be specified either via their labels or directly through a bi-permutation.

Keyword arguments

  • Keyword arguments are passed on directly to MatrixAlgebraKit.

See also MatrixAlgebraKit.right_orth!.

source
TensorAlgebra.right_polarFunction
right_polar(A, labels_A, labels_codomain, labels_domain; kwargs...) -> P, W
right_polar(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> P, W
right_polar(A, ndims_codomain::Val; kwargs...) -> P, W

Compute the right polar decomposition of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions. These can be specified either via their labels or directly through a bi-permutation.

Keyword arguments

  • Keyword arguments are passed on directly to MatrixAlgebraKit.

See also MatrixAlgebraKit.right_polar!.

source
TensorAlgebra.similar_mapMethod
similar_map(prototype, [T,] codomain_axes, domain_axes) -> M

Allocate an array shaped as a linear map from domain_axes to codomain_axes with element type T (defaulting to eltype(prototype)), using prototype to determine the array backend. The domain axes are given un-dualized (codomain facing) and stored dual, so the default is similar(prototype, T, (codomain_axes..., conj.(domain_axes)...)). conj dualizes a graded axis and is a no-op on a dense axis. Backends with map-shaped storage (e.g. a TensorMap) overload this to build the codomain/domain directly.

Examples

julia> using TensorAlgebra: similar_map

julia> cod, dom = (Base.OneTo(2), Base.OneTo(3)), (Base.OneTo(4), Base.OneTo(5));

julia> M = similar_map(randn(3), Float32, cod, dom);

julia> eltype(M), size(M)
(Float32, (2, 3, 4, 5))
source
TensorAlgebra.sqrth_invsqrth_safeFunction
sqrth_invsqrth_safe(A, labels_A, labels_codomain, labels_domain; kwargs...) -> P, Pinv
sqrth_invsqrth_safe(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> P, Pinv
sqrth_invsqrth_safe(A, ndims_codomain::Val; kwargs...) -> P, Pinv

Square root and pseudo-inverse square root of a generic N-dimensional array (see sqrth_safe and invsqrth_safe), from a single eigendecomposition. Both results carry the same codomain and domain axes as A.

Keyword arguments

  • alg: forwarded to MatrixAlgebraKit.eigh_full.

  • atol::Real: absolute clamping threshold. Default 0.

  • rtol::Real: relative clamping threshold. Default eps(real(eltype(A)))^(3//4) when atol = 0, else 0.

See also MatrixAlgebra.sqrth_invsqrth_safe.

source
TensorAlgebra.sqrth_safeFunction
sqrth_safe(A, labels_A, labels_codomain, labels_domain; kwargs...) -> P
sqrth_safe(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> P
sqrth_safe(A, ndims_codomain::Val; kwargs...) -> P

Square root of a generic N-dimensional array, interpreting it as a Hermitian positive semi-definite linear map from the domain to the codomain dimensions. The result carries the same codomain and domain axes as A. Eigenvalues below tolerance are clamped to zero. The input must be Hermitian: project with project_hermitian first if it is Hermitian only up to numerical noise.

Keyword arguments

  • alg: forwarded to MatrixAlgebraKit.eigh_full.

  • atol::Real: absolute clamping threshold. Default 0.

  • rtol::Real: relative clamping threshold. Default eps(real(eltype(A)))^(3//4) when atol = 0, else 0.

See also invsqrth_safe, sqrth_invsqrth_safe, and MatrixAlgebra.sqrth_safe.

source
TensorAlgebra.svd_compactFunction
svd_compact(A, labels_A, labels_codomain, labels_domain; kwargs...) -> U, S, Vᴴ
svd_compact(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> U, S, Vᴴ
svd_compact(A, ndims_codomain::Val; kwargs...) -> U, S, Vᴴ

Compute the compact (thin) SVD of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions, where U and Vᴴ are isometric. The partition is specified either via labels or directly through a bi-permutation.

See also MatrixAlgebraKit.svd_compact!.

source
TensorAlgebra.svd_fullFunction
svd_full(A, labels_A, labels_codomain, labels_domain; kwargs...) -> U, S, Vᴴ
svd_full(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; kwargs...) -> U, S, Vᴴ
svd_full(A, ndims_codomain::Val; kwargs...) -> U, S, Vᴴ

Compute the full (thick) SVD of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions, where U and Vᴴ are unitary. The partition is specified either via labels or directly through a bi-permutation.

See also MatrixAlgebraKit.svd_full!.

source
TensorAlgebra.svd_truncFunction
svd_trunc(A, labels_A, labels_codomain, labels_domain; trunc, kwargs...) -> U, S, Vᴴ
svd_trunc(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}; trunc, kwargs...) -> U, S, Vᴴ
svd_trunc(A, ndims_codomain::Val; trunc, kwargs...) -> U, S, Vᴴ

Compute the truncated SVD of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions. The partition is specified either via labels or directly through a bi-permutation.

Keyword arguments

  • trunc: truncation strategy, passed on to MatrixAlgebraKit.svd_trunc.
  • Other keywords are passed on directly to MatrixAlgebraKit.

See also MatrixAlgebraKit.svd_trunc!.

source
TensorAlgebra.svd_valsFunction
svd_vals(A, labels_A, labels_codomain, labels_domain) -> S
svd_vals(A, perm_codomain::Tuple{Vararg{Int}}, perm_domain::Tuple{Vararg{Int}}) -> S
svd_vals(A, ndims_codomain::Val) -> S

Compute the singular values of a generic N-dimensional array, by interpreting it as a linear map from the domain to the codomain dimensions. The partition is specified either via labels or directly through a bi-permutation. The output is a vector of singular values.

See also MatrixAlgebraKit.svd_vals!.

source
TensorAlgebra.to_rangeMethod
TensorAlgebra.to_range(space)

Convert a description of a space into a default range type, returning the range unchanged if it already is one. This lets range and axis constructors accept a space uniformly instead of each reimplementing the conversion.

  • an Integer length -> Base.OneTo
  • an existing AbstractUnitRange -> itself (idempotent passthrough)

Downstream packages extend this for richer spaces; for example, GradedArrays adds a method that turns a vector of sector-to-multiplicity pairs into a graded range.

source
TensorAlgebra.trivialrangeMethod
TensorAlgebra.trivialrange(R::Type{<:AbstractUnitRange}[, n::Integer])
TensorAlgebra.trivialrange(r::AbstractUnitRange[, n::Integer])

Return the identity range for fusing ranges of type R: a one-dimensional range t for which fusing t with any other range of the same family leaves that range unchanged. Defaults to Base.OneTo(1). Downstream packages overload the type-level methods to return their own identity (for example, a charge-0 one-dimensional sector for a graded range).

With a length n, return the n-dimensional analogue: n copies of the identity range stacked into one range (for a graded range, a charge-0 sector of dimension n).

source
TensorAlgebra.tryflattenlinearMethod
tryflattenlinear(bc::Broadcasted) -> LinearBroadcasted or nothing

Recursively convert a Broadcasted tree to a LinearBroadcasted tree. Returns nothing if any node is not linear (as determined by islinearbroadcast).

Analogous to Broadcast.flatten for Broadcasted trees, but converts to LinearBroadcasted subtypes via linearbroadcasted.

Downstream styles call this from Base.copy(::Broadcasted{MyStyle}) to opt into linear broadcasting at materialization time.

source
TensorAlgebra.tryprojectMethod
tryproject(raw, codomain_axes, domain_axes; kwargs...) -> Union{dest, Nothing}
tryproject(raw, axes; kwargs...) -> Union{dest, Nothing}

Like project, but return nothing instead of throwing when more than a negligible component of raw would be discarded. Useful for branching on whether raw is symmetry-allowed in the given axes, e.g. projecting a state as invariant and falling back to deriving an auxiliary flux-carrying leg:

@something tryproject(v, (cod,)) project(reshape(v, (length(v), 1)), (cod,))

Keyword arguments are forwarded to the isapprox tolerance check.

source
TensorAlgebra.unchecked_projectMethod
unchecked_project(raw, codomain_axes, domain_axes) -> dest
unchecked_project(raw, axes) -> dest

Project raw into a symmetry-restricted array shaped as a map from domain_axes to codomain_axes, without checking which components are discarded: entries of raw outside the symmetry-allowed structure are dropped without inspection. Most callers want project, which verifies that nothing was discarded, or tryproject, its nullable sibling. All three derive from the backend customization points: this one is projectto!(allocate_project(raw, codomain_axes, domain_axes), raw). The two-argument form takes a flat list of axes and is equivalent to an empty domain.

source
TensorAlgebra.zerosFunction
zeros([T,] axes) -> A
randn([rng,] [T,] axes) -> A
rand([rng,] [T,] axes) -> A

Axis-friendly counterparts of Base.zeros/Base.randn/Base.rand, taking the axes as a single tuple. Base.zeros already accepts axes, but Base.randn/Base.rand accept only integer dims, so these fill that gap for dense Base.OneTo axes and otherwise forward to Base (so a graded-axis backend that extends Base.randn/rand on its axis type is picked up). These are the flat (non-map) companions of zeros_map.

source
TensorAlgebra.zeros_mapFunction
zeros_map([T,] codomain_axes, domain_axes) -> M
randn_map([rng,] [T,] codomain_axes, domain_axes) -> M
rand_map([rng,] [T,] codomain_axes, domain_axes) -> M

Construct an array shaped as a linear map from domain_axes to codomain_axes, filled with zeros (zeros_map), normally-distributed values (randn_map), or uniformly-distributed values (rand_map), with element type T (defaulting to Float64). These are the value-filling companions of similar_map: the domain axes are given un-dualized (codomain facing) and stored dual, so the default flattens to the axis-friendly zeros/randn/rand over (codomain_axes..., conj.(domain_axes)...) (conj dualizes a graded axis and is a no-op on a dense one). Backends with map-shaped storage (e.g. a TensorMap) overload these to build the codomain/domain directly.

source
TensorAlgebra.MatrixAlgebra.gram_eigh_fullFunction
gram_eigh_full(A::AbstractMatrix; alg=nothing, atol=0, rtol=eps(real(eltype(A)))^(3//4)) -> X

Gram factorization of a Hermitian positive semi-definite matrix via its eigendecomposition (balanced eigh): returns X = V * sqrth_safe(D; atol, rtol) such that A ≈ X * X', where A = V * D * V'. The square-root of D is absorbed symmetrically into the two factors of the eigendecomposition. Eigenvalues below tol (see pow_diag_safe) are clamped to zero.

Keyword arguments

  • alg: forwarded to MatrixAlgebraKit.eigh_full.

  • atol::Real: absolute clamping threshold. Default 0.

  • rtol::Real: relative clamping threshold. Default eps(real(eltype(A)))^(3//4) when atol = 0, else 0.

Examples

julia> using TensorAlgebra.MatrixAlgebra: gram_eigh_full

julia> B = [1.0 0.5; 0.5 2.0];

julia> A = B' * B;

julia> X = gram_eigh_full(A);

julia> X * X' ≈ A
true

See also gram_eigh_full_with_pinv.

source
TensorAlgebra.MatrixAlgebra.gram_eigh_full_with_pinvFunction
gram_eigh_full_with_pinv(A::AbstractMatrix; alg=nothing, atol=0, rtol=eps(real(eltype(A)))^(3//4)) -> X, Y

Like gram_eigh_full, but additionally returns Y = invsqrth_safe(D; atol, rtol) * V' ≈ pinv(X), a left inverse of X on the rank subspace: Y * X ≈ I. Eigenvalues below tol are clamped to zero in both factors.

Keyword arguments

  • alg: forwarded to MatrixAlgebraKit.eigh_full.

  • atol::Real: absolute clamping threshold. Default 0.

  • rtol::Real: relative clamping threshold. Default eps(real(eltype(A)))^(3//4) when atol = 0, else 0.

Examples

julia> using LinearAlgebra: I

julia> using TensorAlgebra.MatrixAlgebra: gram_eigh_full_with_pinv

julia> B = [1.0 0.5; 0.5 2.0];

julia> A = B' * B;

julia> X, Y = gram_eigh_full_with_pinv(A);

julia> X * X' ≈ A
true

julia> Y * X ≈ I
true
source
TensorAlgebra.MatrixAlgebra.invsqrt_diag_safeMethod
invsqrt_diag_safe(D; atol=0, rtol=eps(real(eltype(D)))^(3//4)) -> D^(-1//2)

Inverse square root of a diagonal-structured matrix D, treating diagonal entries below tolerance as zero (Moore-Penrose convention). Equivalent to pow_diag_safe(D, -1//2; atol, rtol).

Keyword arguments

  • atol::Real: absolute clamping threshold. Default 0.
  • rtol::Real: relative clamping threshold. Default eps(real(eltype(D)))^(3//4) when atol = 0, else 0.
source
TensorAlgebra.MatrixAlgebra.invsqrth_safeMethod
invsqrth_safe(M; alg=nothing, atol=0, rtol=eps(real(eltype(M)))^(3//4)) -> M^(-1//2)

Inverse square root of a Hermitian positive semi-definite matrix. Equivalent to powh_safe(M, -1//2; alg, atol, rtol).

Keyword arguments

  • alg: forwarded to MatrixAlgebraKit.eigh_full.

  • atol::Real: absolute clamping threshold. Default 0.

  • rtol::Real: relative clamping threshold. Default eps(real(eltype(M)))^(3//4) when atol = 0, else 0.

source
TensorAlgebra.MatrixAlgebra.pow_diag_safe!Method
pow_diag_safe!(Dp, D, p, tol) -> Dp

In-place kernel behind pow_diag_safe: write the clamped powers of D's diagonal onto Dp, where entries d with abs(d) < tol become zero and the rest become d^p. Dp must be diagonal-structured with the same structure as D (in the allocating pow_diag_safe path it is copy(D)).

This is the backend overload point. The generic method maps over MAK.diagview, valid when the diagonal view is a single in-place-mappable vector (dense). A backend whose diagonal is stored per sector (a TensorMap, or a graded matrix) overloads this method to clamp each reduced block.

source
TensorAlgebra.MatrixAlgebra.pow_diag_safeMethod
pow_diag_safe(D, p; atol=0, rtol=eps(real(eltype(D)))^(3//4)) -> D^p
pow_diag_safe(D, p, tol) -> D^p

Raise a diagonal-structured matrix D to the power p. Diagonal entries d with abs(d) < tol are clamped to zero before exponentiation, where tol = max(atol, rtol * norm(D, Inf)) (the largest-magnitude entry, which is the largest-magnitude diagonal entry for a diagonal-structured matrix). The three-argument form takes tol directly. Negative d above tol cause d^p to error for fractional p (e.g. p = 1//2) and pass through for integer p, so the operation itself enforces the PSD precondition per-power. Errors if isdiag(D) is false.

The clamped powers are written onto a copy of D via pow_diag_safe!, so the result keeps the input's type and structure. This drives sqrt_diag_safe, invsqrt_diag_safe, and the powh_safe family, and works for any diagonal-structured backend (dense, graded, or a TensorMap).

Keyword arguments

  • atol::Real: absolute clamping threshold. Default 0.
  • rtol::Real: relative clamping threshold. Default eps(real(eltype(D)))^(3//4) when atol = 0, else 0.
source
TensorAlgebra.MatrixAlgebra.powh_safeMethod
powh_safe(M, p; alg=nothing, atol=0, rtol=eps(real(eltype(M)))^(3//4)) -> M^p

Raise a Hermitian positive semi-definite matrix to the power p. For diagonal-structured M (isdiag(M) == true), dispatches to pow_diag_safe and skips the eigendecomposition. Otherwise computes via M = V * D * V' as V * pow_diag_safe(D, p; atol, rtol) * V'.

The input must be Hermitian (as for MatrixAlgebraKit.eigh_full): project with MatrixAlgebraKit.project_hermitian first if it is Hermitian only up to numerical noise.

Keyword arguments

  • alg: forwarded to MatrixAlgebraKit.eigh_full.

  • atol::Real: absolute clamping threshold. Default 0.

  • rtol::Real: relative clamping threshold. Default eps(real(eltype(M)))^(3//4) when atol = 0, else 0.

source
TensorAlgebra.MatrixAlgebra.sqrt_diag_safeMethod
sqrt_diag_safe(D; atol=0, rtol=eps(real(eltype(D)))^(3//4)) -> D^(1//2)

Square root of a diagonal-structured matrix D, equivalent to pow_diag_safe(D, 1//2; atol, rtol).

Keyword arguments

  • atol::Real: absolute clamping threshold. Default 0.
  • rtol::Real: relative clamping threshold. Default eps(real(eltype(D)))^(3//4) when atol = 0, else 0.
source
TensorAlgebra.MatrixAlgebra.sqrth_invsqrth_safeMethod
sqrth_invsqrth_safe(M; alg=nothing, atol=0, rtol=eps(real(eltype(M)))^(3//4)) -> M^(1//2), M^(-1//2)

Square root and pseudo-inverse square root of a Hermitian positive semi-definite matrix, from a single eigendecomposition. Equivalent to (sqrth_safe(M; ...), invsqrth_safe(M; ...)) but with the eigendecomposition computed once. Eigenvalues below tolerance are clamped to zero in both factors (Moore-Penrose convention for the inverse).

The input must be Hermitian (as for MatrixAlgebraKit.eigh_full): project with MatrixAlgebraKit.project_hermitian first if it is Hermitian only up to numerical noise.

Keyword arguments

  • alg: forwarded to MatrixAlgebraKit.eigh_full.

  • atol::Real: absolute clamping threshold. Default 0.

  • rtol::Real: relative clamping threshold. Default eps(real(eltype(M)))^(3//4) when atol = 0, else 0.

source
TensorAlgebra.MatrixAlgebra.sqrth_safeMethod
sqrth_safe(M; alg=nothing, atol=0, rtol=eps(real(eltype(M)))^(3//4)) -> M^(1//2)

Square root of a Hermitian positive semi-definite matrix. Equivalent to powh_safe(M, 1//2; alg, atol, rtol).

Keyword arguments

  • alg: forwarded to MatrixAlgebraKit.eigh_full.

  • atol::Real: absolute clamping threshold. Default 0.

  • rtol::Real: relative clamping threshold. Default eps(real(eltype(M)))^(3//4) when atol = 0, else 0.

source
TensorAlgebra.MatrixAlgebra.truncdegenMethod
truncdegen(trunc::TruncationStrategy; atol::Real=0, rtol::Real=0)

Modify a truncation strategy so that if the truncation falls within a degenerate subspace, the entire subspace gets truncated as well. A value val is considered degenerate if norm(val - truncval) ≤ max(atol, rtol * norm(truncval)) where truncval is the largest value truncated by the original truncation strategy trunc.

For now, this truncation strategy assumes the spectrum being truncated has already been reverse sorted and the strategy being wrapped outputs a contiguous subset of values including the largest one. It also only truncates for now, so may not respect if a minimum dimension was requested in the strategy being wrapped. These restrictions may be lifted in the future or provided through a different truncation strategy.

source