@@ -168,24 +168,31 @@ function Base.isapprox(α, q::RationalPoly{C}; kwargs...) where {C}
168
168
return isapprox (constant_term (α, q. den), q; kwargs... )
169
169
end
170
170
171
+ # TODO refer to the parallel with `mstructure(p)(e1, e2)` which gives the result
172
+ # of multiplying the monomials corresponding to the exponent vectors `e1`
173
+ # and `e2`.
171
174
"""
172
175
abstract type AbstractMonomialOrdering end
173
176
174
177
Abstract type for monomial ordering as defined in [CLO13, Definition 2.2.1, p. 55]
175
178
179
+ Given an ordering `ordering::AbstractMonomialOrdering` and vector of exponents `e1`
180
+ and `e2`, `cmp(ordering, e1, e2)` returns a negative number if `e1` is before `e2`
181
+ in the ordering, a positive number if `e2` is before `e1` and 0 if they are equal.
182
+ For convenience, `ordering(e1, e2)` returns a `Bool` indicating whether
183
+ `cmp(ordering, e1, e2)` is negative.
184
+
176
185
[CLO13] Cox, D., Little, J., & OShea, D.
177
186
*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*.
178
187
Springer Science & Business Media, **2013**.
179
188
"""
180
189
abstract type AbstractMonomialOrdering end
181
190
182
- """
183
- compare(a, b, order::Type{<:AbstractMonomialOrdering})
184
-
185
- Returns a negative number if `a < b`, a positive number if `a > b` and zero if `a == b`.
186
- The comparison is done according to `order`.
187
- """
188
- function compare end
191
+ # We can't write this with a type instead of an instance so this motivates
192
+ # why we work with instances and not types even if they don't have any data
193
+ # that's not already in the type.
194
+ # This is also to be consistent with `StarAlgebras.MultiplicativeStructure`
195
+ (ordering:: AbstractMonomialOrdering )(i, j) = cmp (ordering, i, j) < 0
189
196
190
197
"""
191
198
struct LexOrder <: AbstractMonomialOrdering end
@@ -202,8 +209,8 @@ struct LexOrder <: AbstractMonomialOrdering end
202
209
203
210
const _TupleOrVector = Union{Tuple,AbstractVector}
204
211
205
- function compare (exp1 :: _TupleOrVector , exp2 :: _TupleOrVector , :: Type{LexOrder} )
206
- return Base . cmp (exp1, exp2)
212
+ function Base . cmp ( :: LexOrder , exp1 :: _TupleOrVector , exp2 :: _TupleOrVector )
213
+ return cmp (exp1, exp2)
207
214
end
208
215
209
216
"""
@@ -228,12 +235,8 @@ struct InverseLexOrder <: AbstractMonomialOrdering end
228
235
# so not `cmp` methods is defined for it.
229
236
_rev (v:: AbstractVector ) = view (v, lastindex (v): - 1 : firstindex (v))
230
237
_rev (t:: Tuple ) = reverse (t)
231
- function compare (
232
- exp1:: _TupleOrVector ,
233
- exp2:: _TupleOrVector ,
234
- :: Type{InverseLexOrder} ,
235
- )
236
- return compare (_rev (exp1), _rev (exp2), LexOrder)
238
+ function Base. cmp (:: InverseLexOrder , exp1:: _TupleOrVector , exp2:: _TupleOrVector )
239
+ return cmp (_rev (exp1), _rev (exp2))
237
240
end
238
241
239
242
"""
@@ -248,30 +251,13 @@ Monomial ordering defined by:
248
251
struct Graded{O<: AbstractMonomialOrdering } <: AbstractMonomialOrdering
249
252
same_degree_ordering:: O
250
253
end
254
+ Graded {O} () where {O<: AbstractMonomialOrdering } = Graded {O} (O ())
251
255
252
- function compare (
253
- a:: _TupleOrVector ,
254
- b:: _TupleOrVector ,
255
- :: Type{Graded{O}} ,
256
- ) where {O}
256
+ function Base. cmp (ordering:: Graded , a:: _TupleOrVector , b:: _TupleOrVector )
257
257
deg_a = sum (a)
258
258
deg_b = sum (b)
259
259
if deg_a == deg_b
260
- return compare (a, b, O)
261
- else
262
- return deg_a - deg_b
263
- end
264
- end
265
- # TODO Backward compat, remove
266
- function compare (
267
- a:: AbstractMonomial ,
268
- b:: AbstractMonomial ,
269
- :: Type{Graded{O}} ,
270
- ) where {O}
271
- deg_a = degree (a)
272
- deg_b = degree (b)
273
- if deg_a == deg_b
274
- return compare (a, b, O)
260
+ return cmp (ordering. same_degree_ordering, a, b)
275
261
else
276
262
return deg_a - deg_b
277
263
end
283
269
end
284
270
285
271
Monomial ordering defined by
286
- `compare(a, b, ::Type{Reverse{O}} ) where {O} = compare(b, a, O )`.
272
+ `cmp(o::Reverse, a, b ) where {O} = cmp(o.reverse_order, b, a )`.
287
273
288
274
Reverse Lex Order defined in [CLO13, Exercise 2.2.9, p. 61] where it is abbreviated as *rinvlex*.
289
275
can be obtained as `Reverse{InverseLexOrder}`.
@@ -298,27 +284,18 @@ Springer Science & Business Media, **2013**.
298
284
struct Reverse{O<: AbstractMonomialOrdering } <: AbstractMonomialOrdering
299
285
reverse_ordering:: O
300
286
end
287
+ Reverse {O} () where {O<: AbstractMonomialOrdering } = Reverse {O} (O ())
301
288
302
- function compare (
303
- a:: _TupleOrVector ,
304
- b:: _TupleOrVector ,
305
- :: Type{Reverse{O}} ,
306
- ) where {O}
307
- return compare (b, a, O)
308
- end
309
- # TODO Backward compat, remove
310
- function compare (
311
- a:: AbstractMonomial ,
312
- b:: AbstractMonomial ,
313
- :: Type{Reverse{O}} ,
314
- ) where {O}
315
- return compare (b, a, O)
289
+ function Base. cmp (ordering:: Reverse , a:: _TupleOrVector , b:: _TupleOrVector )
290
+ return cmp (ordering. reverse_ordering, b, a)
316
291
end
317
292
293
+ # TODO (breaking) Return an instance, not a type
318
294
"""
319
- ordering(p::AbstractPolynomialLike)
295
+ ordering(p::AbstractPolynomialLike)::Type{<:AbstractMonomialOrdering}
320
296
321
- Returns the [`AbstractMonomialOrdering`](@ref) used for the monomials of `p`.
297
+ Returns the [`AbstractMonomialOrdering`](@ref) type to be used to compare
298
+ exponent vectors for the monomials of `p`.
322
299
"""
323
300
function ordering end
324
301
@@ -330,10 +307,10 @@ ordering(p::AbstractPolynomialLike) = ordering(typeof(p))
330
307
# of x < y is equal to the result of Monomial(x) < Monomial(y)
331
308
# Without `Base.@pure`, TypedPolynomials allocates on Julia v1.6
332
309
# with `promote(x * y, x)`
333
- Base. @pure function compare (
310
+ Base. @pure function Base. cmp (
311
+ :: AbstractMonomialOrdering ,
334
312
v1:: AbstractVariable ,
335
313
v2:: AbstractVariable ,
336
- :: Type{<:AbstractMonomialOrdering} ,
337
314
)
338
315
return - cmp (name (v1), name (v2))
339
316
end
@@ -344,7 +321,7 @@ function compare(
344
321
:: Type{O} ,
345
322
) where {O<: AbstractMonomialOrdering }
346
323
s1, s2 = promote_variables (m1, m2)
347
- return compare ( exponents (s1), exponents (s2), O )
324
+ return cmp ( O (), exponents (s1), exponents (s2))
348
325
end
349
326
350
327
# Implement this to make coefficients be compared with terms.
@@ -358,25 +335,23 @@ end
358
335
# less than `b`, they are considered sort of equal.
359
336
_cmp_coefficient (a, b) = 0
360
337
361
- function compare (
338
+ function Base. cmp (
339
+ ordering:: O ,
362
340
t1:: AbstractTermLike ,
363
341
t2:: AbstractTermLike ,
364
- :: Type{O} ,
365
342
) where {O<: AbstractMonomialOrdering }
366
- Δ = compare ( monomial (t1), monomial (t2), O )
343
+ Δ = cmp (ordering, monomial (t1), monomial (t2))
367
344
if iszero (Δ)
368
345
return _cmp_coefficient (coefficient (t1), coefficient (t2))
369
346
end
370
347
return Δ
371
348
end
372
349
373
350
function Base. cmp (t1:: AbstractTermLike , t2:: AbstractTermLike )
374
- return compare (t1, t2, ordering (t1) )
351
+ return cmp ( ordering (t1)(), t1, t2 )
375
352
end
376
- # TODO for backward compat, remove in next breaking release
377
- compare (t1:: AbstractTermLike , t2:: AbstractTermLike ) = cmp (t1, t2)
378
353
379
- Base. isless (t1:: AbstractTermLike , t2:: AbstractTermLike ) = cmp (t1, t2) < 0
354
+ Base. isless (t1:: AbstractTermLike , t2:: AbstractTermLike ) = compare (t1, t2) < 0
380
355
381
356
_last_lex_index (n, :: Type{LexOrder} ) = n
382
357
_prev_lex_index (i, :: Type{LexOrder} ) = i - 1
@@ -573,3 +548,62 @@ function Base.iterate(it::ExponentsIterator, state)
573
548
end
574
549
return state[1 ], state
575
550
end
551
+
552
+ # TODO Backward compat, remove the following in next breaking release
553
+ """
554
+ compare(a, b, order::Type{<:AbstractMonomialOrdering})
555
+
556
+ Returns a negative number if `a < b`, a positive number if `a > b` and zero if `a == b`.
557
+ The comparison is done according to `order`.
558
+
559
+ **Warning** This is deprecated, use `cmp(order(), a, b)` instead.
560
+ """
561
+ function compare end
562
+
563
+ function compare (t1:: AbstractTermLike , t2:: AbstractTermLike )
564
+ return compare (t1, t2, ordering (t1))
565
+ end
566
+
567
+ function compare (
568
+ e1:: _TupleOrVector ,
569
+ e2:: _TupleOrVector ,
570
+ :: Type{O} ,
571
+ ) where {O<: AbstractMonomialOrdering }
572
+ return cmp (O (), e1, e2)
573
+ end
574
+
575
+ function compare (
576
+ t1:: AbstractTermLike ,
577
+ t2:: AbstractTermLike ,
578
+ :: Type{O} ,
579
+ ) where {O<: AbstractMonomialOrdering }
580
+ Δ = compare (monomial (t1), monomial (t2), O)
581
+ if iszero (Δ)
582
+ return _cmp_coefficient (coefficient (t1), coefficient (t2))
583
+ end
584
+ return Δ
585
+ end
586
+
587
+ function compare (
588
+ a:: AbstractMonomial ,
589
+ b:: AbstractMonomial ,
590
+ :: Type{Graded{O}} ,
591
+ ) where {O}
592
+ deg_a = degree (a)
593
+ deg_b = degree (b)
594
+ if deg_a == deg_b
595
+ return compare (a, b, O)
596
+ else
597
+ return deg_a - deg_b
598
+ end
599
+ end
600
+
601
+ function compare (
602
+ a:: AbstractMonomial ,
603
+ b:: AbstractMonomial ,
604
+ :: Type{Reverse{O}} ,
605
+ ) where {O}
606
+ return compare (b, a, O)
607
+ end
608
+
609
+ Base. isless (v1:: AbstractVariable , v2:: AbstractVariable ) = cmp (v1, v2) < 0
0 commit comments