SymBasis.jl is a Julia package for generating bases that conserve symmetries in systems with a discrete number of degrees of freedom, with a focus on quantum many-body applications.
Key features
- Simple API to generate bases with one or multiple symmetries
- Custom symmetries (and predefined ones)
- Supports any discrete DoF: spins, fermions, bosons, or custom objects
- Custom base positional numbering for basis states
Predefined symmetries
- Total magnetization (spins)
- Spatial reflection
- Translational symmetry
(Planned: spin inversion, particle number conservation, etc.)
Installation (Julia β₯ 1.11)
pkg> add SymBasis
Quick example (spin-1/2, N=4, Sz=0)
using SymBasis.DoFObjects
using SymBasis.SymGroups
using SymBasis.Bases
N = 4
Sz = 0//1
dofo = dof_object(:Spin, 1 // 2)
sg = sym(:TotalMagnetization, dofo, Sz, N)
basis(dofo, N, sg)
Project status: active development; please benchmark for your use case. Issues/feedback:
https://github.com/cevenkadir/SymBasis.jl/issues/new
5 Likes
Interesting
I have written somethings in this direction (but focused on spin-half only) myself a couple of years ago. Maybe it useful for you as a reference. GitHub - abraemer/SpinSymmetry.jl: One can never have enough symmetries in one's quantum spin chain.
As a general feedback: In Julia using symbols as arguments just to convert them to Val and then dispatch on is not very idiomatic. I think it would better to just use types for that. Thatβs more discoverable, documentable and less prone to runtime dispatch.
So
dof_object(:Spin, 1//2)
# could be
dof_object(Spin(), 1//2)
# or even simpler
Spin(1//2)
3 Likes
I was not aware of this package, but I will definitely check it out.
As for your feedback: you are right. I will consider changing from Symbol to Type in upcoming versions. Thanks a lot.
With v0.1.2, you can now use types instead of symbols to call predefined symmetry groups and DoF objects:
julia> using SymBasis.DoFObjects
julia> using SymBasis.SymGroups
julia> using SymBasis.Bases
julia> N = 4; # number of sites
julia> Sz = 0; # total magnetization
# define an object for spin-1/2
julia> dofo = dof_object(Spin(1 // 2))
DoFObject: Spin (B=2)
ldof: (-1//2, 1//2)
index types: T=UInt64, Ti=Int64
# define the symmetry group for total magnetization
julia> sg = sym(TotalMagnetization(Sz, N), dofo)
SymGroup{2,Rational{Int64},UInt64,Int64,Float64} with 1 cycle(s)
N: 4
DoF-object: DoFObject(Spin, B=2)
cycles: (N0 = 2, N1 = 2, N = 4)
factors: 1 element(s), eltype=Float64
check: check_Nβ
apply: apply_Nβ
# generate the basis
julia> basis(dofo, N, sg)
Basis{SymBasis.DigitBase.BaseInt{UInt64, Int64, 2},Float64} with 6 states
states: Vector{SymBasis.DigitBase.BaseInt{UInt64, Int64, 2}}
norms : Vector{Float64}
first 6 states/norms:
(11)β (norm=1.0)
(101)β (norm=1.0)
(110)β (norm=1.0)
(1001)β (norm=1.0)
(1010)β (norm=1.0)
(1100)β (norm=1.0)
1 Like