Skip to content

Commit

Permalink
Serialization refactor (Lie theory part) (#4563)
Browse files Browse the repository at this point in the history
* Use `grading_group` for `MPolyDecRing`

* Fix some formatting

* Some progress

* Fix loading AbstractLieAlgebra

* LinearLieAlgebras working

* Modules working

* Attrs are handled centrally now

* Root system data working

* Module construction data works

* DirectSumLieAlgebras work

* oops

* Run formatter

* Reduce diff
  • Loading branch information
lgoettgens authored Feb 7, 2025
1 parent be1de89 commit e6d0f4a
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 84 deletions.
141 changes: 73 additions & 68 deletions experimental/LieAlgebras/src/serialization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,25 @@ const lie_algebra_serialization_attributes = [

@register_serialization_type AbstractLieAlgebra uses_id lie_algebra_serialization_attributes

type_params(L::AbstractLieAlgebra) = TypeParams(
AbstractLieAlgebra,
:base_ring => coefficient_ring(L),
)

function save_object(s::SerializerState, L::AbstractLieAlgebra)
save_data_dict(s) do
save_typed_object(s, coefficient_ring(L), :base_ring)
save_object(s, _struct_consts(L), :struct_consts)
save_object(s, symbols(L), :symbols)
save_root_system_data(s, L)
save_attrs(s, L)
end
end

function load_object(s::DeserializerState, ::Type{<:AbstractLieAlgebra})
R = load_typed_object(s, :base_ring)
struct_consts = load_object(s, Matrix, (sparse_row_type(R), R), :struct_consts)
symbs = load_object(s, Vector, Symbol, :symbols)
function load_object(s::DeserializerState, ::Type{<:AbstractLieAlgebra}, d::Dict)
R = d[:base_ring]
struct_consts = load_object(s, Matrix{sparse_row_type(R)}, R, :struct_consts)
symbs = load_object(s, Vector{Symbol}, :symbols)
L = lie_algebra(R, struct_consts, symbs; check=false)
load_root_system_data(s, L)
load_attrs(s, L)
return L
end

Expand All @@ -35,46 +37,53 @@ end
[:type, :form]
]

type_params(L::LinearLieAlgebra) = TypeParams(
LinearLieAlgebra,
:base_ring => coefficient_ring(L),
)

function save_object(s::SerializerState, L::LinearLieAlgebra)
save_data_dict(s) do
save_typed_object(s, coefficient_ring(L), :base_ring)
save_object(s, L.n, :n)
save_object(s, matrix_repr_basis(L), :basis)
save_object(s, symbols(L), :symbols)
save_root_system_data(s, L)
save_attrs(s, L)
end
end

function load_object(s::DeserializerState, ::Type{<:LinearLieAlgebra})
R = load_typed_object(s, :base_ring)
function load_object(s::DeserializerState, ::Type{<:LinearLieAlgebra}, d::Dict)
R = d[:base_ring]
n = load_object(s, Int, :n)
basis = load_object(s, Vector, (dense_matrix_type(R), matrix_space(R, n, n)), :basis)
symbs = load_object(s, Vector, Symbol, :symbols)
basis = Vector{dense_matrix_type(R)}(
load_object(s, Vector{dense_matrix_type(R)}, matrix_space(R, n, n), :basis)
) # coercion needed due to https://github.com/oscar-system/Oscar.jl/issues/3983
symbs = load_object(s, Vector{Symbol}, :symbols)
L = lie_algebra(R, n, basis, symbs; check=false)
load_root_system_data(s, L)
load_attrs(s, L)
return L
end

@register_serialization_type DirectSumLieAlgebra uses_id lie_algebra_serialization_attributes

type_params(L::DirectSumLieAlgebra) = TypeParams(
DirectSumLieAlgebra,
:base_ring => coefficient_ring(L),
)

function save_object(s::SerializerState, L::DirectSumLieAlgebra)
save_data_dict(s) do
save_typed_object(s, coefficient_ring(L), :base_ring)
save_data_array(s, :summands) do
for summand in L.summands
ref = save_as_ref(s, summand)
save_object(s, ref)
end
end
save_root_system_data(s, L)
save_attrs(s, L)
end
end

function load_object(s::DeserializerState, ::Type{<:DirectSumLieAlgebra})
R = load_typed_object(s, :base_ring)
function load_object(s::DeserializerState, ::Type{<:DirectSumLieAlgebra}, d::Dict)
R = d[:base_ring]
summands = Vector{LieAlgebra{elem_type(R)}}(
load_array_node(s, :summands) do _
load_ref(s)
Expand All @@ -83,52 +92,41 @@ function load_object(s::DeserializerState, ::Type{<:DirectSumLieAlgebra})

L = direct_sum(R, summands)
load_root_system_data(s, L)
load_attrs(s, L)
return L
end

function save_root_system_data(s::SerializerState, L::LieAlgebra)
if has_root_system(L)
save_typed_object(s, root_system(L), :root_system)
save_object(s, save_as_ref(s, root_system(L)), :root_system)
save_object(s, chevalley_basis(L), :chevalley_basis)
end
end

function load_root_system_data(s::DeserializerState, L::LieAlgebra)
if haskey(s, :root_system)
rs = load_typed_object(s, :root_system)
rs = load_node(_ -> load_ref(s), s, :root_system)
chev = NTuple{3,Vector{elem_type(L)}}(
load_object(
s, Tuple, [(Vector, (AbstractLieAlgebraElem, L)) for _ in 1:3], :chevalley_basis
s, NTuple{3,Vector{elem_type(L)}}, (L, L, L), :chevalley_basis
),
) # coercion needed due to https://github.com/oscar-system/Oscar.jl/issues/3983
set_root_system_and_chevalley_basis!(L, rs, chev)
end
end

@register_serialization_type AbstractLieAlgebraElem uses_params
@register_serialization_type LinearLieAlgebraElem uses_params
@register_serialization_type DirectSumLieAlgebraElem uses_params
@register_serialization_type AbstractLieAlgebraElem
@register_serialization_type LinearLieAlgebraElem
@register_serialization_type DirectSumLieAlgebraElem

type_params(x::T) where {T<:LieAlgebraElem} = TypeParams(T, parent(x))

function save_object(s::SerializerState, x::LieAlgebraElem)
save_object(s, coefficients(x))
end

function load_object(s::DeserializerState, ::Type{<:LieAlgebraElem}, L::LieAlgebra)
return L(load_object(s, Vector, coefficient_ring(L)))
end

function save_type_params(s::SerializerState, x::LieAlgebraElem)
save_data_dict(s) do
save_object(s, encode_type(typeof(x)), :name)
parent_x = parent(x)
parent_ref = save_as_ref(s, parent_x)
save_object(s, parent_ref, :params)
end
end

function load_type_params(s::DeserializerState, ::Type{<:LieAlgebraElem})
return load_typed_object(s)
R = coefficient_ring(L)
return L(load_object(s, Vector{elem_type(R)}, R))
end

###############################################################################
Expand All @@ -139,30 +137,32 @@ end

@register_serialization_type LieAlgebraModule uses_id

type_params(V::LieAlgebraModule) = TypeParams(
LieAlgebraModule,
:lie_algebra => base_lie_algebra(V),
)

function save_object(s::SerializerState, V::LieAlgebraModule)
save_data_dict(s) do
save_typed_object(s, base_lie_algebra(V), :lie_algebra)
save_object(s, dim(V), :dim)
save_object(s, transformation_matrices(V), :transformation_matrices)
save_object(s, symbols(V), :symbols)
save_construction_data(s, V)
save_attrs(s, V)
end
end

function load_object(s::DeserializerState, T::Type{<:LieAlgebraModule})
L = load_typed_object(s, :lie_algebra)
function load_object(s::DeserializerState, T::Type{<:LieAlgebraModule}, d::Dict)
L = d[:lie_algebra]
R = coefficient_ring(L)
dim = load_object(s, Int, :dim)
transformation_matrices = load_object(
s, Vector, (dense_matrix_type(R), matrix_space(R, dim, dim)), :transformation_matrices
s, Vector{dense_matrix_type(R)}, matrix_space(R, dim, dim), :transformation_matrices
)
symbs = load_object(s, Vector, Symbol, :symbols)
symbs = load_object(s, Vector{Symbol}, :symbols)
V = load_construction_data(s, T)
if isnothing(V)
V = abstract_module(L, dim, transformation_matrices, symbs; check=false)
end
load_attrs(s, V)
return V
end

Expand Down Expand Up @@ -192,31 +192,48 @@ function load_construction_data(s::DeserializerState, T::Type{<:LieAlgebraModule
with_attrs(s) && haskey(s, :construction_data) &&
load_node(s, :construction_data) do _
if haskey(s, :is_standard_module)
V = standard_module(load_typed_object(s, :is_standard_module))
L = load_node(s, :is_standard_module) do _
load_ref(s)
end
V = standard_module(L)
elseif haskey(s, :is_dual)
W = load_typed_object(s, :is_dual)
W = load_node(s, :is_dual) do _
load_ref(s)
end
V = dual(W)
elseif haskey(s, :is_direct_sum)
Vs = load_object(s, Vector, LieAlgebraModule, :is_direct_sum)
Vs = load_array_node(s, :is_direct_sum) do _
load_ref(s)
end
V = direct_sum(Vs...)
elseif haskey(s, :is_tensor_product)
Vs = load_object(s, Vector, LieAlgebraModule, :is_tensor_product)
Vs = load_array_node(s, :is_tensor_product) do _
load_ref(s)
end
V = tensor_product(Vs...)
elseif haskey(s, :is_exterior_power)
W, k = load_object(s, Tuple, [LieAlgebraModule, Int], :is_exterior_power)
W, k = load_node(s, :is_exterior_power) do _
(load_node(_ -> load_ref(s), s, 1), load_object(s, Int, 2))
end
V = exterior_power(W, k)[1]
elseif haskey(s, :is_symmetric_power)
W, k = load_object(s, Tuple, [LieAlgebraModule, Int], :is_symmetric_power)
W, k = load_node(s, :is_symmetric_power) do _
(load_node(_ -> load_ref(s), s, 1), load_object(s, Int, 2))
end
V = symmetric_power(W, k)[1]
elseif haskey(s, :is_tensor_power)
W, k = load_object(s, Tuple, [LieAlgebraModule, Int], :is_tensor_power)
W, k = load_node(s, :is_tensor_power) do _
(load_node(_ -> load_ref(s), s, 1), load_object(s, Int, 2))
end
V = tensor_power(W, k)[1]
end
end
return V::Union{T,Nothing}
end

@register_serialization_type LieAlgebraModuleElem uses_params
@register_serialization_type LieAlgebraModuleElem

type_params(x::T) where {T<:LieAlgebraModuleElem} = TypeParams(T, parent(x))

function save_object(s::SerializerState, x::LieAlgebraModuleElem)
save_object(s, coefficients(x))
Expand All @@ -225,18 +242,6 @@ end
function load_object(
s::DeserializerState, ::Type{<:LieAlgebraModuleElem}, V::LieAlgebraModule
)
return V(load_object(s, Vector, coefficient_ring(V)))
end

function save_type_params(s::SerializerState, v::LieAlgebraModuleElem)
save_data_dict(s) do
save_object(s, encode_type(typeof(v)), :name)
parent_x = parent(v)
parent_ref = save_as_ref(s, parent_x)
save_object(s, parent_ref, :params)
end
end

function load_type_params(s::DeserializerState, ::Type{<:LieAlgebraModuleElem})
return load_typed_object(s)
R = coefficient_ring(V)
return V(load_object(s, Vector{elem_type(R)}, R))
end
1 change: 0 additions & 1 deletion src/Serialization/Groups.jl
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ function save_object(s::SerializerState, G::PermGroup)
save_data_dict(s) do
save_object(s, n, :degree)
save_object(s, [Vector{Int}(GAPWrap.ListPerm(GapObj(x))) for x in gens(G)], :gens)
save_attrs(s, G)
end
end

Expand Down
7 changes: 3 additions & 4 deletions src/Serialization/LieTheory.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function load_object(s::DeserializerState, ::Type{RootSystem})
cm = load_object(s, Matrix{Int}, :cartan_matrix)
R = root_system(cm; check=false, detect_type=false)
if haskey(s, :type)
type = load_object(s, Vector{Tuple{Symbol, Int}}, :type)
type = load_object(s, Vector{Tuple{Symbol,Int}}, :type)
if haskey(s, :type_ordering)
type_ordering = load_object(s, Vector{Int}, :type_ordering)
set_root_system_type!(R, type, type_ordering)
Expand All @@ -49,7 +49,6 @@ function load_object(
return T(R, load_object(s, Vector{QQFieldElem}))
end


###############################################################################
#
# Weight lattices
Expand All @@ -71,7 +70,7 @@ function load_object(s::DeserializerState, ::Type{WeightLattice}, R::RootSystem)
return weight_lattice(R)
end

@register_serialization_type WeightLatticeElem
@register_serialization_type WeightLatticeElem

type_params(w::WeightLatticeElem) = TypeParams(WeightLatticeElem, parent(w))

Expand All @@ -94,7 +93,7 @@ end
type_params(W::WeylGroup) = TypeParams(WeylGroup, root_system(W))

function save_object(s::SerializerState, W::WeylGroup)
save_data_dict(s) do
save_data_dict(s) do
# no data required but we leave this function here to generate a valid json
# and leave root for possible future attrs
end
Expand Down
5 changes: 3 additions & 2 deletions src/Serialization/Rings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,9 @@ end
# with grading
type_params(R::MPolyDecRing) = TypeParams(
MPolyDecRing,
:grading_group => parent(_grading(R)[1]), # there may be a way to make this cleaner
:ring => forget_grading(R))
:grading_group => grading_group(R),
:ring => forget_grading(R),
)

function save_object(s::SerializerState, R::MPolyDecRing)
save_data_dict(s) do
Expand Down
2 changes: 1 addition & 1 deletion src/Serialization/containers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ function load_object(s::DeserializerState, T::Type{<:Matrix{S}}, params::Ring) w
m = reduce(vcat, [
permutedims(load_object(s, Vector{S}, params, i)) for i in 1:len
])
return Matrix{elem_type(params)}(m)
return T(m)
end
end

Expand Down
13 changes: 5 additions & 8 deletions src/Serialization/main.jl
Original file line number Diff line number Diff line change
Expand Up @@ -492,34 +492,31 @@ for convenience.
macro import_all_serialization_functions()
return quote
import Oscar:
load_attrs,
load_object,
load_type_params,
save_attrs,
save_object,
save_type_params
type_params

using Oscar:
@register_serialization_type,
DeserializerState,
SerializerState,
TypeParams,
encode_type,
haskey,
load_array_node,
load_attrs,
load_node,
load_ref,
load_typed_object,
save_as_ref,
save_attrs,
save_data_array,
save_data_basic,
save_data_dict,
save_data_json,
save_typed_object,
serialize_with_id,
serialize_with_params,
set_key,
with_attrs,
type_attr_map
with_attrs
end
end

Expand Down

0 comments on commit e6d0f4a

Please sign in to comment.