Skip to content

Commit

Permalink
Revert fℤ₂ to FermionParity
Browse files Browse the repository at this point in the history
This keeps `FermionParity` as the default representation for fermionic charges. While not (yet) removing `fℤ₂` from the library in order to not break existing code, the idea is that `fℤ₂` has more of an interpretation as category, and the sectors should really be thought of as objects in this category. This is similar to how `ℤ₂` is the group, and the sectors are `ℤ₂Irrep`. However, `fℤ₂` is not a group, and thus labeling the sectors as irrep is not entirely correct.

Possibly, we can think of adding categories and objects at some point, but this is outside of the scope of this pr
  • Loading branch information
lkdvos committed Jan 17, 2024
1 parent 2e7958b commit 91344d7
Showing 1 changed file with 31 additions and 31 deletions.
62 changes: 31 additions & 31 deletions src/sectors/fermions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,74 +10,74 @@ struct FermionParity <: Sector
isodd::Bool
end
const fℤ₂ = FermionParity
fermionparity(f::fℤ₂) = f.isodd
fermionparity(f::FermionParity) = f.isodd

Base.convert(::Type{fℤ₂}, a::fℤ₂) = a
Base.convert(::Type{fℤ₂}, a) = fℤ₂(a)
Base.convert(::Type{FermionParity}, a::FermionParity) = a
Base.convert(::Type{FermionParity}, a) = FermionParity(a)

Base.IteratorSize(::Type{SectorValues{fℤ₂}}) = HasLength()
Base.length(::SectorValues{fℤ₂}) = 2
function Base.iterate(::SectorValues{fℤ₂}, i=0)
return i == 2 ? nothing : (fℤ₂(i), i + 1)
Base.IteratorSize(::Type{SectorValues{FermionParity}}) = HasLength()
Base.length(::SectorValues{FermionParity}) = 2
function Base.iterate(::SectorValues{FermionParity}, i=0)
return i == 2 ? nothing : (FermionParity(i), i + 1)
end
function Base.getindex(::SectorValues{fℤ₂}, i)
return 1 <= i <= 2 ? fℤ₂(i - 1) : throw(BoundsError(values(fℤ₂), i))
function Base.getindex(::SectorValues{FermionParity}, i)
return 1 <= i <= 2 ? FermionParity(i - 1) : throw(BoundsError(values(FermionParity), i))
end
findindex(::SectorValues{fℤ₂}, f::fℤ₂) = f.isodd ? 2 : 1
findindex(::SectorValues{FermionParity}, f::FermionParity) = f.isodd ? 2 : 1

Base.one(::Type{fℤ₂}) = fℤ₂(false)
Base.conj(f::fℤ₂) = f
dim(f::fℤ₂) = 1
Base.one(::Type{FermionParity}) = FermionParity(false)
Base.conj(f::FermionParity) = f
dim(f::FermionParity) = 1

FusionStyle(::Type{fℤ₂}) = UniqueFusion()
BraidingStyle(::Type{fℤ₂}) = Fermionic()
Base.isreal(::Type{fℤ₂}) = true
FusionStyle(::Type{FermionParity}) = UniqueFusion()
BraidingStyle(::Type{FermionParity}) = Fermionic()
Base.isreal(::Type{FermionParity}) = true

(a::fℤ₂, b::fℤ₂) = (fℤ₂(a.isodd b.isodd),)
(a::FermionParity, b::FermionParity) = (FermionParity(a.isodd b.isodd),)

function Nsymbol(a::fℤ₂, b::fℤ₂, c::fℤ₂)
function Nsymbol(a::FermionParity, b::FermionParity, c::FermionParity)
return (a.isodd b.isodd) == c.isodd
end
function Fsymbol(a::I, b::I, c::I, d::I, e::I, f::I) where {I<:fℤ₂}
function Fsymbol(a::I, b::I, c::I, d::I, e::I, f::I) where {I<:FermionParity}
return Int(Nsymbol(a, b, e) * Nsymbol(e, c, d) * Nsymbol(b, c, f) * Nsymbol(a, f, d))
end
function Rsymbol(a::I, b::I, c::I) where {I<:fℤ₂}
function Rsymbol(a::I, b::I, c::I) where {I<:FermionParity}
return a.isodd && b.isodd ? -Int(Nsymbol(a, b, c)) : Int(Nsymbol(a, b, c))
end
twist(a::fℤ₂) = a.isodd ? -1 : +1
twist(a::FermionParity) = a.isodd ? -1 : +1

function fusiontensor(a::I, b::I, c::I) where {I<:fℤ₂}
@warn "fℤ₂ Arrays do not preserve categorical properties." maxlog = 1
function fusiontensor(a::I, b::I, c::I) where {I<:FermionParity}
@warn "FermionParity Arrays do not preserve categorical properties." maxlog = 1
return fill(Int(Nsymbol(a, b, c)), (1, 1, 1, 1))
end

function Base.show(io::IO, a::fℤ₂)
function Base.show(io::IO, a::FermionParity)
if get(io, :typeinfo, nothing) === typeof(a)
print(io, Int(a.isodd))
else
print(io, type_repr(typeof(a)), "(", Int(a.isodd), ")")
end
end
type_repr(::Type{fℤ₂}) = "fℤ₂"
type_repr(::Type{FermionParity}) = "FermionParity"

Base.hash(f::fℤ₂, h::UInt) = hash(f.isodd, h)
Base.isless(a::fℤ₂, b::fℤ₂) = isless(a.isodd, b.isodd)
Base.hash(f::FermionParity, h::UInt) = hash(f.isodd, h)
Base.isless(a::FermionParity, b::FermionParity) = isless(a.isodd, b.isodd)

# Common fermionic combinations
# -----------------------------

const FermionNumber = U1Irrep fℤ₂
const FermionNumber = U1Irrep FermionParity
const fU₁ = FermionNumber
fU₁(a::Int) = U1Irrep(a) fℤ₂(isodd(a))
fU₁(a::Int) = U1Irrep(a) FermionParity(isodd(a))
type_repr(::Type{fU₁}) = "fU₁"

# convenience default converter -> allows Vect[fU₁](1 => 1)
Base.convert(::Type{fU₁}, a::Int) = fU₁(a)

const FermionSpin = SU2Irrep fℤ₂
const FermionSpin = SU2Irrep FermionParity
const fSU₂ = FermionSpin
fSU₂(a::Real) = (s = SU2Irrep(a);
s fℤ₂(isodd(twice(s.j))))
s FermionParity(isodd(twice(s.j))))
type_repr(::Type{fSU₂}) = "fSU₂"

# convenience default converter -> allows Vect[fSU₂](1 => 1)
Expand Down

0 comments on commit 91344d7

Please sign in to comment.