Skip to content

Commit

Permalink
Some advances on serialization.
Browse files Browse the repository at this point in the history
  • Loading branch information
HechtiDerLachs committed Sep 18, 2024
1 parent c51813c commit 5e0aa27
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 6 deletions.
14 changes: 11 additions & 3 deletions src/Serialization/MPolyMap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,33 @@ function load_type_params(s::DeserializerState, ::Type{<:MPolyAnyMap})
return (d, c)
end

function save_object(s::SerializerState, phi::MPolyAnyMap)
function save_object(s::SerializerState{T}, phi::MPolyAnyMap) where {T}
save_data_dict(s) do
save_object(s, _images(phi), :images)

cm = coefficient_map(phi)

@req _check_whether_this_is_admissible_serialization(typeof(cm), T) "the type of the coefficient map is not supported for long term storage"
if !isnothing(cm)
save_object(s, cm, :coeff_map)
end
end
end

_check_whether_this_is_admissible_serialization(::Type{CMType}, ::Type{SerializeParam}) where {CMType, SerializeParam <: OscarSerializer} = false
_check_whether_this_is_admissible_serialization(::Type{Nothing}, ::Type{SerializeParam}) where {SerializeParam <: OscarSerializer} = true
# TODO This list can be extended for more types of coefficient maps if needed
_check_whether_this_is_admissible_serialization(::Type{CMType}, ::Type{SerializeParam}) where {CMType, SerializeParam <: IPCSerializer} = true

function load_object(s::DeserializerState, ::Type{<:MPolyAnyMap},
params::Tuple{MPolyRing, MPolyRing})
params::Tuple{<:Union{<:MPolyRing, <:MPolyQuoRing}, <:Ring}
)
d = params[1]
c = params[2]
imgs = load_object(s, Vector, c, :images)

if haskey(s, :coeff_map)
throw("MPolyAnyMap with coefficient map serialization unimplemented")
return hom(d, c, load_object(s, :coeff_map), img_gens)
end
return MPolyAnyMap(d, c, nothing, imgs)
end
109 changes: 106 additions & 3 deletions src/Serialization/Rings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -287,14 +287,21 @@ end

@register_serialization_type MPolyIdeal uses_params
@register_serialization_type LaurentMPolyIdeal uses_params
@register_serialization_type MPolyLocalizedIdeal uses_params
@register_serialization_type MPolyQuoLocalizedIdeal uses_params
@register_serialization_type MPolyQuoIdeal uses_params

# we should avoid this list getting too long and find a
# way to abstract saving params soon
const IdealOrdUnionType = Union{MPolyIdeal,
LaurentMPolyIdeal,
FreeAssociativeAlgebraIdeal,
IdealGens,
MonomialOrdering}
MonomialOrdering,
MPolyLocalizedIdeal,
MPolyQuoLocalizedIdeal,
MPolyQuoIdeal
}

function save_type_params(s::SerializerState, x::T) where T <: IdealOrdUnionType
save_data_dict(s) do
Expand Down Expand Up @@ -779,7 +786,7 @@ end

function load_object(s::DeserializerState, ::Type{<:MPolyPowersOfElement})
R = load_typed_object(s, :ring)
dens = load_typed_object(s, :dens)
dens = Vector{elem_type(R)}(load_typed_object(s, :dens)) # casting is necessary for empty arrays
return MPolyPowersOfElement(R, dens)
end

