From d15ac2dd49dd937f76b6314dcf057bb27a16af1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Sat, 15 Apr 2023 16:48:18 +0200 Subject: [PATCH] LieAlgebras: add dual modules --- .../LieAlgebras/src/LieAlgebraModule.jl | 34 ++++++++++++++++++- experimental/LieAlgebras/src/LieAlgebras.jl | 2 ++ .../LieAlgebras/test/LieAlgebraModule-test.jl | 33 ++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/experimental/LieAlgebras/src/LieAlgebraModule.jl b/experimental/LieAlgebras/src/LieAlgebraModule.jl index 4d65d9e435de..be1c90e2766d 100644 --- a/experimental/LieAlgebras/src/LieAlgebraModule.jl +++ b/experimental/LieAlgebras/src/LieAlgebraModule.jl @@ -126,6 +126,11 @@ function show_standard_module(io::IO, V::LieAlgebraModule{C}) where {C<:RingElem print(IOContext(io, :compact => true), base_lie_algebra(V)) end +function show_dual(io::IO, V::LieAlgebraModule{C}) where {C<:RingElement} + print(io, "Dual of ") + print(IOContext(io, :compact => true), get_attribute(V, :base_module)) +end + function show_exterior_power(io::IO, V::LieAlgebraModule{C}) where {C<:RingElement} print(io, "$(get_attribute(V, :power))-th exterior power of ") print(IOContext(io, :compact => true), base_module(V)) @@ -189,6 +194,9 @@ function (V::LieAlgebraModule{C})(v::SRow{C}) where {C<:RingElement} end function (V::LieAlgebraModule{C})(v::LieAlgebraModuleElem{C}) where {C<:RingElement} + if is_dual(V) && base_module(V) == parent(v) + return V(coefficients(v)) + end @req V == parent(v) "Incompatible modules." return v end @@ -336,6 +344,10 @@ function is_standard_module(V::LieAlgebraModule{C}) where {C<:RingElement} return get_attribute(V, :type, :fallback) == :standard_module end +function is_dual(V::LieAlgebraModule{C}) where {C<:RingElement} + return get_attribute(V, :type, :fallback) == :dual +end + function is_exterior_power(V::LieAlgebraModule{C}) where {C<:RingElement} return get_attribute(V, :type, :fallback) == :exterior_power end @@ -349,7 +361,7 @@ function is_tensor_power(V::LieAlgebraModule{C}) where {C<:RingElement} end function base_module(V::LieAlgebraModule{C}) where {C<:RingElement} - @req is_exterior_power(V) || is_symmetric_power(V) || is_tensor_power(V) "Not a power module." + @req is_dual(V) || is_exterior_power(V) || is_symmetric_power(V) || is_tensor_power(V) "Not a power module." return get_attribute(V, :base_module) end @@ -407,6 +419,26 @@ function standard_module(L::LinearLieAlgebra{C}) where {C<:RingElement} return std_V end +function dual(V::LieAlgebraModule{C}) where {C<:RingElement} + L = base_lie_algebra(V) + dim_dual_V = dim(V) + + transformation_matrices = map(1:dim(L)) do i + -transpose(transformation_matrix(V, i)) + end + + if is_standard_module(V) + parentheses = identity + else + parentheses = x -> "($x)" + end + s = [Symbol("$(parentheses(s))*") for s in symbols(V)] + + pow_V = LieAlgebraModule{C}(L, dim_dual_V, transformation_matrices, s; check=false) + set_attribute!(pow_V, :type => :dual, :base_module => V, :show => show_dual) + return pow_V +end + function exterior_power(V::LieAlgebraModule{C}, k::Int) where {C<:RingElement} L = base_lie_algebra(V) dim_pow_V = binomial(dim(V), k) diff --git a/experimental/LieAlgebras/src/LieAlgebras.jl b/experimental/LieAlgebras/src/LieAlgebras.jl index f6a72817d3e6..192d1b05c7a2 100644 --- a/experimental/LieAlgebras/src/LieAlgebras.jl +++ b/experimental/LieAlgebras/src/LieAlgebras.jl @@ -17,6 +17,7 @@ import ..Oscar: coeff, coefficients, dim, + dual, elem_type, expressify, exterior_power, @@ -43,6 +44,7 @@ export combinations export exterior_power export general_linear_lie_algebra export highest_weight_module +export is_dual export is_exterior_power export is_standard_module export is_symmetric_power diff --git a/experimental/LieAlgebras/test/LieAlgebraModule-test.jl b/experimental/LieAlgebras/test/LieAlgebraModule-test.jl index 438470d5d3af..9f2157836c83 100644 --- a/experimental/LieAlgebras/test/LieAlgebraModule-test.jl +++ b/experimental/LieAlgebras/test/LieAlgebraModule-test.jl @@ -22,6 +22,8 @@ function lie_algebra_module_conformance_test( @test base_ring(v) == base_ring(V) @test elem_type(base_ring(V)) == C + @test base_lie_algebra(V) === L + # this block stays only as long as `ngens` and `gens` are not specialized for Lie algebra modules @test dim(V) == ngens(V) @test basis(V) == gens(V) @@ -202,6 +204,7 @@ end @test length(repr(V)) < 10^4 # outputs tend to be excessively long due to recursion @test is_standard_module(V) + @test !is_dual(V) @test !is_exterior_power(V) @test !is_symmetric_power(V) @test !is_tensor_power(V) @@ -211,6 +214,33 @@ end @test x * v == V(matrix_repr(x) * coefficients(v)) end + @testset "dual" begin + L = special_orthogonal_lie_algebra(QQ, 4) + V = symmetric_power(standard_module(L), 2) + type_V = module_type_bools(V) + + dual_V = dual(V) + @test type_V == module_type_bools(V) # construction of dual_V should not change type of V + @test base_module(dual_V) === V + @test dim(dual_V) == dim(V) + @test length(repr(dual_V)) < 10^4 # outputs tend to be excessively long due to recursion + + @test !is_standard_module(dual_V) + @test is_dual(dual_V) + @test !is_exterior_power(dual_V) + @test !is_symmetric_power(dual_V) + @test !is_tensor_power(dual_V) + + dual_dual_V = dual(dual_V) + @test dim(dual_dual_V) == dim(V) + @test all( + i -> + Oscar.LieAlgebras.transformation_matrix(dual_dual_V, i) == + Oscar.LieAlgebras.transformation_matrix(V, i), + 1:dim(L), + ) + end + @testset "exterior_power" begin L = special_orthogonal_lie_algebra(QQ, 4) V = symmetric_power(standard_module(L), 2) @@ -224,6 +254,7 @@ end @test length(repr(pow_V)) < 10^4 # outputs tend to be excessively long due to recursion @test !is_standard_module(pow_V) + @test !is_dual(V) @test is_exterior_power(pow_V) @test !is_symmetric_power(pow_V) @test !is_tensor_power(pow_V) @@ -256,6 +287,7 @@ end @test length(repr(pow_V)) < 10^4 # outputs tend to be excessively long due to recursion @test !is_standard_module(pow_V) + @test !is_dual(V) @test !is_exterior_power(pow_V) @test is_symmetric_power(pow_V) @test !is_tensor_power(pow_V) @@ -288,6 +320,7 @@ end @test length(repr(pow_V)) < 10^4 # outputs tend to be excessively long due to recursion @test !is_standard_module(pow_V) + @test !is_dual(V) @test !is_exterior_power(pow_V) @test !is_symmetric_power(pow_V) @test is_tensor_power(pow_V)