Internal functions

Documented functions and constants that are neither exported nor public. They may change in a minor release.

Base.reshape — Method
reshape(t, mappings...; repeat=false, projection=false)

Reshape the array t by splitting or combining its indices according to Hilbert-space mappings. The mappings are applied left to right, each one consuming the next consecutive group of input indices. Each mapping reads input => output; see Pair arguments.

Mapping forms

H => (H1, H2, ...)   split one index into several(H1, H2, ...) => H   combine several consecutive indices into one(H1, H2, ...) => (K1, K2, ...)  repartition several indices into severalH => H               leave one index unchanged

Specifying multiple mappings

Give one mapping per group of input indices:

reshape(A, H1 => (H1a, H1b), (H2a, H2b) => H2, H3 => H3)

This splits the first index, combines the next two, and leaves the last unchanged.

Single-mapping shorthand

When only one mapping is given, it is replicated if needed:

  • If it consumes all indices of t, it is applied once:

    reshape(v, H => (H1, H2))        # length-1 vector → 2-index tensor
  • If t has twice as many indices as the mapping consumes, the mapping is applied to the first half and again to the second half. This covers the common case of a square operator matrix, where the first index is the output space and the second is the input space:

    reshape(m, H => (H1, H2))        # matrix → 4-index tensor
    # equivalent to reshape(m, H => (H1, H2), H => (H1, H2))
    
    reshape(T, (H1, H2) => H)        # 4-index tensor → matrix
    # equivalent to reshape(T, (H1, H2) => H, (H1, H2) => H)

For asymmetric operators, specify both mappings explicitly:

reshape(m, Hout => (H1, H2), Hin => (K1, K2))

Many-to-many mappings are evaluated directly and are equivalent to an explicit combine-then-split composition:

reshape(A, (H1, H2) => (K1, K2))# equivalent to reshape(reshape(A, (H1, H2) => Hmid), Hmid => (K1, K2))

where Hmid is the canonical combined space of the input tuple.

When repeat=true, the single given mapping is applied to every consecutive group of input indices. For example, with a 3-index array where every index lives on H:

reshape(A, H => (H1, H2); repeat=true)# equivalent to reshape(A, H => (H1, H2), H => (H1, H2), H => (H1, H2))

Missing states

Some basis states of the input spaces may have no counterpart in the output spaces, e.g. when splitting into a truncated space or combining into a symmetry-constrained space. By default an ArgumentError is thrown if t has a nonzero entry on such a state, since that amplitude would be lost. Zero entries are fine, so e.g. combining unconstrained spaces into a parity-conserving space works for parity-preserving operators. With projection=true, the components on missing states are silently dropped.

Precomputed form

reshape(mappings...; repeat=false, projection=false)

returns a callable ReshapeMap that precomputes the transitions, and can be applied as op(t) or in place as op(out, t).

source
FermionicHilbertSpaces._combined_sector_constraint — Method
_combined_sector_constraint(spaces)

Given a collection of Hilbert spaces, construct a combined constraint from the stored constraints of any SectorHilbertSpace inputs (localized to their respective subspaces). Returns missing if no usable sector information exists.

source
FermionicHilbertSpaces._foreach_kron_term — Method
_foreach_kron_term(op, inds, ms, Hs, H, extend_state; phase_factors, projection)

Kernel shared by the dense and sparse generalized matrix kron. Calls op(K1, K2, v) for each output matrix element in H, where v is the product of the selected input elements, the recombination weights and the phase factor. inds supplies one row/column index pair per local matrix. Terms whose column state is not in H are skipped. When projection=false, a nonzero term from a state of H to a state that is not in H throws ArgumentError.

source
FermionicHilbertSpaces._foreach_kron_vec_term — Method
_foreach_kron_vec_term(op, inds, ms, Hs, H, extend_state; phase_factors, projection)

Kernel for the generalized vector kron. Calls op(K, v) for each output vector entry in H, where v is the product of the selected input entries, the recombination weight and the phase factor. When projection=false, a nonzero term on a state that is not in H throws ArgumentError.

source
FermionicHilbertSpaces._foreach_partial_trace_term — Method
_foreach_partial_trace_term(op, inds, H, Hsub, complement, mapper, alg; phase_factors)

