Skip to content

Commit 4f33ce7

Browse files
committed
Towards inplace iterators for exponents of multivariate polynomials etc.
1 parent 2980528 commit 4f33ce7

File tree

5 files changed

+80
-65
lines changed

5 files changed

+80
-65
lines changed

src/MPoly.jl

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -500,8 +500,9 @@ end
500500
Return an iterator for the coefficients of the given polynomial. To retrieve
501501
an array of the coefficients, use `collect(coefficients(a))`.
502502
"""
503-
function coefficients(a::MPolyRingElem{T}) where T <: RingElement
504-
return Generic.MPolyCoeffs(a)
503+
function coefficients(a::MPolyRingElem{T}; inplace::Bool = false) where T <: RingElement
504+
t = zero(coefficient_ring(parent(a)))
505+
return Generic.MPolyCoeffs(a, inplace, t)
505506
end
506507

507508
@doc raw"""
@@ -511,8 +512,9 @@ Return an iterator for the exponent vectors of the given polynomial. To
511512
retrieve an array of the exponent vectors, use
512513
`collect(exponent_vectors(a))`.
513514
"""
514-
function exponent_vectors(a::MPolyRingElem{T}) where T <: RingElement
515-
return Generic.MPolyExponentVectors(a)
515+
function exponent_vectors(a::MPolyRingElem{T}; inplace::Bool = false) where T <: RingElement
516+
t = zeros(Int, nvars(parent(a)))
517+
return Generic.MPolyExponentVectors(a, inplace, t)
516518
end
517519

518520
@doc raw"""
@@ -521,8 +523,9 @@ end
521523
Return an iterator for the monomials of the given polynomial. To retrieve
522524
an array of the monomials, use `collect(monomials(a))`.
523525
"""
524-
function monomials(a::MPolyRingElem{T}) where T <: RingElement
525-
return Generic.MPolyMonomials(a)
526+
function monomials(a::MPolyRingElem{T}; inplace::Bool = false) where T <: RingElement
527+
t = zero(parent(a))
528+
return Generic.MPolyMonomials(a, inplace, t)
526529
end
527530

528531
@doc raw"""
@@ -531,8 +534,9 @@ end
531534
Return an iterator for the terms of the given polynomial. To retrieve
532535
an array of the terms, use `collect(terms(a))`.
533536
"""
534-
function terms(a::MPolyRingElem{T}) where T <: RingElement
535-
return Generic.MPolyTerms(a)
537+
function terms(a::MPolyRingElem{T}; inplace::Bool = false) where T <: RingElement
538+
t = zero(parent(a))
539+
return Generic.MPolyTerms(a, inplace, t)
536540
end
537541

538542
###############################################################################

src/exports.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ export check_composable
154154
export check_parent
155155
export codomain
156156
export coeff
157+
export coeff!
157158
export coefficient_ring
158159
export coefficient_ring_type
159160
export coefficients
@@ -213,6 +214,7 @@ export evaluate
213214
export exp_gcd
214215
export exponent
215216
export exponent_vector
217+
export exponent_vector!
216218
export exponent_vectors
217219
export exponent_word
218220
export exponent_words
@@ -579,6 +581,7 @@ export symbols
579581
export tail
580582
export term
581583
export terms
584+
export term!
582585
export to_univariate
583586
export total_degree
584587
export total_ring_of_fractions

src/generic/GenericTypes.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,20 +385,28 @@ end
385385

386386
# Iterators
387387

388-
struct MPolyCoeffs{T <: AbstractAlgebra.NCRingElem}
388+
struct MPolyCoeffs{T <: AbstractAlgebra.NCRingElem, S <: AbstractAlgebra.RingElement}
389389
poly::T
390+
inplace::Bool
391+
temp::S # only used if inplace == true
390392
end
391393

392394
struct MPolyExponentVectors{T <: AbstractAlgebra.RingElem}
393395
poly::T
396+
inplace::Bool
397+
temp::Vector{Int} # only used if inplace == true
394398
end
395399

396400
struct MPolyTerms{T <: AbstractAlgebra.NCRingElem}
397401
poly::T
402+
inplace::Bool
403+
temp::T # only used if inplace == true
398404
end
399405

400406
struct MPolyMonomials{T <: AbstractAlgebra.NCRingElem}
401407
poly::T
408+
inplace::Bool
409+
temp::T # only used if inplace == true
402410
end
403411

404412
mutable struct MPolyBuildCtx{T, S}

src/generic/MPoly.jl

Lines changed: 53 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -125,19 +125,31 @@ are given in the order of the variables for the ring, as supplied when the
125125
ring was created.
126126
"""
127127
function exponent_vector(a::MPoly{T}, i::Int) where T <: RingElement
128+
e = Vector{Int}(undef, nvars(parent(a)))
129+
return exponent_vector!(e, a, i)
130+
end
131+
132+
function exponent_vector!(e::Vector{Int}, a::MPoly{T}, i::Int) where T <: RingElement
133+
@assert length(e) == nvars(parent(a))
128134
A = a.exps
129135
N = size(A, 1)
130136

