Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 94 additions & 6 deletions src/tjoperators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ function tj_space(::Type{Trivial}, ::Type{U1Irrep}; slave_fermion::Bool=false)
end
end
function tj_space(::Type{Trivial}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
return error("Not implemented")
return slave_fermion ? Vect[FermionParity ⊠ SU2Irrep]((1, 0) => 1, (0, 1 // 2) => 1) :
Vect[FermionParity ⊠ SU2Irrep]((0, 0) => 1, (1, 1 // 2) => 1)
end
function tj_space(::Type{U1Irrep}, ::Type{Trivial}; slave_fermion::Bool=false)
return if slave_fermion
Expand All @@ -67,7 +68,11 @@ function tj_space(::Type{U1Irrep}, ::Type{U1Irrep}; slave_fermion::Bool=false)
end
end
function tj_space(::Type{U1Irrep}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
return error("Not implemented")
return if slave_fermion
Vect[FermionParity ⊠ U1Irrep ⊠ SU2Irrep]((1, 0, 0) => 1, (0, 1, 1 // 2) => 1)
else
Vect[FermionParity ⊠ U1Irrep ⊠ SU2Irrep]((0, 0, 0) => 1, (1, 1, 1 // 2) => 1)
end
end

# Single-site operators
Expand Down Expand Up @@ -181,6 +186,26 @@ function c_num(T, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Secto
return u_num(T, particle_symmetry, spin_symmetry; slave_fermion) +
d_num(T, particle_symmetry, spin_symmetry; slave_fermion)
end
function c_num(T, ::Type{Trivial}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
t = single_site_operator(T, Trivial, SU2Irrep; slave_fermion)
I = sectortype(t)
if slave_fermion
block(t, I(0, 1 // 2))[1, 1] = 1
else
block(t, I(1, 1 // 2))[1, 1] = 1
end
return t
end
function c_num(T, ::Type{U1Irrep}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
t = single_site_operator(T, U1Irrep, SU2Irrep; slave_fermion)
I = sectortype(t)
if slave_fermion
block(t, I(0, 1, 1 // 2))[1, 1] = 1
else
block(t, I(1, 1, 1 // 2))[1, 1] = 1
end
return t
end
const n = c_num

@doc """
Expand Down Expand Up @@ -364,7 +389,7 @@ function u_plus_u_min(T, ::Type{Trivial}, ::Type{U1Irrep}; slave_fermion::Bool=f
return t
end
function u_plus_u_min(T, ::Type{Trivial}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
return error("Not implemented")
throw(ArgumentError("`u_plus_u_min` is not symmetric under `SU2Irrep` spin symmetry"))
end
function u_plus_u_min(T, ::Type{U1Irrep}, ::Type{Trivial}; slave_fermion::Bool=false)
t = two_site_operator(T, U1Irrep, Trivial; slave_fermion)
Expand All @@ -381,7 +406,7 @@ function u_plus_u_min(T, ::Type{U1Irrep}, ::Type{U1Irrep}; slave_fermion::Bool=f
return t
end
function u_plus_u_min(T, ::Type{U1Irrep}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
return error("Not implemented")
throw(ArgumentError("`u_plus_u_min` is not symmetric under `SU2Irrep` spin symmetry"))
end
const u⁺u⁻ = u_plus_u_min

Expand Down Expand Up @@ -409,7 +434,7 @@ function d_plus_d_min(T, ::Type{Trivial}, ::Type{U1Irrep}; slave_fermion::Bool=f
return t
end
function d_plus_d_min(T, ::Type{Trivial}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
return error("Not implemented")
throw(ArgumentError("`d_plus_d_min` is not symmetric under `SU2Irrep` spin symmetry"))
end
function d_plus_d_min(T, ::Type{U1Irrep}, ::Type{Trivial}; slave_fermion::Bool=false)
t = two_site_operator(T, U1Irrep, Trivial; slave_fermion)
Expand All @@ -426,7 +451,7 @@ function d_plus_d_min(T, ::Type{U1Irrep}, ::Type{U1Irrep}; slave_fermion::Bool=f
return t
end
function d_plus_d_min(T, ::Type{U1Irrep}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
return error("Not implemented")
throw(ArgumentError("`d_plus_d_min` is not symmetric under `SU2Irrep` spin symmetry"))
end
const d⁺d⁻ = d_plus_d_min

Expand Down Expand Up @@ -490,6 +515,12 @@ end
function u_min_d_min(T, ::Type{U1Irrep}, ::Type{<:Sector}; slave_fermion::Bool=false)
throw(ArgumentError("`u_min_d_min` is not symmetric under `U1Irrep` particle symmetry"))
end
function u_min_d_min(T, ::Type{<:Sector}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
throw(ArgumentError("`u_min_d_min` is not symmetric under `SU2Irrep` spin symmetry"))
end
function u_min_d_min(T, ::Type{U1Irrep}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
throw(ArgumentError("`u_min_d_min` is not symmetric under `U1Irrep` particle symmetry or under `SU2Irrep` spin symmetry"))
end
const u⁻d⁻ = u_min_d_min

@doc """
Expand Down Expand Up @@ -518,6 +549,12 @@ end
function d_min_u_min(T, ::Type{U1Irrep}, ::Type{<:Sector}; slave_fermion::Bool=false)
throw(ArgumentError("`d_min_u_min` is not symmetric under `U1Irrep` particle symmetry"))
end
function d_min_u_min(T, ::Type{<:Sector}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
throw(ArgumentError("`d_min_u_min` is not symmetric under `SU2Irrep` spin symmetry"))
end
function d_min_u_min(T, ::Type{U1Irrep}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
throw(ArgumentError("`d_min_u_min` is not symmetric under `U1Irrep` particle symmetry or under `SU2Irrep` particle symmetry"))
end
const d⁻u⁻ = d_min_u_min

@doc """
Expand All @@ -534,6 +571,35 @@ function c_plus_c_min(T, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{
return u_plus_u_min(T, particle_symmetry, spin_symmetry; slave_fermion) +
d_plus_d_min(T, particle_symmetry, spin_symmetry; slave_fermion)
end
function c_plus_c_min(T, ::Type{Trivial}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
t = two_site_operator(T, Trivial, SU2Irrep; slave_fermion)
I = sectortype(t)
if slave_fermion
f1 = only(fusiontrees((I(1, 0), I(0, 1 // 2)), I(1, 1 // 2)))
f2 = only(fusiontrees((I(0, 1 // 2), I(1, 0)), I(1, 1 // 2)))
t[f1, f2][1, 1, 1, 1] = 1
else
f1 = only(fusiontrees((I(0, 0), I(1, 1 // 2)), I(1, 1 // 2)))
f2 = only(fusiontrees((I(1, 1 // 2), I(0, 0)), I(1, 1 // 2)))
t[f1, f2][1, 1, 1, 1] = 1
end
return t
end
function c_plus_c_min(T, ::Type{U1Irrep}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
t = two_site_operator(T, U1Irrep, SU2Irrep; slave_fermion)
I = sectortype(t)
if slave_fermion
f1 = only(fusiontrees((I(1, 0, 0), I(0, 1, 1 // 2)), I(1, 1, 1 // 2)))
f2 = only(fusiontrees((I(0, 1, 1 // 2), I(1, 0, 0)), I(1, 1, 1 // 2)))
t[f1, f2][1, 1, 1, 1] = 1
else
f1 = only(fusiontrees((I(0, 0, 0), I(1, 1, 1 // 2)), I(1, 1, 1 // 2)))
f2 = only(fusiontrees((I(1, 1, 1 // 2), I(0, 0, 0)), I(1, 1, 1 // 2)))
t[f1, f2][1, 1, 1, 1] = 1
end
return t
end

const c⁺c⁻ = c_plus_c_min

@doc """
Expand Down Expand Up @@ -635,5 +701,27 @@ function S_exchange(T, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:
S_minplus(T, particle_symmetry, spin_symmetry; slave_fermion)) +
Sz ⊗ Sz
end
function S_exchange(T, ::Type{Trivial}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
t = two_site_operator(T, Trivial, SU2Irrep; slave_fermion)

for (s, f) in fusiontrees(t)
l3 = f.uncoupled[1][2].j
l4 = f.uncoupled[2][2].j
k = f.coupled[2].j
t[s, f] .= (k * (k + 1) - l3 * (l3 + 1) - l4 * (l4 + 1)) / 2
end
return t
end
function S_exchange(T, ::Type{U1Irrep}, ::Type{SU2Irrep}; slave_fermion::Bool=false)
t = two_site_operator(T, U1Irrep, SU2Irrep; slave_fermion)

for (s, f) in fusiontrees(t)
l3 = f.uncoupled[1][3].j
l4 = f.uncoupled[2][3].j
k = f.coupled[3].j
t[s, f] .= (k * (k + 1) - l3 * (l3 + 1) - l4 * (l4 + 1)) / 2
end
return t
end

end
38 changes: 23 additions & 15 deletions test/tjoperators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,30 @@ using .TensorKitTensorsTestSetup
using TensorKitTensors.TJOperators
using StableRNGs

implemented_symmetries = [(Trivial, Trivial), (Trivial, U1Irrep),
(U1Irrep, Trivial), (U1Irrep, U1Irrep)]
implemented_symmetries = [(Trivial, Trivial), (Trivial, U1Irrep), (Trivial, SU2Irrep),
(U1Irrep, Trivial), (U1Irrep, U1Irrep), (U1Irrep, SU2Irrep)]

@testset "Compare symmetric with trivial tensors" begin
for particle_symmetry in [Trivial, U1Irrep],
spin_symmetry in [Trivial, U1Irrep, SU2Irrep]

if (particle_symmetry, spin_symmetry) in implemented_symmetries
space = tj_space(particle_symmetry, spin_symmetry)
for slave_fermion in (false, true)
if (particle_symmetry, spin_symmetry) in implemented_symmetries
space = tj_space(particle_symmetry, spin_symmetry; slave_fermion)

O = c_plus_c_min(ComplexF64, particle_symmetry, spin_symmetry)
O_triv = c_plus_c_min(ComplexF64, Trivial, Trivial)
test_operator(O, O_triv)
O = c_plus_c_min(ComplexF64, particle_symmetry, spin_symmetry;
slave_fermion)
O_triv = c_plus_c_min(ComplexF64, Trivial, Trivial; slave_fermion)
test_operator(O, O_triv)

O = c_num(ComplexF64, particle_symmetry, spin_symmetry)
O_triv = c_num(ComplexF64, Trivial, Trivial)
test_operator(O, O_triv)
O = c_num(ComplexF64, particle_symmetry, spin_symmetry; slave_fermion)
O_triv = c_num(ComplexF64, Trivial, Trivial; slave_fermion)
test_operator(O, O_triv)

else
@test_broken c_plus_c_min(ComplexF64, particle_symmetry, spin_symmetry)
@test_broken c_num(ComplexF64, particle_symmetry, spin_symmetry)
else
@test_broken c_plus_c_min(ComplexF64, particle_symmetry, spin_symmetry)
@test_broken c_num(ComplexF64, particle_symmetry, spin_symmetry)
end
end
end
end
Expand Down Expand Up @@ -74,17 +77,22 @@ end
c_num_hole(particle_symmetry, spin_symmetry; slave_fermion) +
c_num(particle_symmetry, spin_symmetry; slave_fermion)
else
@test_broken c_num(particle_symmetry, spin_symmetry; slave_fermion)
@test_broken u_num(particle_symmetry, spin_symmetry; slave_fermion)
@test_broken d_num(particle_symmetry, spin_symmetry; slave_fermion)
end

# test spin operator
if particle_symmetry == Trivial
if particle_symmetry == Trivial && spin_symmetry !== SU2Irrep
@test c_singlet(particle_symmetry, spin_symmetry; slave_fermion) ≈
(u_min_d_min(particle_symmetry, spin_symmetry; slave_fermion) -
d_min_u_min(particle_symmetry, spin_symmetry; slave_fermion)) /
sqrt(2)
else
@test_broken c_singlet(particle_symmetry, spin_symmetry; slave_fermion)
@test_broken u_min_d_min(particle_symmetry, spin_symmetry;
slave_fermion)
@test_broken d_min_u_min(particle_symmetry, spin_symmetry;
slave_fermion)
end

if spin_symmetry == Trivial
Expand Down