Skip to content

Commit

Permalink
MeatAxe
Browse files Browse the repository at this point in the history
  • Loading branch information
FabianMaeurer committed Oct 16, 2024
1 parent 1bef28d commit 5c30ebc
Show file tree
Hide file tree
Showing 15 changed files with 538 additions and 113 deletions.
51 changes: 2 additions & 49 deletions src/CategoryFramework/AbstractMethods.jl
Original file line number Diff line number Diff line change
Expand Up @@ -468,55 +468,6 @@ end
# _indecomposable_subobjects(X,E)
# end

function simple_subobjects(X::Object, E = End(X), is_simple = false)
if base_ring(X) == QQBar
return simple_subobjects_over_qqbar(X,E)
end

if length(basis(E)) == 1
return [X]
end

if is_simple && is_squarefree(dim(E))
#A simple algebra of squarefree dimension is a division algebra
return [X]
end

R = endomorphism_ring(X,E)

i = findfirst(f -> !is_irreducible(f), minpoly.(basis(E)))

if !is_simple && is_semisimple(endomorphism_ring(X,E))
img = [image(i)[1] for i central_primitive_idempotents(E)]
return vcat([simple_subobjects(i, End(i), true) for i in img]...)
end

if i !== nothing && is_semisimple(R)
f = E[i]
l = roots(minpoly(f))[1]
K = kernel(f - l*id(X))[1]
I = image(f - l*id(X))[1]
K = simple_subobjects(K, End(K), true)
I = simple_subobjects(I, End(I), true)

return unique_simples([K;I])
end


M = regular_module(R)
M.action_of_gens = [representation_matrix(g) for g gens(R)]

submods = minimal_submodules(M)
fi = [sum(collect(s)[1,:] .* basis(E)) for s in submods]

unique_simples([image(f)[1] for f fi])
# indecomposables = indecomposable_subobjects(X, E)
# if is_semisimple(parent(X))
# return indecomposables
# else
# return indecomposables[is_simple.(indecomposables)]
# end
end

is_isomorphic_simples(X::Object, Y::Object) = is_isomorphic(X,Y)

Expand Down Expand Up @@ -693,6 +644,8 @@ zero_morphism(C::Category) = zero_morphism(zero(C))

is_zero(f::Morphism) = f == zero_morphism(domain(f), codomain(f))

is_zero(X::Object) = int_dim(End(X)) == 0

function ==(f::Morphism, x::T) where T <: Union{RingElem, Int}
if x == 0
return is_zero(f)
Expand Down
64 changes: 64 additions & 0 deletions src/CategoryFramework/DecompositionInAbelianCategories.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#=----------------------------------------------------------
Methods for decomposition of objects in abelian
categories.
In the cases cases where it is possible we provide
methods to compute simple subobjects.
----------------------------------------------------------=#

function simple_subobjects(X::Object, E = End(X), is_simple = false)
#= Compute all simple subobjects in a tensor category
The approach is the MeatAxe algorithm.
=#

# Over QQBar it's easier
if base_ring(X) == QQBar
return simple_subobjects_over_qqbar(X,E)
end

# Just a single Endomorphism -> Done
if length(basis(E)) == 1
return [X]
end

#A simple algebra of squarefree dimension is a division algebra
if is_simple && is_squarefree(dim(E))
return [X]
end

R = endomorphism_ring(X,E)

i = findfirst(f -> !is_irreducible(f), minpoly.(basis(E)))

if !is_simple && is_semisimple(endomorphism_ring(X,E))
img = [image(i)[1] for i central_primitive_idempotents(E)]
return vcat([simple_subobjects(i, End(i), true) for i in img]...)
end

if i !== nothing && is_semisimple(R)
f = E[i]
l = roots(minpoly(f))[1]
K = kernel(f - l*id(X))[1]
I = image(f - l*id(X))[1]
K = simple_subobjects(K, End(K), true)
I = simple_subobjects(I, End(I), true)

return unique_simples([K;I])
end


M = regular_module(R)
M.action_of_gens = [representation_matrix(g) for g gens(R)]

submods = minimal_submodules(M)
fi = [sum(collect(s)[1,:] .* basis(E)) for s in submods]

unique_simples([image(f)[1] for f fi])
# indecomposables = indecomposable_subobjects(X, E)
# if is_semisimple(parent(X))
# return indecomposables
# else
# return indecomposables[is_simple.(indecomposables)]
# end
end
3 changes: 2 additions & 1 deletion src/CategoryFramework/Fallbacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ morphisms.
Return the tensor product object.
"""
(X::Object...) = tensor_product(X...)
(X::T...) where T <: Object = tensor_product(X...)
(X::Object, Y::Object) = tensor_product(X,Y)

(C::Category, K::Field) = extension_of_scalars(C,K)
(X::Object, K::Field) = extension_of_scalars(X,K)
Expand Down
54 changes: 54 additions & 0 deletions src/DecategorifiedFramework/multiplication_table.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,31 @@ function pretty_print_decomposable(m::Object,indecomposables::Vector{<:Object},n
return str
end

function pretty_print_decomposable(facs::Vector{Int}, names::Vector{String})

str = ""

for (k,s) zip(facs, names)

k == 0 && continue
str = length(str) > 0 ? str*""* (k > 1 ? "$k$(s)" : "$(s)") : (k > 1 ? str*"$k$(s)" : str*"$(s)")
end
return str
end

function coefficients(X::T, indecomposables::Vector{T} = indecomposables(parent(X))) where {T <: Object}
if is_semisimple(parent(X))
return fusion_coefficients(X, indecomposables)
else
return _coefficients(X, indecomposables)
end
end

function fusion_coefficients(X::T, simpls::Vector{T} = simples(parent(X))) where {T <: Object}
[int_dim(Hom(s,X)) for s simpls]
end

function _coefficients(X::T, indecomposables::Vector{T} = indecomposables(parent(X))) where {T <: Object}
facs = decompose(X)
coeffs = [0 for i 1:length(indecomposables)]
for (x,k) facs
Expand Down Expand Up @@ -84,4 +107,35 @@ function print_module_action(M::T, names = nothing) where T <: Union{RightModule
names = names === nothing ? ["m$i" for i 1:length(simples_M)] : names

reshape(vcat([[print_sum(collect(r), names) for r eachrow(action_matrix(X,M))] for X simples_C]...), length(simples_C), length(simples_M))
end

#=----------------------------------------------------------
Live progress
----------------------------------------------------------=#

function multiplication_table_with_progress(C::Category, indecs::Vector{<:Object} = indecomposables(C); symmetric::Bool = false, names = simples_names(C))

n = length(indecs)
m = Array{Int}(undef,n,n,n)

displ = ["" for _ 1:n, _ 1:n]

for i 1:n, j (symmetric ? i : 1):n
m[i,j,:] = coefficients(indecs[i] indecs[j])
if symmetric m[j,i] = m[i,j] end

displ[i,j] = pretty_print_decomposable(m[i,j,:], names)
if symmetric displ[j,i] = displ[i,j] end

if i*j != 1
for _ 1:n+1
print("\e[A\e[2K")
end
end

display(displ)
end

println("")
return m
end
13 changes: 9 additions & 4 deletions src/Examples/GradedVectorSpaces/GradedVectorSpaces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,23 @@ end
Return the tensor product ``V⊗W``.
"""
function tensor_product(X::GVSObject, Y::GVSObject)
W = X.V Y.V
W = VectorSpaceObject(parent(X.V), int_dim(X)*int_dim(Y))
G = base_group(X)
elems = elements(G)
grading = vcat([[i*j for i Y.grading] for j X.grading]...)
grading = [i*j for i Y.grading, j X.grading][:]
return GVSObject(parent(X), W, length(grading) == 0 ? elem_type(G)[] : grading)
end

function braiding(X::GVSObject, Y::GVSObject)
twist(parent(X)).m !== nothing && error("Braiding not implemented")
χ = parent(X).braiding
m = diagonal_matrix(base_ring(X),[χ(g,h) for g in grading(X), h grading(Y)][:])
morphism(XY,YX, m)
K = base_ring(X)
m = diagonal_matrix(K,elem_type(K)[χ(g,h) for g in grading(X), h grading(Y)][:])

# permutation
p = permutation_matrix(K, perm(sortperm([(i,j) for i 1:int_dim(X), j 1:int_dim(Y)][:])))

morphism(XY,YX, p * m)
end

#-----------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/Examples/TambaraYamagami/TambaraYamagami.jl
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ function Ising(F::Ring, sqrt_2::RingElem, q::Int)
braid[3,3,:] = α .* matrices((id(C[1]) (inv(ξ) * id(C[2]))))

set_braiding!(C,braid)
catch
catch e
end
return C
end
Expand Down
2 changes: 1 addition & 1 deletion src/Examples/Verlinde/Verlinde.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,4 @@ function verlinde_category(K::Ring, m::Int, l::Int = 1, k::Int = 1)
return C
end

verlinde_category(m::Int, l::Int = 1, k::Int = 1) = verlinde_category(cyclotomic_field(2*m+2)[1],m, l, k)
verlinde_category(m::Int, l::Int = 1, k::Int = 1) = verlinde_category(cyclotomic_field(4*m+4)[1],m, l, k)
9 changes: 7 additions & 2 deletions src/TensorCategories.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module TensorCategories
import Base: *, +, -, ==, ^, getindex, getproperty, in, issubset, iterate, length, show,div, rand, split

