Reference
TensorAlgebra.ConjBroadcasted — Type
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.
TensorAlgebra.LinearBroadcasted — Type
LinearBroadcastedAbstract 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)
TensorAlgebra.PermutedDims — Type
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.
TensorAlgebra.add! — Method
add!(dest, src, α, β)dest = β * dest + α * src.
TensorAlgebra.add! — Method
add!(dest, src)dest .+= src.
TensorAlgebra.allocate_project — Method
allocate_project(raw, codomain_axes, domain_axes) -> destAllocate 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.
TensorAlgebra.bipartition — Method
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...].
TensorAlgebra.biperm — Method
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.
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.
TensorAlgebra.eig_full — Function
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, VCompute 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!.
TensorAlgebra.eig_trunc — Function
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, VTruncated general eigenvalue decomposition, like eig_full but keeping only the eigenvalues selected by the trunc strategy.
See also MatrixAlgebraKit.eig_trunc!.
TensorAlgebra.eig_vals — Function
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...) -> DCompute 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!.
TensorAlgebra.eigh_full — Function
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, VCompute 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!.
TensorAlgebra.eigh_trunc — Function
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, VTruncated Hermitian eigenvalue decomposition, like eigh_full but keeping only the eigenvalues selected by the trunc strategy.
See also MatrixAlgebraKit.eigh_trunc!.
TensorAlgebra.eigh_vals — Function
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...) -> DCompute 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!.
TensorAlgebra.gram_eigh_full — Function
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...) -> XGram 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 toMatrixAlgebraKit.eigh_full.atol::Real: absolute clamping threshold. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(A)))^(3//4)whenatol = 0, else0.
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))
trueSee also gram_eigh_full_with_pinv and MatrixAlgebra.gram_eigh_full.
TensorAlgebra.gram_eigh_full_with_pinv — Function
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, YLike 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 toMatrixAlgebraKit.eigh_full.atol::Real: absolute clamping threshold. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(A)))^(3//4)whenatol = 0, else0.
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
trueSee also MatrixAlgebra.gram_eigh_full_with_pinv.
TensorAlgebra.invsqrth_safe — Function
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...) -> PPseudo-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 toMatrixAlgebraKit.eigh_full.atol::Real: absolute clamping threshold. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(A)))^(3//4)whenatol = 0, else0.
See also sqrth_safe, sqrth_invsqrth_safe, and MatrixAlgebra.invsqrth_safe.
TensorAlgebra.is_projected — Method
is_projected(dest, src; kwargs...) -> BoolWhether 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.
TensorAlgebra.label_type — Method
label_type(::Type{L}) -> TypeThe 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}) = IntTensorAlgebra.left_null — Function
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...) -> NCompute 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,:qrposand:svd. The former two require0 == atol == rtol. The default is:qrposifatol == rtol == 0, and:svdotherwise.
TensorAlgebra.left_orth — Function
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, CCompute 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!.
TensorAlgebra.left_polar — Function
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, PCompute 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!.
TensorAlgebra.linearbroadcasted — Function
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)TensorAlgebra.lq_compact — Function
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, QCompute 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 ofLshould be positive, leading to a unique decomposition.- Other keywords are passed on directly to MatrixAlgebraKit.
See also MatrixAlgebraKit.lq_compact!.
TensorAlgebra.lq_full — Function
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, QCompute 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 ofLshould be positive, leading to a unique decomposition.- Other keywords are passed on directly to MatrixAlgebraKit.
See also MatrixAlgebraKit.lq_full!.
TensorAlgebra.matricizeopperm — Method
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.
TensorAlgebra.one — Function
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) -> IdConstruct 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
trueTensorAlgebra.permuteddims — Method
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.
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.
TensorAlgebra.permutedims — Method
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.
TensorAlgebra.permutedimsadd! — Method
permutedimsadd!(dest, src, perm, α, β)dest = β * dest + α * permutedims(src, perm).
TensorAlgebra.permutedimsop — Method
permutedimsop(op, src, perm_codomain, perm_domain)Non-mutating version of bipermutedimsopadd!: returns op.(permutedims(src, (perm_codomain..., perm_domain...))).
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 = ().
TensorAlgebra.project! — Method
project!(dest, src; kwargs...) -> destIn-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.
TensorAlgebra.project — Method
project(raw, codomain_axes, domain_axes; kwargs...) -> dest
project(raw, axes; kwargs...) -> destProject 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.
TensorAlgebra.project_hermitian — Function
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...) -> HHermitian 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.
TensorAlgebra.projectto! — Method
projectto!(dest, src) -> destProject 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.
TensorAlgebra.qr_compact — Function
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, RCompute 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 ofRshould be positive, leading to a unique decomposition.- Other keywords are passed on directly to MatrixAlgebraKit.
See also MatrixAlgebraKit.qr_compact!.
TensorAlgebra.qr_full — Function
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, RCompute 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 ofRshould be positive, leading to a unique decomposition.- Other keywords are passed on directly to MatrixAlgebraKit.
See also MatrixAlgebraKit.qr_full!.
TensorAlgebra.rand — Function
zeros([T,] axes) -> A
randn([rng,] [T,] axes) -> A
rand([rng,] [T,] axes) -> AAxis-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.
TensorAlgebra.rand_map — Function
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) -> MConstruct 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.
TensorAlgebra.randn — Function
zeros([T,] axes) -> A
randn([rng,] [T,] axes) -> A
rand([rng,] [T,] axes) -> AAxis-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.
TensorAlgebra.randn_map — Function
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) -> MConstruct 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.
TensorAlgebra.right_null — Function
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,:lqposand:svd. The former two require0 == atol == rtol. The default is:lqposifatol == rtol == 0, and:svdotherwise.
TensorAlgebra.right_orth — Function
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, VCompute 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!.
TensorAlgebra.right_polar — Function
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, WCompute 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!.
TensorAlgebra.scale! — Method
scale!(a::AbstractArray, β::Number) -> aIn-place scaling: multiply every entry of a by β.
TensorAlgebra.similar_map — Method
similar_map(prototype, [T,] codomain_axes, domain_axes) -> MAllocate 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))TensorAlgebra.sqrth_invsqrth_safe — Function
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, PinvSquare 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 toMatrixAlgebraKit.eigh_full.atol::Real: absolute clamping threshold. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(A)))^(3//4)whenatol = 0, else0.
See also MatrixAlgebra.sqrth_invsqrth_safe.
TensorAlgebra.sqrth_safe — Function
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...) -> PSquare 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 toMatrixAlgebraKit.eigh_full.atol::Real: absolute clamping threshold. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(A)))^(3//4)whenatol = 0, else0.
See also invsqrth_safe, sqrth_invsqrth_safe, and MatrixAlgebra.sqrth_safe.
TensorAlgebra.svd_compact — Function
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!.
TensorAlgebra.svd_full — Function
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!.
TensorAlgebra.svd_trunc — Function
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 toMatrixAlgebraKit.svd_trunc.- Other keywords are passed on directly to MatrixAlgebraKit.
See also MatrixAlgebraKit.svd_trunc!.
TensorAlgebra.svd_vals — Function
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) -> SCompute 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!.
TensorAlgebra.to_range — Method
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
Integerlength ->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.
TensorAlgebra.trivialrange — Method
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).
TensorAlgebra.tryflattenlinear — Method
tryflattenlinear(bc::Broadcasted) -> LinearBroadcasted or nothingRecursively 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.
TensorAlgebra.tryproject — Method
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.
TensorAlgebra.unchecked_project — Method
unchecked_project(raw, codomain_axes, domain_axes) -> dest
unchecked_project(raw, axes) -> destProject 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.
TensorAlgebra.zero! — Method
zero!(a::AbstractArray) -> aIn-place zero: set every entry of a to zero.
TensorAlgebra.zeros — Function
zeros([T,] axes) -> A
randn([rng,] [T,] axes) -> A
rand([rng,] [T,] axes) -> AAxis-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.
TensorAlgebra.zeros_map — Function
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) -> MConstruct 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.
TensorAlgebra.MatrixAlgebra.gram_eigh_full — Function
gram_eigh_full(A::AbstractMatrix; alg=nothing, atol=0, rtol=eps(real(eltype(A)))^(3//4)) -> XGram 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 toMatrixAlgebraKit.eigh_full.atol::Real: absolute clamping threshold. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(A)))^(3//4)whenatol = 0, else0.
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
trueSee also gram_eigh_full_with_pinv.
TensorAlgebra.MatrixAlgebra.gram_eigh_full_with_pinv — Function
gram_eigh_full_with_pinv(A::AbstractMatrix; alg=nothing, atol=0, rtol=eps(real(eltype(A)))^(3//4)) -> X, YLike 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 toMatrixAlgebraKit.eigh_full.atol::Real: absolute clamping threshold. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(A)))^(3//4)whenatol = 0, else0.
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
trueTensorAlgebra.MatrixAlgebra.invsqrt_diag_safe — Method
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. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(D)))^(3//4)whenatol = 0, else0.
TensorAlgebra.MatrixAlgebra.invsqrth_safe — Method
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 toMatrixAlgebraKit.eigh_full.atol::Real: absolute clamping threshold. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(M)))^(3//4)whenatol = 0, else0.
TensorAlgebra.MatrixAlgebra.pow_diag_safe! — Method
pow_diag_safe!(Dp, D, p, tol) -> DpIn-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.
TensorAlgebra.MatrixAlgebra.pow_diag_safe — Method
pow_diag_safe(D, p; atol=0, rtol=eps(real(eltype(D)))^(3//4)) -> D^p
pow_diag_safe(D, p, tol) -> D^pRaise 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. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(D)))^(3//4)whenatol = 0, else0.
TensorAlgebra.MatrixAlgebra.powh_safe — Method
powh_safe(M, p; alg=nothing, atol=0, rtol=eps(real(eltype(M)))^(3//4)) -> M^pRaise 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 toMatrixAlgebraKit.eigh_full.atol::Real: absolute clamping threshold. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(M)))^(3//4)whenatol = 0, else0.
TensorAlgebra.MatrixAlgebra.sqrt_diag_safe — Method
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. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(D)))^(3//4)whenatol = 0, else0.
TensorAlgebra.MatrixAlgebra.sqrth_invsqrth_safe — Method
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 toMatrixAlgebraKit.eigh_full.atol::Real: absolute clamping threshold. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(M)))^(3//4)whenatol = 0, else0.
TensorAlgebra.MatrixAlgebra.sqrth_safe — Method
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 toMatrixAlgebraKit.eigh_full.atol::Real: absolute clamping threshold. Default0.rtol::Real: relative clamping threshold. Defaulteps(real(eltype(M)))^(3//4)whenatol = 0, else0.
TensorAlgebra.MatrixAlgebra.truncdegen — Method
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.