@@ -150,32 +150,85 @@ end
150
150
Base. copy (p:: VectorPolynomial ) = MA. mutable_copy (p)
151
151
152
152
function 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
156
162
end
157
- get2 = let p = p
163
+ get2 = let t = t, q = q
158
164
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) ... ))
161
167
end
162
168
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
166
176
end
167
177
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
170
208
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
172
218
(t, j) -> begin
173
219
if t isa Int && j isa Int
174
220
t = get1 (t)
175
221
end
176
222
grlex (monomials (q)[j], monomial (t))
177
223
end
178
224
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
179
232
combine = let p= p, q= q
180
233
(i, j) -> begin
181
234
if i isa Int
@@ -185,6 +238,25 @@ function MA.operate!(op::Union{typeof(+), typeof(-)}, p::Polynomial{T,TT}, q::Un
185
238
end
186
239
end
187
240
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
188
260
resize = let p= p
189
261
(n) -> resize! (p. terms, n)
190
262
end
@@ -198,12 +270,29 @@ function MA.operate!(op::Union{typeof(+), typeof(-)}, p::Polynomial{T,TT}, q::Un
198
270
end
199
271
end
200
272
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... )
205
274
return p
206
275
end
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
+
207
296
function MA. operate_to! (output:: Polynomial , :: typeof (* ), p:: Polynomial , q:: Polynomial )
208
297
empty! (output. terms)
209
298
mul_to_terms! (output. terms, p, q)
214
303
function MA. operate! (:: typeof (* ), p:: Polynomial , q:: Polynomial )
215
304
return MA. operate_to! (p, * , MA. mutable_copy (p), q)
216
305
end
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
217
312
218
313
function MA. operate! (:: typeof (zero), p:: Polynomial )
219
314
empty! (p. terms)
@@ -234,3 +329,9 @@ function MA.operate!(::typeof(removeleadingterm), p::Polynomial)
234
329
pop! (p. terms)
235
330
return p
236
331
end
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