Skip to content

Commit 8a2a7ff

Browse files
Add spin and singlet operators to HubbardOperators (#19)
* Remove redundant ArgumentErrors * Undo "Remove redundant ArgumentErrors" * Add spin and singlet operators to HubbardOperators * Change mu sign in hubbard_hamiltonian * Add comma to seperate two sites in a state * Throw ArgumentError from `S_plus` for non-trivial spin symmetry * Add `@test_throws` for S_plus etc with non-trivial spin symmetry (t-J and Hubbard) * Fix HubbardOperators exports * Change convention of `x_min_x_plus` in HubbardOperators * Improve test on tJ/Hubbard hopping terms and S_exchange * Refactor `e_plus_e_min` for t-J model * Undo distracting indent changes * Change Hubbard doubly-occupied state notation * Fix typo Co-authored-by: Lukas Devos <[email protected]> * Fix one more typo --------- Co-authored-by: Lukas Devos <[email protected]>
1 parent af3b441 commit 8a2a7ff

File tree

6 files changed

+447
-83
lines changed

6 files changed

+447
-83
lines changed

src/hubbardoperators.jl

Lines changed: 303 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,27 @@ module HubbardOperators
33
using TensorKit
44

55
export hubbard_space
6-
export e_plus_e_min, u_plus_u_min, d_plus_d_min
7-
export e_min_e_plus, u_min_u_plus, d_min_d_plus
86
export e_num, u_num, d_num, ud_num
9-
export e_hopping
7+
export S_x, S_y, S_z, S_plus, S_min
8+
export u_plus_u_min, d_plus_d_min
9+
export u_min_u_plus, d_min_d_plus
10+
export u_min_d_min, d_min_u_min
11+
export e_plus_e_min, e_min_e_plus, singlet_min, e_hopping
12+
export S_plus_S_min, S_min_S_plus, S_exchange
1013

11-
export e⁺e⁻, u⁺u⁻, d⁺d⁻, e⁻e⁺, u⁻u⁺, d⁻d⁺
1214
export n, nꜛ, nꜜ, nꜛꜜ
13-
export e_hop
15+
export Sˣ, Sʸ, Sᶻ, S⁺, S⁻
16+
export u⁺u⁻, d⁺d⁻, u⁻u⁺, d⁻d⁺, u⁻d⁻, d⁻u⁻
17+
export e⁺e⁻, e⁻e⁺, singlet⁻, e_hop
18+
export S⁻S⁺, S⁺S⁻
1419

1520
"""
1621
hubbard_space(particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
1722
18-
Return the local hilbert space for a Hubbard-type model with the given particle and spin symmetries.
23+
Return the local hilbert space for a Hubbard-type model with the given particle and spin symmetries. The four basis states are
24+
```
25+
|0⟩ (vacuum), |↑⟩ = (c↑)†|0⟩, |↓⟩ = (c↓)†|0⟩, |↑↓⟩ = (c↑)†(c↓)†|0⟩.
26+
```
1927
The possible symmetries are `Trivial`, `U1Irrep`, and `SU2Irrep`, for both particle number and spin.
2028
"""
2129
function hubbard_space((::Type{Trivial})=Trivial, (::Type{Trivial})=Trivial)
@@ -214,6 +222,100 @@ function ud_num(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{SU2Irrep})
214222
end
215223
const nꜛꜜ = ud_num
216224

225+
@doc """
226+
S_plus(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
227+
S⁺(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
228+
229+
Return the spin-plus operator `S⁺ = e†_↑ e_↓` (only defined for `Trivial` spin symmetry).
230+
""" S_plus
231+
function S_plus(P::Type{<:Sector}, S::Type{<:Sector})
232+
return S_plus(ComplexF64, P, S)
233+
end
234+
function S_plus(elt::Type{<:Number}, ::Type{Trivial}, ::Type{Trivial})
235+
t = single_site_operator(elt, Trivial, Trivial)
236+
I = sectortype(t)
237+
t[(I(1), dual(I(1)))][1, 2] = 1.0
238+
return t
239+
end
240+
function S_plus(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{Trivial})
241+
t = single_site_operator(elt, U1Irrep, Trivial)
242+
I = sectortype(t)
243+
t[(I(1, 1), dual(I(1, 1)))][1, 2] = 1.0
244+
return t
245+
end
246+
function S_plus(elt::Type{<:Number}, ::Type{<:Sector}, ::Type{U1Irrep})
247+
throw(ArgumentError("`S_plus`, `S_min` are not symmetric under `U1Irrep` spin symmetry"))
248+
end
249+
function S_plus(elt::Type{<:Number}, ::Type{<:Sector}, ::Type{SU2Irrep})
250+
throw(ArgumentError("`S_plus`, `S_min` are not symmetric under `SU2Irrep` spin symmetry"))
251+
end
252+
const S⁺ = S_plus
253+
254+
@doc """
255+
S_min(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
256+
S⁻(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
257+
258+
Return the spin-minus operator (only defined for `Trivial` spin symmetry).
259+
""" S_min
260+
function S_min(P::Type{<:Sector}, S::Type{<:Sector})
261+
return S_min(ComplexF64, P, S)
262+
end
263+
function S_min(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
264+
spin_symmetry::Type{<:Sector})
265+
return copy(adjoint(S_plus(elt, particle_symmetry, spin_symmetry)))
266+
end
267+
const S⁻ = S_min
268+
269+
@doc """
270+
S_x(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
271+
Sˣ(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
272+
273+
Return the one-body spin-1/2 x-operator on the electrons (only defined for `Trivial` symmetry). .
274+
""" S_x
275+
function S_x(P::Type{<:Sector}=Trivial, S::Type{<:Sector}=Trivial)
276+
return S_x(ComplexF64, P, S)
277+
end
278+
function S_x(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
279+
spin_symmetry::Type{<:Sector})
280+
return (S_plus(elt, particle_symmetry, spin_symmetry)
281+
+
282+
S_min(elt, particle_symmetry, spin_symmetry)) / 2
283+
end
284+
const= S_x
285+
286+
@doc """
287+
S_y(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
288+
Sʸ(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
289+
290+
Return the one-body spin-1/2 y-operator on the electrons (only defined for `Trivial` symmetry).
291+
""" S_y
292+
function S_y(P::Type{<:Sector}=Trivial, S::Type{<:Sector}=Trivial)
293+
return S_y(ComplexF64, P, S)
294+
end
295+
function S_y(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
296+
spin_symmetry::Type{<:Sector})
297+
return (S_plus(elt, particle_symmetry, spin_symmetry)
298+
-
299+
S_min(elt, particle_symmetry, spin_symmetry)) / (2im)
300+
end
301+
const= S_y
302+
303+
@doc """
304+
S_z(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
305+
Sᶻ(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
306+
307+
Return the one-body spin-1/2 z-operator on the electrons.
308+
""" S_z
309+
function S_z(P::Type{<:Sector}=Trivial, S::Type{<:Sector}=Trivial)
310+
return S_z(ComplexF64, P, S)
311+
end
312+
function S_z(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
313+
spin_symmetry::Type{<:Sector})
314+
return (u_num(elt, particle_symmetry, spin_symmetry) -
315+
d_num(elt, particle_symmetry, spin_symmetry)) / 2
316+
end
317+
const Sᶻ = S_z
318+
217319
# Two site operators
218320
# ------------------
219321
function two_site_operator(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
@@ -346,29 +448,25 @@ const d⁺d⁻ = d_plus_d_min
346448
u_min_u_plus([elt::Type{<:Number}], [particle_symmetry::Type{<:Sector}], [spin_symmetry::Type{<:Sector}])
347449
u⁻u⁺([elt::Type{<:Number}], [particle_symmetry::Type{<:Sector}], [spin_symmetry::Type{<:Sector}])
348450
349-
Return the Hermitian conjugate of `u_plus_u_min`, i.e.
350-
``(e†_{1,↑}, e_{2,↑})† = -e_{1,↑}, e†_{2,↑}`` (note the extra minus sign).
351-
It annihilates a spin-up particle at the first site and creates a spin-up particle at the second.
451+
Return the two-body operator ``e_{1,↑}, e†_{2,↑}`` that annihilates a spin-up particle at the first site and creates a spin-up particle at the second.
352452
""" u_min_u_plus
353453
u_min_u_plus(P::Type{<:Sector}, S::Type{<:Sector}) = u_min_u_plus(ComplexF64, P, S)
354454
function u_min_u_plus(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
355455
spin_symmetry::Type{<:Sector})
356-
return copy(adjoint(u_plus_u_min(elt, particle_symmetry, spin_symmetry)))
456+
return -copy(adjoint(u_plus_u_min(elt, particle_symmetry, spin_symmetry)))
357457
end
358458
const u⁻u⁺ = u_min_u_plus
359459

360460
@doc """
361461
d_min_d_plus([elt::Type{<:Number}], [particle_symmetry::Type{<:Sector}], [spin_symmetry::Type{<:Sector}])
362462
d⁻d⁺([elt::Type{<:Number}], [particle_symmetry::Type{<:Sector}], [spin_symmetry::Type{<:Sector}])
363463
364-
Return the Hermitian conjugate of `d_plus_d_min`, i.e.
365-
``(e†_{1,↓}, e_{2,↓})† = -e_{1,↓}, e†_{2,↓}`` (note the extra minus sign).
366-
It annihilates a spin-down particle at the first site and creates a spin-down particle at the second.
464+
Return the two-body operator ``e_{1,↓}, e†_{2,↓}`` that annihilates a spin-down particle at the first site and creates a spin-down particle at the second.
367465
""" d_min_d_plus
368466
d_min_d_plus(P::Type{<:Sector}, S::Type{<:Sector}) = d_min_d_plus(ComplexF64, P, S)
369467
function d_min_d_plus(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
370468
spin_symmetry::Type{<:Sector})
371-
return copy(adjoint(d_plus_d_min(elt, particle_symmetry, spin_symmetry)))
469+
return -copy(adjoint(d_plus_d_min(elt, particle_symmetry, spin_symmetry)))
372470
end
373471
const d⁻d⁺ = d_min_d_plus
374472

@@ -449,4 +547,195 @@ function e_hopping(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
449547
end
450548
const e_hop = e_hopping
451549

550+
@doc """
551+
u_min_d_min(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
552+
u⁻d⁻(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
553+
554+
Return the two-body operator ``e_{1,↑} e_{2,↓}`` that annihilates a spin-up particle at the first site and a spin-down particle at the second site.
555+
The nonzero matrix elements are
556+
```
557+
-|0,0⟩ ↤ |↑,↓⟩, +|0,↑⟩ ↤ |↑,↑↓⟩,
558+
+|↓,0⟩ ↤ |↑↓,↓⟩, -|↓,↑⟩ ↤ |↑↓,↑↓⟩
559+
```
560+
""" u_min_d_min
561+
function u_min_d_min(P::Type{<:Sector}, S::Type{<:Sector})
562+
return u_min_d_min(ComplexF64, P, S)
563+
end
564+
function u_min_d_min(elt::Type{<:Number}, ::Type{Trivial}, ::Type{Trivial})
565+
t = two_site_operator(elt, Trivial, Trivial)
566+
I = sectortype(t)
567+
t[(I(0), I(0), dual(I(1)), dual(I(1)))][1, 1, 1, 2] = -1
568+
t[(I(0), I(1), dual(I(1)), dual(I(0)))][1, 1, 1, 2] = 1
569+
t[(I(1), I(0), dual(I(0)), dual(I(1)))][2, 1, 2, 2] = 1
570+
t[(I(1), I(1), dual(I(0)), dual(I(0)))][2, 1, 2, 2] = -1
571+
return t
572+
end
573+
function u_min_d_min(elt::Type{<:Number}, ::Type{Trivial}, ::Type{U1Irrep})
574+
t = two_site_operator(elt, Trivial, U1Irrep)
575+
I = sectortype(t)
576+
t[(I(0, 0), I(0, 0), dual(I(1, 1 // 2)), dual(I(1, -1 // 2)))][1, 1, 1, 1] = -1
577+
t[(I(0, 0), I(1, 1 // 2), dual(I(1, 1 // 2)), dual(I(0, 0)))][1, 1, 1, 2] = 1
578+
t[(I(1, -1 // 2), I(0, 0), dual(I(0, 0)), dual(I(1, -1 // 2)))][1, 1, 2, 1] = 1
579+
t[(I(1, -1 // 2), I(1, 1 // 2), dual(I(0, 0)), dual(I(0, 0)))][1, 1, 2, 2] = -1
580+
return t
581+
end
582+
function u_min_d_min(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{<:Sector})
583+
throw(ArgumentError("`u_min_d_min` is not symmetric under `U1Irrep` particle symmetry"))
584+
end
585+
function u_min_d_min(elt::Type{<:Number}, ::Type{<:Sector}, ::Type{SU2Irrep})
586+
throw(ArgumentError("`u_min_d_min` is not symmetric under `SU2Irrep` spin symmetry"))
587+
end
588+
function u_min_d_min(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{SU2Irrep})
589+
throw(ArgumentError("`u_min_d_min` is not symmetric under `U1Irrep` particle symmetry or under `SU2Irrep` spin symmetry"))
590+
end
591+
const u⁻d⁻ = u_min_d_min
592+
593+
@doc """
594+
d_min_u_min(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
595+
d⁻u⁻(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
596+
597+
Return the two-body operator ``e_{1,↓} e_{2,↑}`` that annihilates a spin-down particle at the first site and a spin-up particle at the second site.
598+
The nonzero matrix elements are
599+
```
600+
-|0,0⟩ ↤ |↓,↑⟩, -|0,↓⟩ ↤ |↓,↑↓⟩
601+
-|↑,0⟩ ↤ |↑↓,↑⟩, -|↑,↓⟩ ↤ |↑↓,↑↓⟩
602+
```
603+
""" d_min_u_min
604+
function d_min_u_min(P::Type{<:Sector}, S::Type{<:Sector})
605+
return d_min_u_min(ComplexF64, P, S)
606+
end
607+
function d_min_u_min(elt::Type{<:Number}, ::Type{Trivial}, ::Type{Trivial})
608+
t = two_site_operator(elt, Trivial, Trivial)
609+
I = sectortype(t)
610+
t[(I(0), I(0), dual(I(1)), dual(I(1)))][1, 1, 2, 1] = -1
611+
t[(I(0), I(1), dual(I(1)), dual(I(0)))][1, 2, 2, 2] = -1
612+
t[(I(1), I(0), dual(I(0)), dual(I(1)))][1, 1, 2, 1] = -1
613+
t[(I(1), I(1), dual(I(0)), dual(I(0)))][1, 2, 2, 2] = -1
614+
return t
615+
end
616+
function d_min_u_min(elt::Type{<:Number}, ::Type{Trivial}, ::Type{U1Irrep})
617+
t = two_site_operator(elt, Trivial, U1Irrep)
618+
I = sectortype(t)
619+
t[(I(0, 0), I(0, 0), dual(I(1, -1 // 2)), dual(I(1, 1 // 2)))][1, 1, 1, 1] = -1
620+
t[(I(0, 0), I(1, -1 // 2), dual(I(1, -1 // 2)), dual(I(0, 0)))][1, 1, 1, 2] = -1
621+
t[(I(1, 1 // 2), I(0, 0), dual(I(0, 0)), dual(I(1, 1 // 2)))][1, 1, 2, 1] = -1
622+
t[(I(1, 1 // 2), I(1, -1 // 2), dual(I(0, 0)), dual(I(0, 0)))][1, 1, 2, 2] = -1
623+
return t
624+
end
625+
function d_min_u_min(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{<:Sector})
626+
throw(ArgumentError("`d_min_u_min` is not symmetric under `U1Irrep` particle symmetry"))
627+
end
628+
function d_min_u_min(elt::Type{<:Number}, ::Type{<:Sector}, ::Type{SU2Irrep})
629+
throw(ArgumentError("`d_min_u_min` is not symmetric under `SU2Irrep` spin symmetry"))
630+
end
631+
function d_min_u_min(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{SU2Irrep})
632+
throw(ArgumentError("`d_min_u_min` is not symmetric under `U1Irrep` particle symmetry or under `SU2Irrep` particle symmetry"))
633+
end
634+
const d⁻u⁻ = d_min_u_min
635+
636+
@doc """
637+
singlet_min(elt, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
638+
singlet⁻(elt, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
639+
640+
Return the two-body singlet operator ``(e_{1,↓} e_{2,↑} - e_{1,↓} e_{2,↑}) / sqrt(2)``.
641+
""" singlet_min
642+
function singlet_min(P::Type{<:Sector}, S::Type{<:Sector})
643+
return singlet_min(ComplexF64, P, S)
644+
end
645+
function singlet_min(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
646+
spin_symmetry::Type{<:Sector})
647+
return (u_min_d_min(elt, particle_symmetry, spin_symmetry) -
648+
d_min_u_min(elt, particle_symmetry, spin_symmetry)) / sqrt(2)
649+
end
650+
const singlet⁻ = singlet_min
651+
652+
@doc """
653+
S_plus_S_min(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
654+
S⁺S⁻(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
655+
656+
Return the two-body operator S⁺S⁻.
657+
The only nonzero matrix element corresponds to `|↑,↓⟩ <-- |↓,↑⟩`.
658+
""" S_plus_S_min
659+
function S_plus_S_min(P::Type{<:Sector}, S::Type{<:Sector})
660+
return S_plus_S_min(ComplexF64, P, S)
661+
end
662+
function S_plus_S_min(elt::Type{<:Number}, ::Type{Trivial}, ::Type{Trivial})
663+
t = two_site_operator(elt, Trivial, Trivial)
664+
I = sectortype(t)
665+
t[(I(1), I(1), dual(I(1)), dual(I(1)))][1, 2, 2, 1] = 1
666+
return t
667+
end
668+
function S_plus_S_min(elt::Type{<:Number}, ::Type{Trivial}, ::Type{U1Irrep})
669+
t = two_site_operator(elt, Trivial, U1Irrep)
670+
I = sectortype(t)
671+
t[(I(1, 1 // 2), I(1, -1 // 2), dual(I(1, -1 // 2)), dual(I(1, 1 // 2)))] .= 1
672+
return t
673+
end
674+
function S_plus_S_min(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{Trivial})
675+
t = two_site_operator(elt, U1Irrep, Trivial)
676+
I = sectortype(t)
677+
t[(I(1, 1), I(1, 1), dual(I(1, 1)), dual(I(1, 1)))][1, 2, 2, 1] = 1
678+
return t
679+
end
680+
function S_plus_S_min(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{U1Irrep})
681+
t = two_site_operator(elt, U1Irrep, U1Irrep)
682+
I = sectortype(t)
683+
t[(I(1, 1, 1 // 2), I(1, 1, -1 // 2), dual(I(1, 1, -1 // 2)), dual(I(1, 1, 1 // 2)))] .= 1
684+
return t
685+
end
686+
const S⁺S⁻ = S_plus_S_min
687+
688+
@doc """
689+
S_min_S_plus(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
690+
S⁻S⁺(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
691+
692+
Return the two-body operator S⁻S⁺.
693+
The only nonzero matrix element corresponds to `|↓,↑⟩ <-- |↑,↓⟩`.
694+
""" S_min_S_plus
695+
function S_min_S_plus(P::Type{<:Sector}, S::Type{<:Sector})
696+
return S_min_S_plus(ComplexF64, P, S)
697+
end
698+
function S_min_S_plus(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
699+
spin_symmetry::Type{<:Sector})
700+
return copy(adjoint(S_plus_S_min(elt, particle_symmetry, spin_symmetry)))
701+
end
702+
const S⁻S⁺ = S_min_S_plus
703+
704+
@doc """
705+
S_exchange(elt::Type{<:Number}, particle_symmetry::Type{<:Sector}, spin_symmetry::Type{<:Sector})
706+
707+
Return the spin exchange operator S⋅S.
708+
""" S_exchange
709+
function S_exchange(P::Type{<:Sector}, S::Type{<:Sector})
710+
return S_exchange(ComplexF64, P, S)
711+
end
712+
function S_exchange(elt::Type{<:Number}, particle_symmetry::Type{<:Sector},
713+
spin_symmetry::Type{<:Sector})
714+
Sz = S_z(elt, particle_symmetry, spin_symmetry)
715+
return (S_plus_S_min(elt, particle_symmetry, spin_symmetry)
716+
+
717+
S_min_S_plus(elt, particle_symmetry, spin_symmetry)) / 2 +
718+
Sz Sz
719+
end
720+
function S_exchange(elt::Type{<:Number}, ::Type{Trivial}, ::Type{SU2Irrep})
721+
t = two_site_operator(elt, Trivial, SU2Irrep)
722+
for (s, f) in fusiontrees(t)
723+
l3 = f.uncoupled[1][2].j
724+
l4 = f.uncoupled[2][2].j
725+
k = f.coupled[2].j
726+
t[s, f] .= (k * (k + 1) - l3 * (l3 + 1) - l4 * (l4 + 1)) / 2
727+
end
728+
return t
729+
end
730+
function S_exchange(elt::Type{<:Number}, ::Type{U1Irrep}, ::Type{SU2Irrep})
731+
t = two_site_operator(elt, U1Irrep, SU2Irrep)
732+
for (s, f) in fusiontrees(t)
733+
l3 = f.uncoupled[1][3].j
734+
l4 = f.uncoupled[2][3].j
735+
k = f.coupled[3].j
736+
t[s, f] .= (k * (k + 1) - l3 * (l3 + 1) - l4 * (l4 + 1)) / 2
737+
end
738+
return t
739+
end
740+
452741
end

0 commit comments

Comments
 (0)