Developer Interface
This page covers the named-array model that indices and tensors are built on, the interface for implementing a new tensor type, and experimental features that are not yet part of the stable user-facing API. For the stable user-facing API, see the User Interface.
Named array types
A concrete tensor type subtypes AbstractNamedTensor. NamedTensor is the built-in implementation, and ITensor is the NamedTensor with dimension names that are IndexNames. Its NamedTensor(array, dimnames) constructor pairs an array of any kind with its dimension names directly. User code usually builds one by calling an array constructor on indices or by indexing an array (see Constructors) rather than calling it. The underlying named-range model has NamedUnitRange as the named-range type that a tensor's dimensions are (Index is the flavor keyed by an index name).
ITensorBase.AbstractNamedTensor — Type
AbstractNamedTensor{DimName}Supertype for tensors whose dimensions are labeled by names of type DimName rather than ordered by position. Subtypes such as NamedTensor line their dimensions up by name under contraction, addition, and indexing. Unlike an AbstractArray, the rank and element type live in the data rather than the type, so ndims and eltype are not fixed at the type level.
See also NamedTensor, dimnames, inds.
ITensorBase.NamedTensor — Type
NamedTensor(array::AbstractArray, dims)A tensor whose dimensions are labeled by names instead of ordered by position. It pairs an underlying array with one name per dimension (dims), so contraction, addition, and indexing line dimensions up by name. A NamedTensor is usually built by calling randn, zeros, and the like on indices, or through nameddims, rather than constructed directly. ITensor is the NamedTensor with dimension names that are IndexNames.
Examples
julia> NamedTensor(zeros(2, 3), (:i, :j))
named(Base.OneTo(2), :i)×named(Base.OneTo(3), :j) NamedTensor{Symbol}:
2×3 Matrix{Float64}:
0.0 0.0 0.0
0.0 0.0 0.0ITensorBase.NamedUnitRange — Type
NamedUnitRange{Name}A unit range with a name attached, used as a named dimension (axis) of a tensor. It pairs an underlying integer unit range with a name of type Name. Index is the NamedUnitRange flavor whose name is an IndexName. Build one by calling named on a range, or use Index to mint a fresh unique name.
Examples
julia> named(1:3, :i)
named(1:3, :i)Named array operations
Construct named objects with named and nameddims, recover their parts with name, unnamed, and dimnames, and query their types with dimnametype, nametype, and unnamedtype. setname and replacedimnames rename, and aligndims and aligneddims reorder a tensor's dimensions by name (a copy and a view, respectively).
ITensorBase.named — Function
named(value, name)Attach name to value, pairing them into a single named object. On a scalar this produces a Named. Arrays and unit ranges have their own more specific methods.
Examples
julia> named(2, :i)
named(2, :i)ITensorBase.nameddims — Function
nameddims(a, dimnames)Construct a named dimensions array from an unnamed parent a and named dimensions dimnames. The parent is usually an AbstractArray, but any object that a NamedTensor can wrap works (e.g. a TensorKit TensorMap).
Examples
julia> nameddims(zeros(2, 3), (:i, :j))
named(Base.OneTo(2), :i)×named(Base.OneTo(3), :j) NamedTensor{Symbol}:
2×3 Matrix{Float64}:
0.0 0.0 0.0
0.0 0.0 0.0See also NamedTensor, named.
ITensorBase.name — Function
name(a)The name attached to a named object a, such as a Named scalar, a named array, or a named unit range. This is the inverse of the name component of named: name recovers the name, unnamed recovers the value.
Examples
julia> using ITensorBase: name
julia> name(named(2, :i))
:iITensorBase.unnamed — Function
unnamed(a)The underlying value of a named object a, with its name stripped off. This is the inverse of the value component of named: name recovers the name, unnamed recovers the value. On an AbstractNamedTensor it returns the underlying unnamed array.
Examples
julia> using ITensorBase: unnamed
julia> unnamed(named(2, :i))
2ITensorBase.dimnames — Function
dimnames(a::AbstractNamedTensor)
dimnames(a::AbstractNamedTensor, dim::Int)The dimension names of a, as a collection in dimension order. The second form returns the name of dimension dim.
Examples
julia> a = nameddims(zeros(2, 3), (:i, :j));
julia> dimnames(a)
2-element Vector{Symbol}:
:i
:j
julia> dimnames(a, 2)
:jITensorBase.dimnametype — Function
dimnametype(a::AbstractNamedTensor)
dimnametype(type::Type{<:AbstractNamedTensor})The type of an individual dimension name of a. The primary method dispatches on the array type, and dimnametype(a) forwards to dimnametype(typeof(a)). A type that does not fix its dimname flavor (such as the unparameterized NamedTensor) returns Any, the same way eltype(Array) is Any.
Examples
julia> a = nameddims(zeros(2, 3), (:i, :j));
julia> dimnametype(a)
Symbol
julia> dimnametype(typeof(a))
SymbolITensorBase.nametype — Function
nametype(type::Type)The type of the name carried by a named type, such as a Named scalar type, a named array type, or a named unit range type.
Examples
julia> using ITensorBase: nametype
julia> nametype(typeof(named(2, :i)))
SymbolSee also name, unnamedtype.
ITensorBase.unnamedtype — Function
unnamedtype(type::Type)The type of the underlying (unnamed) value carried by a named type.
Examples
julia> using ITensorBase: unnamedtype
julia> unnamedtype(typeof(named(2, :i)))
Int64ITensorBase.setname — Function
setname(a, name)Return a copy of the named object a with its name replaced by name, keeping the underlying value unchanged.
Examples
julia> using ITensorBase: setname
julia> setname(named(2, :i), :j)
named(2, :j)ITensorBase.replacedimnames — Function
replacedimnames(a::AbstractNamedTensor, replacements::Pair...)
replacedimnames(f, a::AbstractNamedTensor)Return a tensor with the same data as a but with its dimension names replaced. The first form takes old => new pairs, replacing matching names and leaving the rest unchanged. The second form replaces each name with f(name).
Examples
julia> using ITensorBase: replacedimnames
julia> a = nameddims(zeros(2, 3), (:i, :j));
julia> dimnames(replacedimnames(a, :i => :k))
2-element Vector{Symbol}:
:k
:jSee also dimnames.
ITensorBase.aligndims — Function
aligndims(a::AbstractNamedTensor, dims)Reorder the dimensions of a into the order given by dims, matched by name. Returns a tensor with the same data and dimension names as a but with the dimensions permuted, and throws a NameMismatch if dims is not a permutation of a's dimension names.
Examples
julia> a = nameddims(zeros(2, 3), (:i, :j));
julia> aligndims(a, (:j, :i))
named(Base.OneTo(3), :j)×named(Base.OneTo(2), :i) NamedTensor{Symbol}:
3×2 Matrix{Float64}:
0.0 0.0
0.0 0.0
0.0 0.0aligndims(a::AbstractNamedTensor, codomain, domain)Reorder the dimensions of a into (codomain..., domain...), matched by name, and forward the codomain/domain split to the underlying storage. Like the two-argument form, the result has the same data and dimension names as a, and a NameMismatch is thrown if (codomain..., domain...) is not a permutation of a's dimension names. A storage backend that supports a bipartition (such as a TensorKit TensorMap) uses it, while a dense backend stores the result flat.
ITensorBase.aligneddims — Function
aligneddims(a::AbstractNamedTensor, dims)Like aligndims, but returns a lazily-permuted view that shares data with a instead of copying. Reorders the dimensions of a into the order given by dims, matched by name, and throws a NameMismatch if dims is not a permutation of a's dimension names.
Examples
julia> a = nameddims(reshape(1:6, 2, 3), (:i, :j));
julia> dimnames(aligneddims(a, (:j, :i)))
2-element Vector{Symbol}:
:j
:iSee also aligndims.
Experimental
These features support building and applying operators, where an operator is a tensor whose dimension names are split into an output set and an input set. The API is still being refined and is subject to change. Build an operator with operator or allocate one with similar_operator, apply it to a tensor with apply, and recover its underlying tensor and name sets with state, outputnames, and inputnames.
ITensorBase.operator — Function
operator(a, output, input)Build a named operator from a tensor (or plain array) a by partitioning its dimension names into an output set and an input set. The operator pairs each output name with an input name, so it can be applied to a tensor with apply, contracting over the input. output and input may be given as dimension names or as named ranges such as Indexes. Recover the underlying tensor with state and the name sets with outputnames and inputnames.
Examples
julia> op = operator(zeros(2, 2), ("i",), ("j",));
julia> outputnames(op)
1-element Vector{String}:
"i"
julia> inputnames(op)
1-element Vector{String}:
"j"See also state, outputnames, inputnames, apply, similar_operator.
ITensorBase.similar_operator — Function
similar_operator(prototype, [T,] unnamed_input_axes, [outputnames,] inputnames) -> op
similar_operator(prototype, [T,] named_input_axes) -> opAllocate an operator-shaped named array with undefined data, with the user-supplied side as the input and a matching output. Element type defaults to eltype(prototype). Output names default to fresh uniquename-generated names. The first form takes unnamed (raw) axes and explicit names, the second takes already-named axes and reuses their names as the input. Storage layout (including the bra/ket flip on the input side for graded axes) is delegated to TensorAlgebra.similar_map.
Examples
julia> op = similar_operator(zeros(2, 2), (Base.OneTo(2),), (:i,), (:j,));
julia> inputnames(op)
1-element Vector{Symbol}:
:jSee also operator, uniquename.
ITensorBase.apply — Function
apply(x::AbstractNamedTensor, y::AbstractNamedTensor)Apply the operator x to y, contracting each input of x with the matching output (or dangling leg) of y and renaming each consumed output of x back to its paired input, so the result sits on x's input space. Uncontracted structure passes through: y's remaining input wires stay wires, and a part of x disjoint from y is tensored in. Applying an operator to a bare state gives a bare state, so applying the identity operator leaves y unchanged; applying it to another operator gives an operator.
Examples
julia> op = operator(reshape(Float64[1, 0, 0, 1], 2, 2), ("i",), ("j",));
julia> v = nameddims([3.0, 4.0], ("j",));
julia> apply(op, v) == v
trueSee also operator, state, outputnames, inputnames.
ITensorBase.state — Function
state(a)The underlying tensor of a named operator, with its output/input structure forgotten. An operator carries a tensor together with a pairing of its output and input dimension names (its Choi, or state, representation). state returns that tensor on its own. For a plain tensor that is not an operator, state returns it unchanged.
Examples
julia> a = nameddims(zeros(2), (:i,));
julia> state(a) == a
trueSee also operator, outputnames, inputnames.
ITensorBase.outputnames — Function
outputnames(a)The output dimension names of an operator a. An operator pairs each of its output names with an input name. Applying the operator contracts over the input and leaves the output. A plain tensor is a trivial operator with no pairing, so its output names are empty.
Examples
julia> op = operator(zeros(2, 2), ("i",), ("j",));
julia> outputnames(op)
1-element Vector{String}:
"i"See also inputnames, operator, apply.
ITensorBase.inputnames — Function
inputnames(a)The input dimension names of an operator a. These are the names contracted over when the operator is applied to a tensor. A plain tensor is a trivial operator with no pairing, so its input names are empty.
Examples
julia> op = operator(zeros(2, 2), ("i",), ("j",));
julia> inputnames(op)
1-element Vector{String}:
"j"See also outputnames, operator, apply.