[ANN] SymBasis.jl: Symmetry-conserving bases for Julia

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 :slight_smile: 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