Module BitStringAddresses.jl
This module contains the implementations of BitString
and various Fock addresses. The addresses serve as a basis for a Hamiltonian.
While there are not restrictions on the type of address a Hamiltonian uses, Rimu provides implementations for Bosonic, Fermionic, and mixed Fock States.
When implementing a new address type, care must be taken to make them space-efficient and stack-allocated - avoid using arrays to represent your addresses at all costs!
Fock addresses
Rimu provides a variety of address implementations (see below) that should make it straightforward to implement efficient Hamiltonians.
Currently, only single-particle operators are implemented directly (via move_particle
). To implement multi-particle operators, convert the address to the onr
representation and back. See the implementation of HubbardMom1D
for an example.
Fock address API
Rimu.BitStringAddresses.AbstractFockAddress
— TypeAbstractFockAddress
Supertype representing a Fock state.
Rimu.BitStringAddresses.SingleComponentFockAddress
— TypeSingleComponentFockAddress{M}
A type representing a single component Fock state with M
modes.
Implemented subtypes: BoseFS
, FermiFS
.
Supported functionality
Rimu.BitStringAddresses.BoseFS
— TypeBoseFS{N,M,S} <: SingleComponentFockAddress
Address type that represents a Fock state of N
spinless bosons in M
modes by wrapping a bitstring of type S <: BitString
.
Constructors
BoseFS{N,M}(bs::BitString)
: Unsafe constructor. Does not check whether the number of particles inbs
is equal toN
.BoseFS(::BitString)
: Automatically determineN
andM
. This constructor is not type stable!BoseFS{[N,M,S]}(onr)
: CreateBoseFS{N,M}
fromonr
representation. This is efficient as long as at leastN
is provided.
See also: SingleComponentFockAddress
, FermiFS
, BitString
.
Rimu.BitStringAddresses.FermiFS
— TypeFermiFS{N,M,S} <: SingleComponentFockAddress
Address type that represents a Fock state of N
fermions of the same spin in M
modes by wrapping a bitstring of type S <: BitString
.
Constructors
FermiFS{N,M}(bs::BitString)
: Unsafe constructor. Does not check whether the number of particles inbs
is equal toN
.FermiFS(::BitString)
: Automatically determineN
andM
. This constructor is not type stable!FermiFS{[N,M,S]}(onr)
: CreateFermiFS{N,M}
fromonr
representation. This is efficient as long as at leastN
is provided.
See also: SingleComponentFockAddress
, BoseFS
, BitString
.
Rimu.BitStringAddresses.BoseFS2C
— TypeBoseFS2C{NA,NB,M,AA,AB} <: AbstractFockAddress
Address type that constructed with two BoseFS{N,M,S}
. It represents a Fock state with two components, e.g. two different species of bosons with particle number NA
from species S and particle number NB
from species B. The number of modes M
is expected to be the same for both components.
Rimu.BitStringAddresses.CompositeFS
— TypeCompositeFS(addresses::SingleComponentFockAddress...) <: AbstractFockAddress
Used to encode addresses for multi-component models. All component addresses are expected have the same number of modes.
See also: BoseFS
, FermiFS
, SingleComponentFockAddress
, num_modes
Rimu.BitStringAddresses.num_particles
— Functionnum_particles(::Type{<:AbstractFockAddress})
num_particles(::AbstractFockAddress)
Number of particles represented by address.
Rimu.BitStringAddresses.num_modes
— Functionnum_modes(::Type{<:AbstractFockAddress})
num_modes(::AbstractFockAddress)
Number of modes represented by address.
Rimu.BitStringAddresses.num_components
— Functionnum_components(::Type{<:AbstractFockAddress})
num_components(::AbstractFockAddress)
Number of components in address.
Rimu.BitStringAddresses.onr
— Functiononr(bs)
Compute and return the occupation number representation of the bit string address bs
as an SVector{M,Int32}
, where M
is the number of modes.
onr(add::AbstractFockAddress, geom::LatticeGeometry)
Returns the occupation number representation of a Fock state address as an SArray
with the shape of the lattice geometry geom
. For composite addresses, a tuple of onr
s is returned.
Rimu.BitStringAddresses.near_uniform
— Functionnear_uniform(BoseFS{N,M})
near_uniform(BoseFS{N,M,S}) -> bfs::BoseFS{N,M,S}
Create bosonic Fock state with near uniform occupation number of M
modes with a total of N
particles. Specifying the bit address type S
is optional.
Examples
julia> near_uniform(BoseFS{7,5,BitString{14}})
BoseFS{7,5}((2, 2, 1, 1, 1))
julia> near_uniform(BoseFS{7,5})
BoseFS{7,5}((2, 2, 1, 1, 1))
Rimu.BitStringAddresses.occupied_modes
— Functionoccupied_modes(::SingleComponentFockAddress)
Iterate over all occupied modes in an address. Iterates BoseFSIndex
for BoseFS
, and an integers for FermiFS
.
Example
julia> b = BoseFS((1,5,0,4));
julia> foreach(println, occupied_modes(b))
[1, 1, 0]
[5, 2, 2]
[4, 4, 9]
julia> f = FermiFS((1,1,0,1,0,0,1));
julia> foreach(println, occupied_modes(f))
1
2
4
7
Rimu.BitStringAddresses.is_occupied
— Functionis_occupied(::SingleComponentFockAddress, i)
Return true
if index i
points to an occupied mode.
Rimu.BitStringAddresses.num_occupied_modes
— Functionnum_occupied_modes(::SingleComponentFockAddress)
Get the number of occupied modes in address. Equivalent to length(
occupied_modes
(address))
, or the number of non-zeros in its ONR representation.
Example
julia> num_occupied_modes(BoseFS((1, 0, 2)))
2
julia> num_occupied_modes(FermiFS((1, 1, 1, 0)))
3
Rimu.BitStringAddresses.find_occupied_mode
— Functionfind_occupied_mode(::SingleComponentFockAddress, k)
Find the k
-th occupied mode in address. Returns BoseFSIndex
for BoseFS
, and an integer for FermiFS
. When unsuccessful it returns zero.
Example
julia> find_occupied_mode(BoseFS((1, 0, 2)), 2)
3-element Rimu.BitStringAddresses.BoseFSIndex with indices SOneTo(3):
2
3
3
julia> find_occupied_mode(FermiFS((1, 1, 1, 0)), 2)
2
Rimu.BitStringAddresses.find_mode
— Functionfind_mode(::SingleComponentFockAddress, i)
Find the i
-th mode in address. Returns BoseFSIndex
for BoseFS
, and an integer index for FermiFS
. Does not check bounds.
julia> find_mode(BoseFS((1, 0, 2)), 2)
3-element Rimu.BitStringAddresses.BoseFSIndex with indices SOneTo(3):
0
2
2
julia> find_mode(FermiFS((1, 1, 1, 0)), 2)
2
Rimu.BitStringAddresses.move_particle
— Functionmove_particle(add::SingleComponentFockAddress, i, j) -> nadd, α
Move particle from mode i
to mode j
. Returns the new Fock state address nadd
and amplitude α
. Equivalent to
\[a^{\dagger}_i a_j |\mathrm{add}\rangle \to α|\mathrm{nadd}\rangle\]
Note that the modes in BoseFS
are indexed by BoseFSIndex
, while the ones in FermiFS
are indexed by integers (see example below). For illegal moves where α == 0
the value of nadd
is undefined.
Example
julia> b = BoseFS((1, 1, 3, 0))
BoseFS{5,4}((1, 1, 3, 0))
julia> i = find_occupied_mode(b, 2)
3-element Rimu.BitStringAddresses.BoseFSIndex with indices SOneTo(3):
1
2
2
julia> j = find_mode(b, i.mode + 1)
3-element Rimu.BitStringAddresses.BoseFSIndex with indices SOneTo(3):
3
3
4
julia> move_particle(b, i, j)
(BoseFS{5,4}((1, 0, 4, 0)), 2.0)
julia> move_particle(b, j, j)
(BoseFS{5,4}((1, 1, 3, 0)), 3.0)
julia> f = FermiFS((1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0))
FermiFS{7,12}((1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0))
julia> i = find_occupied_mode(f, 2)
6
julia> move_particle(f, i, i + 1)
(FermiFS{7,12}((1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0)), 0.0)
julia> move_particle(f, i, i - 1)
(FermiFS{7,12}((1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0)), 1.0)
julia> move_particle(f, i, 12)
(FermiFS{7,12}((1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1)), -1.0)
BitStrings
The atomic addresses, BoseFS
and FermiFS
, are implemented as bitstrings. Using this approach over an occupation number representation makes the addresses much more space-efficient. The API for BitString
s is as follows.
BitString API
Rimu.BitStringAddresses.BitString
— TypeBitString{B,N,T<:Unsigned}
Type for storing bitstrings of static size. Holds B
bits in N
chunks, where each chunk is of type T
.
N
is chosen automatically to accommodate B
bits as efficiently as possible.
Constructors
BitString{B,N,T}(::SVector{N,T})
: unsafe constructor. Does not check for ghost bits.BitString{B,N,T}(i::T)
: as above, but setsi
as the rightmost chunk.BitString{B}(::Integer)
: Convert integer toBitString
. Integer is truncated to the correct number of bits.
Rimu.BitStringAddresses.num_bits
— Functionnum_bits(::Type{<:BitString})
num_bits(s::BitString)
Total number of bits stored in bitstring.
Rimu.BitStringAddresses.num_chunks
— Functionnum_chunks(::Val{B})
Determine the number and type of chunks needed to store B
bits.
num_chunks(::Type{<:BitString})
num_chunks(s::BitString)
Number of chunks in bitstring. Equivalent to length(chunks(s))
.
Rimu.BitStringAddresses.chunk_type
— Functionchunk_type(::Type{<:BitString})
chunk_type(s::BitString)
Type of unsigned integer used to store the chunks.
Rimu.BitStringAddresses.chunk_bits
— Functionchunks_bits(::Type{<:BitString}, i)
chunks_bits(s, i)
Number of bits in the i
-th chunk of s
.
Rimu.BitStringAddresses.top_chunk_bits
— Functiontop_chunk_bits(::Type{<:BitString})
top_chunk_bits(s::BitString)
Number of bits stored in top chunk. Equivalent to chunk_bits(s, 1)
.