Extending and performance hooks
This page lists the places where code outside the package can plug in new operators, states and spaces. Each entry links to the full docstring.
Most of the methods below are not exported. Add methods to them with import FermionicHilbertSpaces: name or by qualifying the name. They are less stable than the exported API and may change in a minor release.
Custom operators
A new kind of symbolic operator is a subtype of AbstractSym. The tutorials Custom operators: Clock and Custom operators: Floquet build one step by step.
Algebra, from NonCommutativeProducts.jl:
@nc MyOpmakes+and*build symbolic sums and products ofMyOp.mul_effect(a::MyOp, b::MyOp)gives the rule for the producta * b:nothingkeeps it,Swap(c)rewrites it asc * b * a, andAddTerms((Swap(c), r, ...))adds further terms. This is required; without it, products such asX * Xthrow anArgumentError.- Operators on different groups commute, ordered by group, so no rule is needed for products of
MyOpwith the operators of the package. Products of different operator types on the same group throw anArgumentErrorunless they have their ownmul_effect. - Operators of the same type on different groups are ordered only by their
mul_effect, which should returnSwap(1)when they are out of order; otherwise equal products can compare unequal.
Connection to Hilbert spaces:
apply_local_operator(op, state, space, precomp) -> (newstate, amplitude)defines howopacts on a basis state. This is required for matrix representations.symbolic_group(op)returns the label of the spaceopacts on. This is required.Base.adjoint(op)returns the adjoint operator. This is required; transposed spaces, as used for open systems, applyadjoint(op).mat_eltype(::Type{<:MyOp})gives the element type of the matrix elements. The default isFloat64, so operators with complex matrix elements need a method.
For speed:
_precomputation_before_operator_application(op, space)computes data once per operator factor, whichapply_local_operatorthen receives asprecompfor every state.apply_local_operators(op::NCMul, state, space, precomps; transpose)applies a whole product at once. A method for products of one operator type avoids applying the factors one by one.
Custom basis states and spaces
FermionicHilbertSpaces.groups(H) returns the spaces that line up with the slots of a basis state: factors(H) for a product space, and (H,) for any other space. See Hilbert space and array operations.
The simplest custom space is a GenericHilbertSpace(label, states), which works with any type of state. Its optional third argument state_index can be a function that computes the index of a state, which avoids the default dictionary lookup.
AbstractBasisStateis the supertype of basis-state types. Subtyping it lets strings name states, and lets constrained spaces return index0for states of other types.interpret_state(input, ::Type{MyState})parses labels such as strings into states, forKets,basisstateandstate_index.internal_rep(state, space, Int)andphysical_rep(n, ::Type{MyState})convert states to integers and back. When all groups of a product space have them, operators on the product space act on integers, which is faster.has_arithmetic_state_index(H)returnstruefor a space type whosestate_indexis computed from the state alone. Constrained spaces over such a space then find states with a table instead of a dictionary. The table relies onstate_indexreturning the exact index in1:dim(H)for each basis state and0for every other state of the same type.AbstractSubspaceis the supertype of spaces spanned by some basis states of a parent space. A subtype implementsparent,subspace_states,subspace_indexandrewrap, and gets tensor products, partial traces and matrix representations from its parent.default_subspace_indexbuilds the index.default_subspace_index(constraint, parent, states)builds the lookup thatstate_indexuses on constrained and sector spaces. A method that dispatches on the type ofconstraintonly, not onparent, selects a custom index. It returnsdefault_subspace_index(NoSymmetry(), parent, states)whenstatesdon't fit it.state_position(index, state, parent)is the one method a custom index implements: the position ofstatein the subspace, or0. It may useparentonly through its basis states andstate_index. Constructors check the index on the first, middle and last state and throw anArgumentErroron a mismatch.
To restrict a space of custom states, use SectorConstraint or FilterConstraint. Their required argument is the reducer, which is called on each basis state. With maps and spaces together, it is called instead on the values that maps gives for the parts of the state in spaces. See Constrained Hilbert spaces and conserved quantum numbers.
Internally, tensor_product, reshape and partial_trace decompose and recombine basis states through a common mapper protocol. state_mapper(H, Hs) returns a mapper object, split_state(state, mapper) returns a pair (outcomes, weights), where each outcome is a tuple with one substate per target subsystem, and combine_states(substates, mapper) returns a pair (states, weights). The collections can have any concrete type; treat them as iterables.