Expand Down Expand Up @@ -847,6 +854,102 @@ function load_object(s::DeserializerState, ::Type{<:MPolyLocRingElem}, prts::Vec
RET = elem_type(P)
num = load_object(s, RET, P, 1)
den = load_object(s, RET, P, 2)
return L(num, den)
return L(num, den; check=false)
end

@register_serialization_type MPolyQuoLocRing uses_id

function save_object(s::SerializerState, L::MPolyQuoLocRing)
save_data_dict(s) do
save_typed_object(s, underlying_quotient(L), :quo_ring)
save_typed_object(s, inverted_set(L), :inv_set)
end
end

function load_object(s::DeserializerState, ::Type{<:MPolyQuoLocRing})
Q = load_typed_object(s, :quo_ring)
U = load_typed_object(s, :inv_set)
return MPolyQuoLocRing(base_ring(Q), modulus(Q), U)
end

@register_serialization_type MPolyQuoLocRingElem uses_params

function save_object(s::SerializerState, a::MPolyQuoLocRingElem)
save_data_array(s) do
save_object(s, lifted_numerator(a))
save_object(s, lifted_denominator(a))
end
end

function load_object(s::DeserializerState, ::Type{<:MPolyQuoLocRingElem}, prts::Vector)
L = prts[end]::MPolyQuoLocRing
P = base_ring(L)
RET = elem_type(P)
num = load_object(s, RET, P, 1)
den = load_object(s, RET, P, 2)
return L(num, den; check=false)
end

### Morphisms of the four types of rings

#=
@register_serialization_type MPolyAnyMap uses_id
function save_object(s::SerializerState, phi::MPolyAnyMap)
save_data_dict(s) do
save_typed_object(s, domain(phi), :domain)
save_typed_object(s, codomain(phi), :codomain)
_has_coefficient_map(phi) && save_object(s, coefficient_map(phi), :coeff_map)
save_object(s, _images(phi), :img_gens)
end
end
function load_object(s::DeserializerState, ::Type{<:MPolyAnyMap})
dom = load_typed_object(s, :domain)
cod = load_typed_object(s, :codomain)
img_gens = load_object(s, :img_gens)
if haskey(s, :coeff_map)
coeff_map = load_object(s, :coeff_map)
return hom(dom, cod, coeff_map, img_gens)
end
return hom(dom, cod, img_gens)
end
=#


@register_serialization_type MPolyLocalizedRingHom uses_id

function save_object(s::SerializerState, phi::MPolyLocalizedRingHom)
save_data_dict(s) do
save_typed_object(s, domain(phi), :domain)
save_typed_object(s, codomain(phi), :codomain)
save_typed_object(s, restricted_map(phi), :res_map)
end
end

function load_object(s::DeserializerState, ::Type{<:MPolyLocalizedRingHom})
dom = load_typed_object(s, :domain)
cod = load_typed_object(s, :codomain)
res = load_typed_object(s, :res_map)
return MPolyLocalizedRingHom(dom, cod, res; check=false)
end


@register_serialization_type MPolyQuoLocalizedRingHom uses_id

function save_object(s::SerializerState, phi::MPolyQuoLocalizedRingHom)
save_data_dict(s) do
save_typed_object(s, domain(phi), :domain)
save_typed_object(s, codomain(phi), :codomain)
save_typed_object(s, restricted_map(phi), :res_map)
end
end

function load_object(s::DeserializerState, ::Type{<:MPolyQuoLocalizedRingHom})
dom = load_typed_object(s, :domain)
cod = load_typed_object(s, :codomain)
res = load_typed_object(s, :res_map)
return MPolyQuoLocalizedRingHom(dom, cod, res; check=false)
end


1 change: 1 addition & 0 deletions src/Serialization/main.jl
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ include("TropicalGeometry.jl")
include("QuadForm.jl")
include("GAP.jl")
include("Groups.jl")
include("Schemes.jl")

include("Upgrades/main.jl")

Expand Down
80 changes: 80 additions & 0 deletions test/Serialization/schemes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
test_save_load_roundtrip(path, b) do loaded
@test !is_unit(b)
end
J = ideal(L, gens(L))
test_save_load_roundtrip(path, J) do loaded
@test is_one(J)
end

U = complement_of_prime_ideal(ideal(R, x+y))
L, _ = localization(R, U)
Expand All @@ -30,6 +34,11 @@
test_save_load_roundtrip(path, b) do loaded
@test !is_unit(b)
end
J = ideal(L, gens(L))
test_save_load_roundtrip(path, J) do loaded
@test is_one(J)
end


U = complement_of_point_ideal(R, QQ.([0, 0]))
L, _ = localization(R, U)
Expand All @@ -46,6 +55,77 @@
@test !is_unit(b)
end

I = ideal(R, [x+y])
Q, _ = quo(R, I)
U = powers_of_element(x*y)
L, _ = localization(Q, U)
test_save_load_roundtrip(path, L) do loaded
@test is_unit(L(x^2*y))
@test !is_unit(L(x-1))
end
a = L(x)
b = L(y*(x-1))
test_save_load_roundtrip(path, a) do loaded
@test is_unit(a)
end
test_save_load_roundtrip(path, b) do loaded
@test !is_unit(b)
end
J = ideal(L, gens(L))
test_save_load_roundtrip(path, J) do loaded
@test is_one(J)
end
end
end

@testset "affine schemes" begin
mktempdir() do path
A = affine_space(QQ, 3)
test_save_load_roundtrip(path, A) do loaded
@test OO(A) isa MPolyRing{<:FieldElem}
@test ngens(OO(A)) == 3
end

(x, y, z) = gens(OO(A))
U = PrincipalOpenSubset(A, [x, y])
test_save_load_roundtrip(path, U) do loaded
@test OO(U) isa Oscar.MPolyLocRing
@test ngens(OO(U)) == 3
@test is_unit(OO(U)(x))
end
end
end

@testset "maps from polynomial rings" begin
mktempdir() do path
R, (x, y) = GF(29^2)[:x, :y]
phi = hom(R, R, x->x^29, gens(R))
@test_throws ArgumentError save(path, phi)
# the following should in principle be supported for some serializations
# which are not for long term storage (to come)
# test_save_load_roundtrip(path, phi) do loaded
# @test phi(one(R)) == one(R)
# end
end
end

@testset "covered schemes" begin
mktempdir() do path
IP = projective_space(GF(29), 3)
X = covered_scheme(IP)
cov = default_covering(X)
for U in affine_charts(X)
for V in affine_charts(X)
glue = cov[U, V]
glue isa SimpleGluing || continue
test_save_load_roundtrip(path, glue) do loaded
f, g = gluing_morphisms(glue)
@test is_isomorphism(f)
@test is_isomorphism(g)
end
end
end
end
end


0 comments on commit 5e0aa27

Please sign in to comment.