import Oscar.AbstractAlgebra.Generic: Poly
import Oscar.Hecke: RelSimpleNumField, regular_module
import Oscar.Hecke: RelSimpleNumField, regular_module, meataxe
import Oscar: +, @alias, @attributes, AbstractSet, AcbField, StructureConstantAlgebra, AssociativeAlgebraElem,
cyclotomic_field, Fac, Field, FieldElem, FinField, GF, GAP, GAPGroup,
GAPGroupHomomorphism, GL, GSet, GroupElem, Hecke.AbstractAssociativeAlgebra,
Expand Down Expand Up @@ -31,7 +31,7 @@ import Oscar: +, @alias, @attributes, AbstractSet, AcbField, StructureConstantAl
number_of_rows, number_of_columns, is_squarefree, is_commutative,
gens, center, graph_from_adjacency_matrix, connected_components, weakly_connected_components, Directed, Undirected, morphism, algebra,
radical, is_zero, minimal_submodules, representation_matrix, QQBarField,
is_irreducible, polynomial, is_univariate, action, is_equivalent, extension_of_scalars, free_module
is_irreducible, polynomial, is_univariate, action, is_equivalent, extension_of_scalars, free_module, perm



Expand Down Expand Up @@ -252,6 +252,9 @@ export left_trace
export load
export matrices
export matrix
export meataxe
export minimal_subquotients
export minimal_subquotients_with_multiplicity
export ModuleCategory
export ModuleMorphism
export ModuleObject
Expand Down Expand Up @@ -385,6 +388,7 @@ export ZPlusRingElem, ℕRingElem, ℤ₊RingElem

include("CategoryFramework/AbstractTypes.jl")
include("CategoryFramework/AbstractMethods.jl")
include("CategoryFramework/DecompositionInAbelianCategories.jl")
include("CategoryFramework/FrameworkChecks.jl")
include("CategoryFramework/ProductCategory.jl")
include("CategoryFramework/Fallbacks.jl")
Expand Down Expand Up @@ -436,6 +440,7 @@ include("TensorCategoryFramework/Center/CenterChecks.jl")
include("TensorCategoryFramework/InternalModules/InternalAlgebras.jl")
include("TensorCategoryFramework/InternalModules/ModuleCategories.jl")
include("TensorCategoryFramework/InternalModules/ComputationOfAlgebras.jl")
include("TensorCategoryFramework/InternalModules/MeatAxe.jl")
include("TensorCategoryFramework/ModuleCategories/MonadModules.jl")

include("DecategorifiedFramework/multiplication_table.jl")
Expand Down
15 changes: 10 additions & 5 deletions src/TensorCategoryFramework/FusionCategory.jl
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,17 @@ function braiding(X::SixJObject, Y::SixJObject)
X_summands = vcat([[s for l 1:X.components[k]] for (k,s) zip(1:n, simple_objects)]...)
Y_summands = vcat([[s for l 1:Y.components[k]] for (k,s) zip(1:n, simple_objects)]...)

braid = direct_sum([braiding(x,y) for x X_summands, y Y_summands][:])
braid = direct_sum([braiding(x,y) for y Y_summands, x X_summands][:])

return braid
distr_before = compose(
distribute_left(X_summands,Y),
direct_sum([distribute_right(x,Y_summands) for x X_summands])
)
distr_after = compose(
distribute_right(Y,X_summands),
direct_sum([distribute_left(Y_summands, x) for x X_summands])
)

distr_before = direct_sum([distribute_right(x,Y_summands) for x X_summands]) distribute_left(X_summands,Y)
distr_after = direct_sum([distribute_left(X_summands,Y) for y Y_summands]) distribute_right(Y_summands,X)

return inv(distr_after) braid distr_before
end

Expand Down Expand Up @@ -308,6 +312,7 @@ end
#-------------------------------------------------------------------------------
is_semisimple(::SixJCategory) = true
is_multiring(::SixJCategory) = true
is_braided(C::SixJCategory) = isdefined(C, :braiding)

function is_multifusion(C::SixJCategory)
try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function _algebra_structures(structure_ideal::Function, X::Object, unit = Hom(on
d = dim(I)

show_dimension && @info "Dimension of solution set: $d"

if d < 0
return AlgebraObject[]
elseif d == 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ function is_separable(A::AlgebraObject)
has_right_inverse(m)
end

function is_commutative(A::AlgebraObject)
m = multiplication(A)
m == m braiding(object(A),object(A))
end
#=----------------------------------------------------------
Group Algebras
----------------------------------------------------------=#
Expand Down
Loading

0 comments on commit 5c30ebc

Please sign in to comment.