From f8294520048aa5f98270c17fec29c0f8df4f74d3 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Mon, 15 Dec 2025 17:27:55 +0100 Subject: [PATCH 01/16] bump compat TKS --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 6c22acc60..5aa0552bc 100644 --- a/Project.toml +++ b/Project.toml @@ -41,7 +41,7 @@ Random = "1" SafeTestsets = "0.1" ScopedValues = "1.3.0" Strided = "2" -TensorKitSectors = "0.3.3" +TensorKitSectors = "0.3.4" TensorOperations = "5.1" Test = "1" TestExtras = "0.2,0.3" From a509ccaae70747827f4046a3f0de6519d3c2a56f Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Mon, 15 Dec 2025 17:28:24 +0100 Subject: [PATCH 02/16] export more sectors + fusiontensor --- src/TensorKit.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/TensorKit.jl b/src/TensorKit.jl index 8e49a368a..095e67cf2 100644 --- a/src/TensorKit.jl +++ b/src/TensorKit.jl @@ -12,7 +12,8 @@ export Sector, AbstractIrrep, Irrep export FusionStyle, UniqueFusion, MultipleFusion, MultiplicityFreeFusion, SimpleFusion, GenericFusion export UnitStyle, SimpleUnit, GenericUnit export BraidingStyle, SymmetricBraiding, Bosonic, Fermionic, Anyonic, NoBraiding, HasBraiding -export Trivial, Z2Irrep, Z3Irrep, Z4Irrep, ZNIrrep, U1Irrep, SU2Irrep, CU1Irrep +export Trivial, Z2Irrep, Z3Irrep, Z4Irrep, ZNIrrep, LargeZNIrrep +export ZNElement, Z2Element, Z3Element, Z4Element, A4Irrep, U1Irrep, SU2Irrep, CU1Irrep export ProductSector export FermionParity, FermionNumber, FermionSpin export FibonacciAnyon, IsingAnyon, IsingBimodule @@ -42,7 +43,8 @@ export infimum, supremum, isisomorphic, ismonomorphic, isepimorphic # Reexport methods for sectors and properties thereof export sectortype, sectors, hassector export unit, rightunit, leftunit, allunits, isunit, otimes -export Nsymbol, Fsymbol, Rsymbol, Bsymbol, frobenius_schur_phase, frobenius_schur_indicator, twist, sectorscalartype, deligneproduct +export Nsymbol, Fsymbol, Rsymbol, Bsymbol, frobenius_schur_phase, frobenius_schur_indicator, twist, fusiontensor +export sectorscalartype, deligneproduct # Export methods for fusion trees export fusiontrees, braid, permute, transpose From 4c964184537137b50404a735a4096242dba22004 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Mon, 15 Dec 2025 17:59:23 +0100 Subject: [PATCH 03/16] more exports --- src/TensorKit.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/TensorKit.jl b/src/TensorKit.jl index 095e67cf2..fce88e4bb 100644 --- a/src/TensorKit.jl +++ b/src/TensorKit.jl @@ -8,12 +8,12 @@ module TensorKit # Exports #--------- # Reexport common sector types: -export Sector, AbstractIrrep, Irrep +export Sector, AbstractIrrep, Irrep, GroupElement, TimeReversed export FusionStyle, UniqueFusion, MultipleFusion, MultiplicityFreeFusion, SimpleFusion, GenericFusion export UnitStyle, SimpleUnit, GenericUnit export BraidingStyle, SymmetricBraiding, Bosonic, Fermionic, Anyonic, NoBraiding, HasBraiding export Trivial, Z2Irrep, Z3Irrep, Z4Irrep, ZNIrrep, LargeZNIrrep -export ZNElement, Z2Element, Z3Element, Z4Element, A4Irrep, U1Irrep, SU2Irrep, CU1Irrep +export ZNElement, Z2Element, Z3Element, Z4Element, DNIrrep, A4Irrep, U1Irrep, SU2Irrep, CU1Irrep export ProductSector export FermionParity, FermionNumber, FermionSpin export FibonacciAnyon, IsingAnyon, IsingBimodule @@ -54,7 +54,7 @@ export fusiontrees, braid, permute, transpose # some unicode export ⊕, ⊗, ⊖, ×, ⊠, ℂ, ℝ, ℤ, ←, →, ≾, ≿, ≅, ≺, ≻ -export ℤ₂, ℤ₃, ℤ₄, U₁, SU, SU₂, CU₁ +export ℤ₂, ℤ₃, ℤ₄, D₃, D₄, A₄, U₁, SU, SU₂, CU₁ export fℤ₂, fU₁, fSU₂ export ℤ₂Space, ℤ₃Space, ℤ₄Space, U₁Space, CU₁Space, SU₂Space From 7890266740434e5ff74fd25165133a6dfb2680c3 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Fri, 19 Dec 2025 13:04:18 +0100 Subject: [PATCH 04/16] expand diagonal space list --- test/tensors/diagonal.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/tensors/diagonal.jl b/test/tensors/diagonal.jl index 9154ed3b4..14b7b9a8d 100644 --- a/test/tensors/diagonal.jl +++ b/test/tensors/diagonal.jl @@ -4,6 +4,8 @@ using TensorKit diagspacelist = ( (ℂ^4)', Vect[Z2Irrep](0 => 2, 1 => 3), + Vect[Z3Element{1}](0 => 2, 1 => 3, 2 => 1), + Vect[A4Irrep](0 => 1, 1 => 2, 2 => 2, 3 => 2), Vect[FermionNumber](0 => 2, 1 => 2, -1 => 1), Vect[SU2Irrep](0 => 2, 1 => 1)', Vect[FibonacciAnyon](:I => 2, :τ => 2), From ae3939f6516290bdcf9e77a79af1b091fcfc884f Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Fri, 19 Dec 2025 13:05:02 +0100 Subject: [PATCH 05/16] expand sectorlist and spacelist --- test/setup.jl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/setup.jl b/test/setup.jl index 6cde01d28..149a39411 100644 --- a/test/setup.jl +++ b/test/setup.jl @@ -90,6 +90,9 @@ end sectorlist = ( Z2Irrep, Z3Irrep, Z4Irrep, Z3Irrep ⊠ Z4Irrep, + Z2Element{0}, Z3Element{0}, Z4Element{0}, + # Z2Element{1}, Z3Element{2}, Z4Element{1}, Z4Element{2}, Z4Element{3}, + DNIrrep{3}, DNIrrep{4}, A4Irrep, U1Irrep, CU1Irrep, SU2Irrep, FermionParity, FermionParity ⊠ FermionParity, FermionParity ⊠ U1Irrep ⊠ SU2Irrep, FermionParity ⊠ SU2Irrep ⊠ SU2Irrep, # Hubbard-like @@ -121,6 +124,20 @@ Vℤ₃ = ( Vect[Z3Irrep](0 => 1, 1 => 2, 2 => 3), Vect[Z3Irrep](0 => 1, 1 => 3, 2 => 3)', ) +VZ2ω = ( + Vect[Z2Element{1}](0 => 1, 1 => 1), + Vect[Z2Element{1}](0 => 1, 1 => 2)', + Vect[Z2Element{1}](0 => 2, 1 => 1)', + Vect[Z2Element{1}](0 => 2, 1 => 3), + Vect[Z2Element{1}](0 => 2, 1 => 5), +) +VA₄ = ( + Vect[A4Irrep](0 => 1, 1 => 1, 2 => 1, 3 => 1), + Vect[A4Irrep](0 => 1, 1 => 2, 2 => 1, 3 => 1), + Vect[A4Irrep](0 => 1, 1 => 1, 2 => 2, 3 => 1)', + Vect[A4Irrep](0 => 1, 1 => 2, 2 => 2, 3 => 2), + Vect[A4Irrep](0 => 1, 1 => 2, 2 => 2, 3 => 3)', +) VU₁ = ( Vect[U1Irrep](0 => 1, 1 => 2, -1 => 2), Vect[U1Irrep](0 => 3, 1 => 1, -1 => 1), From 615226e460040555247f4020c67d85b344df81f0 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Fri, 19 Dec 2025 14:11:33 +0100 Subject: [PATCH 06/16] change A4 V1 space for factorization tests (hermitian and posdef check) --- test/setup.jl | 2 +- test/tensors/factorizations.jl | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/setup.jl b/test/setup.jl index 149a39411..7b4b3ba0e 100644 --- a/test/setup.jl +++ b/test/setup.jl @@ -132,7 +132,7 @@ VZ2ω = ( Vect[Z2Element{1}](0 => 2, 1 => 5), ) VA₄ = ( - Vect[A4Irrep](0 => 1, 1 => 1, 2 => 1, 3 => 1), + Vect[A4Irrep](0 => 2, 1 => 1, 2 => 1, 3 => 1), Vect[A4Irrep](0 => 1, 1 => 2, 2 => 1, 3 => 1), Vect[A4Irrep](0 => 1, 1 => 1, 2 => 2, 3 => 1)', Vect[A4Irrep](0 => 1, 1 => 2, 2 => 2, 3 => 2), diff --git a/test/tensors/factorizations.jl b/test/tensors/factorizations.jl index e63312f9c..bfa86647c 100644 --- a/test/tensors/factorizations.jl +++ b/test/tensors/factorizations.jl @@ -9,17 +9,17 @@ spacelist = try if ENV["CI"] == "true" println("Detected running on CI") if Sys.iswindows() - (Vtr, Vℤ₃, VU₁, VfU₁, VCU₁, VSU₂, VIB_diag) + (Vtr, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂, VIB_diag) elseif Sys.isapple() - (Vtr, Vℤ₃, VfU₁, VfSU₂, VIB_M) + (Vtr, Vℤ₃, VA₄, VfU₁, VfSU₂, VIB_M) else - (Vtr, VU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) + (Vtr, VA₄, VU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) end else - (Vtr, Vℤ₃, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) + (Vtr, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) end catch - (Vtr, Vℤ₃, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) + (Vtr, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) end eltypes = (Float32, ComplexF64) From 3cb49d43cb2d1c846abadb5321aa1fa8a8280201 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Fri, 19 Dec 2025 14:13:54 +0100 Subject: [PATCH 07/16] add A4 spaces to tensors spacelist --- test/tensors/tensors.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/tensors/tensors.jl b/test/tensors/tensors.jl index 74cb9cfa0..e7ca07672 100644 --- a/test/tensors/tensors.jl +++ b/test/tensors/tensors.jl @@ -11,17 +11,17 @@ spacelist = try if get(ENV, "CI", "false") == "true" println("Detected running on CI") if Sys.iswindows() - (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VU₁, VfU₁, VCU₁, VSU₂, VIB_diag) + (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂, VIB_diag) elseif Sys.isapple() - (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VfU₁, VfSU₂, VSU₂U₁, VIB_M) #, VSU₃) + (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, VfU₁, VfSU₂, VSU₂U₁, VIB_M) #, VSU₃) else - (Vtr, Vℤ₂, Vfℤ₂, VU₁, VCU₁, VSU₂, VfSU₂, VSU₂U₁, VIB_diag, VIB_M) #, VSU₃) + (Vtr, Vℤ₂, Vfℤ₂, VA₄, VU₁, VCU₁, VSU₂, VfSU₂, VSU₂U₁, VIB_diag, VIB_M) #, VSU₃) end else - (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VSU₂U₁, VIB_diag, VIB_M) #, VSU₃) + (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VSU₂U₁, VIB_diag, VIB_M) #, VSU₃) end catch - (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VSU₂U₁, VIB_diag, VIB_M) #, VSU₃) + (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VSU₂U₁, VIB_diag, VIB_M) #, VSU₃) end for V in spacelist From 02ea3578b043a30bc2774d2a0da9dc11396ae90c Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Fri, 13 Mar 2026 20:21:36 +0100 Subject: [PATCH 08/16] edit sectors and spaces --- test/setup.jl | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/test/setup.jl b/test/setup.jl index 424dabbf2..d29111ea9 100644 --- a/test/setup.jl +++ b/test/setup.jl @@ -78,9 +78,9 @@ function randsector(::Type{I}) where {I <: Sector} return a end function hasfusiontensor(I::Type{<:Sector}) - isa(UnitStyle(I), GenericUnit) && return false try - TensorKit.fusiontensor(unit(I), unit(I), unit(I)) + u = first(allunits(I)) + TensorKit.fusiontensor(u, u, u) return true catch e if e isa MethodError @@ -145,17 +145,30 @@ function test_dim_isapprox(V::ProductSpace, d::Int) return @test max(0, d - dim_c_max) ≤ dim(V) ≤ d + dim_c_max end -sectorlist = ( +uniquefusionsectorlist = ( Z2Irrep, Z3Irrep, Z4Irrep, Z3Irrep ⊠ Z4Irrep, - Z2Element{0}, Z3Element{0}, Z4Element{0}, - # Z2Element{1}, Z3Element{2}, Z4Element{1}, Z4Element{2}, Z4Element{3}, - DNIrrep{3}, DNIrrep{4}, A4Irrep, - U1Irrep, CU1Irrep, SU2Irrep, - FermionParity, FermionParity ⊠ FermionParity, - FermionParity ⊠ U1Irrep ⊠ SU2Irrep, FermionParity ⊠ SU2Irrep ⊠ SU2Irrep, # Hubbard-like - FibonacciAnyon, IsingAnyon, - Z2Irrep ⊠ FibonacciAnyon ⊠ FibonacciAnyon, + U1Irrep, FermionParity, FermionParity ⊠ FermionParity, FermionNumber, + Z3Element{1}, Z4Element{2}, ZNElement{5, 2} +) +simplefusionsectorlist = ( + CU1Irrep, SU2Irrep, FibonacciAnyon, IsingAnyon, + FermionParity ⊠ U1Irrep ⊠ SU2Irrep, FermionParity ⊠ SU2Irrep ⊠ SU2Irrep, + Z3Element{1} ⊠ FibonacciAnyon ⊠ FibonacciAnyon, +) +genericfusionsectorlist = ( + A4Irrep, A4Irrep ⊠ FermionParity, A4Irrep ⊠ SU2Irrep, + A4Irrep ⊠ Z3Element{2}, A4Irrep ⊠ A4Irrep, +) +multifusionsectorlist = ( IsingBimodule, IsingBimodule ⊠ SU2Irrep, IsingBimodule ⊠ IsingBimodule, + IsingBimodule ⊠ Z3Element{1}, IsingBimodule ⊠ FibonacciAnyon ⊠ A4Irrep, +) + +sectorlist = ( + uniquefusionsectorlist..., + simplefusionsectorlist..., + genericfusionsectorlist..., + multifusionsectorlist..., ) # spaces @@ -182,14 +195,14 @@ Vℤ₃ = ( Vect[Z3Irrep](0 => 1, 1 => 3, 2 => 3)', ) VZ2ω = ( - Vect[Z2Element{1}](0 => 1, 1 => 1), + Vect[Z2Element{1}](0 => 2, 1 => 1), Vect[Z2Element{1}](0 => 1, 1 => 2)', Vect[Z2Element{1}](0 => 2, 1 => 1)', Vect[Z2Element{1}](0 => 2, 1 => 3), Vect[Z2Element{1}](0 => 2, 1 => 5), ) VA₄ = ( - Vect[A4Irrep](0 => 2, 1 => 1, 2 => 1, 3 => 1), + Vect[A4Irrep](0 => 1, 1 => 1, 2 => 1, 3 => 3), # dim large enough for truncated factorization tests Vect[A4Irrep](0 => 1, 1 => 2, 2 => 1, 3 => 1), Vect[A4Irrep](0 => 1, 1 => 1, 2 => 2, 3 => 1)', Vect[A4Irrep](0 => 1, 1 => 2, 2 => 2, 3 => 2), @@ -241,7 +254,7 @@ VSU₂U₁ = ( Vect[SU2Irrep ⊠ U1Irrep]((0, 0) => 1, (1 // 2, 1) => 1)', ) Vfib = ( - Vect[FibonacciAnyon](:I => 1, :τ => 1), + Vect[FibonacciAnyon](:I => 2, :τ => 1), Vect[FibonacciAnyon](:I => 1, :τ => 2)', Vect[FibonacciAnyon](:I => 3, :τ => 2)', Vect[FibonacciAnyon](:I => 2, :τ => 3), From 1e1296f92b5b1826ed3f3fd52fcf78361f5feb61 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Fri, 13 Mar 2026 20:21:54 +0100 Subject: [PATCH 09/16] fix foldright --- src/fusiontrees/manipulations.jl | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/fusiontrees/manipulations.jl b/src/fusiontrees/manipulations.jl index 3cc6a16b6..764696f66 100644 --- a/src/fusiontrees/manipulations.jl +++ b/src/fusiontrees/manipulations.jl @@ -351,9 +351,21 @@ function foldright(f₁::FusionTree{I, N₁}, f₂::FusionTree{I, N₂}) where { isdual = Base.tail(f₁.isdual) if FusionStyle(I) isa UniqueFusion c = first(c1 ⊗ c2) - fl = FusionTree{I}(Base.tail(f₁.uncoupled), c, Base.tail(f₁.isdual)) - fr = FusionTree{I}((c1, f₂.uncoupled...), c, (!isduala, f₂.isdual...)) - return fusiontreedict(I)((fl, fr) => factor) + cvalid = N₁ == 1 ? leftunit(c1) : only(⊗(uncoupled...)) + @assert c == cvalid + fc = FusionTree((c1, c2), c, (!isduala, false)) + fl′, coeff1 = only(insertat(fc, 2, f₁)) # this coeff is not always 1 + N₁ > 1 && @assert isunit(fl′.innerlines[1]) + + coupled = fl′.coupled + uncoupled = Base.tail(Base.tail(fl′.uncoupled)) + isdual = Base.tail(Base.tail(fl′.isdual)) + inner = N₁ <= 3 ? () : Base.tail(Base.tail(fl′.innerlines)) + vertices = N₁ <= 2 ? () : Base.tail(Base.tail(fl′.vertices)) + fl = FusionTree{I}(uncoupled, coupled, isdual, inner, vertices) + fr, coeff2 = only(insertat(fc, 2, f₂)) # same here + coeff = factor * coeff1 * conj(coeff2) + return fusiontreedict(I)((fl, fr) => coeff) else hasmultiplicities = FusionStyle(a) isa GenericFusion local newtrees From 5d6264555e6bb45573c42b68d0edf7fa6ab8a156 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Fri, 13 Mar 2026 20:23:00 +0100 Subject: [PATCH 10/16] remove `target` and `source` --- src/tensors/abstracttensor.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tensors/abstracttensor.jl b/src/tensors/abstracttensor.jl index 2d7239460..b53dbf7ed 100644 --- a/src/tensors/abstracttensor.jl +++ b/src/tensors/abstracttensor.jl @@ -212,7 +212,6 @@ See also [`domain`](@ref) and [`space`](@ref). codomain(t::AbstractTensorMap) = codomain(space(t)) codomain(t::AbstractTensorMap, i) = codomain(t)[i] -target(t::AbstractTensorMap) = codomain(t) # categorical terminology @doc """ domain(t::AbstractTensorMap{T,S,N₁,N₂}) -> ProductSpace{S,N₂} @@ -226,7 +225,6 @@ See also [`codomain`](@ref) and [`space`](@ref). domain(t::AbstractTensorMap) = domain(space(t)) domain(t::AbstractTensorMap, i) = domain(t)[i] -source(t::AbstractTensorMap) = domain(t) # categorical terminology @doc """ numout(x) -> Int From 095b089d6938c239ee04c7f09c04f27d33d524df Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Fri, 13 Mar 2026 20:23:20 +0100 Subject: [PATCH 11/16] add spaces to cuda tests --- test/cuda/factorizations.jl | 8 ++++---- test/cuda/tensors.jl | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/cuda/factorizations.jl b/test/cuda/factorizations.jl index 1b46cb646..46e5ee2b5 100644 --- a/test/cuda/factorizations.jl +++ b/test/cuda/factorizations.jl @@ -17,14 +17,14 @@ using .TestSetup spacelist = if get(ENV, "CI", "false") == "true" println("Detected running on CI") if Sys.iswindows() - (Vtr, Vℤ₃, VU₁, VfU₁, VCU₁, VSU₂, VIB_diag) + (Vtr, Vℤ₃, VA₄, Vfib, VU₁, VfU₁, VCU₁, VSU₂, VIB_diag) elseif Sys.isapple() - (Vtr, Vℤ₃, VfU₁, VfSU₂, VIB_M) + (Vtr, Vℤ₃, VA₄, Vfib, VfU₁, VfSU₂, VIB_M) else - (Vtr, VU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) + (Vtr, VA₄, VU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) end else - (Vtr, Vℤ₃, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) + (Vtr, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) end eltypes = (Float32, ComplexF64) diff --git a/test/cuda/tensors.jl b/test/cuda/tensors.jl index 0fad13473..4d4da9825 100644 --- a/test/cuda/tensors.jl +++ b/test/cuda/tensors.jl @@ -13,7 +13,7 @@ using CUDA: rand as curand, rand! as curand!, randn as curandn, randn! as curand @isdefined(TestSetup) || include("../setup.jl") using .TestSetup -for V in (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂) #, VSU₃) +for V in (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, Vfib, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂) #, VSU₃) V1, V2, V3, V4, V5 = V @assert V3 * V4 * V2 ≿ V1' * V5' # necessary for leftorth tests @assert V3 * V4 ≾ V1' * V2' * V5' # necessary for rightorth tests @@ -23,17 +23,17 @@ spacelist = try if ENV["CI"] == "true" println("Detected running on CI") if Sys.iswindows() - (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VU₁, VfU₁, VCU₁, VSU₂) + (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂) elseif Sys.isapple() - (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VfU₁, VfSU₂) #, VSU₃) + (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, Vfib, VfU₁, VfSU₂) #, VSU₃) else - (Vtr, Vℤ₂, Vfℤ₂, VU₁, VCU₁, VSU₂, VfSU₂) #, VSU₃) + (Vtr, Vℤ₂, Vfℤ₂, VA₄, Vfib, VU₁, VCU₁, VSU₂, VfSU₂) #, VSU₃) end else - (Vtr, VU₁, VSU₂, Vfℤ₂) + (Vtr, VU₁, VSU₂, Vfℤ₂, VA₄) end catch - (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂) #, VSU₃) + (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, Vfib, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂) #, VSU₃) end for V in spacelist From 91c44fd69981e3070263ce1f97ceba1c4ea94fa4 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Fri, 13 Mar 2026 20:24:07 +0100 Subject: [PATCH 12/16] add braiding condition to insertat test --- test/symmetries/fusiontrees.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/symmetries/fusiontrees.jl b/test/symmetries/fusiontrees.jl index e5dbf8132..737a15049 100644 --- a/test/symmetries/fusiontrees.jl +++ b/test/symmetries/fusiontrees.jl @@ -105,7 +105,7 @@ using .TestSetup @test length(TK.insertat(f1b, 1, f1a)) == 1 @test first(TK.insertat(f1b, 1, f1a)) == (f1 => 1) - if UnitStyle(I) isa SimpleUnit + if UnitStyle(I) isa SimpleUnit && BraidingStyle(I) isa HasBraiding levels = ntuple(identity, N) function _reinsert_partial_tree(t, f) (t′, c′) = first(TK.insertat(t, 1, f)) From e82683c4d6a61647a20c45c1fd022ed086764f27 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Fri, 13 Mar 2026 20:24:46 +0100 Subject: [PATCH 13/16] add spaces to diagonal and factorisation tests --- test/tensors/diagonal.jl | 2 ++ test/tensors/factorizations.jl | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/test/tensors/diagonal.jl b/test/tensors/diagonal.jl index 7a7d59a88..65ed62a8d 100644 --- a/test/tensors/diagonal.jl +++ b/test/tensors/diagonal.jl @@ -9,6 +9,8 @@ diagspacelist = ( Vect[FermionNumber](0 => 2, 1 => 2, -1 => 1), Vect[SU2Irrep](0 => 2, 1 => 1)', Vect[FibonacciAnyon](:I => 2, :τ => 2), + Vect[Z3Element{1}](0 => 2, 1 => 2, 2 => 1), + Vect[IsingBimodule](C0 => 2, C1 => 3) ) @testset "DiagonalTensor with domain $V" for V in diagspacelist diff --git a/test/tensors/factorizations.jl b/test/tensors/factorizations.jl index 3740e0561..a786f65ae 100644 --- a/test/tensors/factorizations.jl +++ b/test/tensors/factorizations.jl @@ -10,17 +10,17 @@ spacelist = try if ENV["CI"] == "true" println("Detected running on CI") if Sys.iswindows() - (Vtr, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂, VIB_diag) + (Vtr, Vℤ₃, VA₄, VU₁, VfU₁, VZ2ω, VCU₁, VSU₂, VIB_diag) elseif Sys.isapple() - (Vtr, Vℤ₃, VA₄, VfU₁, VfSU₂, VIB_M) + (Vtr, Vℤ₃, VA₄, Vfib, VZ2ω, VfU₁, VfSU₂, VIB_M) else - (Vtr, VA₄, VU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) + (Vtr, VA₄, Vfib, VU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) end else - (Vtr, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) + (Vtr, Vℤ₃, VA₄, Vfib, VZ2ω, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) end catch - (Vtr, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) + (Vtr, Vℤ₃, VA₄, Vfib, VZ2ω, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VIB_diag, VIB_M) end eltypes = (Float32, ComplexF64) From 52e7772a0b2950eed29a882f19382abb66f1ee88 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Fri, 13 Mar 2026 20:26:18 +0100 Subject: [PATCH 14/16] add spaces to tensor tests + additional tests + make costly tests less costly --- test/tensors/tensors.jl | 55 ++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/test/tensors/tensors.jl b/test/tensors/tensors.jl index db763adef..7613ca2e5 100644 --- a/test/tensors/tensors.jl +++ b/test/tensors/tensors.jl @@ -13,15 +13,15 @@ spacelist = try if Sys.iswindows() (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂, VIB_diag) elseif Sys.isapple() - (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, VfU₁, VfSU₂, VSU₂U₁, VIB_M) #, VSU₃) + (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, VfU₁, VfSU₂, VSU₂U₁, VIB_M) else - (Vtr, Vℤ₂, Vfℤ₂, VA₄, VU₁, VCU₁, VSU₂, VfSU₂, VSU₂U₁, VIB_diag, VIB_M) #, VSU₃) + (Vtr, Vℤ₂, Vfℤ₂, VA₄, VU₁, VCU₁, VSU₂, VfSU₂, VSU₂U₁, VIB_diag, VIB_M) end else - (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VSU₂U₁, VIB_diag, VIB_M) #, VSU₃) + (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, Vfib, VZ2ω, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VSU₂U₁, VIB_diag, VIB_M) end catch - (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VSU₂U₁, VIB_diag, VIB_M) #, VSU₃) + (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VA₄, Vfib, VZ2ω, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂, VSU₂U₁, VIB_diag, VIB_M) end for V in spacelist @@ -53,6 +53,8 @@ for V in spacelist @test space(t) == (W ← one(W)) @test domain(t) == one(W) @test typeof(t) == TensorMap{T, spacetype(t), 5, 0, Vector{T}} + @test complex(t) == real(t) + im*imag(t) + @test T <: Real ? real(t) == t : complex(t) == t # blocks bs = @constinferred blocks(t) if !isempty(blocksectors(t)) # multifusion space ending on module gives empty data @@ -157,6 +159,21 @@ for V in spacelist @test dim(w) == 2 * dim(V1 ← V1) @test w' * w == id(Vector{T}, V1) @test w * w' == (w * w')^2 + + # concatenation + t3 = rand(T, V1 ⊗ V2 ← V2) + t3data2 = T[] + for c in blocksectors(t3) + append!(t3data2, repeat(block(t3, c), 1, 2)) + end + @test @constinferred(catdomain(t3, t3)) == TensorMap(t3data2, V1 ⊗ V2 ← V2 ⊕ V2) + + t4 = rand(T, V2 ← V1 ⊗ V2) + t4data2 = T[] + for c in blocksectors(t4) + append!(t4data2, repeat(block(t4, c), 2, 1)) + end + @test @constinferred(catcodomain(t4, t4)) == TensorMap(t4data2, V2 ⊕ V2 ← V1 ⊗ V2) end end @timedtestset "Trivial space insertion and removal" begin @@ -242,13 +259,14 @@ for V in spacelist @test Base.promote_typeof(tc, t) == typeof(tc + t) end symmetricbraiding && @timedtestset "Permutations: test via inner product invariance" begin - W = V1 ⊗ V2 ⊗ V3 ⊗ V4 ⊗ V5 + W = V1 ⊗ V2 ⊗ V3 ⊗ V4 + n = length(W) t = rand(ComplexF64, W) t′ = randn!(similar(t)) - for k in 0:5 - for p in permutations(1:5) + for k in 0:n + for p in permutations(1:n) p1 = ntuple(n -> p[n], k) - p2 = ntuple(n -> p[k + n], 5 - k) + p2 = ntuple(n -> p[k + n], n - k) t2 = @constinferred permute(t, (p1, p2)) @test norm(t2) ≈ norm(t) t2′ = permute(t′, (p1, p2)) @@ -264,24 +282,25 @@ for V in spacelist end if BraidingStyle(I) isa Bosonic && hasfusiontensor(I) @timedtestset "Permutations: test via conversion" begin - W = V1 ⊗ V2 ⊗ V3 ⊗ V4 ⊗ V5 + W = V1 ⊗ V2 ⊗ V3 ⊗ V4 + N = length(W) t = rand(ComplexF64, W) a = convert(Array, t) - for k in 0:5 - for p in permutations(1:5) + for k in 0:N + for p in permutations(1:N) p1 = ntuple(n -> p[n], k) - p2 = ntuple(n -> p[k + n], 5 - k) + p2 = ntuple(n -> p[k + n], N - k) t2 = permute(t, (p1, p2)) a2 = convert(Array, t2) @test a2 ≈ permutedims(a, (p1..., p2...)) @test convert(Array, transpose(t2)) ≈ - permutedims(a2, (5, 4, 3, 2, 1)) + permutedims(a2, reverse(ntuple(i -> i, N))) end t3 = repartition(t, k) a3 = convert(Array, t3) @test a3 ≈ permutedims( - a, (ntuple(identity, k)..., reverse(ntuple(i -> i + k, 5 - k))...) + a, (ntuple(identity, k)..., reverse(ntuple(i -> i + k, N - k))...) ) end end @@ -545,9 +564,17 @@ for V in spacelist if UnitStyle(I) isa SimpleUnit || !isempty(blocksectors(V2 ⊗ V1)) t1 = rand(T, V2 ⊗ V3 ⊗ V1, V1 ⊗ V2) t2 = rand(T, V2 ⊗ V1 ⊗ V3, V1 ⊗ V1) + if dim(t1) * dim(t2) > 1e7 # make t1⊗t2 factor dim(V3)^2 smaller + t1 = rand(T, V2 ⊗ V1, V1 ⊗ V2) + t2 = rand(T, V2 ⊗ V1, V1 ⊗ V1) + end else t1 = rand(T, V3 ⊗ V4 ⊗ V5, V1 ⊗ V2) t2 = rand(T, V5' ⊗ V4' ⊗ V3', V2' ⊗ V1') + if dim(t1) * dim(t2) > 1e7 # make t1⊗t2 factor dim(V5)^2 smaller + t1 = rand(T, V3 ⊗ V4, V1 ⊗ V2) + t2 = rand(T, V4' ⊗ V3', V2' ⊗ V1') + end end t = @constinferred (t1 ⊗ t2) @test norm(t) ≈ norm(t1) * norm(t2) From 7ee5345d32287007ff0d57ff43f19349ce1f834b Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Fri, 13 Mar 2026 20:26:34 +0100 Subject: [PATCH 15/16] remove `VectorDict` --- src/auxiliary/dicts.jl | 78 ------------------------------------------ 1 file changed, 78 deletions(-) diff --git a/src/auxiliary/dicts.jl b/src/auxiliary/dicts.jl index f43838010..8ce6c4532 100644 --- a/src/auxiliary/dicts.jl +++ b/src/auxiliary/dicts.jl @@ -21,84 +21,6 @@ Base.get(d::SingletonDict, key, default) = isequal(d.key, key) ? d.value : defau Base.iterate(d::SingletonDict, s = true) = s ? ((d.key => d.value), false) : nothing -struct VectorDict{K, V} <: AbstractDict{K, V} - keys::Vector{K} - values::Vector{V} -end -VectorDict{K, V}() where {K, V} = VectorDict{K, V}(Vector{K}(), Vector{V}()) -VectorDict() = VectorDict{Any, Any}() - -function VectorDict{K, V}(kvs) where {K, V} - keys = Vector{K}() - values = Vector{V}() - if Base.IteratorSize(kv) !== SizeUnknown() - sizehint!(keys, length(kvs)) - sizehint!(values, length(kvs)) - end - for (k, v) in kvs - push!(keys, k) - push!(values, v) - end - return VectorDict{K, V}(keys, values) -end -VectorDict(kv1::Pair{K, V}, kvs::Pair{K, V}...) where {K, V} = VectorDict{K, V}((kv1, kvs...)) -VectorDict(g::Base.Generator) = VectorDict(g...) - -Base.length(d::VectorDict) = length(d.keys) -function Base.sizehint!(d::VectorDict, newsz) - (sizehint!(d.keys, newsz); sizehint!(d.values, newsz); return d) -end - -@propagate_inbounds getpair(d::VectorDict, i::Integer) = d.keys[i] => d.values[i] - -Base.copy(d::VectorDict) = VectorDict(copy(d.keys), copy(d.values)) -Base.empty(::VectorDict, ::Type{K}, ::Type{V}) where {K, V} = VectorDict{K, V}() -Base.empty!(d::VectorDict) = (empty!(d.keys); empty!(d.values); return d) - -function Base.delete!(d::VectorDict, key) - i = findfirst(isequal(key), d.keys) - if !(i === nothing || i == 0) - deleteat!(d.keys, i) - deleteat!(d.values, i) - end - return d -end - -Base.keys(d::VectorDict) = d.keys -Base.values(d::VectorDict) = d.values -Base.haskey(d::VectorDict, key) = key in d.keys -function Base.getindex(d::VectorDict, key) - i = findfirst(isequal(key), d.keys) - @inbounds begin - return i !== nothing ? d.values[i] : throw(KeyError(key)) - end -end -function Base.setindex!(d::VectorDict, v, key) - i = findfirst(isequal(key), d.keys) - if i === nothing - push!(d.keys, key) - push!(d.values, v) - else - d.values[i] = v - end - return d -end - -function Base.get(d::VectorDict, key, default) - i = findfirst(isequal(key), d.keys) - @inbounds begin - return i !== nothing ? d.values[i] : default - end -end - -function Base.iterate(d::VectorDict, s = 1) - @inbounds if s > length(d) - return nothing - else - return (d.keys[s] => d.values[s]), s + 1 - end -end - struct SortedVectorDict{K, V} <: AbstractDict{K, V} keys::Vector{K} values::Vector{V} From 62a03427332c2281d0cef9c500993a4aae855e04 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Fri, 13 Mar 2026 21:25:04 +0100 Subject: [PATCH 16/16] format --- test/setup.jl | 2 +- test/tensors/diagonal.jl | 2 +- test/tensors/tensors.jl | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/setup.jl b/test/setup.jl index d29111ea9..e84100195 100644 --- a/test/setup.jl +++ b/test/setup.jl @@ -148,7 +148,7 @@ end uniquefusionsectorlist = ( Z2Irrep, Z3Irrep, Z4Irrep, Z3Irrep ⊠ Z4Irrep, U1Irrep, FermionParity, FermionParity ⊠ FermionParity, FermionNumber, - Z3Element{1}, Z4Element{2}, ZNElement{5, 2} + Z3Element{1}, Z4Element{2}, ZNElement{5, 2}, ) simplefusionsectorlist = ( CU1Irrep, SU2Irrep, FibonacciAnyon, IsingAnyon, diff --git a/test/tensors/diagonal.jl b/test/tensors/diagonal.jl index 65ed62a8d..b3e634a7e 100644 --- a/test/tensors/diagonal.jl +++ b/test/tensors/diagonal.jl @@ -10,7 +10,7 @@ diagspacelist = ( Vect[SU2Irrep](0 => 2, 1 => 1)', Vect[FibonacciAnyon](:I => 2, :τ => 2), Vect[Z3Element{1}](0 => 2, 1 => 2, 2 => 1), - Vect[IsingBimodule](C0 => 2, C1 => 3) + Vect[IsingBimodule](C0 => 2, C1 => 3), ) @testset "DiagonalTensor with domain $V" for V in diagspacelist diff --git a/test/tensors/tensors.jl b/test/tensors/tensors.jl index 7613ca2e5..c6b639d21 100644 --- a/test/tensors/tensors.jl +++ b/test/tensors/tensors.jl @@ -53,7 +53,7 @@ for V in spacelist @test space(t) == (W ← one(W)) @test domain(t) == one(W) @test typeof(t) == TensorMap{T, spacetype(t), 5, 0, Vector{T}} - @test complex(t) == real(t) + im*imag(t) + @test complex(t) == real(t) + im * imag(t) @test T <: Real ? real(t) == t : complex(t) == t # blocks bs = @constinferred blocks(t) @@ -159,7 +159,7 @@ for V in spacelist @test dim(w) == 2 * dim(V1 ← V1) @test w' * w == id(Vector{T}, V1) @test w * w' == (w * w')^2 - + # concatenation t3 = rand(T, V1 ⊗ V2 ← V2) t3data2 = T[] @@ -564,14 +564,14 @@ for V in spacelist if UnitStyle(I) isa SimpleUnit || !isempty(blocksectors(V2 ⊗ V1)) t1 = rand(T, V2 ⊗ V3 ⊗ V1, V1 ⊗ V2) t2 = rand(T, V2 ⊗ V1 ⊗ V3, V1 ⊗ V1) - if dim(t1) * dim(t2) > 1e7 # make t1⊗t2 factor dim(V3)^2 smaller + if dim(t1) * dim(t2) > 1.0e7 # make t1⊗t2 factor dim(V3)^2 smaller t1 = rand(T, V2 ⊗ V1, V1 ⊗ V2) t2 = rand(T, V2 ⊗ V1, V1 ⊗ V1) end else t1 = rand(T, V3 ⊗ V4 ⊗ V5, V1 ⊗ V2) t2 = rand(T, V5' ⊗ V4' ⊗ V3', V2' ⊗ V1') - if dim(t1) * dim(t2) > 1e7 # make t1⊗t2 factor dim(V5)^2 smaller + if dim(t1) * dim(t2) > 1.0e7 # make t1⊗t2 factor dim(V5)^2 smaller t1 = rand(T, V3 ⊗ V4, V1 ⊗ V2) t2 = rand(T, V4' ⊗ V3', V2' ⊗ V1') end