Interface
Segment Spaces
The segment Hilber space is stored in a SegSpace (when fully fermionic) or SSegSpace (when bosonic or mixed), both as subtypes of AbstractSegSpace.
FuzzifiED.SO3lver.SegSpace — TypeSegSpace{Float64}
SegSpace{ComplexF64}The mutable type SegSpace stores the Hilbert space of a single segment (part) of the system, diagonalized to have definite total angular momentum $l$ and, facultatively, definite flavour Casimir $C_2$.
\[ |QC_2,lm,α⟩\]
where $Q$ is a set of QNDiag, and $α$ is the multiplicity of the sector. For each multiplet only one state with representative $m$ is stored. Throughout this type the angular momenta are stored as twice their value (i. e. $2l$, $2m$) so that they remain integers.
Fields
sec :: Matrix{Int64}collects the QNDiag sectors that are diagonalized. It takes two indicessec[iqn, isec]whereiqnis the index of the QNDiag andisecis the index of the sector.sec_modul :: Vector{Int64}collects the moduli of the QNDiags.l_rng :: Vector{Vector{Int64}}records, for each sector, the sorted list of the values of $2l$ that appear. It takes two indicesl_rng[isec][il].l_lookup :: Vector{Dict{Int64, Int64}}gives, for each sector, a dictionary that maps a value of $2l$ to its index inl_rng.ptr_st :: Vector{Vector{Int64}}records, for each sector, the pointers that delimit the block of states of each $l$ : the states of angular momentuml_rng[isec][il]are numberedptr_st[isec][il] : ptr_st[isec][il + 1] - 1, and the states of sector indexedisecare numberedptr_st[isec][1] : ptr_st[isec][end] - 1.bs :: Vector{Basis}stores, for each sector, the basis of the configurations.bs1 :: Vector{Basis}stores, for each $m=0$ sector, the basis of the auxiliary $m=1$ sector, used when the $3j$-symbol of the $m=0$ component vanishes.sts :: Vector{Matrix{T}}stores, for each sector, the states as its columns.sts1 :: Vector{Matrix{T}}stores, for each $m=0$ sector, the $m=1$ components $L^+|l0,α⟩=\sqrt{l(l+1)}|l1,α⟩$, used when the $3j$-symbol vanishes.
FuzzifiED.SO3lver.SSegSpace — TypeSSegSpace{Float64}
SSegSpace{ComplexF64}The mutable type SSegSpace stores the Hilbert space of a single segment (part) of the system, diagonalized to have definite total angular momentum $l$ and, facultatively, definite flavour Casimir $C_2$.
\[ |QC_2,lm,α⟩\]
where $Q$ is a set of QNDiag, and $α$ is the multiplicity of the sector. For each multiplet only one state with representative $m$ is stored. Throughout this type the angular momenta are stored as twice their value (i. e. $2l$, $2m$) so that they remain integers.
Fields
sec :: Matrix{Int64}collects the QNDiag sectors that are diagonalized. It takes two indicessec[iqn, isec]whereiqnis the index of the SQNDiag andisecis the index of the sector.sec_modul :: Vector{Int64}collects the moduli of the SQNDiags.l_rng :: Vector{Vector{Int64}}records, for each sector, the sorted list of the values of $2l$ that appear. It takes two indicesl_rng[isec][il].l_lookup :: Vector{Dict{Int64, Int64}}gives, for each sector, a dictionary that maps a value of $2l$ to its index inl_rng.ptr_st :: Vector{Vector{Int64}}records, for each sector, the pointers that delimit the block of states of each $l$ : the states of angular momentuml_rng[isec][il]are numberedptr_st[isec][il] : ptr_st[isec][il + 1] - 1, and the states of sector indexedisecare numberedptr_st[isec][1] : ptr_st[isec][end] - 1.bs :: Vector{SBasis}stores, for each sector, the basis of the configurations.bs1 :: Vector{SBasis}stores, for each $m=0$ sector, the basis of the auxiliary $m=1$ sector, used when the $3j$-symbol of the $m=0$ component vanishes.sts :: Vector{Matrix{T}}stores, for each sector, the states as its columns.sts1 :: Vector{Matrix{T}}stores, for each $m=0$ sector, the $m=1$ components $L^+|l0,α⟩=\sqrt{l(l+1)}|l1,α⟩$, used together withbs1when the $3j$-symbol vanishes.
FuzzifiED.SO3lver.AbstractSegSpace — TypeAbstractSegSpace{T}Abstract supertype of the single-segment Hilbert spaces. Its concrete subtypes are SegSpace for a fermionic segment and SSegSpace for a boson-fermion-mixed segment. Both share the same field layout.
They can be built by
FuzzifiED.SO3lver.BuildSegSpace — FunctionBuildSegSpace(no :: Int64, sec :: Matrix{Int64}, qnd :: Vector{QNDiag}, tms_lzlp :: Tuple{Terms, Terms}[, tms_c2 :: Terms, c2_rng :: Vector{Float64}][, sec_modul :: Vector{Int64}] ; l2c2_ratio :: Float64, nst_max :: Vector{Int64}, eltype :: Type, num_th :: Int64) :: SegSpaceconstructs a SegSpace by diagonalizing the total angular momentum $L^2$ — and, facultatively, the flavour Casimir $C_2$ — within each diagonal quantum number sector, and organizing the resulting eigen-states into multiplets.
N. b., in including the diagonal quantum numbers, it is required that the first QNDiag must contain fermion parity — it must be odd the when state contains odd number of fermions and even when the state contains even number of fermions, and in many cases the total electric charge satisfies this requirement — and the second QNDiag must be the angular momentum $2L^z$.
For each sector the operator $αL^2+C_2$ is built and diagonalized ; the factor $α$ usually guarantees that the eigen-values of $L^2$ and $C_2$ can be disentangled. Only the multiplets whose $C_2$ lies within c2_rng are retained. For sectors with $m=0$ the $m=1$ components $L^+|l,0⟩=\sqrt{l(l+1)}|l,1⟩$ are also computed and stored.
Arguments
no :: Int64is the number of orbitals $N_o$ of the segment.sec :: Matrix{Int64}collects the diagonal quantum number (QNDiag) sectors that are diagonalized. It takes two indicessec[iqn, isec]whereiqnis the index of the QNDiag andisecis the index of the sector.qnd :: Vector{QNDiag}is the list of diagonal quantum numbersQNDiag, where the first contains fermion parity, and the second is $2L^z$.tms_lzlp :: Tuple{Terms, Terms}is the pair of terms $(L^z,L^+)$ from which $L^2$ is built, e. g., fromGetLzLpTerms.tms_c2 :: Termsis the flavour Casimir $C_2$. Facultative, no flavour resolution by default.c2_rng :: Vector{Float64}is the list of allowed eigenvalues of $C_2$ ; a multiplet is kept when its Casimir is within1E-4of one of these values. Facultative,[0.0]by default.sec_modul :: Vector{Int64}collects the moduli of the QNDiags. Facultative, all 1 by default.l2c2_ratio :: Float64is the ratio $α$ that determines $αL^2+C_2$ to be diagonalized. Facultative, $\sqrt{2}$ by default.nst_max :: Vector{Int64}specifies the maximal number of eigen-states for each sector. For each sector, if the number is0or exceeds half the total dimension, then $αL^2+C_2$ is fully diagonalized ; if the number is non-zero, then the lowestnst_max[i]eigen-states of $αL^2+C_2$ will be generated using the method specified bydiag_method.diag_method :: Functionis the method that generates the lowestnststates. It takes in five arguments :no :: Int64,sec :: Vector{Int64},bs :: SBasis,l2c2_mat :: Opmat, andnst :: Int64and returnsl2c2_val :: Vector{Float64}that specifies the eigen-values andst :: Matrix{Float64}that specifies the eigen-states. Facultative, a block Lanczos method by default.eltype :: Typeis the type of the matrix elements, eitherFloat64orComplexF64. Facultative,ElementTypeby default.num_th :: Int64is the number of threads. Facultative,NumThreadsby default.disp_std :: Bool, whether or not the log shall be displayed. Facultative,!SilentStdby default.
Output
sgsp :: SegSpaceis the resulting SegSpace object.
BuildSegSpace(nof :: Int64, nob :: Int64, nebm :: Vector{Int64}, sec :: Matrix{Int64}, qnd :: Vector{SQNDiag}, tms_lzlp :: Tuple{STerms, STerms}[, tms_c2 :: STerms, c2_rng :: Vector{Float64}][, sec_modul :: Vector{Int64}] ; l2c2_ratio :: Float64, nst_max :: Vector{Int64}, eltype :: Type, num_th :: Int64) :: SSegSpaceconstructs a SSegSpace by diagonalizing the total angular momentum $L^2$ — and, facultatively, the flavour Casimir $C_2$ — within each diagonal quantum number sector, and organizing the resulting eigen-states into multiplets.
N. b., in including the diagonal quantum numbers, it is required that the first SQNDiag must contain fermion parity — it must be odd the when state contains odd number of fermions and even when the state contains even number of fermions, and in many cases the total electric charge satisfies this requirement — and the second SQNDiag must be the angular momentum $2L^z$.
For each sector the operator $αL^2+C_2$ is built and diagonalized ; the factor $α$ usually guarantees that the eigen-values of $L^2$ and $C_2$ can be disentangled. Only the multiplets whose $C_2$ lies within c2_rng are retained. For sectors with $m=0$ the $m=1$ components $L^+|l,0⟩=\sqrt{l(l+1)}|l,1⟩$ are also computed and stored.
Arguments
nof :: Int64is the number of fermionic orbitals $N_{of}$ of the segment.nob :: Int64is the number of bosonic orbitals $N_{ob}$ of the segment.nebm :: Vector{Int64}is the maximal number of bosons allowed in each sector ; it takes one indexnebm[isec]whereisecis the index of the sector.sec :: Matrix{Int64}collects the diagonal quantum number (SQNDiag) sectors that are diagonalized. It takes two indicessec[iqn, isec]whereiqnis the index of the SQNDiag andisecis the index of the sector.qnd :: Vector{SQNDiag}is the list of diagonal quantum numbersSQNDiag, where the first contains fermion parity, and the second is $2L^z$.tms_lzlp :: Tuple{STerms, STerms}is the pair of terms $(L^z,L^+)$ from which $L^2$ is built, e. g., fromGetLzLpTermsconverted toSTerms(for fermions) orGetBosonLzLpSTerms(for bosons).tms_c2 :: STermsis the flavour Casimir $C_2$. Facultative, no flavour resolution by default.c2_rng :: Vector{Float64}is the list of allowed eigenvalues of $C_2$ ; a multiplet is kept when its Casimir is within1E-4of one of these values. Facultative,[0.0]by default.sec_modul :: Vector{Int64}collects the moduli of the SQNDiags. Facultative, all 1 by default.l2c2_ratio :: Float64is the ratio $α$ that determines $αL^2+C_2$ to be diagonalized. Facultative, $\sqrt{2}$ by default.nst_max :: Vector{Int64}specifies the maximal number of eigen-states for each sector. For each sector, if the number is0or exceeds half the total dimension, then $αL^2+C_2$ is fully diagonalized ; if the number is non-zero, then the lowestnst_max[i]eigen-states of $αL^2+C_2$ will be generated using the method specified bydiag_method.diag_method :: Functionis the method that generates the lowestnststates. It takes in six arguments :nof :: Int64,nob :: Int64,sec :: Vector{Int64},bs :: SBasis,l2c2_mat :: Opmat, andnst :: Int64and returnsl2c2_val :: Vector{Float64}that specifies the eigen-values andst :: Matrix{Float64}that specifies the eigen-states. Facultative, a block Lanczos method by default.eltype :: Typeis the type of the matrix elements, eitherFloat64orComplexF64. Facultative,ElementTypeby default.num_th :: Int64is the number of threads. Facultative,NumThreadsby default.disp_std :: Bool, whether or not the log shall be displayed. Facultative,!SilentStdby default.
Output
sgsp :: SSegSpaceis the resulting SSegSpace object.
Spaces with different $C_2$ can be built simultaneously.
FuzzifiED.SO3lver.BuildSegSpaces — FunctionBuildSegSpaces(no :: Int64, sec :: Matrix{Int64}, qnd :: Vector{QNDiag}, tms_lzlp :: Tuple{Terms, Terms}[, tms_c2 :: Terms, c2_rng :: Vector{Float64}][, sec_modul :: Vector{Int64}] ; l2c2_ratio :: Float64, nst_max :: Vector{Int64}, eltype :: Type, num_th :: Int64) :: SegSpaceconstructs multiple SegSpaces simultaneosly with different list of flavour Casimir $C_2$.
Arguments
no :: Int64is the number of orbitals $N_o$ of the segment.sec :: Matrix{Int64}collects the QNDiag sectors that are diagonalized. It takes two indicessec[iqn, isec]whereiqnis the index of the QNDiag andisecis the index of the sector.qnd :: Vector{QNDiag}is the list of diagonal quantum numbersQNDiag, where the first contains fermion parity, and the second is $2L^z$.tms_lzlp :: Tuple{Terms, Terms}is the pair of terms $(L^z,L^+)$ from which $L^2$ is built, e. g., fromGetLzLpTerms.tms_c2 :: Termsis the flavour Casimir $C_2$.c2_rng :: Vector{Vector{Float64}}is a collection of lists of allowed eigenvalues of $C_2$ ; for each list within, a SegSpace is generated.sec_modul :: Vector{Int64}collects the moduli of the QNDiags. Facultative, all 1 by default.l2c2_ratio :: Float64is the ratio $α$ that determines $αL^2+C_2$ to be diagonalized. Facultative, $\sqrt{2}$ by default.nst_max :: Vector{Int64}specifies the maximal number of eigen-states for each sector. For each sector, if the number is0or exceeds half the total dimension, then $αL^2+C_2$ is fully diagonalized ; if the number is non-zero, then the lowestnst_max[i]eigen-states of $αL^2+C_2$ will be generated using the method specified bydiag_method.diag_method :: Functionis the method that generates the lowestnststates. It takes in five arguments :no :: Int64,sec :: Vector{Int64},bs :: SBasis,l2c2_mat :: Opmat, andnst :: Int64and returnsl2c2_val :: Vector{Float64}that specifies the eigen-values andst :: Matrix{Float64}that specifies the eigen-states. Facultative, a block Lanczos method by default.eltype :: Typeis the type of the matrix elements, eitherFloat64orComplexF64. Facultative,ElementTypeby default.num_th :: Int64is the number of threads. Facultative,NumThreadsby default.disp_std :: Bool, whether or not the log shall be displayed. Facultative,!SilentStdby default.
Output
sgsp :: SegSpaceis the resulting SegSpace object.
BuildSegSpaces(nof :: Int64, nob :: Int64, nebm :: Vector{Int64}, sec :: Matrix{Int64}, qnd :: Vector{SQNDiag}, tms_lzlp :: Tuple{STerms, STerms}, tms_c2 :: STerms, c2_rng :: Vector{Vector{Float64}}[, sec_modul :: Vector{Int64}] ; l2c2_ratio :: Float64 = √2, eltype :: Type, num_th :: Int64) :: Vector{SSegSpace}constructs multiple SSegSpaces simultaneosly with different list of flavour Casimir $C_2$.
Arguments
nof :: Int64is the number of fermionic orbitals $N_{of}$ of the segment.nob :: Int64is the number of bosonic orbitals $N_{ob}$ of the segment.nebm :: Vector{Int64}is the maximal number of bosons allowed in each sector ; it takes one indexnebm[isec]whereisecis the index of the sector.sec :: Matrix{Int64}collects the QNDiag sectors that are diagonalized. It takes two indicessec[iqn, isec]whereiqnis the index of the SQNDiag andisecis the index of the sector.qnd :: Vector{SQNDiag}is the list of diagonal quantum numbersSQNDiag, where the first contains fermion parity, and the second is $2L^z$.tms_lzlp :: Tuple{STerms, STerms}is the pair of terms $(L^z,L^+)$ from which $L^2$ is built, e. g., fromGetLzLpTermsconverted toSTerms(for fermions) orGetBosonLzLpSTerms(for bosons).tms_c2 :: STermsis the flavour Casimir $C_2$.c2_rng :: Vector{Vector{Float64}}is a collection of lists of allowed eigenvalues of $C_2$ ; for each list within, a SSegSpace is generated.sec_modul :: Vector{Int64}collects the moduli of the SQNDiags. Facultative, all 1 by default.l2c2_ratio :: Float64is the ratio $α$ that determines $αL^2+C_2$ to be diagonalized. Facultative, $\sqrt{2}$ by default.nst_max :: Vector{Int64}specifies the maximal number of eigen-states for each sector. For each sector, if the number is0or exceeds half the total dimension, then $αL^2+C_2$ is fully diagonalized ; if the number is non-zero, then the lowestnst_max[i]eigen-states of $αL^2+C_2$ will be generated using the method specified bydiag_method.diag_method :: Functionis the method that generates the lowestnststates. It takes in six arguments :nof :: Int64,nob :: Int64,sec :: Vector{Int64},bs :: SBasis,l2c2_mat :: Opmat, andnst :: Int64and returnsl2c2_val :: Vector{Float64}that specifies the eigen-values andst :: Matrix{Float64}that specifies the eigen-states. Facultative, a block Lanczos method by default.eltype :: Typeis the type of the matrix elements, eitherFloat64orComplexF64. Facultative,ElementTypeby default.num_th :: Int64is the number of threads. Facultative,NumThreadsby default.disp_std :: Bool, whether or not the log shall be displayed. Facultative,!SilentStdby default.
Output
sgsp :: Vector{SSegSpace}is the resulting list of SSegSpace objects.
Composite Spaces
FuzzifiED.SO3lver.CompSpace — TypeCompSpace{Float64}
CompSpace{ComplexF64}The mutable type CompSpace stores the composite Hilbert space obtained by combining the segment spaces of all the parts and projecting onto a definite total angular momentum $l_{\text{tot}}$. A basis state of the composite space is specified by a composite sector (which sector each part sits in), a coupling channel (the angular momentum of each part and the intermediate totals along the coupling chain), and the position of the multiplet within each part. E. g. for bipartite and tri-partite systems, it may take the form
\[\begin{aligned} |Q_{\{12\}}C_{2,\{12\}},(l_1l_2)lm,α_{\{12\}}⟩&=∑_{m_1m_2}|Q_1C_{2,1},l_1m_1,α_1⟩|Q_2C_{2,2},l_2m_2,α_2⟩⟨l_1m_1,l_2m_2|lm⟩\\ |Q_{\{123\}}C_{2,\{123\}},((l_1l_2)l_{12}l_3)lm,α_{\{123\}}⟩&=∑_{m_1m_2m_3}|Q_1C_{2,1},l_1m_1,α_1⟩|Q_2C_{2,2},l_2m_2,α_2⟩|Q_3C_{2,3},l_3m_3,α_3⟩⟨l_1m_1,l_2m_2|l_{12}m_{12}⟩⟨l_{12}m_{12},l_3m_3|lm⟩ \end{aligned}\]
Angular momenta are stored as twice their value so that they remain integers.
Fields
np :: Int64is the number of parts.nch :: Int64is the total number of coupling channels summed over all composite sectors.dim :: Int64is the total dimension of the composite space.ltot :: Int64is twice the total angular momentum $2l_{\text{tot}}$.sgsp :: Vector{<:AbstractSegSpace{T}}is the list of the AbstractSegSpaces of the parts, which may mix fermionic SegSpace and bosonic SSegSpace.idsec :: Matrix{Int64}is the list of composite sector indices. It takes two indicesidsec[p, isec]whereisecis the index of the composite sector andpis the index of the part. The sector is then given bysgsp[p].sec[idsec[p, isec]].chs :: Vector{Vector{Matrix{Int64}}}records, for each composite sector, the list of angular momentum coupling channels. Each channel is stored as a $2×N_p$ matrix $\begin{pmatrix}l_1&l_2&⋯&l_p&⋯&l_{N_p}\\l_1&l_{12}&⋯&l_{1⋯ p}&⋯&l\end{pmatrix}$
, where the first row is the angular momentum of each part $2l_p$, and the second row is the accumulated angular momentum $2l_{12⋯p}$ of the first $p$ parts. It takes two indices chs[isec][ich] where the isec is the index of the composite sector and ich is the index of the channel within the sector.
ptr_ch :: Vector{Int64}are the pointers that delimit the channels of each composite sector.ptr_st :: Vector{Vector{Int64}}records the pointers that delimit the states of each channel.
FuzzifiED.SO3lver.BuildCompSpace — FunctionBuildCompSpace(sgsp :: Vector{<:AbstractSegSpace{T}}, idsec :: Matrix{Int64}, ltot :: Int64) :: CompSpace
BuildCompSpace(sgsp :: Vector{<:AbstractSegSpace{T}}, sec_tot :: Vector{Int64}, ltot :: Int64) :: CompSpaceconstructs a CompSpace from the segment spaces of the parts with total angular momentum ltot. For every composite sector it enumerates, through FindCouplingChannels, all the ways of coupling the per-part angular momenta into $l_{\text{tot}}$, and computes the resulting dimensions and pointers.
Arguments
sgsp :: Vector{<:AbstractSegSpace{T}}is the list of the AbstractSegSpaces of the parts, which may mix fermionic SegSpace and bosonic SSegSpace.idsec :: Matrix{Int64}is the list of composite sector indices. It takes two indicesidsec[p, isec].ltot :: Int64is twice the total angular momentum $2l_{\text{tot}}$.
Output
cpsp :: CompSpaceis the resulting composite space.
BuildCompSpace(sgsp :: Vector{<:AbstractSegSpace{T}}, sec_tot :: Vector{Int64}, ltot :: Int64) :: CompSpaceconstructs a CompSpace from the segment spaces of the parts with total angular momentum ltot. For every composite sector it enumerates, through FindCouplingChannels, all the ways of coupling the per-part angular momenta into $l_{\text{tot}}$, and computes the resulting dimensions and pointers. The composite sectors are found automatically with ComposeSec.
Arguments
sgsp :: Vector{<:AbstractSegSpace{T}}is the list of the AbstractSegSpaces of the parts, which may mix fermionic SegSpace and bosonic SSegSpace.sec_tot :: Vector{Int64}the target total diagonal quantum numbers.ltot :: Int64is twice the total angular momentum $2l_{\text{tot}}$.
Output
cpsp :: CompSpaceis the resulting composite space.
When the first two segments of a CompSpace are identical, to permute them for a state
FuzzifiED.SO3lver.PermFirstSecondSegs — FunctionPermFirstSecondSegs(cpsp :: CompSpace{T}, st :: Vector{T}) :: Vector{T}When the first two segments in cpsp are the same, this function returns the state with the first two segments permuted.
Several methods help comparing, composing sectors, and finding coupling channels of angular momenta.
FuzzifiED.SO3lver.EquivSec — FunctionEquivSec(sec1 :: Vector{Int64}, sec2 :: Vector{Int64}, modul :: Vector{Int64}) :: Booltests whether two diagonal quantum number sectors sec1 and sec2 are equivalent. The comparison skips the second entry $L^z$ ; for every other quantum number i the entries must agree, either exactly when modul[i] == 1 or modulo modul[i].
FuzzifiED.SO3lver.ComposeSec — FunctionComposeSec(sec_tot :: Vector{Int64}, sec_pt :: Vector{Matrix{Int64}}[, modul :: Vector{Int64}]) :: Matrix{Int64}finds every combination of segment sectors into the total sector sec_tot.
Arguments
sec_tot :: Vector{Int64}is the target total diagonal quantum numbers.sec_pt :: Vector{Matrix{Int64}}lists, for each part, the sectors available in that part. It takes three indicessec_pt[p][iqn, isec].modul :: Vector{Int64}are the moduli used to match the quantum numbers. Facultative, all $1$ by default.
Output
idsec_tot :: Matrix{Int64}is the sorted list of composite sectors, one per column ; each column is a vector of per-part sector indices.
FuzzifiED.SO3lver.FindCouplingChannels — FunctionFindCouplingChannels(np :: Int64, lpt :: Vector{Int64}, ltot :: Int64) :: Vector{Matrix{Int64}}recursively enumerates every way of coupling the np angular momenta lpt successively along the chain of parts into the total angular momentum ltot. All the angular momenta are given as twice their value.
Arguments
np :: Int64is the number of parts.lpt :: Vector{Int64}is the list of the individual angular momenta $2l_p$ to be coupled.ltot :: Int64is twice the target total angular momentum $2l_{\text{tot}}$.
Output
chs :: Vector{Matrix{Int64}}is the list of coupling channels.
Coupling Decompositions
FuzzifiED.SO3lver.CoupleDecomp — TypeCoupleDecompThe mutable type CoupleDecomp records an angular-moemntum channel of a coupling — a direct product of spherical-symmetric actions on each part, coupled to a definite total angular momentum. A full operator is represented as a CoupleDecomps, i. e. a sum of such channels. E. g. for bipartite and tri-partite systems, a channel may take the form
\[\begin{aligned} [𝒪]_{(l_1l_2)l}&=\Big[[𝒪_1]_{l_1}⊗[𝒪_2]_{l_2}\Big]_l&𝒪_{lm}&=[𝒪_1]_{l_1l_1}[𝒪_2]_{l_2m_2}⟨l_1m_1,l_2m_2|lm⟩\\ [𝒪]_{((l_1l_2)l_{12}l_3)l}&=\Big[\big[[𝒪_1]_{l_1}[𝒪_2]_{l_2}\big]_{l_{12}}[𝒪_3]_{l_3}\Big]_l&𝒪_{lm}&=[𝒪_1]_{l_1l_1}[𝒪_2]_{l_2m_2}[𝒪_3]_{l_3m_3}⟨l_1m_1,l_2m_2|l_{12}m_{12}⟩⟨l_{12}m_{12},l_3m_3|lm⟩ \end{aligned}\]
Fields
amd :: Vector{Union{AngModes, SAngModes, Symbol}}records, for each segment $p$, its angular modes $[Φ_p]_{lm}$ — anAngModeson a fermionic segment, anSAngModeson a bosonic one, or:Identityon an inert segment.ch :: Matrix{Int64}is the coupling channel in the form of a $2×N_p$ matrix.coeff :: ComplexF64is the coefficient of the channel.sec :: Matrix{Int64}records the change of quantum numbers that the term induces :sec[iqn, p]is the shift of theiqn-th diagonal quantum number on part $p$.
FuzzifiED.SO3lver.CoupleDecomps — TypeCoupleDecomps = Vector{CoupleDecomp}Alias for Vector{CoupleDecomp}, representing a full operator as a list of single-channel CoupleDecomps.
Base.:+ — Methodcpd1 + cpd2 :: CoupleDecomps
cpd1 - cpd2 :: CoupleDecomps
-cpd :: CoupleDecomps
fac * cpd :: CoupleDecompsenable the linear combination of coupling decompositions.
Several methods are used to generate contact couplings and operators that act only on one segment.
FuzzifiED.SO3lver.ContactCouple — FunctionContactCouple(obs :: Vector{<:Union{SphereObs, SSphereObs}}, sec :: Matrix{Int64}, ltot :: Int64) :: CoupleDecompsconstructs a CoupleDecomps for a contact term, i. e. the product of one spherical observable per part evaluated at the same point on the sphere
\[ ∫\mathrm{d}^2𝐫\,\sqrt{4π}Ȳ_{lm}(𝐫)\,Φ_1(𝐫)Φ_2(𝐫)⋯Φ_{N_p}(𝐫)\]
Arguments
obs :: Vectoris the list of spherical observables acting on each segment — each a fermionicSphereObsor a bosonicSSphereObs, and the two may be mixed.sec :: Matrix{Int64}records the change of quantum numbers,sec[iqn, p]for theiqn-th quantum number on part $p$.ltot :: Int64is twice the total angular momentum $2l_{\text{tot}}$ of the term. Facultative, $0$ (a scalar) by default.
Output
cpd :: CoupleDecompsis the resulting coupling decompositions, one CoupleDecomps per channel.
FuzzifiED.SO3lver.SingleSegCouple — FunctionSingleSegCouple([np :: Int64, p :: Int64, ]amdp :: Union{AngModes, SAngModes}, l :: Int64, secp :: Vector{Int64}) :: CoupleDecompsconstructs a CoupleDecomps for an angular mode that acts only on a single part $p$ and as the identity on all the other parts.
Arguments
np :: Int64is the number of parts. Facultative, 1 by default.p :: Int64is the index of the part on which the operator acts. Facultative, 1 by default.amdp :: AngModesoramdp :: SAngModesis the angular modes acting on part $p$.l :: Int64is twice the rank $2l$ of the operator on part $p$.secp :: Vector{Int64}is the change of quantum numbers on part $p$.
Output
cpd :: CoupleDecompsis the resulting coupling decomposition (a single channel).
SingleSegCouple([np :: Int64, p :: Int64, ]tms :: Union{Terms, STerms}, sec :: Vector{Int64}) :: CoupleDecompsconstructs a $\mathrm{SO}(3)$-spin-$0$ CoupleDecomps for terms that acts only on a single part $p$ and as the identity on all the other parts.
Arguments
np :: Int64is the number of parts. Facultative, 1 by default.p :: Int64is the index of the part on which the operator acts. Facultative, 1 by default.tms :: Termsortms :: Termsis the $\mathrm{SO}(3)$-spin-$0$ terms acting on part $p$.l :: Int64is twice the rank $2l$ of the operator on part $p$.secp :: Vector{Int64}is the change of quantum numbers on part $p$.
Output
cpd :: CoupleDecompsis the resulting coupling decomposition (a single channel).
FuzzifiED.SO3lver.InsertSegment — FunctionInsertSegment(np :: Int64, p_rng :: Vector{Int64}, ch :: Matrix{Int64}) :: Matrix{Int64}
InsertSegment(np :: Int64, p_rng :: Vector{Int64}, cpd :: CoupleDecomps) :: CoupleDecompsInsert segments where the coupling acts as identity to channel(s) or CoupleDecomp(s)
\[ H_1⊗H_2⊗⋯↦𝕀⊗⋯⊗H_1⊗𝕀⊗⋯⊗H_2⊗𝕀⊗⋯\]
Arguments
np :: Int64is the number of segments after the insertion.p_rng :: Int64is the positions of the non-trivial segments after the insertion.ch :: Matrix{Int64},ch :: Vector{Matrix{Int64}},cpd :: CoupleDecomp,cpd :: CoupleDecompsis the channel(s) or CoupleDecomp(s) before the insertion.
Several methods help re-coupling angular momenta and converting pseudo-potentials to coupling channel.
FuzzifiED.SO3lver.RecoupleAngMom — FunctionRecoupleAngMom(s1 :: Number, s2 :: Number, s3 :: Number, s4 :: Number, ps_pot0 :: Dict) :: Dictre-couples the pseudo-potentials of a four-fermion term $c^†_1c^†_2c_3c_4$ from the pairing channel $(12)(34)$ into the density channel $(14)(23)$ using Wigner's $6j$-symbol.
Arguments
s1, s2, s3, s4 :: Numberare the spins of the four particles.ps_pot0 :: Dictis a dictionary mapping a density rank $l$ to its coefficient $V_l$
Output
ps_pot1 :: Dict mapping the angular momentum $l$ to the pseudoo-potential $W_l$
RecoupleAngMom(s :: Number, ps_pot :: Vector{<:Number}) :: Dictre-couples the pseudo-potentials of a four-fermion term $c^†_1c^†_2c_3c_4$ from the pairing channel $(12)(34)$ into the density channel $(14)(23)$ using Wigner's $6j$-symbol.
Arguments
sis the single-particle spin, andps_potis a vector of pseudo-potentials froml=2sdownwards.
Output
ps_pot1 :: Dict mapping the angular momentum $l$ to the pseudoo-potential $W_l$
RecoupleAngMom(s1 :: Number, s2 :: Number, s3 :: Number, s4 :: Number, ch0 :: Vector{Matrix{Int64}}, coeff0 :: Vector{<:Number}) :: Tuple{Vector{Matrix{Int64}}, Vector{<:Number}}re-couples the angular momentum composition of a four-fermion term $c^†_1c^†_2c_3c_4$ from the pairing channel $(12)(34)$ into the density channel $(14)(23)$ using Wigner's $9j$-symbol. This is the most general method and allows non-zero total angular momentum.
Arguments
s1, s2, s3, s4 :: Numberare the spins of the four particles.ch0 :: Vector{Matrix{Int64}}are the angular-momentum channels.coeff0 :: Vectorare the coefficient of each channel.
Output
A tuple of re-coupled channels ch0 :: Vector{Matrix{Int64}} and co-efficients coeff0 :: Vector{<:Number}
FuzzifiED.SO3lver.ConvPsPot — FunctionConvPsPot(ps_pot0 :: Dict) :: Tuple{Vector{Matrix{Int64}}, Vector{ComplexF64}}converts a pseudo-potential into the coupling channels and coefficients used by a CoupleDecomps. The co-efficient is connected to the pseudo-potential by $Ṽ_l = (-1)^l\sqrt{2l+1}V_l$.
Arguments
ps_pot0 :: Dictis a dictionary mapping a density rank $l$ to its coefficient $V_l$
Output
ch :: Vector{Matrix{Int64}}is the list of coupling channels.coeff :: Vector{ComplexF64}is the list of channel coefficients.
ConvPsPot(s :: Number, ps_pot :: Vector{<:Number}) :: Tuple{Vector{Matrix{Int64}}, Vector{ComplexF64}}converts a pseudo-potential into the coupling channels and coefficients used by a CoupleDecomps. The co-efficient is connected to the pseudo-potential by $Ṽ_l = (-1)^l\sqrt{2l+1}V_l$.
Arguments
sis the spin of a single electron, andps_potis a vector of pseudo-potentials froml=2sdownwards.
Output
ch :: Vector{Matrix{Int64}}is the list of coupling channels.coeff :: Vector{ComplexF64}is the list of channel coefficients.
Segmented Operators
FuzzifiED.SO3lver.SegOperator — TypeSegOperator{Float64}
SegOperator{ComplexF64}The mutable type SegOperator stores the action of a spherical-symmetric operator from an initial SegSpace to a final SegSpace. By virtue of the Wigner-Eckart theorem, the full $m$-dependence is factored out and only the reduced matrix elements $⟨l_2\|[Φ]_l\|l_1⟩$ – independent of $l^z$ – need to be kept, and
\[ ⟨l_2m_2|[Φ]_{lm}|l_1m_1⟩=(-1)^{l_2-m_2}\begin{pmatrix}l_2&l&l_1\\-m_2&m&m_1\end{pmatrix}⟨l_2\|[Φ]_l\|l_1⟩\]
The matrix $⟨Q_2l_2α_2\|[Φ]_l\|Q_1l_1α_1⟩$ is stored in blocks of QNDiag – for given sectors $Q_{\{12\}}$, the matrix elements $(M_{l_2l_1})_{α_2α_1}$ are stored.
Fields
sgspd :: SegSpaceandsgspf :: SegSpaceare the initial and final segment spaces.colptr :: Vector{Int64}androwid :: Vector{Int64}store the allowed blocks of sectors $Q_{12}$ in the format of a CSC sparse matrix.elmat :: Vector{Matrix{Matrix{T}}}stores, for each block of sectors, the reduced matrix elements. It takes five indiceselmat[e][ich, jch][i, j], whereeis the index for the sector block,ichandjchare the channel index, andiandjare the state index within each channel.
FuzzifiED.SO3lver.BuildSegOperator — FunctionBuildSegOperator(sgspd :: SegSpace{T}[, sgspf :: SegSpace{T}], amd :: AngModes, ll :: Int64, secop :: Vector{Int64} ; full_mat :: Bool, num_th :: Int64) :: SegOperator{T}
BuildSegOperator(sgspd :: SSegSpace{T}[, sgspf :: SSegSpace{T}], amd :: SAngModes, ll :: Int64, secop :: Vector{Int64} ; full_mat :: Bool, num_th :: Int64) :: SegOperator{T}constructs a SegOperator from the angular modes amd acting on a single segment and the angular momentum ll. For each allowed pair of sectors and angular momenta, it computes the reduced matrix element from the full matrix element via the Wigner-Eckart theorem by dividing out the phase and the $3j$-symbol. When the $3j$-symbol vanishes (for odd $l'+L+l$ when $m_1=m_2=0$) the reduced matrix element is instead calculated from the pre-stored$m=1$ components.
Arguments
sgspd :: SegSpace{T}orsgspd :: SSegSpace{T}is the initial segment space.sgspf :: SegSpace{T}orsgspf :: SSegSpace{T}is the final segment space. Facultative, the same assgspdby default.amd :: AngModesoramd :: SAngModesis the angular modes.ll :: Int64is twice the angular momentum $2l$ of the segment operator.secop :: Vector{Int64}is the QNDiag shift of the operator.full_mat :: Booldetermines whether a full matrix instead of sparse matrix is generated when generating the segment operators. It should be turned on if the flavour symmetry $C_2$ is not selected when constructing the segment space. Facultative,falseby default.num_th :: Int64is the number of threads. Facultative,NumThreadsby default.
Output
sgop :: SegOperator{T}is the resulting segment operator.
FuzzifiED.SO3lver.BuildSegOperators — FunctionBuildSegOperators(sgspd :: Vector{<:AbstractSegSpace{T}}[, sgspf :: Vector{<:AbstractSegSpace{T}}], cpd :: CoupleDecomps ; p_rng :: Vector{Int64}, ident_seg :: Vector{Int64}, full_mat :: Bool, num_th :: Int64) :: Matrix{SegOperator}constructs, in parallel, all the SegOperators required to assemble the composite operators described by the coupling decompositions cpd.
Arguments
sgspd :: Vector{<:AbstractSegSpace{T}}is the list of the initial segment spaces. Its elements are eitherSegSpaceorSSegSpace.sgspf :: Vector{<:AbstractSegSpace{T}}is the list of the final segment spaces. Its elements are eitherSegSpaceorSSegSpace. Facultative, the same assgspdby default.cpd :: CoupleDecompsis the list of coupling decompositions, e. g., an assembled Hamiltonian.p_rng :: Vector{Int64}. When specified, only the SegOperators of the specified parts will be generated. It must be of the same length assgspd. An array $1:N_p$ by default.ident_seg :: Vector{Int64}labels the identical segments. If given, an array of length $N_p$, identical segments carry identical index. Facultative, empty by default, marking no identification.full_mat :: Booldetermines whether a full matrix instead of sparse matrix is generated when generating the segment operators. It should be turned on if the flavour symmetry $C_2$ is not selected when constructing the segment space. Facultative,falseby default.num_th :: Int64is the number of threads. BLAS and Generation of $OpMat$ are parallelized. Facultative,NumThreadsby default.disp_std :: Bool, whether or not the log shall be displayed. Facultative,!SilentStdby default.
Output
sgop :: Matrix{SegOperator}is a matrix of segment operators of size $N_p×N_d$, where $N_p$ is the number of parts and $N_d$ the total number of channels ofcpd. It is passed together with the samecpdto BuildCompOperator.
Composite Operators
FuzzifiED.SO3lver.CompOperator — TypeCompOperator{Float64}
CompOperator{ComplexF64}The mutable type CompOperator represents a composite operator — such as the Hamiltonian — acting on a CompSpace of definite total angular momentum. It combines the reduced matrix elements of the per-part SegOperators with the $9j$ re-coupling coefficients that relate the coupled basis of the initial and final composite spaces. The operator is stored in a block-structured form. It can be multiplied formally to a state.
Fields
cpspd :: CompSpaceandcpspf :: CompSpaceare the initial and final composite spaces.nd :: Int64is the number of decomposition channels of the operator.ltot :: Int64is twice the total angular momentum $2l_{\text{tot}}$ carried by the operator ($0$ for a scalar such as the Hamiltonian).coeff :: Vector{T}is the coefficient of each decomposition channel.sgop :: Matrix{SegOperator}is the $N_p×N_d$ matrix of segment operators produced by BuildSegOperators.colptr :: Matrix{Int64}androwid :: Vector{Vector{Int64}}store the allowed blocks of sectors for each channel.colptr[:, d]androwid[d]bear the format of a CSC sparse matrix.idel :: Vector{Matrix{Int64}}locates the matrix element block in the SegOperators for each segment. It takes three indicesidel[d][p, e]wheredis the channel index,eis the element index, andpis the part index.mat9j :: Vector{Vector{Matrix{Float64}}}stores the precomputed $9j$ re-coupling coefficients, including the fermionic reordering sign. It takes four indicesmat9j[d][e][ich, jch]whereich,jchis the channel indices within the sectors specified bye.wklist :: Vector{Tuple{Int64, Int64, Int64}}is the flattened list of the(jsec, d, e)matrix element blocks, ordered from the most to the least expensive. The threads of the operator application take their blocks greedily from this list.
FuzzifiED.SO3lver.BuildCompOperator — FunctionBuildCompOperator(cpspd :: CompSpace{T}[, cpspf :: CompSpace{T}], cpd :: CoupleDecomps[, sgop :: Matrix{SegOperator}][, ltot :: Int64] ; ident_seg :: Vector{Int64}, full_mat :: Bool, num_th :: Int64) :: CompOperatorconstructs a CompOperator from the composite spaces, the coupling decompositions cpd and the segment operators sgop. It computes and stores the $9j$ re-coupling coefficient between every pair of initial and final coupling channels and every decomposition channel together with the sign arising from fermion parity.
Arguments
cpspd :: CompSpace{T}is the initial composite space.cpspf :: CompSpace{T}is the final composite space. Facultative, the same ascpspdby default.cpd :: CoupleDecompsis the list of coupling decompositions ; it must be the same one used to buildsgop.sgop :: Matrix{SegOperator}is the matrix of segment operators. Facultative, if omitted, the segment operators will be automatically generated fromBuildSegOperators.ltot :: Int64is twice the total angular momentum $2l_{\text{tot}}$ carried by the operator. Facultative, $0$ (a scalar) by default.ident_seg :: Vector{Int64},full_mat :: Bool, andnum_th :: Int64are forwarded toBuildSegOperators; they are accepted only whensgopis omitted.disp_std :: Bool, whether or not the log shall be displayed. Facultative,!SilentStdby default.
Output
cpop :: CompOperatoris the resulting composite operator.
Base.:* — Method*(cpop :: CompOperator{T}, std :: Vector{T} ; num_th :: Int64) :: Vector{T}
*(stf :: LinearAlgebra.Adjoint{T, Vector{T}}, cpop :: CompOperator{T}, std :: Vector{T} ; num_th :: Int64) :: Vector{T}applies the composite operator cpop to a state std of the initial composite space and returns the resulting state of the final composite space or calculates its inner product between an initial and a final state. The action is evaluated block by block : for every decomposition channel and every pair of coupling channels it takes the Kronecker product of the corresponding per-part reduced matrix element blocks, weighted by the channel coefficient and the $9j$ re-coupling factor. The number of threads used num_th is by default NumThreads.
Base.Matrix — MethodMatrix(cpop :: CompOperator{T} ; disp_std :: Bool, num_th :: Int64) :: Matrix{T}materializes the composite operator cpop into a dense matrix. The number of threads used num_th is by default NumThreads.
FuzzifiED.GetEigensystem — MethodGetEigensystem(cpop :: CompOperator{T}, nst :: Int64 ; tol :: Float64, ncv :: Int64, initvec :: Vector{T}, full_mat :: Bool, proj_sym :: Function, num_th :: Int64, kwargs...) :: Tuple{Vector{T}, Matrix{T}}computes the lowest nst eigen-values and eigen-states of the composite operator cpop through KrylovKit.eigsolve.
Arguments
cpop :: CompOperator{T}is the composite operator (usually the Hamiltonian).nst :: Int64is the number of eigen-states to compute.tol :: Float64is the tolerance of the eigen-solver. Facultative,1E-8by default.ncv :: Int64is the dimension of the Krylov subspace. Facultative,max(2 * nst, nst + 10)by default.initvec :: Vector{T}is the initial vector. Facultative, a random vector by default.full_mat :: Bool, whether the operator is first materialized into a dense matrix and this matrix is handed toeigsolve. Facultative,falseby default.proj_sym :: Function. To implement a off-diagonal symmetry, feed in a function from a vector to a vector that projects it to the desired sector. Facultative,identityby default. Only supported whenfull_matisfalse. N. b., some unphysical null states may appear. E. g., to target the sector that is even under the permutation of the first two segments, feed inst -> (st .+ PermFirstSecondSegs(cpsp, st)) ./ 2.num_th :: Int64is the number of threads used in matrix multiplication. Facultative,NumThreadsby default.kwargs...are further key-word arguments forwarded toeigsolve, e. g.,ishermitian = truefor complex andissymmetric = truefor real matrix.
Output
eigval :: Vector{T}is the vector of thenstlowest eigen-values.eigvec :: Matrix{T}is the matrix whose columns are the corresponding eigen-states.