diff --git a/experimental/LieAlgebras/docs/src/lie_algebras.md b/experimental/LieAlgebras/docs/src/lie_algebras.md index 4fedc32a33ff..244ef204d9c1 100644 --- a/experimental/LieAlgebras/docs/src/lie_algebras.md +++ b/experimental/LieAlgebras/docs/src/lie_algebras.md @@ -21,6 +21,8 @@ dim(::LieAlgebra) basis(::LieAlgebra) basis(::LieAlgebra, ::Int) coefficients(::LieAlgebraElem) +coefficients_sparse(::LieAlgebraElem) +coefficients_dense(::LieAlgebraElem) coeff(::LieAlgebraElem, ::Int) getindex(::LieAlgebraElem, ::Int) symbols(::LieAlgebra) diff --git a/experimental/LieAlgebras/docs/src/modules.md b/experimental/LieAlgebras/docs/src/modules.md index 1a41783076a2..a30225bb75e1 100644 --- a/experimental/LieAlgebras/docs/src/modules.md +++ b/experimental/LieAlgebras/docs/src/modules.md @@ -20,6 +20,8 @@ dim(::LieAlgebraModule) basis(::LieAlgebraModule) basis(::LieAlgebraModule, ::Int) coefficients(::LieAlgebraModuleElem) +coefficients_sparse(::LieAlgebraModuleElem) +coefficients_dense(::LieAlgebraModuleElem) coeff(::LieAlgebraModuleElem, ::Int) getindex(::LieAlgebraModuleElem, ::Int) symbols(::LieAlgebraModule) diff --git a/experimental/LieAlgebras/src/AbstractLieAlgebra.jl b/experimental/LieAlgebras/src/AbstractLieAlgebra.jl index 2959e13728b6..a0b38c504f27 100644 --- a/experimental/LieAlgebras/src/AbstractLieAlgebra.jl +++ b/experimental/LieAlgebras/src/AbstractLieAlgebra.jl @@ -50,7 +50,7 @@ const AbstractLieAlgebraDict = CacheDictType{ struct AbstractLieAlgebraElem{C<:RingElement} <: LieAlgebraElem{C} parent::AbstractLieAlgebra{C} - mat::MatElem{C} + mat::SRow{C} end ############################################################################### @@ -70,6 +70,8 @@ coefficient_ring(L::AbstractLieAlgebra{C}) where {C<:RingElement} = L.R::parent_ dim(L::AbstractLieAlgebra) = L.dim +coefficients_sparse(x::AbstractLieAlgebraElem) = x.mat + ############################################################################### # # String I/O @@ -118,8 +120,8 @@ function bracket( check_parent(x, y) L = parent(x) mat = sum( - cxi * cyj * L.struct_consts[i, j] for (i, cxi) in enumerate(coefficients(x)), - (j, cyj) in enumerate(coefficients(y)); + cxi * cyj * L.struct_consts[i, j] for (i, cxi) in coefficients_sparse(x), + (j, cyj) in coefficients_sparse(y); init=sparse_row(coefficient_ring(L)), ) return L(mat) @@ -256,7 +258,7 @@ function lie_algebra( end struct_consts = Matrix{SRow{elem_type(R)}}(undef, length(basis), length(basis)) for (i, bi) in enumerate(basis), (j, bj) in enumerate(basis) - fl, row = can_solve_with_solution(basis_matrix, _matrix(bi * bj); side=:left) + fl, row = can_solve_with_solution(basis_matrix, coefficients_row(bi * bj); side=:left) @req fl "Not closed under the bracket." struct_consts[i, j] = sparse_row(row) end diff --git a/experimental/LieAlgebras/src/LieAlgebra.jl b/experimental/LieAlgebras/src/LieAlgebra.jl index 1a5041fba620..da4380ca9cba 100644 --- a/experimental/LieAlgebras/src/LieAlgebra.jl +++ b/experimental/LieAlgebras/src/LieAlgebra.jl @@ -14,6 +14,7 @@ abstract type LieAlgebraElem{C<:RingElement} end # parent(x::MyLieAlgebraElem{C}) # coefficient_ring(L::MyLieAlgebra{C}) # dim(L::MyLieAlgebra{C}) +# coefficients_sparse(x::LieAlgebraElem{C}) # Base.show(io::IO, x::MyLieAlgebra{C}) # symbols(L::MyLieAlgebra{C}) # bracket(x::MyLieAlgebraElem{C}, y::MyLieAlgebraElem{C}) @@ -63,8 +64,7 @@ end Return the zero element of the Lie algebra `L`. """ function zero(L::LieAlgebra) - mat = zero_matrix(coefficient_ring(L), 1, dim(L)) - return elem_type(L)(L, mat) + return L(sparse_row(coefficient_ring(L))) end @doc raw""" @@ -73,11 +73,25 @@ end Check whether the Lie algebra element `x` is zero. """ function iszero(x::LieAlgebraElem) - return iszero(coefficients(x)) + return iszero(coefficients_sparse(x)) end -@inline function _matrix(x::LieAlgebraElem{C}) where {C<:RingElement} - return (x.mat)::dense_matrix_type(C) +@doc raw""" + coefficients_sparse(x::LieAlgebraElem{C}) -> SRow{C} + +Return the coefficients of `x` with respect to [`basis(::LieAlgebra)`](@ref) +as a sparse row. This is the fastes access to the coefficients of `x`. +""" +coefficients_sparse(_::LieAlgebraElem) = error("Should be implemented by subtypes.") + +@doc raw""" + coefficients_sparse(x::LieAlgebraElem{C}) -> MatElem{C} + +Return the coefficients of `x` with respect to [`basis(::LieAlgebra)`](@ref) +as a dense row, i.e. a $1 \times \dim(L)$ matrix +""" +function coefficients_dense(x::LieAlgebraElem) + return dense_row(coefficients_sparse(x), dim(parent(x))) end @doc raw""" @@ -86,7 +100,7 @@ end Return the coefficients of `x` with respect to [`basis(::LieAlgebra)`](@ref). """ function coefficients(x::LieAlgebraElem) - return collect(_matrix(x))[1, :] + return Vector(coefficients_sparse(x), dim(parent(x))) end @doc raw""" @@ -95,7 +109,7 @@ end Return the `i`-th coefficient of `x` with respect to [`basis(::LieAlgebra)`](@ref). """ function coeff(x::LieAlgebraElem, i::Int) - return _matrix(x)[1, i] + return coefficients_sparse(x)[i] end @doc raw""" @@ -108,7 +122,7 @@ function getindex(x::LieAlgebraElem, i::Int) end function Base.deepcopy_internal(x::LieAlgebraElem, dict::IdDict) - return parent(x)(deepcopy_internal(_matrix(x), dict)) + return parent(x)(deepcopy_internal(coefficients_sparse(x), dict)) end function check_parent(x1::LieAlgebraElem{C}, x2::LieAlgebraElem{C}) where {C<:RingElement} @@ -130,7 +144,7 @@ symbols(_::LieAlgebra) = error("Should be implemented by subtypes.") function expressify(v::LieAlgebraElem, s=symbols(parent(v)); context=nothing) sum = Expr(:call, :+) - for (i, c) in enumerate(coefficients(v)) + for (i, c) in coefficients_sparse(v) push!(sum.args, Expr(:call, :*, expressify(c; context=context), s[i])) end return sum @@ -171,7 +185,7 @@ Return the element of `L` with coefficient vector `v`. function (L::LieAlgebra{C})(v::Vector{C}) where {C<:RingElement} @req length(v) == dim(L) "Length of vector does not match dimension." mat = matrix(coefficient_ring(L), 1, length(v), v) - return elem_type(L)(L, mat) + return L(mat) end @doc raw""" @@ -181,8 +195,8 @@ Return the element of `L` with coefficient vector equivalent to the $1 \times \dim(L)$ matrix `mat`. """ function (L::LieAlgebra{C})(mat::MatElem{C}) where {C<:RingElement} - @req size(mat) == (1, dim(L)) "Invalid matrix dimensions." - return elem_type(L)(L, mat) + @req size(mat) == (1, dim(L)) "Invalid dimensions." + return L(sparse_row(mat)) end @doc raw""" @@ -191,8 +205,7 @@ end Return the element of `L` with coefficient vector `v`. """ function (L::LieAlgebra{C})(v::SRow{C}) where {C<:RingElement} - mat = dense_row(v, dim(L)) - return elem_type(L)(L, mat) + return elem_type(L)(L, v) end @doc raw""" @@ -212,43 +225,43 @@ end ############################################################################### function Base.:-(x::LieAlgebraElem{C}) where {C<:RingElement} - return parent(x)(-_matrix(x)) + return parent(x)(-coefficients_sparse(x)) end function Base.:+(x1::LieAlgebraElem{C}, x2::LieAlgebraElem{C}) where {C<:RingElement} check_parent(x1, x2) - return parent(x1)(_matrix(x1) + _matrix(x2)) + return parent(x1)(coefficients_sparse(x1) + coefficients_sparse(x2)) end function Base.:-(x1::LieAlgebraElem{C}, x2::LieAlgebraElem{C}) where {C<:RingElement} check_parent(x1, x2) - return parent(x1)(_matrix(x1) - _matrix(x2)) + return parent(x1)(coefficients_sparse(x1) - coefficients_sparse(x2)) end function Base.:*(x::LieAlgebraElem{C}, c::C) where {C<:RingElem} coefficient_ring(x) != parent(c) && error("Incompatible rings.") - return parent(x)(_matrix(x) * c) + return parent(x)(coefficients_sparse(x) * c) end function Base.:*(x::LieAlgebraElem, c::U) where {U<:Union{Rational,IntegerUnion}} - return parent(x)(_matrix(x) * c) + return parent(x)(coefficients_sparse(x) * c) end function Base.:*(x::LieAlgebraElem{ZZRingElem}, c::ZZRingElem) - return parent(x)(_matrix(x) * c) + return parent(x)(coefficients_sparse(x) * c) end function Base.:*(c::C, x::LieAlgebraElem{C}) where {C<:RingElem} coefficient_ring(x) != parent(c) && error("Incompatible rings.") - return parent(x)(c * _matrix(x)) + return parent(x)(c * coefficients_sparse(x)) end function Base.:*(c::U, x::LieAlgebraElem) where {U<:Union{Rational,IntegerUnion}} - return parent(x)(c * _matrix(x)) + return parent(x)(c * coefficients_sparse(x)) end function Base.:*(c::ZZRingElem, x::LieAlgebraElem{ZZRingElem}) - return parent(x)(c * _matrix(x)) + return parent(x)(c * coefficients_sparse(x)) end function Base.:*(x::LieAlgebraElem{C}, y::LieAlgebraElem{C}) where {C<:RingElement} @@ -263,13 +276,13 @@ end function Base.:(==)(x1::LieAlgebraElem{C}, x2::LieAlgebraElem{C}) where {C<:RingElement} check_parent(x1, x2) - return coefficients(x1) == coefficients(x2) + return coefficients_sparse(x1) == coefficients_sparse(x2) end function Base.hash(x::LieAlgebraElem, h::UInt) b = 0x6724cbedbd860982 % UInt h = hash(parent(x), h) - h = hash(coefficients(x), h) + h = hash(coefficients_sparse(x), h) return xor(h, b) end @@ -300,7 +313,7 @@ function center(L::LieAlgebra) mat = zero_matrix(coefficient_ring(L), dim(L), dim(L)^2) for (i, bi) in enumerate(basis(L)) for (j, bj) in enumerate(basis(L)) - mat[i, ((j - 1) * dim(L) + 1):(j * dim(L))] = _matrix(bi * bj) + mat[i, ((j - 1) * dim(L) + 1):(j * dim(L))] = coefficients_dense(bi * bj) end end @@ -319,7 +332,7 @@ function centralizer(L::LieAlgebra, xs::AbstractVector{<:LieAlgebraElem}) mat = zero_matrix(coefficient_ring(L), dim(L), dim(L) * length(xs)) for (i, bi) in enumerate(basis(L)) for (j, xj) in enumerate(xs) - mat[i, ((j - 1) * dim(L) + 1):(j * dim(L))] = _matrix(bracket(bi, xj)) + mat[i, ((j - 1) * dim(L) + 1):(j * dim(L))] = coefficients_dense(bracket(bi, xj)) end end @@ -392,7 +405,7 @@ Return `true` if `L` is abelian, i.e. $[L, L] = 0$. @attr Bool function is_abelian(L::LieAlgebra) b = basis(L) n = length(b) - return all(iszero, b[i] * b[j] for i in 1:n for j in i+1:n) + return all(iszero, b[i] * b[j] for i in 1:n for j in (i + 1):n) end @doc raw""" @@ -453,7 +466,7 @@ function universal_enveloping_algebra(L::LieAlgebra; ordering::Symbol=:lex) b = basis(L) to_R(x::LieAlgebraElem) = - sum(c * g for (c, g) in zip(coefficients(x), gensR); init=zero(R)) + sum(c * gensR[i] for (i, c) in coefficients_sparse(x); init=zero(R)) rel = strictly_upper_triangular_matrix([ to_R(b[i]) * to_R(b[j]) - to_R(b[i] * b[j]) for i in 1:(n - 1) for j in (i + 1):n @@ -462,7 +475,7 @@ function universal_enveloping_algebra(L::LieAlgebra; ordering::Symbol=:lex) L_to_U = MapFromFunc( L, U, function (x::LieAlgebraElem) - sum(c * g for (c, g) in zip(coefficients(x), gensU); init=zero(U)) + sum(c * gensU[i] for (i, c) in coefficients_sparse(x); init=zero(U)) end ) return U, L_to_U diff --git a/experimental/LieAlgebras/src/LieAlgebraHom.jl b/experimental/LieAlgebras/src/LieAlgebraHom.jl index cbd78e90e3a3..3a8d1dd1badf 100644 --- a/experimental/LieAlgebras/src/LieAlgebraHom.jl +++ b/experimental/LieAlgebras/src/LieAlgebraHom.jl @@ -14,7 +14,7 @@ mat = zero_matrix(coefficient_ring(L2), dim(L1), dim(L2)) for (i, img) in enumerate(imgs) - mat[i, :] = _matrix(img) + mat[i, :] = coefficients_dense(img) end return LieAlgebraHom(L1, L2, mat; check) end @@ -121,7 +121,7 @@ Return the image of `x` under `h`. """ function image(h::LieAlgebraHom, x::LieAlgebraElem) @req parent(x) === domain(h) "Domain mismatch" - return codomain(h)(_matrix(x) * matrix(h)) + return codomain(h)(coefficients_dense(x) * matrix(h)) end @doc raw""" diff --git a/experimental/LieAlgebras/src/LieAlgebraIdeal.jl b/experimental/LieAlgebras/src/LieAlgebraIdeal.jl index 3aa17b358a78..c57d9b680afd 100644 --- a/experimental/LieAlgebras/src/LieAlgebraIdeal.jl +++ b/experimental/LieAlgebras/src/LieAlgebraIdeal.jl @@ -23,11 +23,11 @@ left = copy(gens) while !isempty(left) g = pop!(left) - can_solve(basis_matrix, _matrix(g); side=:left) && continue + can_solve(basis_matrix, coefficients_dense(g); side=:left) && continue for b in basis(L) push!(left, b * g) end - basis_matrix = vcat(basis_matrix, _matrix(g)) + basis_matrix = vcat(basis_matrix, coefficients_dense(g)) rank = rref!(basis_matrix) basis_matrix = basis_matrix[1:rank, :] end @@ -163,7 +163,7 @@ end Return `true` if `x` is in the ideal `I`, `false` otherwise. """ function Base.in(x::LieAlgebraElem, I::LieAlgebraIdeal) - return can_solve(basis_matrix(I), _matrix(x); side=:left) + return can_solve(basis_matrix(I), coefficients_dense(x); side=:left) end ############################################################################### diff --git a/experimental/LieAlgebras/src/LieAlgebraModule.jl b/experimental/LieAlgebras/src/LieAlgebraModule.jl index 933e86c11413..5173c16e2115 100644 --- a/experimental/LieAlgebras/src/LieAlgebraModule.jl +++ b/experimental/LieAlgebras/src/LieAlgebraModule.jl @@ -28,7 +28,7 @@ end struct LieAlgebraModuleElem{C<:RingElement} parent::LieAlgebraModule{C} - mat::MatElem{C} + mat::SRow{C} end ############################################################################### @@ -91,8 +91,7 @@ end Return the zero element of the Lie algebra module `V`. """ function zero(V::LieAlgebraModule) - mat = zero_matrix(coefficient_ring(V), 1, dim(V)) - return elem_type(V)(V, mat) + return V(sparse_row(coefficient_ring(V))) end @doc raw""" @@ -101,11 +100,27 @@ end Check whether the Lie algebra module element `v` is zero. """ function iszero(v::LieAlgebraModuleElem) - return iszero(coefficients(v)) + return iszero(coefficients_sparse(v)) end -@inline function _matrix(v::LieAlgebraModuleElem{C}) where {C<:RingElement} - return (v.mat)::dense_matrix_type(C) +@doc raw""" + coefficients_sparse(v::LieAlgebraElem{C}) -> SRow{C} + +Return the coefficients of `v` with respect to [`basis(::LieAlgebraModule)`](@ref) +as a sparse row. This is the fastes access to the coefficients of `v`. +""" +function coefficients_sparse(v::LieAlgebraModuleElem) + return v.mat +end + +@doc raw""" + coefficients_sparse(v::LieAlgebraElem{C}) -> MatElem{C} + +Return the coefficients of `v` with respect to [`basis(::LieAlgebraModule)`](@ref) +as a dense row, i.e. a $1 \times \dim(V)$ matrix +""" +function coefficients_dense(v::LieAlgebraModuleElem) + return dense_row(coefficients_sparse(v), dim(parent(v))) end @doc raw""" @@ -114,7 +129,7 @@ end Return the coefficients of `v` with respect to [`basis(::LieAlgebraModule)`](@ref). """ function coefficients(v::LieAlgebraModuleElem) - return collect(_matrix(v))[1, :] + return Vector(coefficients_sparse(v), dim(parent(v))) end @doc raw""" @@ -123,7 +138,7 @@ end Return the `i`-th coefficient of `v` with respect to [`basis(::LieAlgebraModule)`](@ref). """ function coeff(v::LieAlgebraModuleElem, i::Int) - return _matrix(v)[1, i] + return coefficients_sparse(v)[i] end @doc raw""" @@ -136,7 +151,7 @@ function getindex(v::LieAlgebraModuleElem, i::Int) end function Base.deepcopy_internal(v::LieAlgebraModuleElem, dict::IdDict) - return parent(v)(deepcopy_internal(_matrix(v), dict)) + return parent(v)(deepcopy_internal(coefficients_sparse(v), dict)) end function check_parent( @@ -257,7 +272,7 @@ end function expressify(v::LieAlgebraModuleElem, s=symbols(parent(v)); context=nothing) sum = Expr(:call, :+) - for (i, c) in enumerate(coefficients(v)) + for (i, c) in coefficients_sparse(v) push!(sum.args, Expr(:call, :*, expressify(c; context=context), s[i])) end return sum @@ -298,7 +313,7 @@ Return the element of `V` with coefficient vector `v`. function (V::LieAlgebraModule{C})(v::Vector{C}) where {C<:RingElement} @req length(v) == dim(V) "Length of vector does not match dimension." mat = matrix(coefficient_ring(V), 1, length(v), v) - return elem_type(V)(V, mat) + return V(mat) end @doc raw""" @@ -307,10 +322,9 @@ end Return the element of `V` with coefficient vector equivalent to the $1 \times \dim(L)$ matrix `mat`. """ -function (V::LieAlgebraModule{C})(v::MatElem{C}) where {C<:RingElement} - @req ncols(v) == dim(V) "Length of vector does not match dimension" - @req nrows(v) == 1 "Not a vector in module constructor" - return elem_type(V)(V, v) +function (V::LieAlgebraModule{C})(mat::MatElem{C}) where {C<:RingElement} + @req size(mat) == (1, dim(V)) "Invalid dimensions." + return V(sparse_row(mat)) end @doc raw""" @@ -319,8 +333,7 @@ end Return the element of `V` with coefficient vector `v`. """ function (V::LieAlgebraModule{C})(v::SRow{C}) where {C<:RingElement} - mat = dense_row(v, dim(V)) - return elem_type(V)(V, mat) + return elem_type(V)(V, v) end @doc raw""" @@ -332,7 +345,7 @@ If `V` is the dual module of the parent of `v`, return the dual of `v`. """ function (V::LieAlgebraModule{C})(v::LieAlgebraModuleElem{C}) where {C<:RingElement} if is_dual(V) && base_module(V) === parent(v) - return V(coefficients(v)) + return V(coefficients_sparse(v)) end @req V === parent(v) "Incompatible modules." return v @@ -390,47 +403,47 @@ end ############################################################################### function Base.:-(v::LieAlgebraModuleElem{C}) where {C<:RingElement} - return parent(v)(-_matrix(v)) + return parent(v)(-coefficients_sparse(v)) end function Base.:+( v1::LieAlgebraModuleElem{C}, v2::LieAlgebraModuleElem{C} ) where {C<:RingElement} check_parent(v1, v2) - return parent(v1)(_matrix(v1) + _matrix(v2)) + return parent(v1)(coefficients_sparse(v1) + coefficients_sparse(v2)) end function Base.:-( v1::LieAlgebraModuleElem{C}, v2::LieAlgebraModuleElem{C} ) where {C<:RingElement} check_parent(v1, v2) - return parent(v1)(_matrix(v1) - _matrix(v2)) + return parent(v1)(coefficients_sparse(v1) - coefficients_sparse(v2)) end function Base.:*(v::LieAlgebraModuleElem{C}, c::C) where {C<:RingElem} coefficient_ring(v) != parent(c) && error("Incompatible rings.") - return parent(v)(_matrix(v) * c) + return parent(v)(coefficients_sparse(v) * c) end function Base.:*(v::LieAlgebraModuleElem, c::U) where {U<:Union{Rational,IntegerUnion}} - return parent(v)(_matrix(v) * c) + return parent(v)(coefficients_sparse(v) * c) end function Base.:*(v::LieAlgebraModuleElem{ZZRingElem}, c::ZZRingElem) - return parent(v)(_matrix(v) * c) + return parent(v)(coefficients_sparse(v) * c) end function Base.:*(c::C, v::LieAlgebraModuleElem{C}) where {C<:RingElem} coefficient_ring(v) != parent(c) && error("Incompatible rings.") - return parent(v)(c * _matrix(v)) + return parent(v)(c * coefficients_sparse(v)) end function Base.:*(c::U, v::LieAlgebraModuleElem) where {U<:Union{Rational,IntegerUnion}} - return parent(v)(c * _matrix(v)) + return parent(v)(c * coefficients_sparse(v)) end function Base.:*(c::ZZRingElem, v::LieAlgebraModuleElem{ZZRingElem}) - return parent(v)(c * _matrix(v)) + return parent(v)(c * coefficients_sparse(v)) end ############################################################################### @@ -459,13 +472,13 @@ function Base.:(==)( v1::LieAlgebraModuleElem{C}, v2::LieAlgebraModuleElem{C} ) where {C<:RingElement} check_parent(v1, v2) - return coefficients(v1) == coefficients(v2) + return coefficients_sparse(v1) == coefficients_sparse(v2) end function Base.hash(v::LieAlgebraModuleElem, h::UInt) b = 0x723913014484513a % UInt h = hash(parent(v), h) - h = hash(coefficients(v), h) + h = hash(coefficients_sparse(v), h) return xor(h, b) end @@ -488,13 +501,12 @@ end function action(x::LieAlgebraElem{C}, v::LieAlgebraModuleElem{C}) where {C<:RingElement} @req parent(x) === base_lie_algebra(parent(v)) "Incompatible Lie algebras." - cx = coefficients(x) + cx = coefficients_sparse(x) V = parent(v) return V( sum( - cx[i] * _matrix(v) * transformation_matrix(V, i) for - i in 1:dim(parent(x)) if !iszero(cx[i]); - init=zero_matrix(coefficient_ring(V), 1, dim(V))::dense_matrix_type(C), + c * coefficients_dense(v) * transformation_matrix(V, i) for (i, c) in cx; + init=zero_matrix(coefficient_ring(V), 1, dim(V)), ), ) end diff --git a/experimental/LieAlgebras/src/LieAlgebraModuleHom.jl b/experimental/LieAlgebras/src/LieAlgebraModuleHom.jl index 323e0a3582ba..ba9b04753b48 100644 --- a/experimental/LieAlgebras/src/LieAlgebraModuleHom.jl +++ b/experimental/LieAlgebras/src/LieAlgebraModuleHom.jl @@ -17,7 +17,7 @@ mat = zero_matrix(coefficient_ring(V2), dim(V1), dim(V2)) for (i, img) in enumerate(imgs) - mat[i, :] = _matrix(img) + mat[i, :] = coefficients_dense(img) end return LieAlgebraModuleHom(V1, V2, mat; check) end @@ -130,7 +130,7 @@ function image( h::LieAlgebraModuleHom{T1,T2}, v::LieAlgebraModuleElem ) where {T1<:LieAlgebraModule,T2<:LieAlgebraModule} @req parent(v) === domain(h) "Domain mismatch" - return codomain(h)(_matrix(v) * matrix(h)) + return codomain(h)(coefficients_dense(v) * matrix(h)) end # TODO: image and kernel, once submodules are implemented diff --git a/experimental/LieAlgebras/src/LieAlgebras.jl b/experimental/LieAlgebras/src/LieAlgebras.jl index 37067f8e5a9c..b874b68ad6ae 100644 --- a/experimental/LieAlgebras/src/LieAlgebras.jl +++ b/experimental/LieAlgebras/src/LieAlgebras.jl @@ -78,6 +78,8 @@ export base_module export base_modules export bracket export coefficient_vector +export coefficients_dense +export coefficients_sparse export coerce_to_lie_algebra_elem export combinations export derived_algebra diff --git a/experimental/LieAlgebras/src/LieSubalgebra.jl b/experimental/LieAlgebras/src/LieSubalgebra.jl index ae4927c240ca..96549c2ad8c5 100644 --- a/experimental/LieAlgebras/src/LieSubalgebra.jl +++ b/experimental/LieAlgebras/src/LieSubalgebra.jl @@ -23,11 +23,11 @@ left = copy(gens) while !isempty(left) g = pop!(left) - can_solve(basis_matrix, _matrix(g); side=:left) && continue + can_solve(basis_matrix, coefficients_dense(g); side=:left) && continue for i in 1:nrows(basis_matrix) push!(left, g * L(basis_matrix[i, :])) end - basis_matrix = vcat(basis_matrix, _matrix(g)) + basis_matrix = vcat(basis_matrix, coefficients_dense(g)) rank = rref!(basis_matrix) basis_matrix = basis_matrix[1:rank, :] end @@ -162,7 +162,7 @@ end Return `true` if `x` is in the Lie subalgebra `S`, `false` otherwise. """ function Base.in(x::LieAlgebraElem, S::LieSubalgebra) - return can_solve(basis_matrix(S), _matrix(x); side=:left) + return can_solve(basis_matrix(S), coefficients_dense(x); side=:left) end ############################################################################### @@ -207,7 +207,7 @@ function normalizer(L::LieAlgebra, S::LieSubalgebra) mat = zero_matrix(coefficient_ring(L), dim(L) + dim(S)^2, dim(L) * dim(S)) for (i, bi) in enumerate(basis(L)) for (j, sj) in enumerate(basis(S)) - mat[i, ((j - 1) * dim(L) + 1):(j * dim(L))] = _matrix(bracket(bi, sj)) + mat[i, ((j - 1) * dim(L) + 1):(j * dim(L))] = coefficients_dense(bracket(bi, sj)) end end for i in 1:dim(S) diff --git a/experimental/LieAlgebras/src/LinearLieAlgebra.jl b/experimental/LieAlgebras/src/LinearLieAlgebra.jl index 34008ca7d8c8..403a0637a680 100644 --- a/experimental/LieAlgebras/src/LinearLieAlgebra.jl +++ b/experimental/LieAlgebras/src/LinearLieAlgebra.jl @@ -37,7 +37,7 @@ const LinearLieAlgebraDict = CacheDictType{ struct LinearLieAlgebraElem{C<:RingElement} <: LieAlgebraElem{C} parent::LinearLieAlgebra{C} - mat::MatElem{C} + mat::SRow{C} end ############################################################################### @@ -56,6 +56,8 @@ coefficient_ring(L::LinearLieAlgebra{C}) where {C<:RingElement} = L.R::parent_ty dim(L::LinearLieAlgebra) = L.dim +coefficients_sparse(x::LinearLieAlgebraElem) = x.mat + @doc raw""" matrix_repr_basis(L::LinearLieAlgebra{C}) -> Vector{MatElem{C}} @@ -167,7 +169,7 @@ Return the Lie algebra element `x` in the underlying matrix representation. function Generic.matrix_repr(x::LinearLieAlgebraElem) L = parent(x) return sum( - c * b for (c, b) in zip(_matrix(x), matrix_repr_basis(L)); + c * matrix_repr_basis(L, i) for (i, c) in coefficients_sparse(x); init=zero_matrix(coefficient_ring(L), L.n, L.n), ) end diff --git a/experimental/LieAlgebras/src/iso_oscar_gap.jl b/experimental/LieAlgebras/src/iso_oscar_gap.jl index c3e6a31427fa..d6cee8627c20 100644 --- a/experimental/LieAlgebras/src/iso_oscar_gap.jl +++ b/experimental/LieAlgebras/src/iso_oscar_gap.jl @@ -41,7 +41,7 @@ function _iso_oscar_gap(LO::AbstractLieAlgebra) [ [ begin - pairs = filter(pair -> !iszero(last(pair)), collect(enumerate(_matrix(xi * xj)))) + pairs = filter(pair -> !iszero(last(pair)), collect(coefficients_sparse(xi * xj))) (map(first, pairs), GAP.Obj[coeffs_iso(c) for c in map(last, pairs)]) end for xj in basis(LO) ] for xi in basis(LO) diff --git a/experimental/LieAlgebras/test/LieAlgebra-test.jl b/experimental/LieAlgebras/test/LieAlgebra-test.jl index 7970ea183ca3..eeafe951edf0 100644 --- a/experimental/LieAlgebras/test/LieAlgebra-test.jl +++ b/experimental/LieAlgebras/test/LieAlgebra-test.jl @@ -29,6 +29,10 @@ function lie_algebra_conformance_test( @test iszero(zero(L)) @test coefficients(x) == [coeff(x, i) for i in 1:dim(L)] + @test Oscar.coefficients_dense(x) == dense_row(Oscar.coefficients_sparse(x), dim(L)) + @test Oscar.coefficients_sparse(x) == sparse_row(Oscar.coefficients_dense(x)) + @test coefficients(x) == Vector(Oscar.coefficients_sparse(x), dim(L)) + @test coefficients(x) == Array(Oscar.coefficients_dense(x))[1, :] @test all(i -> coeff(x, i) == x[i], 1:dim(L)) @test sum(x[i] * basis(L, i) for i in 1:dim(L); init=zero(L)) == x diff --git a/experimental/LieAlgebras/test/LieAlgebraModule-test.jl b/experimental/LieAlgebras/test/LieAlgebraModule-test.jl index f9d17df5d7ae..e138d9d6981f 100644 --- a/experimental/LieAlgebras/test/LieAlgebraModule-test.jl +++ b/experimental/LieAlgebras/test/LieAlgebraModule-test.jl @@ -35,6 +35,10 @@ function lie_algebra_module_conformance_test( @test iszero(zero(V)) @test coefficients(v) == [coeff(v, i) for i in 1:dim(V)] + @test Oscar.coefficients_dense(v) == dense_row(Oscar.coefficients_sparse(v), dim(V)) + @test Oscar.coefficients_sparse(v) == sparse_row(Oscar.coefficients_dense(v)) + @test coefficients(v) == Vector(Oscar.coefficients_sparse(v), dim(V)) + @test coefficients(v) == Array(Oscar.coefficients_dense(v))[1, :] @test all(i -> coeff(v, i) == v[i], 1:dim(V)) @test sum(v[i] * basis(V, i) for i in 1:dim(V); init=zero(V)) == v @@ -217,7 +221,7 @@ end ) @testset "standard_module" begin - L = special_orthogonal_lie_algebra(QQ, 4) + L = special_linear_lie_algebra(QQ, 4) V = standard_module(L) @test dim(V) == 4 @test length(repr(V)) < 10^4 # outputs tend to be excessively long due to recursion @@ -226,7 +230,7 @@ end x = L(rand(-10:10, dim(L))) v = V(rand(-10:10, dim(V))) - @test x * v == V(matrix_repr(x) * coefficients(v)) + @test x * v == V(transpose(matrix_repr(x) * transpose(Oscar.coefficients_dense(v)))) end @testset "dual" begin @@ -446,9 +450,7 @@ end dimV = dim(V) struct_const_V = Matrix{Vector{Tuple{elem_type(R),Int}}}(undef, dimL, dimV) for (i, xi) in enumerate(basis(L)), (j, vj) in enumerate(basis(V)) - struct_const_V[i, j] = [ - (c, k) for (k, c) in enumerate(coefficients(xi * vj)) if !iszero(c) - ] + struct_const_V[i, j] = [(c, k) for (k, c) in Oscar.coefficients_sparse(xi * vj)] end return struct_const_V end diff --git a/experimental/LieAlgebras/test/LinearLieAlgebra-test.jl b/experimental/LieAlgebras/test/LinearLieAlgebra-test.jl index 8ff1da2ab3a9..c7eb3a573539 100644 --- a/experimental/LieAlgebras/test/LinearLieAlgebra-test.jl +++ b/experimental/LieAlgebras/test/LinearLieAlgebra-test.jl @@ -76,9 +76,7 @@ dimL = dim(L) struct_const_L = Matrix{Vector{Tuple{elem_type(R),Int}}}(undef, dimL, dimL) for (i, xi) in enumerate(basis(L)), (j, xj) in enumerate(basis(L)) - struct_const_L[i, j] = [ - (c, k) for (k, c) in enumerate(coefficients(xi * xj)) if !iszero(c) - ] + struct_const_L[i, j] = [(c, k) for (k, c) in Oscar.coefficients_sparse(xi * xj)] end return struct_const_L end