131137
ord = internal_ordering(parent(a))
132138
if ord == :lex
133-
return [Int(A[j, i]) for j in N:-1:1]
139+
range = N:-1:1
134140
elseif ord == :deglex
135-
return [Int(A[j, i]) for j in N - 1:-1:1]
141+
range = N - 1:-1:1
136142
elseif ord == :degrevlex
137-
return [Int(A[j, i]) for j in 1:N - 1]
143+
range = 1:N - 1
138144
else
139145
error("invalid ordering")
140146
end
147+
k = 1
148+
for j in range
149+
e[k] = Int(A[j, i])
150+
k += 1
151+
end
152+
return e
141153
end
142154

143155
@doc raw"""
@@ -635,6 +647,11 @@ function coeff(x::MPoly, i::Int)
635647
return x.coeffs[i]
636648
end
637649

650+
# Only for compatibility, we can't do anything in place here
651+
function coeff!(c::T, x::MPoly{T}, i::Int) where T <: RingElement
652+
return x.coeffs[i]
653+
end
654+
638655
function trailing_coefficient(p::MPoly{T}) where T <: RingElement
639656
@req !iszero(p) "Zero polynomial does not have a leading monomial"
640657
return coeff(p, length(p))
@@ -664,7 +681,9 @@ function monomial!(m::MPoly{T}, x::MPoly{T}, i::Int) where T <: RingElement
664681
N = size(x.exps, 1)
665682
fit!(m, 1)
666683
monomial_set!(m.exps, 1, x.exps, i, N)
667-
m.coeffs[1] = one(base_ring(x))
684+
if !isassigned(m.coeffs, 1) || !is_one(m.coeffs[1])
685+
m.coeffs[1] = one(base_ring(x))
686+
end
668687
m.length = 1
669688
return m
670689
end
@@ -675,11 +694,17 @@ end
675694
Return the $i$-th nonzero term of the polynomial $x$ (as a polynomial).
676695
"""
677696
function term(x::MPoly, i::Int)
678-
R = base_ring(x)
697+
y = zero(parent(x))
698+
return term!(y, x, i)
699+
end
700+
701+
function term!(y::T, x::T, i::Int) where T <: MPoly
679702
N = size(x.exps, 1)
680-
exps = Matrix{UInt}(undef, N, 1)
681-
monomial_set!(exps, 1, x.exps, i, N)
682-
return parent(x)([deepcopy(x.coeffs[i])], exps)
703+
fit!(y, 1)
704+
monomial_set!(y.exps, 1, x.exps, i, N)
705+
y.coeffs[1] = deepcopy(x.coeffs[i])
706+
y.length = 1
707+
return y
683708
end
684709