Kernel of the partial-trace map builders, and of the direct partial trace with SubsystemPartialTraceAlg. Calls op(J1, J2, K1, K2, v) for each contribution, where (J1, J2) indexes the input matrix in H, (K1, K2) the output matrix in Hsub, and v excludes the input matrix element. inds is ignored by SubsystemPartialTraceAlg; FullPartialTraceAlg visits the index pairs in inds. States that are not in H or Hsub are skipped.

source
FermionicHilbertSpaces._foreach_partial_transpose_term — Method
_foreach_partial_transpose_term(op, inds, H, Hsub, Hout, splits, mapper_out; phase_factors, projection)

Kernel shared by the direct and the sparse-map implementation. For every index pair (J1, J2) in inds (matrix element |f1⟩⟨f2| of H), split f1 → (a1, b1), f2 → (a2, b2), swap the transposed parts, |a1 b1⟩⟨a2 b2| ↦ |a2 b1⟩⟨a1 b2|, recombine into Hout and call op(J1, J2, K1, K2, v) with the full coefficient v.

source
FermionicHilbertSpaces.apply_local_operator — Function
apply_local_operator(op, state, space, precomp) -> (newstate, amplitude)

Apply the symbolic operator op to the basis state state of space. Returns the new state and its amplitude; an amplitude of zero means that op annihilates state. space is the group that op acts on, so it can be used for dispatch. precomp is the value of _precomputation_before_operator_application for op and space.

This is the method that connects a custom operator type to matrix representations, partial traces and the other operations on spaces.

source
FermionicHilbertSpaces.apply_local_operator — Method
apply_local_operator(op::SpinSym, state::SpinState, space::SpinSpace, precomp) -> (newstate, amplitude)

Apply a single spin operator to a spin state. Returns (newstate, amplitude) where amplitude is 0 if the operation is not allowed, and a nonzero value otherwise.

source
FermionicHilbertSpaces.apply_local_operators — Method
apply_local_operators(op::NCMul, state, space, precomps; transpose) -> (newstate, amplitude)

Apply the product op, including its coefficient, to the basis state state of space. precomps holds one value per factor, from _precomputation_before_operator_application. With transpose=true, apply the transpose of op instead. The generic method applies the factors one by one with apply_local_operator. A method for products of one operator type can be faster, as for fermions, where the whole product acts on a Fock state with bit operations.

source
FermionicHilbertSpaces.atom_ids — Method
atom_ids(H)

Names of the atoms of H, map(atomic_id, atomic_factors(H)). Since atoms are ordered group-major, this is canonical: two spaces over the same degrees of freedom, in the same order within each group, have equal atom_ids whatever their truncation, transposition or constraints.

source
FermionicHilbertSpaces.atom_position — Method
atom_position(x, H)

Position among atomic_factors(H) of the atom named by x (an atom or a symbol naming one), or 0 if H has no such atom. The lookup is by atomic_id only, so the basis of x is not compared; see match_atoms for that.

source
FermionicHilbertSpaces.atomic_factors — Method
atomic_factors(H)

Return the atoms of H: the indivisible spaces it is built from. Atoms are fixed points, atomic_factors(a) == (a,). For product spaces they are ordered group-major, i.e. atomic_factors(H) is the concatenation of atomic_factors.(groups(H)).

source
FermionicHilbertSpaces.atomic_id — Method
atomic_id(atom)

Name of an atom: the key that identifies its degrees of freedom. It is built only from symbolic identity (basis, label and tags), never from truncation, spin value, transposition or constraints, so a symbol naming a whole atom has the same id as the atom. Only atoms and symbols have an atomic_id; composite spaces are named by atom_ids.

source
FermionicHilbertSpaces.basis_transformation — Method
basis_transformation(Hfrom, Hto)

Return (U, dropped), the basis change U from Hfrom to Hto and the dropped states.

U is the sparse dim(Hto) × dim(Hfrom) matrix with U[i, j] = 1 if basis state j of Hfrom is basis state i of Hto, and dropped are the indices of the states of Hfrom that do not exist in Hto. States of Hto that do not exist in Hfrom give zero rows. Hfrom and Hto must have the same atoms (see match_same_atoms), but their groups may come in different orders.

source
FermionicHilbertSpaces.build_subspace_index — Method
build_subspace_index(constraint, parent, states)

default_subspace_index(constraint, parent, states), after checking that it gives the first, middle and last of states their positions. Throws an ArgumentError otherwise.

