Making Bases

Basis

	BASIS(L;
	a :: Int64 = 1,
	syms :: Dict{String,Int} = (),
	constraint :: Function = identity
	)

A struct that stores a basis for a Hilbert space. A BASIS is constructed by specifiying its attributes. - The number of spins L - The number of spins per unit cell a, whose default is 1. - Any symmetries of the basis, specified as a dictionary syms. The default is no symmetries. - A constraint function state :: UInt64 -> Bool where only states where the constraint evaluates to true are admitted to the Hilbert space.

Symmetries are specified by giving their name and sector. For instance, "tr" => 3 represents the translation symmetry in sector 3, where one application of the symmetry moves the state around by 3 basis vectors. The complete list of implemented symmetries is below.

NameSymmetryValuesGenerator
TrTranslation$1 \le t \le L/a$$S_i^\mu \to S_{i+t \pmod{L/a}}$
PParity (Spin flip)$\{-1,1\}$$\displaystyle \prod_{i=0}^{L-1} S_i^x$
IInversion$\{-1,1\}$$S_i^\mu \to S_{L-1-i}^\mu$
SzTotal $S^z$$-L \le Sz \le L$n/a; counts $\sum_{i=0}^{L-1} S_i^z$
PAP for even spins$\{-1,1\}$$\displaystyle \prod_{\substack{i=0\\ i \equiv 0 \pmod 2}}^{L-1} S_i^x$
PBP for odd spins$\{-1,1\}$$\displaystyle \prod_{\substack{i=0\\ i \equiv 1 \pmod 2}}^{L-1} S_i^x$
SzA$S^z$ for even spins$-L/2 \le SzA \le L/2$n/a; counts $\displaystyle\sum_{\substack{i=0\\ i \equiv 0 \pmod 2}}^{L-1} S_i^z$
SzB$S^z$ for odd spins$-L/2 \le SzB \le L/2$n/a; counts $\displaystyle\sum_{\substack{i=0\\ i \equiv 1 \pmod 2}}^{L-1} S_i^z$

Using some symmetries requires extra conditions. Explicitly, translation symmetry requires periodic boundary conditions, and even/odd parity and spin sectors require a even number of total sites. However, multiple symmetries can be used at the same time.

Index Convention

Spins are zero-indexed, so the left-most site is spin zero and is in the "A" sublattice.

Users can also supply arbitrary constraint functions UInt64 -> Bool, which specify states that are allowed in the Hilbert space.

Note

A BASIS can require a very large amount of memory to store. Internally, it is composed of one hashmap from states in the full Hilbert space to a representative of their conjugacy classes, and another from representatives of conjugacy classes to indices in the small Hilbert space. Altogether, this requires 2^L space. For truly large sizes, one can –- in principle –- generate these hashmaps as needed, but this is not implemented yet here.

Examples

julia> BASIS(8)
BASIS[L: 8, a: 1, dim: 256, symmetries: none]

julia> BASIS(8; a=2)
BASIS[L: 8, a: 2, dim: 256, symmetries: none]

julia> BASIS(8; syms = Dict("Tr"=>1))
BASIS[L: 8, a: 1, dim: 30, symmetries: "Tr" => 1]

julia> BASIS(8; a=2, syms = Dict("Tr"=>1))
BASIS[L: 8, a: 2, dim: 60, symmetries: "Tr" => 1]

julia> BASIS(8; syms = Dict("Sz" => 3, "Tr" => 2))
BASIS[L: 8, a: 1, dim: 7, symmetries: "Sz" => 3, "Tr" => 2]

julia> cons_fcn = x -> x < 17;

julia> BASIS(8; constraint = cons_fcn)
BASIS[L: 8, a: 1, dim: 17, symmetries: "constrained" => 1]
source