|
1 | 1 | export isapproxzero
|
2 | 2 |
|
| 3 | +export LexOrder, InverseLexOrder, Reverse, Graded |
| 4 | + |
3 | 5 | Base.iszero(v::AbstractVariable) = false
|
4 | 6 | Base.iszero(m::AbstractMonomial) = false
|
5 | 7 | Base.iszero(t::AbstractTerm) = iszero(coefficient(t))
|
@@ -169,3 +171,145 @@ end
|
169 | 171 | function Base.isapprox(α, q::RationalPoly{C}; kwargs...) where {C}
|
170 | 172 | return isapprox(constant_term(α, q.den), q; kwargs...)
|
171 | 173 | end
|
| 174 | + |
| 175 | +""" |
| 176 | + abstract type AbstractMonomialOrdering end |
| 177 | +
|
| 178 | +Abstract type for monomial ordering as defined in [CLO13, Definition 2.2.1, p. 55] |
| 179 | +
|
| 180 | +[CLO13] Cox, D., Little, J., & OShea, D. |
| 181 | +*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*. |
| 182 | +Springer Science & Business Media, **2013**. |
| 183 | +""" |
| 184 | +abstract type AbstractMonomialOrdering end |
| 185 | + |
| 186 | +""" |
| 187 | + compare(a, b, order::Type{<:AbstractMonomialOrdering}) |
| 188 | +
|
| 189 | +Returns a negative number if `a < b`, a positive number if `a > b` and zero if `a == b`. |
| 190 | +The comparison is done according to `order`. |
| 191 | +""" |
| 192 | +function compare end |
| 193 | + |
| 194 | +""" |
| 195 | + struct LexOrder <: AbstractMonomialOrdering end |
| 196 | +
|
| 197 | +Lexicographic (Lex for short) Order often abbreviated as *lex* order as defined in [CLO13, Definition 2.2.3, p. 56] |
| 198 | +
|
| 199 | +The [`Graded`](@ref) version is often abbreviated as *grlex* order and is defined in [CLO13, Definition 2.2.5, p. 58] |
| 200 | +
|
| 201 | +[CLO13] Cox, D., Little, J., & OShea, D. |
| 202 | +*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*. |
| 203 | +Springer Science & Business Media, **2013**. |
| 204 | +""" |
| 205 | +struct LexOrder <: AbstractMonomialOrdering end |
| 206 | + |
| 207 | +function compare( |
| 208 | + exp1::AbstractVector{T}, |
| 209 | + exp2::AbstractVector{T}, |
| 210 | + ::Type{LexOrder}, |
| 211 | +) where {T} |
| 212 | + if eachindex(exp1) != eachindex(exp2) |
| 213 | + throw( |
| 214 | + ArgumentError( |
| 215 | + "Cannot compare exponent vectors `$exp1` and `$exp2` of different indices.", |
| 216 | + ), |
| 217 | + ) |
| 218 | + end |
| 219 | + @inbounds for i in eachindex(exp1) |
| 220 | + Δ = exp1[i] - exp2[i] |
| 221 | + if !iszero(Δ) |
| 222 | + return Δ |
| 223 | + end |
| 224 | + end |
| 225 | + return zero(T) |
| 226 | +end |
| 227 | + |
| 228 | +""" |
| 229 | + struct InverseLexOrder <: AbstractMonomialOrdering end |
| 230 | +
|
| 231 | +Inverse Lex Order defined in [CLO13, Exercise 2.2.6, p. 61] where it is abbreviated as *invlex*. |
| 232 | +It corresponds to [`LexOrder`](@ref) but with the variables in reverse order. |
| 233 | +
|
| 234 | +The [`Graded`](@ref) version can be abbreviated as *grinvlex* order. |
| 235 | +It is defined in [BDD13, Definition 2.1] where it is called *Graded xel order*. |
| 236 | +
|
| 237 | +[CLO13] Cox, D., Little, J., & OShea, D. |
| 238 | +*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*. |
| 239 | +Springer Science & Business Media, **2013**. |
| 240 | +[BDD13] Batselier, K., Dreesen, P., & De Moor, B. |
| 241 | +*The geometry of multivariate polynomial division and elimination*. |
| 242 | +SIAM Journal on Matrix Analysis and Applications, 34(1), 102-125, *2013*. |
| 243 | +""" |
| 244 | +struct InverseLexOrder <: AbstractMonomialOrdering end |
| 245 | + |
| 246 | +function compare( |
| 247 | + exp1::AbstractVector{T}, |
| 248 | + exp2::AbstractVector{T}, |
| 249 | + ::Type{InverseLexOrder}, |
| 250 | +) where {T} |
| 251 | + if eachindex(exp1) != eachindex(exp2) |
| 252 | + throw( |
| 253 | + ArgumentError( |
| 254 | + "Cannot compare exponent vectors `$exp1` and `$exp2` of different indices.", |
| 255 | + ), |
| 256 | + ) |
| 257 | + end |
| 258 | + @inbounds for i in Iterators.Reverse(eachindex(exp1)) |
| 259 | + Δ = exp1[i] - exp2[i] |
| 260 | + if !iszero(Δ) |
| 261 | + return Δ |
| 262 | + end |
| 263 | + end |
| 264 | + return zero(T) |
| 265 | +end |
| 266 | + |
| 267 | +""" |
| 268 | + struct Graded{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering |
| 269 | + same_degree_ordering::O |
| 270 | + end |
| 271 | +
|
| 272 | +Monomial ordering defined by: |
| 273 | +* `degree(a) == degree(b)` then the ordering is determined by `same_degree_ordering`, |
| 274 | +* otherwise, it is the ordering between the integers `degree(a)` and `degree(b)`. |
| 275 | +""" |
| 276 | +struct Graded{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering |
| 277 | + same_degree_ordering::O |
| 278 | +end |
| 279 | + |
| 280 | +_deg(exponents) = sum(exponents) |
| 281 | +_deg(mono::AbstractMonomial) = degree(mono) |
| 282 | + |
| 283 | +function compare(a, b, ::Type{Graded{O}}) where {O} |
| 284 | + deg_a = _deg(a) |
| 285 | + deg_b = _deg(b) |
| 286 | + if deg_a == deg_b |
| 287 | + return compare(a, b, O) |
| 288 | + else |
| 289 | + return deg_a - deg_b |
| 290 | + end |
| 291 | +end |
| 292 | + |
| 293 | +""" |
| 294 | + struct Reverse{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering |
| 295 | + reverse_order::O |
| 296 | + end |
| 297 | +
|
| 298 | +Monomial ordering defined by |
| 299 | +`compare(a, b, ::Type{Reverse{O}}) where {O} = compare(b, a, O)`. |
| 300 | +
|
| 301 | +Reverse Lex Order defined in [CLO13, Exercise 2.2.9, p. 61] where it is abbreviated as *rinvlex*. |
| 302 | +can be obtained as `Reverse(InverseLexOrder())`. |
| 303 | +
|
| 304 | +The Graded Reverse Lex Order often abbreviated as *grevlex* order defined in [CLO13, Definition 2.2.6, p. 58] |
| 305 | +can be obtained as `Graded(Reverse(InverseLexOrder()))`. |
| 306 | +
|
| 307 | +[CLO13] Cox, D., Little, J., & OShea, D. |
| 308 | +*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*. |
| 309 | +Springer Science & Business Media, **2013**. |
| 310 | +""" |
| 311 | +struct Reverse{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering |
| 312 | + reverse_ordering::O |
| 313 | +end |
| 314 | + |
| 315 | +compare(a, b, ::Type{Reverse{O}}) where {O} = compare(b, a, O) |
0 commit comments