source
FermionicHilbertSpaces.change_basis — Method
change_basis(m, Hfrom => Hto; projection=false)
change_basis(m, Hfrom, Hto; projection=false)

Express m in the basis of Hto, where Hfrom and Hto have the same atoms but possibly different (or differently ordered) basis states. Unless projection=true, throws an ArgumentError if m has nonzero elements involving states of Hfrom that are not in Hto.

Either side can be an Axes, one space per axis of m: change_basis(m, H => Axes(Hout, Hin)) extracts the block of m with rows on Hout and columns on Hin, and change_basis(blk, Axes(Hout, Hin) => H) places it in a matrix on H that is zero elsewhere.

source
FermionicHilbertSpaces.combine_states — Method
combine_states(substates, mapper)

Combine subsystem states using mapper.

Returns a pair (states, weights), where states holds the resulting states of the combined space and weights the coefficient of each. A state that combines uniquely gives (state,), (1,).

source
FermionicHilbertSpaces.complementary_subsystem — Method
complementary_subsystem(H, Hsub)

Return the subsystem of H made of the atoms not in Hsub, or nothing if there are none. Hsub must be a subsystem of H, see match_atoms. If H is constrained, the complement only keeps the states that are compatible with some state of Hsub.

source
FermionicHilbertSpaces.default_subspace_index — Method
default_subspace_index(constraint, parent, states)

Build the index (see state_position) of the subspace of parent with basis states, in order. constraint is the constraint that selected states: the one given to hilbert_space, constrain_space, tensor_product or sector, or for a tensor_product of sector spaces without a new constraint, the one built from the constraints of the factors. It is NoSymmetry() otherwise, for example for listed states and for sector without a constraint. The generic method returns a lookup table or a Dict, and throws an ArgumentError on repeated states.

To specialize, add a method that dispatches on the type of constraint only, since restricting parent as well makes extensions ambiguous with each other. When states don't fit the custom index, for example when they are not a whole sector in the expected order, return default_subspace_index(NoSymmetry(), parent, states).

source
FermionicHilbertSpaces.generate_states — Method
generate_states(spaces, constraints; partial_processor=nothing, process_result=(state, space) -> state)

Generate all tensor product states from spaces satisfying constraint. Uses backtracking with pruning via valid_branch.

partial_processor(partial_state, depth, spaces) is called whenever a branch is accepted. process_result(full_state, spaces) can transform each completed state before storing it.

source
FermionicHilbertSpaces.group_id — Method
group_id(atom)

Key used by tensor_product to merge atoms into one group (see combine_into_group). It equals symbolic_group(op) for every symbolic operator op acting on the atom.

source
FermionicHilbertSpaces.groups — Method
groups(H)

Return the groups of H, which line up with the slots of its basis states: for a product space, groups(H)[i] is the space of state.states[i]; otherwise groups(H) == (H,). Groups are fixed points, groups(g) == (g,), and they are the factors of the ordinary tensor product, so tensor_product(groups(H)) recovers H (without its constraints).

source
FermionicHilbertSpaces.has_arithmetic_state_index — Method
has_arithmetic_state_index(H)

Whether state_index(state, H) is computed from state alone, without a lookup table, and is the exact index in 1:dim(H) of each basis state of H and 0 for other states of type statetype(H).

source
FermionicHilbertSpaces.internal_rep — Method
internal_rep(state, space, ::Type{Int}) -> Int
physical_rep(n::Int, ::Type{B}) -> B

Convert a basis state of type B to an integer and back, with physical_rep(internal_rep(state, space, Int), B) == state. When every group of a product space has these methods, operators on the product space act on the integers instead of on the states. Without them, the product space uses the states directly, which is slower.

source
FermionicHilbertSpaces.interpret_state — Method
interpret_state(input, space)
interpret_state(input, ::Type{B})

Convert input, such as the string "10", to a basis state of space, or to a state of type B. Kets, basisstate and state_index call it for strings and characters. A custom basis-state type adds a method for the inputs it accepts; a state is returned as it is.

source
FermionicHilbertSpaces.ispartition — Method
ispartition(Hs, H::AbstractHilbertSpace)

Check that the spaces Hs are subsystems of H (see match_atoms) that together contain each atom of H exactly once.

source
FermionicHilbertSpaces.localize_constraint — Method
localize_constraint(c, H::SectorHilbertSpace)

