Skip to content

Commit af3b441

Browse files
Reduce unnecessary manual definitions in TJOperators (#18)
* Use `S_plus, u_num, d_num` to express all one-body spin operators * Fix typo in tjoperators test * Fix docstring of `x_min_x_plus` * Improve test on `singlet`
1 parent 4c7a19e commit af3b441

File tree

2 files changed

+69
-113
lines changed

2 files changed

+69
-113
lines changed

src/tjoperators.jl

Lines changed: 59 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -239,62 +239,83 @@ end
239239
const= h_num
240240

241241
@doc """
242-
S_x(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
243-
(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
242+
S_plus(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
243+
S⁺(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
244244
245-
Return the one-body spin-1/2 x-operator on the electrons.
246-
""" S_x
247-
function S_x(P::Type{<:Sector}=Trivial, S::Type{<:Sector}=Trivial;
248-
slave_fermion::Bool=false)
249-
return S_x(ComplexF64, P, S; slave_fermion)
245+
Return the spin-plus operator (only defined for `Trivial` spin symmetry).
246+
""" S_plus
247+
function S_plus(P::Type{<:Sector}, S::Type{<:Sector}; slave_fermion::Bool=false)
248+
return S_plus(ComplexF64, P, S; slave_fermion)
250249
end
251-
function S_x(elt::Type{<:Number}, ::Type{Trivial}, ::Type{Trivial};
252-
slave_fermion::Bool=false)
250+
function S_plus(elt::Type{<:Number}, ::Type{Trivial}, ::Type{Trivial};
251+
slave_fermion::Bool=false)
253252
t = single_site_operator(elt, Trivial, Trivial; slave_fermion)
254253
I = sectortype(t)
255254
b = slave_fermion ? 0 : 1
256-
t[(I(b), dual(I(b)))][1, 2] = 0.5
257-
t[(I(b), dual(I(b)))][2, 1] = 0.5
255+
t[(I(b), dual(I(b)))][1, 2] = 1.0
258256
return t
259257
end
260-
function S_x(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{Trivial};
261-
slave_fermion::Bool=false)
258+
function S_plus(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{Trivial};
259+
slave_fermion::Bool=false)
262260
t = single_site_operator(elt, U1Irrep, Trivial; slave_fermion)
263261
I = sectortype(t)
264262
b = slave_fermion ? 0 : 1
265-
t[(I(b, 1), dual(I(b, 1)))][1, 2] = 0.5
266-
t[(I(b, 1), dual(I(b, 1)))][2, 1] = 0.5
263+
t[(I(b, 1), dual(I(b, 1)))][1, 2] = 1.0
267264
return t
268265
end
266+
const S⁺ = S_plus
267+
268+
@doc """
269+
S_min(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
270+
S⁻(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
271+
272+
Return the spin-minus operator (only defined for `Trivial` spin symmetry).
273+
""" S_min
274+
function S_min(P::Type{<:Sector}, S::Type{<:Sector}; slave_fermion::Bool=false)
275+
return S_min(ComplexF64, P, S; slave_fermion)
276+
end
277+
function S_min(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
278+
spin_symmetry::Type{<:Sector};
279+
slave_fermion::Bool=false)
280+
return copy(adjoint(S_plus(elt, particle_symmetry, spin_symmetry; slave_fermion)))
281+
end
282+
const S⁻ = S_min
283+
284+
@doc """
285+
S_x(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
286+
Sˣ(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
287+
288+
Return the one-body spin-1/2 x-operator on the electrons (only defined for `Trivial` spin symmetry).
289+
""" S_x
290+
function S_x(P::Type{<:Sector}=Trivial, S::Type{<:Sector}=Trivial;
291+
slave_fermion::Bool=false)
292+
return S_x(ComplexF64, P, S; slave_fermion)
293+
end
294+
function S_x(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
295+
spin_symmetry::Type{<:Sector};
296+
slave_fermion::Bool=false)
297+
return (S_plus(elt, particle_symmetry, spin_symmetry; slave_fermion)
298+
+
299+
S_min(elt, particle_symmetry, spin_symmetry; slave_fermion)) / 2
300+
end
269301
const= S_x
270302

271303
@doc """
272304
S_y(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
273305
Sʸ(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
274306
275-
Return the one-body spin-1/2 x-operator on the electrons (only defined for `Trivial` symmetry).
307+
Return the one-body spin-1/2 y-operator on the electrons (only defined for `Trivial` spin symmetry).
276308
""" S_y
277309
function S_y(P::Type{<:Sector}=Trivial, S::Type{<:Sector}=Trivial;
278310
slave_fermion::Bool=false)
279311
return S_y(ComplexF64, P, S; slave_fermion)
280312
end
281-
function S_y(elt::Type{<:Number}, ::Type{Trivial}, ::Type{Trivial};
282-
slave_fermion::Bool=false)
283-
t = single_site_operator(elt, Trivial, Trivial; slave_fermion)
284-
I = sectortype(t)
285-
b = slave_fermion ? 0 : 1
286-
t[(I(b), dual(I(b)))][1, 2] = -0.5im
287-
t[(I(b), dual(I(b)))][2, 1] = 0.5im
288-
return t
289-
end
290-
function S_y(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{Trivial};
313+
function S_y(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
314+
spin_symmetry::Type{<:Sector};
291315
slave_fermion::Bool=false)
292-
t = single_site_operator(elt, U1Irrep, Trivial; slave_fermion)
293-
I = sectortype(t)
294-
b = slave_fermion ? 0 : 1
295-
t[(I(b, 1), dual(I(b, 1)))][1, 2] = -0.5im
296-
t[(I(b, 1), dual(I(b, 1)))][2, 1] = 0.5im
297-
return t
316+
return (S_plus(elt, particle_symmetry, spin_symmetry; slave_fermion)
317+
-
318+
S_min(elt, particle_symmetry, spin_symmetry; slave_fermion)) / (2im)
298319
end
299320
const= S_y
300321

@@ -308,78 +329,14 @@ function S_z(P::Type{<:Sector}=Trivial, S::Type{<:Sector}=Trivial;
308329
slave_fermion::Bool=false)
309330
return S_z(ComplexF64, P, S; slave_fermion)
310331
end
311-
function S_z(elt::Type{<:Number}, ::Type{Trivial}, ::Type{Trivial};
312-
slave_fermion::Bool=false)
313-
t = single_site_operator(elt, Trivial, Trivial; slave_fermion)
314-
I = sectortype(t)
315-
b = slave_fermion ? 0 : 1
316-
t[(I(b), dual(I(b)))][1, 1] = 0.5
317-
t[(I(b), dual(I(b)))][2, 2] = -0.5
318-
return t
319-
end
320-
function S_z(elt::Type{<:Number}, ::Type{Trivial}, ::Type{U1Irrep};
321-
slave_fermion::Bool=false)
322-
t = single_site_operator(elt, Trivial, U1Irrep; slave_fermion)
323-
I = sectortype(t)
324-
b = slave_fermion ? 0 : 1
325-
t[(I(b, 1 // 2), dual(I(b, 1 // 2)))] .= 0.5
326-
t[(I(b, -1 // 2), dual(I(b, -1 // 2)))] .= -0.5
327-
return t
328-
end
329-
function S_z(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{Trivial};
332+
function S_z(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
333+
spin_symmetry::Type{<:Sector};
330334
slave_fermion::Bool=false)
331-
t = single_site_operator(elt, U1Irrep, Trivial; slave_fermion)
332-
I = sectortype(t)
333-
b = slave_fermion ? 0 : 1
334-
t[(I(b, 1), dual(I(b, 1)))][1, 1] = 0.5
335-
t[(I(b, 1), dual(I(b, 1)))][2, 2] = -0.5
336-
return t
337-
end
338-
function S_z(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{U1Irrep};
339-
slave_fermion::Bool=false)
340-
t = single_site_operator(elt, U1Irrep, U1Irrep; slave_fermion)
341-
I = sectortype(t)
342-
b = slave_fermion ? 0 : 1
343-
t[(I(b, 1, 1 // 2), dual(I(b, 1, 1 // 2)))] .= 0.5
344-
t[(I(b, 1, -1 // 2), dual(I(b, 1, -1 // 2)))] .= -0.5
345-
return t
335+
return (u_num(elt, particle_symmetry, spin_symmetry; slave_fermion) -
336+
d_num(elt, particle_symmetry, spin_symmetry; slave_fermion)) / 2
346337
end
347338
const Sᶻ = S_z
348339

349-
@doc """
350-
S_plus(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
351-
S⁺(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
352-
353-
Return the spin-plus operator.
354-
""" S_plus
355-
function S_plus(P::Type{<:Sector}, S::Type{<:Sector}; slave_fermion::Bool=false)
356-
return S_plus(ComplexF64, P, S; slave_fermion)
357-
end
358-
function S_plus(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
359-
spin_symmetry::Type{<:Sector};
360-
slave_fermion::Bool=false)
361-
return S_x(elt::Type{<:Number}, particle_symmetry, spin_symmetry; slave_fermion) +
362-
1im * S_y(elt, particle_symmetry, spin_symmetry; slave_fermion)
363-
end
364-
const S⁺ = S_plus
365-
366-
@doc """
367-
S_min(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
368-
S⁻(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool=false)
369-
370-
Return the spin-minus operator.
371-
""" S_min
372-
function S_min(P::Type{<:Sector}, S::Type{<:Sector}; slave_fermion::Bool=false)
373-
return S_min(ComplexF64, P, S; slave_fermion)
374-
end
375-
function S_min(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
376-
spin_symmetry::Type{<:Sector};
377-
slave_fermion::Bool=false)
378-
return S_x(elt, particle_symmetry, spin_symmetry; slave_fermion) -
379-
1im * S_y(elt, particle_symmetry, spin_symmetry; slave_fermion)
380-
end
381-
const S⁻ = S_min
382-
383340
# Two site operators
384341
# ------------------
385342
function two_site_operator(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
@@ -503,9 +460,7 @@ const d⁺d⁻ = d_plus_d_min
503460
u_min_u_plus(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool = false)
504461
u⁻u⁺(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool = false)
505462
506-
Return the Hermitian conjugate of `u_plus_u_min`, i.e.
507-
``(e†_{1,↑}, e_{2,↑})† = -e_{1,↑}, e†_{2,↑}`` (note the extra minus sign).
508-
It annihilates a spin-up electron at the first site and creates a spin-up electron at the second.
463+
Return the two-body operator ``e_{1,↑}, e†_{2,↑}`` that annihilates a spin-up electron at the first site and creates a spin-up electron at the second.
509464
The only nonzero matrix element corresponds to `|0↑⟩ <-- |↑0⟩`.
510465
""" u_min_u_plus
511466
function u_min_u_plus(P::Type{<:Sector}, S::Type{<:Sector}; slave_fermion::Bool=false)
@@ -522,9 +477,7 @@ const u⁻u⁺ = u_min_u_plus
522477
d_min_d_plus(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool = false)
523478
d⁻d⁺(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector}; slave_fermion::Bool = false)
524479
525-
Return the Hermitian conjugate of `d_plus_d_min`, i.e.
526-
``(e†_{1,↓}, e_{2,↓})† = -e_{1,↓}, e†_{2,↓}`` (note the extra minus sign).
527-
It annihilates a spin-down electron at the first site and creates a spin-down electron at the second.
480+
Return the two-body operator ``e_{1,↓}, e†_{2,↓}`` that annihilates a spin-down electron at the first site and creates a spin-down electron at the second.
528481
The only nonzero matrix element corresponds to `|0↓⟩ <-- |↓0⟩`.
529482
""" d_min_d_plus
530483
function d_min_d_plus(P::Type{<:Sector}, S::Type{<:Sector}; slave_fermion::Bool=false)
@@ -798,7 +751,6 @@ end
798751
function S_exchange(elt::Type{<:Number}, ::Type{Trivial}, ::Type{SU2Irrep};
799752
slave_fermion::Bool=false)
800753
t = two_site_operator(elt, Trivial, SU2Irrep; slave_fermion)
801-
802754
for (s, f) in fusiontrees(t)
803755
l3 = f.uncoupled[1][2].j
804756
l4 = f.uncoupled[2][2].j
@@ -810,7 +762,6 @@ end
810762
function S_exchange(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{SU2Irrep};
811763
slave_fermion::Bool=false)
812764
t = two_site_operator(elt, U1Irrep, SU2Irrep; slave_fermion)
813-
814765
for (s, f) in fusiontrees(t)
815766
l3 = f.uncoupled[1][3].j
816767
l4 = f.uncoupled[2][3].j

test/tjoperators.jl

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,16 @@ end
8383
slave_fermion)
8484
end
8585

86-
# test spin operator
86+
# test singlet operator
8787
if particle_symmetry == Trivial && spin_symmetry !== SU2Irrep
88-
@test singlet_min(particle_symmetry, spin_symmetry; slave_fermion)
89-
(u_min_d_min(particle_symmetry, spin_symmetry; slave_fermion) -
90-
d_min_u_min(particle_symmetry, spin_symmetry; slave_fermion)) /
91-
sqrt(2)
88+
sing = singlet_min(particle_symmetry, spin_symmetry;
89+
slave_fermion)
90+
ud = u_min_d_min(particle_symmetry, spin_symmetry;
91+
slave_fermion)
92+
du = d_min_u_min(particle_symmetry, spin_symmetry; slave_fermion)
93+
@test permute(ud, ((2, 1), (4, 3))) -du
94+
@test permute(sing, ((2, 1), (4, 3))) sing
95+
@test sing (ud - du) / sqrt(2)
9296
else
9397
@test_throws ArgumentError singlet_min(particle_symmetry, spin_symmetry;
9498
slave_fermion)
@@ -103,6 +107,7 @@ end
103107
e_plus_e_min(particle_symmetry, spin_symmetry; slave_fermion) -
104108
e_min_e_plus(particle_symmetry, spin_symmetry; slave_fermion)
105109

110+
# test spin operator
106111
if spin_symmetry == Trivial
107112
ε = zeros(ComplexF64, 3, 3, 3)
108113
for i in 1:3

0 commit comments

Comments
 (0)