Skip to content

Commit

Permalink
Added Laurent Mpoly elem and ideals to serialization (oscar-system#2592)
Browse files Browse the repository at this point in the history
* Added Laurent Mpoly elem and ideals to serialization

* Tests for LaurentMPoly rings and their ideals
  • Loading branch information
antonydellavecchia authored Aug 1, 2023
1 parent 6be3dfe commit 73816e6
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 15 deletions.
49 changes: 39 additions & 10 deletions src/Serialization/Rings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ end
@registerSerializationType(PolyRing, true)
@registerSerializationType(MPolyRing, true)
@registerSerializationType(UniversalPolyRing, true)
@registerSerializationType(AbstractAlgebra.Generic.LaurentMPolyWrapRing, true)

function save_internal(s::SerializerState, R::Union{UniversalPolyRing, MPolyRing, PolyRing})
function save_internal(s::SerializerState, R::Union{UniversalPolyRing, MPolyRing, PolyRing, AbstractAlgebra.Generic.LaurentMPolyWrapRing})
base = base_ring(R)

return Dict(
Expand All @@ -85,7 +86,7 @@ function save_internal(s::SerializerState, R::Union{UniversalPolyRing, MPolyRing
end

function load_internal(s::DeserializerState,
T::Type{<: Union{UniversalPolyRing, MPolyRing, PolyRing}},
T::Type{<: Union{UniversalPolyRing, MPolyRing, PolyRing, AbstractAlgebra.Generic.LaurentMPolyWrapRing}},
dict::Dict)
base_ring = load_unknown_type(s, dict[:base_ring])
symbols = load_type_dispatch(s, Vector{Symbol}, dict[:symbols])
Expand All @@ -96,6 +97,8 @@ function load_internal(s::DeserializerState,
poly_ring = UniversalPolynomialRing(base_ring, cached=false)
gens(poly_ring, symbols)
return poly_ring
elseif T <: AbstractAlgebra.Generic.LaurentMPolyWrapRing
return LaurentPolynomialRing(base_ring, symbols, cached=false)[1]
end

return polynomial_ring(base_ring, symbols, cached=false)[1]
Expand Down Expand Up @@ -126,6 +129,29 @@ function save_internal(s::SerializerState, p::Union{UniversalPolyRingElem, MPoly
return encoded_terms
end

@registerSerializationType(AbstractAlgebra.Generic.LaurentMPolyWrap)
function save_internal(s::SerializerState, p::AbstractAlgebra.Generic.LaurentMPolyWrap;
include_parents::Bool=true)
parent_ring = parent(p)
base = base_ring(parent_ring)
encoded_terms = []

exponent_vectors_gen = AbstractAlgebra.exponent_vectors(p)
index = 0
for c in coefficients(p)
exponent_vector, index = iterate(exponent_vectors_gen, index)
encoded_coeff = save_internal(s, c; include_parents=false)
push!(encoded_terms, (exponent_vector, encoded_coeff))
end

if include_parents
return Dict(
:terms => encoded_terms,
:parents => get_parent_refs(s, parent_ring),
)
end
return encoded_terms
end

################################################################################
# Univariate Polynomials
Expand Down Expand Up @@ -188,7 +214,7 @@ function load_terms(s::DeserializerState, parents::Vector, terms::Vector,
end

function load_terms(s::DeserializerState, parents::Vector, terms::Vector,
parent_ring::Union{MPolyRing, UniversalPolyRing})
parent_ring::Union{MPolyRing, UniversalPolyRing, AbstractAlgebra.Generic.LaurentMPolyWrapRing})
base = base_ring(parent_ring)
polynomial = MPolyBuildCtx(parent_ring)
for (e, coeff) in terms
Expand All @@ -207,14 +233,14 @@ end


function load_internal(s::DeserializerState, ::Type{<: Union{
PolyRingElem, UniversalPolyRingElem, MPolyRingElem}}, dict::Dict)
PolyRingElem, UniversalPolyRingElem, MPolyRingElem, AbstractAlgebra.Generic.LaurentMPolyWrap}}, dict::Dict)
loaded_parents = load_parents(s, dict[:parents])
return load_terms(s, loaded_parents, dict[:terms], loaded_parents[end])
end

function load_internal_with_parent(s::DeserializerState, ::Type{<: Union{
PolyRingElem, UniversalPolyRingElem, MPolyRingElem}}, dict::Dict,
parent_ring::Union{PolyRing, MPolyRing, UniversalPolyRing})
PolyRingElem, UniversalPolyRingElem, MPolyRingElem, AbstractAlgebra.Generic.LaurentMPolyWrap}}, dict::Dict,
parent_ring::Union{PolyRing, MPolyRing, UniversalPolyRing, AbstractAlgebra.Generic.LaurentMPolyWrapRing})
parents = get_parents(parent_ring)
return load_terms(s, parents, dict[:terms], parents[end])
end
Expand All @@ -223,25 +249,28 @@ end
# Polynomial Ideals

@registerSerializationType(MPolyIdeal)
@registerSerializationType(Laurent.LaurentMPolyIdeal)

function save_internal(s::SerializerState, I::MPolyIdeal)
function save_internal(s::SerializerState,
I::Union{MPolyIdeal, Laurent.LaurentMPolyIdeal})
generators = gens(I)

return Dict(
:gens => save_type_dispatch(s, generators),
)
end

function load_internal(s::DeserializerState, ::Type{<: MPolyIdeal}, dict::Dict)
function load_internal(s::DeserializerState, ::Type{<: Union{
MPolyIdeal, Laurent.LaurentMPolyIdeal}}, dict::Dict)
gens = load_type_dispatch(s, Vector, dict[:gens])

return ideal(parent(gens[1]), gens)
end

function load_internal_with_parent(s::DeserializerState,
::Type{<: MPolyIdeal},
::Type{<: Union{MPolyIdeal, Laurent.LaurentMPolyIdeal}},
dict::Dict,
parent_ring::MPolyRing)
parent_ring::Union{MPolyRing, AbstractAlgebra.Generic.LaurentMPolyWrapRing})
gens = load_type_dispatch(s, Vector{elem_type(parent_ring)},
dict[:gens], parent=parent_ring)
return ideal(parent_ring, gens)
Expand Down
44 changes: 39 additions & 5 deletions test/Serialization/PolynomialsSeries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ cases = [
]

function get_hom(R1::T, R2::T) where T <: Union{
MPolyRing{NfAbsNSElem}, PolyRing{NfAbsNSElem}}
MPolyRing{NfAbsNSElem}, PolyRing{NfAbsNSElem},
AbstractAlgebra.Generic.LaurentMPolyWrapRing{NfAbsNSElem}}
D = coefficient_ring(R1)
I = coefficient_ring(R2)
return hom(D, I, gens(I))
Expand All @@ -48,6 +49,7 @@ end

function get_hom(R1::T, R2::T) where T <: Union{
MPolyRing{Hecke.NfRelElem{nf_elem}}, PolyRing{Hecke.NfRelElem{nf_elem}},
AbstractAlgebra.Generic.LaurentMPolyWrapRing{Hecke.NfRelElem{nf_elem}},
AbstractAlgebra.PolyRing{AbstractAlgebra.Generic.Frac{QQPolyRingElem}},
AbstractAlgebra.PolyRing{AbstractAlgebra.Generic.RationalFunctionField{QQFieldElem, QQPolyRingElem}}}
D = coefficient_ring(R1)
Expand All @@ -72,6 +74,7 @@ function get_hom(R1::T, R2::T) where T <: (
end

function get_hom(R1::T, R2::T) where T <: Union{
AbstractAlgebra.Generic.LaurentMPolyWrapRing{Hecke.NfRelNSElem{nf_elem}},
MPolyRing{Hecke.NfRelNSElem{nf_elem}},
PolyRing{Hecke.NfRelNSElem{nf_elem}}}
D = coefficient_ring(R1)
Expand All @@ -93,7 +96,7 @@ function get_hom(R1::T, R2::T) where T <: Union{
end

function get_hom(R1::T, R2::T) where {
T <: Union{MPolyRing{S}, PolyRing{S}} where S <: Union{
T <: Union{MPolyRing{S}, PolyRing{S}, AbstractAlgebra.Generic.LaurentMPolyWrapRing{S}} where S <: Union{
nf_elem, zzModRingElem, ZZRingElem, QQFieldElem, fqPolyRepFieldElem}}
D = coefficient_ring(R1)
I = coefficient_ring(R2)
Expand All @@ -109,7 +112,7 @@ function get_hom(R1::T, R2::T) where T <: Union{
end

function test_equality(p::T, l::T) where T <: (
MPolyRingElem{S} where S <:Union{
Union{MPolyRingElem{S}, AbstractAlgebra.Generic.LaurentMPolyWrap{S}} where S <:Union{
QQFieldElem, ZZRingElem, zzModRingElem, padic, Oscar.TropicalSemiringElem
})
P = parent(p)
Expand Down Expand Up @@ -167,7 +170,7 @@ function test_equality(p::T, l::T) where T <: (
end

function test_equality(p::T, l:: T) where T <: Union{
MPolyRingElem{S}, PolyRingElem{S}} where S <: Union{
MPolyRingElem{S}, PolyRingElem{S}, AbstractAlgebra.Generic.LaurentMPolyWrap{S}} where S <: Union{
AbstractAlgebra.Generic.Frac{QQPolyRingElem},
AbstractAlgebra.Generic.RationalFunctionFieldElem{QQFieldElem, QQPolyRingElem},
QQPolyRingElem}
Expand All @@ -190,7 +193,7 @@ end


function test_equality(p::T, l::T) where T <: (
MPolyRingElem{S} where S <: Union{
Union{MPolyRingElem{S}, AbstractAlgebra.Generic.LaurentMPolyWrap{S}} where S <: Union{
Hecke.NfRelNSElem{nf_elem},
Hecke.NfRelElem{nf_elem},
NfAbsNSElem,
Expand Down Expand Up @@ -316,6 +319,37 @@ end
end
end

@testset "Multivariate Laurent Polynomial over $(case[4])" begin
R, (z, w) = LaurentPolynomialRing(case[1], ["z", "w"])
p = z^2 + case[2] * z * w^(-4) + case[3] * w^(-3)
test_save_load_roundtrip(path, p) do loaded
@test test_equality(p, loaded)
end

@testset "Load with parent" begin
test_save_load_roundtrip(path, p; parent=R) do loaded
@test p == loaded
end
end

if R isa AbstractAlgebra.Generic.LaurentMPolyWrapRing{T} where T <: Union{QQFieldElem, ZZRingElem, zzModRingElem}
@testset "Laurent MPoly Ideals over $(case[4])" begin
q = w^2 + z
i = Oscar.ideal(R, [p, q])
test_save_load_roundtrip(path, i) do loaded_i
S = parent(gens(loaded_i)[1])
h = hom(R, S, gens(S))
@test [h(g) for g in gens(i)] == gens(loaded_i)
end

S = parent(gens(i)[1])
test_save_load_roundtrip(path, i; parent=S) do loaded_i
@test gens(i) == gens(loaded_i)
end
end
end
end

# Tropical Semirings currently can't have formal power series
filter!(case-> case[4] != "Tropical Semiring", cases)

Expand Down

0 comments on commit 73816e6

Please sign in to comment.