Return a version of constraint c that is bound to H as its subspace, so that when sector_function is later called on a larger combined space it knows to extract the contribution from H only. Already-localized (non-Missing subspace) or unsupported constraints are returned unchanged.

source
FermionicHilbertSpaces.mat_eltype — Method
mat_eltype(::Type{O})

Element type of the matrix elements of a symbolic operator of type O. Matrix representations promote it with the coefficients of the expression. The fallback is Float64, so an operator type with complex matrix elements must add a method, for example mat_eltype(::Type{<:MyOp}) = ComplexF64.

source
FermionicHilbertSpaces.match_atoms — Method
match_atoms(Hsub, H)

Return the positions of the atoms of Hsub among atomic_factors(H), after checking that Hsub is a subsystem of H. Each atom of Hsub is looked up by name (atom_position) and must then

  • occur in H, and only once in Hsub,
  • keep the relative order it has in H among the atoms of its group (e.g. the Jordan-Wigner order of fermions). The order between groups does not matter.

Throws an ArgumentError describing the first violation.

source
FermionicHilbertSpaces.match_same_atoms — Method
match_same_atoms(H1, H2)

Check that H1 and H2 have the same atoms, in the same order within each group (see match_atoms). The order between groups may differ. Throws an ArgumentError otherwise.

source
FermionicHilbertSpaces.mode_position — Method
mode_position(op, H)

Position of the mode that the operator op acts on, in the mode ordering of H (e.g. the Jordan-Wigner order of fermions), or 0 if H has no such mode.

source
FermionicHilbertSpaces.partial_trace! — Method
partial_trace!(mout, m, H, Hsub; complement=complementary_subsystem(H, Hsub), alg, phase_factors=true, projection=false)
partial_trace!(mout, m, H => Hsub; kwargs...)

In-place partial trace of m (an operator on H or a pure state) from H to Hsub, written to mout, which must have size (dim(Hsub), dim(Hsub)). See partial_trace.

alg is SubsystemPartialTraceAlg() or FullPartialTraceAlg(), chosen from the dimensions and sparsity of m by default; both give the same result and throw in the same cases.

source
FermionicHilbertSpaces.partial_transpose_phase_factor — Method
partial_transpose_phase_factor(f1, f2, Hsub)

Local phase of the matrix unit |f1⟩⟨f2| of Hsub under the graded partial transpose.

It is i^k for fermions, where k is the number of modes in which f1 and f2 differ, and 1 for spaces without phase factors.

source
FermionicHilbertSpaces.partition_product — Function
partition_product(op::NCMul, bases, spaces, concr=NoConcretizer())

Split op into a ProductOperator with one NCMul per basis it acts on. The coefficient goes to the first of them.

source
FermionicHilbertSpaces.permutation_projector — Method
permutation_projector(H, Hs, perms[, weights[, T]]; normalize=true, sparse=true)

Build a group-averaged projector/operator from permutation operators: P = sum(weights[g] * R_g for g), where R_g permutes the factors Hs according to perms[g]. Without weights, every weight is one.

T is the element type of P. It defaults to Int without weights, and otherwise to the element type of weights. For floating point and complex element types, P is replaced by zero if its largest entry is at most sqrt(eps) times the largest weight, so that a sector absent from H gives an exactly zero P instead of roundoff.

Keywords:

  • normalize: rescale P by conj(tr(P)) / sum(abs2, P), which makes P^2 == P when P is proportional to a projector.
  • sparse: return a SparseMatrixCSC if true, and a Matrix otherwise.

Hs may be either a full partition of H (covering all atomic factors) or a proper subsystem list (covering only a subset of atomic factors). In the subsystem case the projector is first constructed on Hsub = tensor_product(Hs...) and then embedded back into H via embed(Psub, Hsub => H).

source
FermionicHilbertSpaces.root_keyed_index — Method
root_keyed_index(space, states)

An IndexTable of the positions of states when it is small enough, otherwise a RootIndexDict, or nothing when space has no arithmetic state_index with Int values. Throws an ArgumentError if a state appears more than once.

source
FermionicHilbertSpaces.split_state — Method
split_state(state, mapper)

Split a state using mapper.

Returns a pair (outcomes, weights). Each element of outcomes is a tuple with one substate per target subsystem, and weights holds the coefficient of the corresponding outcome. A state that splits uniquely gives a single outcome with weight 1, for example ((substate1, substate2),), (1,).

