-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Remove FermionNumber, FermionSpin Refactors Fermion to always mean FermionParity * update FermionSpin/FermionNumber alias * Minor fermionic doc improvements
- Loading branch information
Showing
7 changed files
with
86 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ ZNIrrep | |
U1Irrep | ||
SU2Irrep | ||
CU1Irrep | ||
FermionParity | ||
FibonacciAnyon | ||
FusionTree | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,96 +1,82 @@ | ||
struct Fermion{P,I<:Sector} <: Sector | ||
sector::I | ||
function Fermion{P,I}(sector::I) where {P,I<:Sector} | ||
@assert BraidingStyle(I) isa Bosonic | ||
return new{P,I}(sector) | ||
end | ||
end | ||
Fermion{P}(sector::I) where {P,I<:Sector} = Fermion{P,I}(sector) | ||
Fermion{P,I}(sector) where {P,I<:Sector} = Fermion{P,I}(convert(I, sector)) | ||
Base.convert(::Type{Fermion{P,I}}, a::Fermion{P,I}) where {P,I<:Sector} = a | ||
Base.convert(::Type{Fermion{P,I}}, a) where {P,I<:Sector} = Fermion{P,I}(convert(I, a)) | ||
""" | ||
FermionParity <: Sector | ||
fermionparity(f::Fermion{P}) where {P} = P(f.sector) | ||
Represents sectors with fermion parity. The fermion parity is a ℤ₂ quantum number that | ||
yields an additional sign when two odd fermions are exchanged. | ||
function Base.IteratorSize(::Type{SectorValues{Fermion{P,I}}}) where {P,I<:Sector} | ||
return Base.IteratorSize(SectorValues{I}) | ||
See also: `FermionNumber`, `FermionSpin` | ||
""" | ||
struct FermionParity <: Sector | ||
isodd::Bool | ||
end | ||
Base.length(::SectorValues{Fermion{P,I}}) where {P,I<:Sector} = length(values(I)) | ||
function Base.iterate(::SectorValues{Fermion{P,I}}) where {P,I<:Sector} | ||
next = iterate(values(I)) | ||
@assert next !== nothing | ||
value, state = next | ||
return Fermion{P}(value), state | ||
end | ||
function Base.iterate(::SectorValues{Fermion{P,I}}, state) where {P,I<:Sector} | ||
next = iterate(values(I), state) | ||
if next === nothing | ||
return nothing | ||
else | ||
value, state = next | ||
return Fermion{P}(value), state | ||
end | ||
end | ||
function Base.getindex(::SectorValues{Fermion{P,I}}, i) where {P,I<:Sector} | ||
return Fermion{P}(values(I)[i]) | ||
const fℤ₂ = FermionParity | ||
fermionparity(f::FermionParity) = f.isodd | ||
|
||
Base.convert(::Type{FermionParity}, a::FermionParity) = a | ||
Base.convert(::Type{FermionParity}, a) = FermionParity(a) | ||
|
||
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 findindex(::SectorValues{Fermion{P,I}}, f::Fermion{P,I}) where {P,I<:Sector} | ||
return findindex(values(I), f.sector) | ||
function Base.getindex(::SectorValues{FermionParity}, i) | ||
return 1 <= i <= 2 ? FermionParity(i - 1) : throw(BoundsError(values(FermionParity), i)) | ||
end | ||
findindex(::SectorValues{FermionParity}, f::FermionParity) = f.isodd ? 2 : 1 | ||
|
||
Base.one(::Type{Fermion{P,I}}) where {P,I<:Sector} = Fermion{P}(one(I)) | ||
Base.conj(f::Fermion{P}) where {P} = Fermion{P}(conj(f.sector)) | ||
Base.one(::Type{FermionParity}) = FermionParity(false) | ||
Base.conj(f::FermionParity) = f | ||
dim(f::FermionParity) = 1 | ||
|
||
dim(f::Fermion) = dim(f.sector) | ||
FusionStyle(::Type{FermionParity}) = UniqueFusion() | ||
BraidingStyle(::Type{FermionParity}) = Fermionic() | ||
Base.isreal(::Type{FermionParity}) = true | ||
|
||
FusionStyle(::Type{<:Fermion{<:Any,I}}) where {I<:Sector} = FusionStyle(I) | ||
BraidingStyle(::Type{<:Fermion}) = Fermionic() | ||
Base.isreal(::Type{Fermion{<:Any,I}}) where {I<:Sector} = isreal(I) | ||
⊗(a::FermionParity, b::FermionParity) = (FermionParity(a.isodd ⊻ b.isodd),) | ||
|
||
⊗(a::F, b::F) where {F<:Fermion} = SectorSet{F}(a.sector ⊗ b.sector) | ||
|
||
Nsymbol(a::F, b::F, c::F) where {F<:Fermion} = Nsymbol(a.sector, b.sector, c.sector) | ||
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<:FermionParity} | ||
return Int(Nsymbol(a, b, e) * Nsymbol(e, c, d) * Nsymbol(b, c, f) * Nsymbol(a, f, d)) | ||
end | ||
|
||
function Fsymbol(a::F, b::F, c::F, d::F, e::F, f::F) where {F<:Fermion} | ||
return Fsymbol(a.sector, b.sector, c.sector, d.sector, e.sector, f.sector) | ||
function Rsymbol(a::F, b::F, c::F) where {F<:FermionParity} | ||
return a.isodd && b.isodd ? -Int(Nsymbol(a, b, c)) : Int(Nsymbol(a, b, c)) | ||
end | ||
twist(a::FermionParity) = a.isodd ? -1 : +1 | ||
|
||
function Rsymbol(a::F, b::F, c::F) where {F<:Fermion} | ||
if fermionparity(a) && fermionparity(b) | ||
return -Rsymbol(a.sector, b.sector, c.sector) | ||
function Base.show(io::IO, a::FermionParity) | ||
if get(io, :typeinfo, nothing) === FermionParity | ||
print(io, Int(a.isodd)) | ||
else | ||
return +Rsymbol(a.sector, b.sector, c.sector) | ||
print(io, "FermionParity(", Int(a.isodd), ")") | ||
end | ||
end | ||
type_repr(::Type{FermionParity}) = "FermionParity" | ||
|
||
twist(a::Fermion) = ifelse(fermionparity(a), -1, +1) * twist(a.sector) | ||
Base.hash(f::FermionParity, h::UInt) = hash(f.isodd, h) | ||
Base.isless(a::FermionParity, b::FermionParity) = isless(a.isodd, b.isodd) | ||
|
||
type_repr(::Type{Fermion{P,I}}) where {P,I<:Sector} = "Fermion{$P, " * type_repr(I) * "}" | ||
# Common fermionic combinations | ||
# ----------------------------- | ||
|
||
function Base.show(io::IO, a::Fermion{P,I}) where {P,I<:Sector} | ||
if get(io, :typeinfo, nothing) !== Fermion{P,I} | ||
print(io, type_repr(typeof(a)), "(") | ||
end | ||
print(IOContext(io, :typeinfo => I), a.sector) | ||
if get(io, :typeinfo, nothing) !== Fermion{P,I} | ||
print(io, ")") | ||
end | ||
end | ||
|
||
Base.hash(f::Fermion, h::UInt) = hash(f.sector, h) | ||
Base.isless(a::F, b::F) where {F<:Fermion} = isless(a.sector, b.sector) | ||
const FermionNumber = U1Irrep ⊠ FermionParity | ||
const fU₁ = FermionNumber | ||
type_repr(::Type{FermionNumber}) = "FermionNumber" | ||
|
||
_fermionparity(a::Z2Irrep) = isodd(a.n) | ||
_fermionnumber(a::U1Irrep) = isodd(convert(Int, a.charge)) | ||
_fermionspin(a::SU2Irrep) = isodd(twice(a.j)) | ||
# convenience default converter -> allows Vect[FermionNumber](1 => 1) | ||
function Base.convert(::Type{FermionNumber}, a::Int) | ||
return U1Irrep(a) ⊠ FermionParity(isodd(a)) | ||
end | ||
|
||
const FermionParity = Fermion{_fermionparity,Z2Irrep} | ||
const FermionNumber = Fermion{_fermionnumber,U1Irrep} | ||
const FermionSpin = Fermion{_fermionspin,SU2Irrep} | ||
const fℤ₂ = FermionParity | ||
const fU₁ = FermionNumber | ||
const FermionSpin = SU2Irrep ⊠ FermionParity | ||
const fSU₂ = FermionSpin | ||
|
||
type_repr(::Type{FermionParity}) = "FermionParity" | ||
type_repr(::Type{FermionNumber}) = "FermionNumber" | ||
type_repr(::Type{FermionSpin}) = "FermionSpin" | ||
|
||
# convenience default converter -> allows Vect[FermionSpin](1 => 1) | ||
function Base.convert(::Type{FermionSpin}, a::Real) | ||
s = SU2Irrep(a) | ||
return s ⊠ FermionParity(isodd(twice(s.j))) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters