@@ -150,32 +150,85 @@ end
150150Base. copy (p:: VectorPolynomial ) = MA. mutable_copy (p)
151151
152152function grlex end
153- function MA. operate! (op:: Union{typeof(+), typeof(-)} , p:: Polynomial{T,TT} , q:: Union{Polynomial,AbstractTermLike} ) where {T,TT}
154- get1 = let p= p
155- i -> p. terms[i]
153+
154+ function __polynomial_merge! (op:: MA.AddSubMul , p:: Polynomial{T,TT} , get1, set, push, resize, keep, q, t:: AbstractTermLike... ) where {T,TT}
155+ compare_monomials = let t= t, get1= get1, q= q
156+ (tp, j) -> begin
157+ if tp isa Int && j isa Int
158+ tp = get1 (tp)
159+ end
160+ grlex (* (monomials (q)[j], monomial .(t)... ), monomial (tp))
161+ end
156162 end
157- get2 = let p = p
163+ get2 = let t = t, q = q
158164 i -> begin
159- t = terms (q)[i]
160- TT (MA. scaling_convert (T, MA. operate (op, coefficient (t))), monomial (t ))
165+ tq = terms (q)[i]
166+ TT (MA. scaling_convert (T, MA. operate (MA . add_sub_op (op), * ( coefficient (tq), coefficient .(t) ... ))), * ( monomial (tq), monomial .(t) ... ))
161167 end
162168 end
163- set = let p= p
164- (i, t) -> begin
165- p. terms[i] = t
169+ combine = let t= t, p= p, q= q
170+ (i, j) -> begin
171+ if i isa Int
172+ p. terms[i] = Term (MA. operate!! (op, coefficient (p. terms[i]), coefficients (q)[j], coefficient .(t)... ), monomial (p. terms[i]))
173+ else
174+ typeof (i)(MA. operate!! (op, coefficient (i), coefficients (q)[j], coefficient .(t)... ), monomial (i))
175+ end
166176 end
167177 end
168- push = let p= p
169- t -> push! (p. terms, t)
178+ polynomial_merge! (
179+ nterms (p), nterms (q), get1, get2, set, push,
180+ compare_monomials, combine, keep, resize
181+ )
182+ return
183+ end
184+
185+ function __polynomial_merge! (op:: MA.AddSubMul , p:: Polynomial{T,TT} , get1, set, push, resize, keep, t:: AbstractTermLike , q:: Polynomial , buffer= nothing ) where {T,TT}
186+ compare_monomials = let t= t, get1= get1, q= q
187+ (tp, j) -> begin
188+ if tp isa Int && j isa Int
189+ tp = get1 (tp)
190+ end
191+ grlex (monomial (t) * monomials (q)[j], monomial (tp))
192+ end
193+ end
194+ get2 = let t= t, q= q
195+ i -> begin
196+ tq = terms (q)[i]
197+ TT (MA. scaling_convert (T, MA. operate (MA. add_sub_op (op), coefficient (t) * coefficient (tq))), monomial (t) * monomial (tq))
198+ end
199+ end
200+ combine = let t= t, p= p, q= q
201+ (i, j) -> begin
202+ if i isa Int
203+ p. terms[i] = Term (MA. buffered_operate!! (buffer, op, coefficient (p. terms[i]), coefficient (t), coefficients (q)[j]), monomial (p. terms[i]))
204+ else
205+ typeof (i)(MA. buffered_operate!! (buffer, op, coefficient (i), coefficient (t), coefficients (q)[j]), monomial (i))
206+ end
207+ end
170208 end
171- compare_monomials = let q= q
209+ polynomial_merge! (
210+ nterms (p), nterms (q), get1, get2, set, push,
211+ compare_monomials, combine, keep, resize
212+ )
213+ return
214+ end
215+
216+ function __polynomial_merge! (op:: Union{typeof(+), typeof(-)} , p:: Polynomial{T,TT} , get1, set, push, resize, keep, q:: Union{Polynomial,AbstractTermLike} ) where {T,TT}
217+ compare_monomials = let get1= get1, q= q
172218 (t, j) -> begin
173219 if t isa Int && j isa Int
174220 t = get1 (t)
175221 end
176222 grlex (monomials (q)[j], monomial (t))
177223 end
178224 end
225+ get2 = let q= q
226+ i -> begin
227+ t = terms (q)[i]
228+ # `operate` makes sure we make a copy of the term as it may be stored directly in `p`
229+ TT (MA. scaling_convert (T, MA. operate (op, coefficient (t))), monomial (t))
230+ end
231+ end
179232 combine = let p= p, q= q
180233 (i, j) -> begin
181234 if i isa Int
@@ -185,6 +238,25 @@ function MA.operate!(op::Union{typeof(+), typeof(-)}, p::Polynomial{T,TT}, q::Un
185238 end
186239 end
187240 end
241+ polynomial_merge! (
242+ nterms (p), nterms (q), get1, get2, set, push,
243+ compare_monomials, combine, keep, resize
244+ )
245+ return
246+ end
247+
248+ function _polynomial_merge! (op:: Union{typeof(+), typeof(-), MA.AddSubMul} , p:: Polynomial{T,TT} , args... ) where {T,TT}
249+ get1 = let p= p
250+ i -> p. terms[i]
251+ end
252+ set = let p= p
253+ (i, t) -> begin
254+ p. terms[i] = t
255+ end
256+ end
257+ push = let p= p
258+ t -> push! (p. terms, t)
259+ end
188260 resize = let p= p
189261 (n) -> resize! (p. terms, n)
190262 end
@@ -198,12 +270,29 @@ function MA.operate!(op::Union{typeof(+), typeof(-)}, p::Polynomial{T,TT}, q::Un
198270 end
199271 end
200272 end
201- polynomial_merge! (
202- nterms (p), nterms (q), get1, get2, set, push,
203- compare_monomials, combine, keep, resize
204- )
273+ __polynomial_merge! (op, p, get1, set, push, resize, keep, args... )
205274 return p
206275end
276+
277+ function MA. operate! (op:: Union{typeof(+), typeof(-)} , p:: Polynomial , q:: Union{AbstractTermLike,Polynomial} )
278+ return _polynomial_merge! (op, p, q)
279+ end
280+
281+ function MA. operate! (op:: MA.AddSubMul , p:: Polynomial , q:: Polynomial , args:: AbstractTermLike... )
282+ return _polynomial_merge! (op, p, q, args... )
283+ end
284+
285+ function MA. operate! (op:: MA.AddSubMul , p:: Polynomial , t:: AbstractTermLike , q:: Polynomial )
286+ return _polynomial_merge! (op, p, t, q)
287+ end
288+
289+ function MA. buffer_for (op:: MA.AddSubMul , :: Type{<:Polynomial{S}} , :: Type{<:AbstractTermLike{T}} , :: Type{<:Polynomial{U}} ) where {S,T,U}
290+ return MA. buffer_for (op, S, T, U)
291+ end
292+ function MA. buffered_operate! (buffer, op:: MA.AddSubMul , p:: Polynomial , t:: AbstractTermLike , q:: Polynomial )
293+ return _polynomial_merge! (op, p, t, q, buffer)
294+ end
295+
207296function MA. operate_to! (output:: Polynomial , :: typeof (* ), p:: Polynomial , q:: Polynomial )
208297 empty! (output. terms)
209298 mul_to_terms! (output. terms, p, q)
214303function MA. operate! (:: typeof (* ), p:: Polynomial , q:: Polynomial )
215304 return MA. operate_to! (p, * , MA. mutable_copy (p), q)
216305end
306+ function MA. operate! (:: typeof (* ), p:: Polynomial , t:: AbstractTermLike )
307+ for i in eachindex (p. terms)
308+ p. terms[i] = MA. operate!! (* , p. terms[i], t)
309+ end
310+ return p
311+ end
217312
218313function MA. operate! (:: typeof (zero), p:: Polynomial )
219314 empty! (p. terms)
@@ -234,3 +329,9 @@ function MA.operate!(::typeof(removeleadingterm), p::Polynomial)
234329 pop! (p. terms)
235330 return p
236331end
332+
333+ function MA. operate! (:: typeof (unsafe_restore_leading_term), p:: Polynomial , t:: AbstractTermLike )
334+ # We don't need to copy the coefficient of `t`, this is why this function is called `unsafe`
335+ push! (p. terms, t)
336+ return p
337+ end
0 commit comments