-
Notifications
You must be signed in to change notification settings - Fork 71
"Inplace" iterators over the coefficients, monomials, terms and exponent vectors of a multivariate polynomial #2196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
06f0944
7f67fd9
85a8cbf
235f8b2
2f4465a
6757cb3
a83914e
18cde7d
d6fdbb7
4adaf5d
48c2948
a597880
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -125,19 +125,31 @@ are given in the order of the variables for the ring, as supplied when the | |
| ring was created. | ||
| """ | ||
| function exponent_vector(a::MPoly{T}, i::Int) where T <: RingElement | ||
| e = Vector{Int}(undef, nvars(parent(a))) | ||
| return exponent_vector!(e, a, i) | ||
| end | ||
|
|
||
| function exponent_vector!(e::Vector{S}, a::MPoly{T}, i::Int) where {T <: RingElement, S} | ||
| @assert length(e) == nvars(parent(a)) | ||
| A = a.exps | ||
| N = size(A, 1) | ||
|
|
||
| ord = internal_ordering(parent(a)) | ||
| if ord == :lex | ||
| return [Int(A[j, i]) for j in N:-1:1] | ||
| range = N:-1:1 | ||
| elseif ord == :deglex | ||
| return [Int(A[j, i]) for j in N - 1:-1:1] | ||
| range = N - 1:-1:1 | ||
| elseif ord == :degrevlex | ||
| return [Int(A[j, i]) for j in 1:N - 1] | ||
| range = 1:N - 1 | ||
| else | ||
| error("invalid ordering") | ||
| end | ||
| k = 1 | ||
| for j in range | ||
| e[k] = S(A[j, i]) | ||
| k += 1 | ||
| end | ||
| return e | ||
| end | ||
|
|
||
| @doc raw""" | ||
|
|
@@ -635,6 +647,11 @@ function coeff(x::MPoly, i::Int) | |
| return x.coeffs[i] | ||
| end | ||
|
|
||
| # Only for compatibility, we can't do anything in place here | ||
| function coeff!(c::T, x::MPoly{T}, i::Int) where T <: RingElement | ||
| return x.coeffs[i] | ||
| end | ||
|
|
||
| function trailing_coefficient(p::MPoly{T}) where T <: RingElement | ||
| @req !iszero(p) "Zero polynomial does not have a leading monomial" | ||
| return coeff(p, length(p)) | ||
|
|
@@ -664,7 +681,9 @@ function monomial!(m::MPoly{T}, x::MPoly{T}, i::Int) where T <: RingElement | |
| N = size(x.exps, 1) | ||
| fit!(m, 1) | ||
| monomial_set!(m.exps, 1, x.exps, i, N) | ||
| m.coeffs[1] = one(base_ring(x)) | ||
| if !isassigned(m.coeffs, 1) || !is_one(m.coeffs[1]) | ||
| m.coeffs[1] = one(base_ring(x)) | ||
| end | ||
|
Comment on lines
+684
to
+686
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a bit ugly, but it gets the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems fine to me |
||
| m.length = 1 | ||
| return m | ||
| end | ||
|
|
@@ -675,11 +694,17 @@ end | |
| Return the $i$-th nonzero term of the polynomial $x$ (as a polynomial). | ||
| """ | ||
| function term(x::MPoly, i::Int) | ||
| R = base_ring(x) | ||
| y = zero(parent(x)) | ||
| return term!(y, x, i) | ||
| end | ||
|
|
||
| function term!(y::T, x::T, i::Int) where T <: MPoly | ||
| N = size(x.exps, 1) | ||
| exps = Matrix{UInt}(undef, N, 1) | ||
| monomial_set!(exps, 1, x.exps, i, N) | ||
| return parent(x)([deepcopy(x.coeffs[i])], exps) | ||
| fit!(y, 1) | ||
| monomial_set!(y.exps, 1, x.exps, i, N) | ||
| y.coeffs[1] = deepcopy(x.coeffs[i]) | ||
| y.length = 1 | ||
| return y | ||
| end | ||
|
|
||
| @doc raw""" | ||
|
|
@@ -804,69 +829,41 @@ Base.copy(f::Generic.MPoly) = deepcopy(f) | |
| # | ||
| ############################################################################### | ||
|
|
||
| function Base.iterate(x::MPolyCoeffs) | ||
| if length(x.poly) >= 1 | ||
| return coeff(x.poly, 1), 1 | ||
| else | ||
| return nothing | ||
| end | ||
| end | ||
|
|
||
| function Base.iterate(x::MPolyCoeffs, state) | ||
| state += 1 | ||
| if length(x.poly) >= state | ||
| return coeff(x.poly, state), state | ||
| else | ||
| return nothing | ||
| end | ||
| end | ||
|
|
||
| function Base.iterate(x::MPolyExponentVectors) | ||
| if length(x.poly) >= 1 | ||
| return exponent_vector(x.poly, 1), 1 | ||
| else | ||
| return nothing | ||
| end | ||
| end | ||
|
|
||
| function Base.iterate(x::MPolyExponentVectors, state) | ||
| state += 1 | ||
| if length(x.poly) >= state | ||
| return exponent_vector(x.poly, state), state | ||
| else | ||
| return nothing | ||
| end | ||
| end | ||
|
|
||
| function Base.iterate(x::MPolyTerms) | ||
| if length(x.poly) >= 1 | ||
| return term(x.poly, 1), 1 | ||
| function Base.iterate(x::MPolyCoeffs, state::Union{Nothing, Int} = nothing) | ||
| s = isnothing(state) ? 1 : state + 1 | ||
| if length(x.poly) >= s | ||
| c = x.inplace ? coeff!(x.temp, x.poly, s) : coeff(x.poly, s) | ||
| return c, s | ||
| else | ||
| return nothing | ||
| end | ||
| end | ||
|
|
||
| function Base.iterate(x::MPolyTerms, state) | ||
| state += 1 | ||
| if length(x.poly) >= state | ||
| return term(x.poly, state), state | ||
| function Base.iterate(x::MPolyExponentVectors, state::Union{Nothing, Int} = nothing) | ||
| s = isnothing(state) ? 1 : state + 1 | ||
| if length(x.poly) >= s | ||
| v = x.inplace ? exponent_vector!(x.temp, x.poly, s) : exponent_vector(x.poly, s) | ||
| return v, s | ||
| else | ||
| return nothing | ||
| end | ||
| end | ||
|
|
||
| function Base.iterate(x::MPolyMonomials) | ||
| if length(x.poly) >= 1 | ||
| return monomial(x.poly, 1), 1 | ||
| function Base.iterate(x::MPolyTerms, state::Union{Nothing, Int} = nothing) | ||
| s = isnothing(state) ? 1 : state + 1 | ||
| if length(x.poly) >= s | ||
| t = x.inplace ? term!(x.temp, x.poly, s) : term(x.poly, s) | ||
| return t, s | ||
| else | ||
| return nothing | ||
| end | ||
| end | ||
|
|
||
| function Base.iterate(x::MPolyMonomials, state) | ||
| state += 1 | ||
| if length(x.poly) >= state | ||
| return monomial(x.poly, state), state | ||
| function Base.iterate(x::MPolyMonomials, state::Union{Nothing, Int} = nothing) | ||
| s = isnothing(state) ? 1 : state + 1 | ||
| if length(x.poly) >= s | ||
| m = x.inplace ? monomial!(x.temp, x.poly, s) : monomial(x.poly, s) | ||
| return m, s | ||
| else | ||
| return nothing | ||
| end | ||
|
|
@@ -876,12 +873,12 @@ function Base.length(x::Union{MPolyCoeffs, MPolyExponentVectors, MPolyTerms, MPo | |
| return length(x.poly) | ||
| end | ||
|
|
||
| function Base.eltype(::Type{MPolyCoeffs{T}}) where T <: AbstractAlgebra.MPolyRingElem{S} where S <: RingElement | ||
| function Base.eltype(::Type{MPolyCoeffs{T, S}}) where {T <: AbstractAlgebra.MPolyRingElem, S <: RingElement} | ||
| return S | ||
| end | ||
|
|
||
| function Base.eltype(::Type{MPolyExponentVectors{T}}) where T <: AbstractAlgebra.MPolyRingElem{S} where S <: RingElement | ||
| return Vector{Int} | ||
| function Base.eltype(::Type{MPolyExponentVectors{T, V}}) where {V, T <: AbstractAlgebra.MPolyRingElem{S} where S <: RingElement} | ||
| return V | ||
| end | ||
|
|
||
| function Base.eltype(::Type{MPolyMonomials{T}}) where T <: AbstractAlgebra.MPolyRingElem{S} where S <: RingElement | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO a bit neater, but I don't really care
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I never really got the hang of this syntax, so if you don't care, I'll prefer my version.