Skip to content

Commit

Permalink
fix: multivariate polynomial rings over zero rings
Browse files Browse the repository at this point in the history
  • Loading branch information
thofma committed Nov 26, 2024
1 parent c062cc1 commit bef95db
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/generic/GenericTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,12 @@ end
ord::Symbol
num_vars::Int
N::Int
istrivial::Bool

function MPolyRing{T}(R::Ring, s::Vector{Symbol}, ord::Symbol, N::Int,
cached::Bool = true) where T <: RingElement
return get_cached!(MPolyID, (R, s, ord, N), cached) do
new{T}(R, s, ord, length(s), N)
new{T}(R, s, ord, length(s), N, is_trivial(R))
end::MPolyRing{T}
end
end
Expand All @@ -372,6 +373,7 @@ mutable struct MPoly{T <: RingElement} <: AbstractAlgebra.MPolyRingElem{T}
return new{T}(Vector{T}(undef, 0), Matrix{UInt}(undef, N, 0), 0, R)
end

# assumes that all elements of a are non-zero
MPoly{T}(R::MPolyRing, a::Vector{T}, b::Matrix{UInt}) where T <: RingElement = new{T}(a, b, length(a), R)

function MPoly{T}(R::MPolyRing, a::T) where T <: RingElement
Expand Down
8 changes: 7 additions & 1 deletion src/generic/MPoly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ elem_type(::Type{MPolyRing{T}}) where T <: RingElement = MPoly{T}

base_ring(R::MPolyRing{T}) where T <: RingElement = R.base_ring::parent_type(T)

is_trivial(R::MPolyRing) = R.istrivial

@doc raw"""
symbols(a::MPolyRing)
Expand All @@ -36,20 +38,23 @@ number_of_variables(a::MPolyRing) = a.num_vars
number_of_generators(a::MPolyRing) = a.num_vars

function gen(a::MPolyRing{T}, i::Int, ::Val{:lex}) where {T <: RingElement}
is_trivial(a) && return zero(a)
n = nvars(a)
@boundscheck 1 <= i <= n || throw(ArgumentError("variable index out of range"))
return a([one(base_ring(a))], reshape(UInt[UInt(j == n - i + 1)
for j = 1:n], n, 1))
end

function gen(a::MPolyRing{T}, i::Int, ::Val{:deglex}) where {T <: RingElement}
is_trivial(a) && return zero(a)
n = nvars(a)
@boundscheck 1 <= i <= n || throw(ArgumentError("variable index out of range"))
return a([one(base_ring(a))], reshape(UInt[(UInt(j == n - i + 1)
for j in 1:n)..., UInt(1)], n + 1, 1))
end

function gen(a::MPolyRing{T}, i::Int, ::Val{:degrevlex}) where {T <: RingElement}
is_trivial(a) && return zero(a)
n = nvars(a)
@boundscheck 1 <= i <= n || throw(ArgumentError("variable index out of range"))
return a([one(base_ring(a))], reshape(UInt[(UInt(j == i)
Expand Down Expand Up @@ -838,7 +843,7 @@ Return the number of terms of the polynomial.
"""
length(x::MPoly) = x.length

isone(x::MPoly) = x.length == 1 && monomial_iszero(x.exps, 1, size(x.exps, 1)) && is_one(x.coeffs[1])
isone(x::MPoly) = is_trivial(parent(x)) || (x.length == 1 && monomial_iszero(x.exps, 1, size(x.exps, 1)) && is_one(x.coeffs[1]))

is_constant(x::MPoly) = x.length == 0 || (x.length == 1 && monomial_iszero(x.exps, 1, size(x.exps, 1)))

Expand Down Expand Up @@ -3896,6 +3901,7 @@ function zero!(a::MPoly{T}) where {T <: RingElement}
end

function one!(a::MPoly{T}) where {T <: RingElement}
is_trivial(parent(a)) && return zero!(a)
a.length = 1
fit!(a, 1)
a.coeffs[1] = one(base_ring(a))
Expand Down
8 changes: 8 additions & 0 deletions test/generic/MPoly-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1719,3 +1719,11 @@ end
S, = polynomial_ring(R, :z => 1:3)
test_Ring_interface(S) # _recursive needs too many ressources
end

@testset "Generic.MPoly.zero_rings" begin
R, = residue_ring(ZZ, 1)
S, = polynomial_ring(R, 2)
@test is_zero(gen(S, 1)) && is_one(gen(S, 1))
@test is_zero(one(S))
test_Ring_interface_recursive(S)
end

0 comments on commit bef95db

Please sign in to comment.