SO(3)lver Explained in a Tutorial
To demonstrate the usage of SO(3)lver interfaces, in this section, we use a tutorial that calculates the eigen-states in the $l=0$ sector and the OPE coefficient $f_{\sigma\sigma\epsilon}=\langle \sigma|n^z_{00}|\epsilon\rangle/\langle \sigma|n^z_{00}|0\rangle$ for the Ising model on the fuzzy sphere. The tutorial can be found at tutorial_ising.jl. In this tutorial, the flavour $\mathbb{Z}_2$ is not resolved. A version resolving the $\mathbb{Z}_2$ is given by using the $XX-Z$ basis.
Practically, the ED calculation can be divided into 3 steps.
- Build the angular-momentum-resolved segment spaces and couple them into a composite space of definite total angular momentum,
- Build the segment operators of the decompositions and assemble them into the composite operator for the Hamiltonian,
- Find the lowest eigen-states and make measurements.
The examples can be found in the directory examples. We also append a list of given examples at the end of the page.
Set-up
We begin by loading the packages and set the real element type.
using FuzzifiED
using FuzzifiED.SO3lver
FuzzifiED.ElementType = Float64We then input the parameters of the system : the number of orbitals $N_m$ and the number of electrons $N_e$.
nm = 12
ne = nmIn this set-up, the system is bi-partited into two segments, viz. spin-up and spin-down flavour. Each segment is treated as a separate 1-flavour system.
The first step is to describe a single segment by its diagonal quantum numbers (QNDiags). For a one-flavour segment these are the electron number $N_e$ and the angular momentum $2L^z$.
qnd_pt = [
GetNeQNDiag(nm),
GetLz2QNDiag(nm, 1)
]N. b., in the construction, 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 $2L^z$ quantum number, e. g., from GetLz2QNDiag.
Next we enumerate the sectors of a single segment. The list of sectors are specified by a $\#_\text{QN}×\#_\text{sec}$ matrix where each column specifies a column [Ne, 2Lz]. The electron number ne1 run from $0$ to ne, and fix the representative $2L^z$ to the smallest compatible integer or half-integer value.
sec_pt = stack([ [ne1, ((nm + 1) * ne1) % 2] for ne1 = 0 : ne])Finally we specify the total sector into which the segments must combine.
sec_tot = [ne, 0]Build Segment and Composite Spaces
The mutable type SegSpace stores the Hilbert space of one segment, diagonalized to have definite total angular momentum $l$ (and, facultatively, a definite flavour Casimir $C_2$).
A segment space is generated by the BuildSegSpace function, which takes the number of orbital, the list of sectors, the quantum numbers, and a pair of terms $(L^z, L^+)$ of a single segment which can be generated from the built-in function GetLzLpTerms :
tms_lzlp_pt = GetLzLpTerms(nm, 1)
sgsp = BuildSegSpace(nm, sec_pt, qnd_pt, tms_lzlp_pt)The two segments are identical, so the same sgsp is used for both.
The mutable type CompSpace stores the composite Hilbert space obtained by coupling the segment spaces into a definite total angular momentum. It is built by BuildCompSpace, which takes in the segment spaces, the total sector, and twice the target total angular momentum $2l_{\mathrm{tot}}$. Here we target $l_{\mathrm{tot}} = 0$.
l = 0
cpsp = BuildCompSpace([sgsp, sgsp], sec_tot, 2l)N. b., throughout the package, angular momenta are stored or specified by twice its value $2l$ or $2m$ to stay an integer.
Record the Coupling Decompositions
Having built the segment and composite spaces, we now record the decomposed Hamiltonian. In SO(3)lver, an operator is written as a sum of decomposed coupling channels. Each channel takes the form of
\[ \Phi_L=\Big[\cdots[[\Phi_1]_{L_1}[\Phi_2]_{L_2}]_{L_{12}}\cdots [\Phi_p]_{L_p}\big]_{L_{1\cdots p}} \cdots [\Phi_{N_p}]_{L_{N_p}}\Big]_L\]
is stored in the type of CoupleDecomp, specified by the angular modes of each segment $[Φ_p]_{L_pM_p}$, the coupling channel $\begin{pmatrix}L_1&L_2&\cdots&L_p&\cdots&L_{N_p}\\L_1&L_{12}&\cdots&L_{1\cdots p}&\cdots&L\end{pmatrix}$, the co-efficient $g_d$, and the shift of quantum numbers in the format of a $\#_{\text{QN}}×N_p$ matrix.
We record the Ising interaction by re-coupling the pseudo-potential $V_0=4.75,V_1=1.0$ from pairing channel $\big[[c^\dagger_1 c^\dagger_2][c_3c_4]\big]$ into the density channel $\big[[c^\dagger_1c_4][c^\dagger_2c_3]\big]$. The re-coupling is done by RecoupleAngMom function, and then ConvPsPot converts it into coupling channels and coefficients. The pairing modes $[c^\dagger c]$ is recorded by the type AngModes (which composes in the manner of CG-co-efficient) and generated from GetDensityMod.
n_mod = GetDensityMod(nm, 1, [1;;])
cpd_int = 2 * CoupleDecomps([ n_mod, n_mod ], ConvPsPot(RecoupleAngMom((nm-1)/2, [4.75, 1.0]))..., [ 0 0 ; 0 0 ])We record the transverse field $h\int\mathrm{d}^2\mathbf{r}\,(c_\uparrow c_\downarrow^\dagger-c_\uparrow^\dagger c_\downarrow)(\mathbf{r})$ in terms of contact coupling. The local electron operator is specified by the type SphereObs and generated from GetElectronObs. The contact coupling is generated from ContactCouple, which takes the local operator on each part and the quantum number shift.
c_obs = GetElectronObs(nm, 1, 1)
cpd_nx = ContactCouple([c_obs', c_obs], [ 1 -1 ; 0 0 ]) - ContactCouple([c_obs, c_obs'], [ -1 1 ; 0 0 ])Coupling decompositions support addition, subtraction and scalar multiplication, so the full Hamiltonian can be directly written as
cpd_hmt = cpd_int - 3.16 * cpd_nxBuild Segment and Composite Operators
The reduced matrix elements of every channel of the Hamiltonian, on each of the two segments, are computed in parallel by BuildSegOperators. The result is a matrix of SegOperators of size $N_p ×N_d$, where $N_d$ is the total number of channels.
sgop_hmt = BuildSegOperators([sgsp, sgsp], cpd_hmt ; ident_seg = [1, 1])Here the key-word ident_seg specifies the identical segmentations.
BuildCompOperator assembles the composite Hamiltonian CompOperator on the composite space cpsp built above, combining the reduced matrix elements of the SegOperators with the re-coupling coefficients relating the initial and final coupling channels.
cpop_hmt = BuildCompOperator(cpsp, cpd_hmt, sgop_hmt)The last argument for segment operators can be omitted and generated automatically. It is stored in a matrix-free, block-structured form, and is applied to a state through *.
Find the Eigen-States
The lowest eigen-states are computed by GetEigensystem, which applies KrylovKit.eigsolve to the matrix-free composite operator. Since the operator is real and symmetric we pass issymmetric = true.
enrg, st = GetEigensystem(cpop_hmt, 10 ; issymmetric = true)To measure the $\mathbb{Z}_2$ quantum number, we need to permute the first and second segments for each state, and measure the overlap of the original and permuted states. This permutation can be done by PermFirstSecondSegs
Z = [ st[:, i]' * PermFirstSecondSegs(cpsp, st[:, i]) for i in axes(st, 2)]
display(hcat(enrg, Z))Make Measurements
Beyond the spectrum, we demonstrate how to make measurements through the example of the OPE co-efficient
\[ f_{σσϵ}=\frac{⟨σ|n^z_{00}|ϵ⟩}{⟨σ|n^z_{00}|𝕀⟩}\]
This calculation do not resolve the $ℤ_2$ symmetry, so $𝕀$, $σ$, and $ϵ$ are obtained within the same Hilbert space.
stI = st[:, 1]
stσ = st[:, 2]
stϵ = st[:, 3]We then need the $n^z$ operator. The decomposed coupling that acts only on a single segment is generated by SingleSegCouple.
nz_00 = GetComponent(GetDensityObs(nm, 1), 0, 0)
cpd_nz = SingleSegCouple(2, 1, nz_00, [0, 0]) - SingleSegCouple(2, 2, nz_00, [0, 0])
cpop_nz = BuildCompOperator(cpsp, cpd_nz ; ident_seg = [1, 1])The matrix element of a composite operator between two states can be obtianed through the * operation.
f_σσϵ = (stσ' * cpop_nz * stϵ) / (stσ' * cpop_nz * stI)
@show f_σσϵGo through Other Sectors
To obtain the full spectrum, one repeats the last three steps — BuildCompSpace, BuildCompOperator and GetEigensystem — for each total angular momentum $l$, reusing the same segment space and segment operators.
for l in 0 : 2
cpsp = BuildCompSpace([sgsp, sgsp], sec_tot, 2l)
cpop_hmt = BuildCompOperator(cpsp, cpd_hmt, sgop_hmt)
enrg, st = GetEigensystem(cpop_hmt, 10 ; issymmetric = true)
for i in eachindex(enrg)
push!(result, [enrg[i], l])
end
endExamples Using SO(3)lver
We offer a series of examples that reproduce various fuzzy-sphere calculations with the full $\mathrm{SO}(3)$ symmetry resolved.
ising_spectrum.jlcalculates the spectrum of the 3D Ising model on the fuzzy sphere at $N_m = 12$ in the sectors with total angular momentum $l = 0,1,2$. It resolves the $\mathbb{Z}_2$ symmetry as a QNDiag by using the $XX - Z$ basis.ising_benchmark.jlprovides a benchmark for the package at its best performance. It calculates the 10 lowest $\mathbb{Z}_2$-even states with $l = 0$.ising_generator.jlconstructs the conformal generator $\Lambda = P + K$ and compare the states $\Lambda|\Phi\rangle$ with $|\partial\Phi\rangle$ where $\Phi=\sigma,\epsilon$.so5_dqcp_spectrum.jlcalculates the spectrum of the $\mathrm{SO}(5)$ deconfined quantum critical point. It uses a bi-partition into two segments each of two flavours. The implemented symmetry is $\mathrm{SU}(2)×\mathrm{SU}(2)⊃\mathrm{SO}(5)$ and the $\mathrm{SO}(5)$ representation is resolved by measuring flavour Casimir.sp3_spectrum.jlcalculates the spectrum of the $\mathrm{Sp}(3)$ CFT. It uses a tri-partition, each with two flavours and a $\mathrm{SU}(2)$ symmetry.majorana_spectrum.jlcalculates the spectrum of a free Majorana fermion.u1_2_higgs_spectrum.jlcalculates the spectrum of the $\mathrm{U}(1)_2$-Higgs theory realized as a transition between a $ν=1/2$ bosonic Laughlin state and a $ν=2$ fIQH state.