-
Notifications
You must be signed in to change notification settings - Fork 53
IsingBimodule
for testing multifusion category within TensorKit
#263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
fb4693f
13bcf82
09467c6
2878e08
10744b2
1ed1ed1
c31b99c
a33d028
0e3c5df
124def4
9635362
4bc1e7c
24be2ea
13af986
095dcda
fbfb564
d7cae4f
a14fc70
4fe82f9
55a00c0
0113f73
8e8b760
78b135e
440b42b
00825af
aad8fc8
c0ef01e
c189284
bdbd2e6
e23e092
06671f3
a18f73d
979036a
279a15f
83d73ce
d7fb9f4
9521574
19ba225
5fef11e
2d9663b
0061588
abb6301
64982d6
520f81d
60bc1fc
490aa4f
8ab417d
6348815
2a7d871
a6bf085
159143e
42fd12b
5393d87
5898bc0
6351cf0
2d107a5
1d3c170
bae646a
99b8d1c
a8e8b81
45ff559
260ef92
cd8e37b
772452f
fd55983
04d6162
5d34b60
d25510a
a3857da
de2bcae
3ea5293
6c20fc6
3dd1257
69e7423
ae10a73
7f01306
8d2e94f
6501e5f
07bcc51
52fa8d4
41013ec
c71b15c
ddc1612
17f1e1b
e8f6a76
df0115e
ac56fae
599cabd
0612656
698d652
9b5ba0b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not great if we have to specialize everything specifically for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what you mean by redoing all that work. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What I mean is that if all we are testing is the specializations that are written solely for IsingBimodule, which is used mainly for testing, this doesn't actually help all that much, since it would have to be both reimplemented and retested for other multifusion categories as well |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
# additional interface to deal with IsingBimodule Sector | ||
#------------------------------------------------------------------------------ | ||
|
||
function dim(V::Vect[IsingBimodule]) | ||
T = Base.promote_op(*, Int, real(sectorscalartype(sectortype(V)))) | ||
return reduce(+, dim(V, c) * dim(c) for c in sectors(V); | ||
init=zero(T)) | ||
end | ||
|
||
function scalar(t::AbstractTensorMap{T,Vect[IsingBimodule],0,0}) where {T} | ||
Bs = collect(blocks(t)) | ||
inds = findall(!iszero ∘ last, Bs) | ||
isempty(inds) && return zero(scalartype(t)) | ||
return only(last(Bs[only(inds)])) | ||
end | ||
|
||
# no custom fuse: we choose to return empty graded space when fusion is forbidden | ||
|
||
function Base.oneunit(S::Vect[IsingBimodule]) | ||
!isempty(sectors(S)) || throw(ArgumentError("Cannot determine type of empty space")) | ||
allequal(a.row for a in sectors(S)) && allequal(a.col for a in sectors(S)) || | ||
throw(ArgumentError("sectors of $S are not all equal")) | ||
first(sectors(S)).row == first(sectors(S)).col || | ||
throw(ArgumentError("sectors of $S are non-diagonal")) | ||
sector = one(first(sectors(S))) | ||
return spacetype(S)(sector => 1) | ||
end | ||
|
||
Base.zero(S::Type{Vect[IsingBimodule]}) = Vect[IsingBimodule]() | ||
|
||
function blocksectors(W::TensorMapSpace{Vect[IsingBimodule],N₁,N₂}) where {N₁,N₂} | ||
codom = codomain(W) | ||
dom = domain(W) | ||
if N₁ == 0 && N₂ == 0 | ||
return [IsingBimodule(1, 1, 0), IsingBimodule(2, 2, 0)] | ||
elseif N₁ == 0 | ||
@assert N₂ != 0 "one of Type IsingBimodule doesn't exist" | ||
return filter!(isone, collect(blocksectors(dom))) # is this what we want? doesn't allow M/Mop to end at empty space | ||
elseif N₂ == 0 | ||
@assert N₁ != 0 "one of Type IsingBimodule doesn't exist" | ||
return filter!(isone, collect(blocksectors(codom))) | ||
elseif N₂ <= N₁ # keep intersection | ||
return filter!(c -> hasblock(codom, c), collect(blocksectors(dom))) | ||
else | ||
return filter!(c -> hasblock(dom, c), collect(blocksectors(codom))) | ||
end | ||
end | ||
|
||
function rightoneunit(S::Vect[IsingBimodule]) | ||
!isempty(sectors(S)) || throw(ArgumentError("Cannot determine type of empty space")) | ||
allequal(a.col for a in sectors(S)) || | ||
throw(ArgumentError("sectors of $S do not have the same rightone")) | ||
|
||
sector = rightone(first(sectors(S))) | ||
return spacetype(S)(sector => 1) | ||
end | ||
|
||
function leftoneunit(S::Vect[IsingBimodule]) | ||
!isempty(sectors(S)) || throw(ArgumentError("Cannot determine type of empty space")) | ||
allequal(a.row for a in sectors(S)) || | ||
throw(ArgumentError("sectors of $S do not have the same leftone")) | ||
|
||
sector = leftone(first(sectors(S))) | ||
return spacetype(S)(sector => 1) | ||
end | ||
|
||
function insertrightunit(P::ProductSpace{Vect[IsingBimodule],N}, ::Val{i}; | ||
conj::Bool=false, | ||
dual::Bool=false) where {i,N} | ||
i > N && error("cannot insert a sensible right unit onto $P at index $(i+1)") | ||
# possible change to rightone of correct space for N = 0 | ||
u = N > 0 ? rightoneunit(P[i]) : error("no unit object in $P") | ||
if dual | ||
u = TensorKit.dual(u) | ||
end | ||
if conj | ||
u = TensorKit.conj(u) | ||
end | ||
return ProductSpace(TupleTools.insertafter(P.spaces, i, (u,))) | ||
end | ||
|
||
# TODO?: overwrite defaults at level of HomSpace and TensorMap? | ||
function insertleftunit(P::ProductSpace{Vect[IsingBimodule],N}, ::Val{i}; # want no defaults? | ||
conj::Bool=false, | ||
dual::Bool=false) where {i,N} | ||
i > N && error("cannot insert a sensible left unit onto $P at index $i") # do we want this to error in the diagonal case? | ||
u = N > 0 ? leftoneunit(P[i]) : error("no unit object in $P") | ||
if dual | ||
u = TensorKit.dual(u) | ||
end | ||
if conj | ||
u = TensorKit.conj(u) | ||
end | ||
return ProductSpace(TupleTools.insertafter(P.spaces, i - 1, (u,))) | ||
end | ||
|
||
# is this even necessary? can let it error at fusiontrees.jl:93 from the one(IsingBimodule) call | ||
# but these errors are maybe more informative | ||
function FusionTree(uncoupled::Tuple{IsingBimodule,Vararg{IsingBimodule}}) | ||
coupled = collect(⊗(uncoupled...)) | ||
if length(coupled) == 0 # illegal fusion somewhere | ||
throw(ArgumentError("Forbidden fusion with uncoupled sectors $uncoupled")) | ||
else # allowed fusions require inner lines | ||
error("fusion tree requires inner lines if `FusionStyle(I) <: MultipleFusion`") | ||
end | ||
end | ||
|
||
# this one might also be overkill, since `FusionTreeIterator`s don't check whether the fusion is allowed | ||
function fusiontrees(uncoupled::Tuple{IsingBimodule,Vararg{IsingBimodule}}) | ||
return throw(ArgumentError("coupled sector must be provided for IsingBimodule fusion")) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was wrong with the previous implementations? This looks like it will always fail for multifusion things
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted
left/rightoneunit
to also work on empty spaces, becauseoneunit
does so. This will indeed fail for multifusion things, hence the specialisation.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, but what do you think about this then: