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
3 changes: 3 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ makedocs(;
"Group Elements" => [
"ℤₙ (Cyclic)" => "sectors/groupelement/znelement.md",
],
"Other" => [
"ℤₙ-Tambara-Yamagami" => "sectors/other/ty.md",
],
"Composite Sectors" => [
"Product" => "sectors/composite/product.md",
"Named" => "sectors/composite/named.md",
Expand Down
1 change: 1 addition & 0 deletions docs/src/sectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ This page provides an overview of the concrete sector types implemented in Tenso
| [`HeisenbergIrrep`](@ref)| Rep[H_N] | Generic | Bosonic | No | Weyl-Heisenberg symmetry, projective representations |
| [`FibonacciAnyon`](@ref) | Fibonacci category | Simple | Anyonic | No | Topological quantum computing |
| [`IsingAnyon`](@ref) | Ising category | Simple | Anyonic | No | Majorana fermions, ν=5/2 QHE |
| [`TambaraYamagami`](@ref) | ℤₙ-Tambara-Yamagami category | Simple | No | No | Self-dual spin chains |
| [`FermionParity`](@ref) | fℤ₂ | Unique | Fermionic | No | Fermion parity conservation |
| [`FermionNumber`](@ref) | fU₁ | Unique | Fermionic | Yes | Fermion number conservation |
| [`FermionSpin`](@ref) | fSU₂ | Simple | Fermionic | Yes | Fermions with spin symmetry |
Expand Down
52 changes: 52 additions & 0 deletions docs/src/sectors/other/ty.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# The $\mathbb Z_N$-Tambara-Yamagami categories: `TambaraYamagami`

`TambaraYamagami{N, K}` represents the Tambara-Yamagami fusion category ${\rm TY}(\mathbb Z_N, K)$ based on the cyclic group of order $N$.

The $N+1$ simple objects coincide with the group elements of $\mathbb Z_N$ supplemented with one non-invertible object $m$. The type parameter `K` specifies the Frobenius-Schur indicator of $m$ as $\varkappa_m = (-1)^K = \pm 1$, i.e. `K = false` corresponds to $\varkappa_m = 1$ and `K = true` to $\varkappa_m = -1$.

## Sector type

```@docs; canonical = false
TambaraYamagami
```
Here, the type parameters `N` and `K` correspond respectively to the order of the underlying cyclic group and the Frobenius-Schur sign $(-1)^K$ of the non-invertible object.

## Fusion Rules

The non-trivial fusion rules read

```math
g ⊗ h = g + h \mod N, \qquad g ⊗ m = m ⊗ g = m, \qquad m ⊗ m = \bigoplus_{g ∈ ℤ_N} g,
```
for all group elements $g, h \in \mathbb Z_N$.

Hence `FusionStyle(::Type{<:TambaraYamagami}) = SimpleFusion()`.

The quantum dimensions are

```math
d_g = 1, \quad \forall g\in\mathbb Z_N, \quad {\rm and} \quad d_m = \sqrt{N}.
```

## Topological Data

We write $χ(g, h) = \exp(2π i g h / N)$ for a normalised non-degenerate symmetric bicharacter on $\mathbb Z_N$. The nontrivial F-symbols are then given by

```math
F^{g\,m\,h}_{m} = χ(g, h), \qquad
F^{m\,g\,m}_{h} = χ(g, h), \qquad
\left[F^{m\,m\,m}_{m}\right]_g^h = \frac{\varkappa_m}{\sqrt{N}}\,\overline{χ(g, h)},
```

for all $g, h \in \mathbb Z_N$.

Crucially, there exists no braiding on this fusion category, except when $N=2$, in which case it coincides with `IsingAnyon`.

## Iteration and basis conventions
`values(TambaraYamagami{N,K})` iterates the labels `0, 1, …, N-1,:m` in increasing order.

## References
[1] D. Tambara and S. Yamagami, *Tensor categories with fusion rules of self-duality for
finite abelian groups*, J. Algebra **209**, 692-707 (1998).

[2] M. Barkeshli, P. Bonderson, M. Cheng and Z. Wang, *Symmetry Fractionalization, Defects, and Gauging of Topological Phases*, Phys. Rev. B **100**, 115147 (2019), [arXiv:1410.4540](https://arxiv.org/abs/1410.4540).
2 changes: 2 additions & 0 deletions src/TensorKitSectors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export ZNElement, Z2Element, Z3Element, Z4Element
export ProductSector, NamedSector, @NamedSector, TimeReversed
export FermionParity, FermionNumber, FermionSpin
export PlanarTrivial, FibonacciAnyon, IsingAnyon
export TambaraYamagami
export IsingBimodule

# accessors
Expand Down Expand Up @@ -83,6 +84,7 @@ include("named.jl") # named tuple product of different sectors
include("fermions.jl") # irreps with defined fermionparity and fermionic braiding
include("anyons.jl") # non-group sectors
include("multifusion.jl") # multifusion example, namely Rep Z2 ⊕ Rep Z2 ≅ Ising
include("ty.jl") # Tambara-Yamagami category for ℤ_N

# precompile
# ----------
Expand Down
142 changes: 142 additions & 0 deletions src/ty.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Tambara-Yamagami category for the cyclic group ℤ_N
#---------------------------------------------------------------------------------------#
"""
struct TambaraYamagami{N, K} <: Sector
TambaraYamagami{N, K}(n::Integer)

Represents the Tambara-Yamagami fusion category built from the cyclic group ``ℤ_N``.
The simple objects are the group elements `0, 1, …, N - 1` of ``ℤ_N``,
together with a single non-invertible object `m`.

The non-trivial fusion rules are given by
```math
g ⊗ h = g + h \\mod N, \\qquad g ⊗ m = m ⊗ g = m, \\qquad m ⊗ m = \\bigoplus_{g ∈ ℤ_N} g.
```

The F-symbols are constructed from a non-degenerate symmetric bicharacter
``χ(g, h) = \\exp(2π i g h / N)``, together with a Frobenius-Schur sign for the
non-invertible object; the latter is fixed as `κ = (-1)^K` through the type parameter
`K::Bool`. For fixed `N`, the two choices `K = false` (`κ = 1`) and `K = true` (`κ = -1`)
generally give distinct fusion categories.

Only the case `N == 2` and `K == false` admits a braiding, as this case coincides with Ising, but this is not currently implemented.

## Fields
- `n::UInt8`: a group element for `0 <= n < N`, or the non-invertible object `m` for `n == N`.

## References
[1] D. Tambara and S. Yamagami, *Tensor categories with fusion rules of self-duality for
finite abelian groups*, J. Algebra **209**, 692-707 (1998).
[2] M. Barkeshli, P. Bonderson, M. Cheng and Z. Wang, *Symmetry Fractionalization, Defects,
and Gauging of Topological Phases*, Phys. Rev. B **100**, 115147 (2019),
[arXiv:1410.4540](https://arxiv.org/abs/1410.4540).
"""
struct TambaraYamagami{N, K} <: Sector
n::UInt8
function TambaraYamagami{N, K}(n) where {N, K}
_check_TY_typeparams(N, K)
0 <= n <= N || throw(DomainError(n, "TambaraYamagami{$N, $K} labels must satisfy 0 <= n <= $N"))
return new{N, K}(n)
end
end
function TambaraYamagami{N, K}(s::Symbol) where {N, K}
s === :m || throw(ArgumentError("Unknown label $s: use an integer or `:m`"))
return TambaraYamagami{N, K}(N)
end

# Labels are stored as `UInt8`; restricting to `N <= 128` guarantees that the sum `a.n + b.n`
# of two group labels (at most `2(N - 1) = 254`) never overflows before taking it modulo `N`.
const SMALL_TY_CUTOFF = (typemax(UInt8) + 1) ÷ 2

function _check_TY_typeparams(N, K)
N isa Int && 1 <= N <= SMALL_TY_CUTOFF || throw(ArgumentError("N must be an Int satisfying 1 <= N <= $SMALL_TY_CUTOFF, got $N::$(typeof(N))"))
K isa Bool || throw(ArgumentError("K must be a Bool, encoding the Frobenius-Schur indicator (-1)^K, got $K"))
return nothing
end

"""
modulus(n::TambaraYamagami{N, K}) -> N
modulus(::Type{<:TambaraYamagami{N, K}}) -> N

The order of the cyclic group, or the modulus of the charge labels.
"""
modulus(n::TambaraYamagami) = modulus(typeof(n))
modulus(::Type{<:TambaraYamagami{N, K}}) where {N, K} = N

_ism(a::TambaraYamagami) = a.n == modulus(a) # Checks whether a is the non-invertible
_chi(a::I, b::I) where {I <: TambaraYamagami} = cispi(2 * a.n * b.n / modulus(I)) # Non-degenerate symmetric bicharacter on ℤ_N

Base.length(::SectorValues{I}) where {I <: TambaraYamagami} = modulus(I) + 1
Base.IteratorSize(::Type{SectorValues{I}}) where {I <: TambaraYamagami} = HasLength()
Base.@propagate_inbounds function Base.getindex(v::SectorValues{I}, i::Int) where {I <: TambaraYamagami}
@boundscheck 1 <= i <= length(v) || throw(BoundsError(v, i))
return I(i - 1)
end
findindex(::SectorValues{I}, c::I) where {I <: TambaraYamagami} = Int(c.n) + 1
Base.IteratorSize(::Type{<:SectorProductIterator{I}}) where {I <: TambaraYamagami} = HasLength()

function Base.length(it::SectorProductIterator{I}) where {I <: TambaraYamagami}
return (_ism(it.a) && _ism(it.b)) ? modulus(I) : 1
end
function Base.iterate(::SectorValues{I}, i::Int = 0) where {I <: TambaraYamagami}
return i > modulus(I) ? nothing : (I(i), i + 1)
end
function Base.iterate(it::SectorProductIterator{I}, state::Int = 0) where {I <: TambaraYamagami}
a, b = it.a, it.b
am, bm = _ism(a), _ism(b)
N = modulus(I)
if am && bm
state == N && return nothing
return I(state), state + 1
else
state == 0 || return nothing
c = (am || bm) ? I(N) : I(mod(a.n + b.n, N))
return c, 1
end
end

Base.isless(a1::I, a2::I) where {I <: TambaraYamagami} = isless(a1.n, a2.n)
dim(a::TambaraYamagami) = _ism(a) ? sqrt(float(modulus(a))) : 1.0
unit(::Type{I}) where {I <: TambaraYamagami} = I(0)
dual(a::TambaraYamagami) = _ism(a) ? a : typeof(a)(mod(- Int(a.n), modulus(a)))

FusionStyle(::Type{<:TambaraYamagami}) = SimpleFusion()
BraidingStyle(::Type{<:TambaraYamagami}) = NoBraiding()
fusionscalartype(::Type{<:TambaraYamagami}) = ComplexF64

function Nsymbol(a::I, b::I, c::I) where {N, I <: TambaraYamagami{N}}
am, bm, cm = _ism(a), _ism(b), _ism(c)
if am && bm
return !cm
elseif am || bm
return cm
else
return !cm && c.n == mod(a.n + b.n, N)
end
end

function Fsymbol(a::I, b::I, c::I, d::I, e::I, f::I) where {N, K, I <: TambaraYamagami{N, K}}
T = fusionscalartype(I)

(Nsymbol(a, b, e) && Nsymbol(e, c, d) && Nsymbol(b, c, f) && Nsymbol(a, f, d)) || return zero(T)

am, bm, cm = _ism(a), _ism(b), _ism(c)

if am && bm && cm # F^{mmm}_m
return ((1 - 2 * K) / sqrt(N)) * conj(_chi(e, f))
elseif !am && bm && !cm # F^{gmh}_{m}
return _chi(a, c)
elseif am && !bm && cm # F^{mgm}_{h}
return _chi(b, d)
else # F^{abc}_{a+b+c}
return one(T)
end
end

function Base.show(io::IO, a::TambaraYamagami)
print_type = get(io, :typeinfo, nothing) !== typeof(a)
print_type && print(io, type_repr(typeof(a)), "(")
print(io, _ism(a) ? ":m" : Int(a.n))
print_type && print(io, ")")
return nothing
end
24 changes: 24 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ const sectorlist = (
FibonacciAnyon ⊠ Z4Element{3},
IsingBimodule, IsingBimodule ⊠ IsingBimodule, IsingBimodule ⊠ Z2Irrep,
IsingBimodule ⊠ SU2Irrep, IsingBimodule ⊠ FibonacciAnyon,
TambaraYamagami{1, false}, TambaraYamagami{1, true},
TambaraYamagami{2, false}, TambaraYamagami{2, true},
TambaraYamagami{4, false}, TambaraYamagami{4, true},
TambaraYamagami{7, false}, TambaraYamagami{8, true},
TambaraYamagami{67, false}, TambaraYamagami{128, false},
TambaraYamagami{3, true} ⊠ TambaraYamagami{2, true}, TambaraYamagami{2, false} ⊠ Z3Irrep,
TambaraYamagami{3, true} ⊠ FibonacciAnyon, TambaraYamagami{5, true} ⊠ IsingAnyon,
TambaraYamagami{64, false} ⊠ Z4Irrep, TambaraYamagami{128, true} ⊠ SU2Irrep,
TimeReversed{Z2Irrep},
TimeReversed{Z3Irrep}, TimeReversed{Z4Irrep}, TimeReversed{A4Irrep},
TimeReversed{U1Irrep}, TimeReversed{CU1Irrep}, TimeReversed{SU2Irrep},
Expand Down Expand Up @@ -223,6 +231,22 @@ end
end
end

@testset "TambaraYamagami edge cases" begin
I = TambaraYamagami{3, true}
@test hash(I) isa UInt
@test hash(I(1)) == hash(I(1))
@test hash(I(1)) != hash(I(2))
@test_throws ArgumentError TambaraYamagami{UInt8(3), true}(1)
@test_throws ArgumentError TambaraYamagami{true, false}(0)
@test_throws ArgumentError TambaraYamagami{3, 1}(0)
for (i, c) in enumerate(values(I))
@test values(I)[i] == c
@test findindex(values(I), c) === i
end
@test_throws BoundsError values(I)[0]
@test_throws BoundsError values(I)[5]
end

@testset "Converter constructions" begin
@test IsingAnyon(:ψ) isa IsingAnyon
@test (IsingAnyon ⊠ IsingAnyon)(:ψ, :σ) isa (IsingAnyon ⊠ IsingAnyon)
Expand Down
Loading