source
FermionicHilbertSpaces.state_mapper — Method
state_mapper(H, Hs)

Create a mapper object for decomposing states in H into the target subsystems Hs. The returned object must subtype AbstractStateMapper.

source
FermionicHilbertSpaces.state_position — Function
state_position(index, state, parent)

The position of state in the subspace that index was built for, or 0 if it is not in it. This is the only method a subspace index implements. It may use parent only through its basis states and state_index, because add_tag and TransposedSpace keep the index but replace the parent.

source
FermionicHilbertSpaces.symbolic_group — Function
symbolic_group(op)

Key that matches the symbolic operator op to the group of a Hilbert space it acts on: symbolic_group(op) == group_id(group). A custom operator type adds a method that returns the label of its space, for example the label of a GenericHilbertSpace.

source
FermionicHilbertSpaces.togglefermions — Method
togglefermions(digitpositions, daggers, f::FockNumber)

Apply creation (dagger == true) and annihilation operators at digitpositions to f.

Returns the new state and the Jordan-Wigner sign, or a sign of 0 if an operator annihilates the state.

source
FermionicHilbertSpaces.togglefermions — Method
togglefermions(sites, daggers, f::FixedNumberFockState, ::Val{M})

Apply creation (dagger == true) and annihilation operators at sites, in order, to f. Returns the resulting state with M particles and the Jordan-Wigner sign, or a sign of 0 if an operator annihilates the state.

source
FermionicHilbertSpaces.valid_branch — Method
valid_branch(constraint, partial_state, depth, spaces) -> Bool

Return true if the branch should be explored, false to prune. For a BranchConstraint this calls constraint.f(partial_state, depth, spaces).

source
FermionicHilbertSpaces.hilbert_space — Method
hilbert_space(f::SymbolicFermionBasis, labels, ::BdG)

The space of Nambu states [f[l] for l in labels; f[l]' for l in labels]. representation gives the particle-hole symmetric BdG matrix, [h Δ; -Δ* -h*] / 2 for op = Σᵢⱼ h[i, j] f[i]' f[j] + (Δ[i, j] f[i]' f[j]' + h.c.) / 2, and only quadratic operators can be represented.

H = hilbert_space(f, 1:2, BdG())representation(f[1]' * f[1], H, :dense) # diagm([1, 0, -1, 0]) / 2
source
FermionicHilbertSpaces.hilbert_space — Method
hilbert_space(f::SymbolicFermionBasis, labels, ::SingleParticle)

The space spanned by the states $c_n^\dagger |0\rangle$ for the modes f[l], l in labels, suitable for non-interacting systems with fermion number conservation. The matrix representation of a quadratic operator is the single-particle matrix, without any contribution from the identity operator. The space wraps a constrained fermionic space, available through parent, and does not combine with tensor products or partial traces.

source
FermionicHilbertSpaces.hilbert_space — Method
hilbert_space(γ::SymbolicMajoranaBasis, labels, ::SingleParticle)

The space of the Majoranas γ[l], l in labels, for quadratic Majorana operators. representation(op, H) is the antisymmetric matrix R with op = Σᵢⱼ R[i, j] γ[i] γ[j] / 2 up to a constant.

@majoranas γH = hilbert_space(γ, 1:2, SingleParticle())representation(1im * γ[1] * γ[2], H, :dense) # [0 1im; -1im 0]
source
FermionicHilbertSpaces.partial_trace — Method
partial_trace(G, Hbdg => Hsub::BdGHilbertSpace)

The Nambu correlation matrix of the modes of Hsub in its order, from the correlation matrix G on Hbdg. Hsub must be a BdG space over a subset of the modes of Hbdg, such as hilbert_space(f, sub, BdG()).

source
FermionicHilbertSpaces.partial_trace — Method
partial_trace(G, Hsp => Hsub::SingleParticleHilbertSpace)

The correlation matrix G[i, j] = ⟨c_i' c_j⟩ of the modes of Hsub in its order, from the one on Hsp. Hsub must be a single-particle space over a subset of the modes of Hsp.

source
FermionicHilbertSpaces.von_neumann_entropy — Method
von_neumann_entropy(G, Hbdg::BdGHilbertSpace)

The von Neumann entropy of the Gaussian state with Nambu correlation matrix G on Hbdg, equal to the entropy of gaussian_state(G, H, Hbdg) for a many-body space H.

source