685710
@doc raw"""
@@ -804,69 +829,41 @@ Base.copy(f::Generic.MPoly) = deepcopy(f)
804829
#
805830
###############################################################################
806831

807-
function Base.iterate(x::MPolyCoeffs)
808-
if length(x.poly) >= 1
809-
return coeff(x.poly, 1), 1
810-
else
811-
return nothing
812-
end
813-
end
814-
815-
function Base.iterate(x::MPolyCoeffs, state)
816-
state += 1
817-
if length(x.poly) >= state
818-
return coeff(x.poly, state), state
819-
else
820-
return nothing
821-
end
822-
end
823-
824-
function Base.iterate(x::MPolyExponentVectors)
825-
if length(x.poly) >= 1
826-
return exponent_vector(x.poly, 1), 1
827-
else
828-
return nothing
829-
end
830-
end
831-
832-
function Base.iterate(x::MPolyExponentVectors, state)
833-
state += 1
834-
if length(x.poly) >= state
835-
return exponent_vector(x.poly, state), state
836-
else
837-
return nothing
838-
end
839-
end
840-
841-
function Base.iterate(x::MPolyTerms)
842-
if length(x.poly) >= 1
843-
return term(x.poly, 1), 1
832+
function Base.iterate(x::MPolyCoeffs, state::Union{Nothing, Int} = nothing)
833+
s = isnothing(state) ? 1 : state + 1
834+
if length(x.poly) >= s
835+
c = x.inplace ? coeff!(x.temp, x.poly, s) : coeff(x.poly, s)
836+
return c, s
844837
else
845838
return nothing
846839
end
847840
end
848841

849-
function Base.iterate(x::MPolyTerms, state)
850-
state += 1
851-
if length(x.poly) >= state
852-
return term(x.poly, state), state
842+
function Base.iterate(x::MPolyExponentVectors, state::Union{Nothing, Int} = nothing)
843+
s = isnothing(state) ? 1 : state + 1
844+
if length(x.poly) >= s
845+
v = x.inplace ? exponent_vector!(x.temp, x.poly, s) : exponent_vector(x.poly, s)
846+
return v, s
853847
else
854848
return nothing
855849
end
856850
end
857851

858-
function Base.iterate(x::MPolyMonomials)
859-
if length(x.poly) >= 1
860-
return monomial(x.poly, 1), 1
852+
function Base.iterate(x::MPolyTerms, state::Union{Nothing, Int} = nothing)
853+
s = isnothing(state) ? 1 : state + 1
854+
if length(x.poly) >= s
855+
t = x.inplace ? term!(x.temp, x.poly, s) : term(x.poly, s)
856+
return t, s
861857
else
862858
return nothing
863859
end
864860
end
865861

866-
function Base.iterate(x::MPolyMonomials, state)
867-
state += 1
868-
if length(x.poly) >= state
869-
return monomial(x.poly, state), state
862+
function Base.iterate(x::MPolyMonomials, state::Union{Nothing, Int} = nothing)
863+
s = isnothing(state) ? 1 : state + 1
864+
if length(x.poly) >= s
865+
m = x.inplace ? monomial!(x.temp, x.poly, s) : monomial(x.poly, s)
866+
return m, s
870867
else
871868
return nothing
872869
end

src/generic/exports.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export abs_series_type
1212
export base_field
1313
export basis
1414
export character
15+
export coeff!
1516
export collength
1617
export combine_like_terms!
1718
export cycles
@@ -25,6 +26,7 @@ export enable_cache!
2526
export exp_gcd
2627
export exponent
2728
export exponent_vector
29+
export exponent_vector!
2830
export exponent_word
2931
export falling_factorial
3032
export finish
@@ -122,6 +124,7 @@ export summands
122124
export supermodule
123125
export term
124126
export terms
127+
export term!
125128
export to_univariate
126129
export total_degree
127130
export trailing_coefficient

0 commit comments

Comments
 (0)