-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathsu2irrep.jl
More file actions
87 lines (72 loc) · 2.87 KB
/
su2irrep.jl
File metadata and controls
87 lines (72 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
"""
struct SU2Irrep <: AbstractIrrep{SU₂}
SU2Irrep(j::Real)
Irrep[SU₂](j::Real)
Represents irreps of the group ``SU₂``. The irrep is labelled by a half integer `j` which
can be entered as an abitrary `Real`, but is stored as a `HalfInt` from the HalfIntegers.jl
package.
## Fields
- `j::HalfInt`: the label of the irrep, which can be any non-negative half integer.
"""
struct SU2Irrep <: AbstractIrrep{SU₂}
j::HalfInt
function SU2Irrep(j)
j >= zero(j) || error("Not a valid SU₂ irrep")
return new(j)
end
end
Base.getindex(::IrrepTable, ::Type{SU₂}) = SU2Irrep
Base.convert(::Type{SU2Irrep}, j::Real) = SU2Irrep(j)
const _su2one = SU2Irrep(zero(HalfInt))
unit(::Type{SU2Irrep}) = _su2one
dual(s::SU2Irrep) = s
const SU2IrrepProdIterator = SectorProductIterator{SU2Irrep}
Base.IteratorSize(::Type{SU2IrrepProdIterator}) = Base.HasLength()
Base.length(it::SU2IrrepProdIterator) = length(abs(it.a.j - it.b.j):(it.a.j + it.b.j))
function Base.iterate(it::SU2IrrepProdIterator, state = abs(it.a.j - it.b.j))
return state > (it.a.j + it.b.j) ? nothing : (SU2Irrep(state), state + 1)
end
Base.IteratorSize(::Type{SectorValues{SU2Irrep}}) = IsInfinite()
Base.iterate(::SectorValues{SU2Irrep}, i::Int = 0) = (SU2Irrep(half(i)), i + 1)
function Base.getindex(::SectorValues{SU2Irrep}, i::Int)
return 1 <= i ? SU2Irrep(half(i - 1)) : throw(BoundsError(values(SU2Irrep), i))
end
findindex(::SectorValues{SU2Irrep}, s::SU2Irrep) = twice(s.j) + 1
dim(s::SU2Irrep) = twice(s.j) + 1
FusionStyle(::Type{SU2Irrep}) = SimpleFusion()
FusionDataStyle(::Type{SU2Irrep}) = NonTrivialFusionData()
sectorscalartype(::Type{SU2Irrep}) = Float64
Base.isreal(::Type{SU2Irrep}) = true
Nsymbol(sa::SU2Irrep, sb::SU2Irrep, sc::SU2Irrep) = WignerSymbols.δ(sa.j, sb.j, sc.j)
function Fsymbol(
s1::SU2Irrep, s2::SU2Irrep, s3::SU2Irrep,
s4::SU2Irrep, s5::SU2Irrep, s6::SU2Irrep
)
if all(==(_su2one), (s1, s2, s3, s4, s5, s6))
return 1.0
else
return sqrtdim(s5) * sqrtdim(s6) *
WignerSymbols.racahW(
sectorscalartype(SU2Irrep), s1.j, s2.j, s4.j, s3.j,
s5.j, s6.j
)
end
end
function Rsymbol(sa::SU2Irrep, sb::SU2Irrep, sc::SU2Irrep)
Nsymbol(sa, sb, sc) || return zero(sectorscalartype(SU2Irrep))
return iseven(convert(Int, sa.j + sb.j - sc.j)) ? one(sectorscalartype(SU2Irrep)) :
-one(sectorscalartype(SU2Irrep))
end
function fusiontensor(a::SU2Irrep, b::SU2Irrep, c::SU2Irrep)
C = Array{Float64}(undef, dim(a), dim(b), dim(c), 1)
ja, jb, jc = a.j, b.j, c.j
for kc in 1:dim(c), kb in 1:dim(b), ka in 1:dim(a)
C[ka, kb, kc, 1] = WignerSymbols.clebschgordan(
ja, ja + 1 - ka, jb, jb + 1 - kb, jc,
jc + 1 - kc
)
end
return C
end
Base.hash(s::SU2Irrep, h::UInt) = hash(s.j, h)
Base.isless(s1::SU2Irrep, s2::SU2Irrep) = isless(s1.j, s2.j)