Skip to content

Commit

Permalink
Rewrite to use flintify
Browse files Browse the repository at this point in the history
  • Loading branch information
fingolfin committed Sep 26, 2024
1 parent 18923be commit 05d75a0
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 46 deletions.
54 changes: 22 additions & 32 deletions src/flint/FlintTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1363,7 +1363,7 @@ mutable struct ZZMPolyRingElem <: MPolyRingElem{ZZRingElem}
return z
end

ZZMPolyRingElem(ctx::ZZMPolyRing, a::Integer) = ZZMPolyRingElem(ctx, FlintInt(a))
ZZMPolyRingElem(ctx::ZZMPolyRing, a::Integer) = ZZMPolyRingElem(ctx, flintify(a))
end

function _fmpz_mpoly_clear_fn(a::ZZMPolyRingElem)
Expand Down Expand Up @@ -6472,20 +6472,21 @@ of methods that accept both Julia and Nemo integers or rationals.
const RationalUnion = Union{Integer, ZZRingElem, Rational, QQFieldElem}

"""
FlintInt = Union{Int, ZZRingElem}
flintify(x::RationalUnion)
The `FlintInt` type union is an internal helper for cleanly and compactly
implementing efficient dispatch for arithmetics that involve native Nemo
objects plus a Julia integer.
Return either an `Int`, `ZZRingElem` or `QQFieldElem` equal to `x`.
Many internal arithmetics functions in FLINT have optimize variants for
the case when one operand is an `ZZRingElem` or an `Int` (sometimes also
`UInt` is supported). E.g. there are special methods for adding
one of these to a `ZZRingPolyElem`.
This internal helper allow us to cleanly and compactly implement efficient
dispatch for arithmetics that involve native Nemo objects plus a Julia
integer.
In order to handling adding an arbitrary Julia integer to a
`ZZRingPolyElem`, further dispatch is needed. The easiest is to
provide a method
Indeed, many internal arithmetics functions in FLINT have optimize variants
for the case when one operand is an `ZZRingElem` or an `Int` (sometimes also
`UInt` is supported). E.g. there are special methods for adding one of these
to a `ZZRingPolyElem`.
In order to handling adding an arbitrary Julia integer to a `ZZRingPolyElem`,
further dispatch is needed. The easiest is to provide a method
+(a::ZZRingPolyElem, b::Integer) = a + ZZ(b)
Expand All @@ -6496,37 +6497,26 @@ do this (at least on a 64 bit machine):
+(a::ZZRingPolyElem, b::{Int64,Int32,Int16,Int8,UInt32,UInt16,UInt8}) = a + Int(b)
Doing this repeatedly is cumbersome and error prone. This can be avoided by
using `FlintInt`, which allows us to write
using `flintify`, which allows us to write
+(a::ZZRingPolyElem, b::Integer) = a + FlintInt(b)
+(a::ZZRingPolyElem, b::Integer) = a + flintify(b)
to get optimal dispatch.
This also works for Nemo types that also have special handlers for `UInt`,
as their method for `b::UInt` takes precedence over the fallback method.
"""
const FlintInt = Union{Int, ZZRingElem}

FlintInt(x::ZZRingElem) = x
FlintInt(x::Integer) = ZZRingElem(x)::ZZRingElem
flintify(x::ZZRingElem) = x
flintify(x::QQFieldElem) = x
flintify(x::Int) = x
flintify(x::Integer) = ZZRingElem(x)::ZZRingElem
flintify(x::Rational) = QQFieldElem(x)::QQFieldElem
@static if Int === Int64
FlintInt(x::Union{Int64,Int32,Int16,Int8,UInt32,UInt16,UInt8}) = Int(x)
flintify(x::Union{Int64,Int32,Int16,Int8,UInt32,UInt16,UInt8}) = Int(x)
else
FlintInt(x::Union{Int32,Int16,Int8,UInt16,UInt8}) = Int(x)
flintify(x::Union{Int32,Int16,Int8,UInt16,UInt8}) = Int(x)
end

"""
FlintRat = Union{FlintInt, QQFieldElem}
The `FlintRat` type union is an internal helper similar to [`FlintInt`](@ref)
but also accepting `QQFieldElem` and `Rational{<:Integer}` arguments.
"""
const FlintRat = Union{FlintInt, QQFieldElem}

FlintRat(x::QQFieldElem) = x
FlintRat(x::Rational{<:Integer}) = QQFieldElem(x)::QQFieldElem
FlintRat(x::Integer) = FlintInt(x)


const ZmodNFmpzPolyRing = Union{ZZModPolyRing, FpPolyRing}

Expand Down
14 changes: 7 additions & 7 deletions src/flint/fmpq_mpoly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -364,11 +364,11 @@ for (jT, cN, cT) in ((QQFieldElem, :fmpq, Ref{QQFieldElem}), (ZZRingElem, :fmpz,
end
end

+(a::QQMPolyRingElem, b::Integer) = a + FlintInt(b)
+(a::QQMPolyRingElem, b::Integer) = a + flintify(b)

+(a::Integer, b::QQMPolyRingElem) = b + a

-(a::QQMPolyRingElem, b::Integer) = a - FlintInt(b)
-(a::QQMPolyRingElem, b::Integer) = a - flintify(b)

-(a::Integer, b::QQMPolyRingElem) = neg!(b - a)

Expand All @@ -380,19 +380,19 @@ end

-(a::Rational{<:Integer}, b::QQMPolyRingElem) = neg!(b - a)

*(a::QQMPolyRingElem, b::Integer) = a * FlintInt(b)
*(a::QQMPolyRingElem, b::Integer) = a * flintify(b)

*(a::Integer, b::QQMPolyRingElem) = b * a

*(a::QQMPolyRingElem, b::Rational{<:Integer}) = a * QQFieldElem(b)

*(a::Rational{<:Integer}, b::QQMPolyRingElem) = b * a

divexact(a::QQMPolyRingElem, b::Integer; check::Bool=true) = divexact(a, FlintInt(b); check=check)
divexact(a::QQMPolyRingElem, b::Integer; check::Bool=true) = divexact(a, flintify(b); check=check)

divexact(a::QQMPolyRingElem, b::Rational{<:Integer}; check::Bool=true) = divexact(a, QQFieldElem(b); check=check)

//(a::QQMPolyRingElem, b::Integer) = //(a, FlintInt(b))
//(a::QQMPolyRingElem, b::Integer) = //(a, flintify(b))

//(a::QQMPolyRingElem, b::Rational{<:Integer}) = //(a, QQFieldElem(b))

Expand Down Expand Up @@ -573,7 +573,7 @@ end

==(a::Int, b::QQMPolyRingElem) = b == a

==(a::QQMPolyRingElem, b::Integer) = a == FlintInt(b)
==(a::QQMPolyRingElem, b::Integer) = a == flintify(b)

==(a::Integer, b::QQMPolyRingElem) = b == a

Expand Down Expand Up @@ -1186,7 +1186,7 @@ function (R::QQMPolyRing)(b::RationalUnion)
return z
end

QQMPolyRingElem(ctx::QQMPolyRing, a::RationalUnion) = QQMPolyRingElem(ctx, FlintRat(a))
QQMPolyRingElem(ctx::QQMPolyRing, a::RationalUnion) = QQMPolyRingElem(ctx, flintify(a))

function (R::QQMPolyRing)(a::QQMPolyRingElem)
parent(a) != R && error("Unable to coerce polynomial")
Expand Down
14 changes: 7 additions & 7 deletions src/flint/fmpz_poly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -225,17 +225,17 @@ end

*(x::ZZPolyRingElem, y::ZZRingElem) = y*x

+(x::Integer, y::ZZPolyRingElem) = y + FlintInt(x)
+(x::Integer, y::ZZPolyRingElem) = y + flintify(x)

-(x::Integer, y::ZZPolyRingElem) = FlintInt(x) - y
-(x::Integer, y::ZZPolyRingElem) = flintify(x) - y

*(x::Integer, y::ZZPolyRingElem) = FlintInt(x)*y
*(x::Integer, y::ZZPolyRingElem) = flintify(x)*y

+(x::ZZPolyRingElem, y::Integer) = x + FlintInt(y)
+(x::ZZPolyRingElem, y::Integer) = x + flintify(y)

-(x::ZZPolyRingElem, y::Integer) = x - FlintInt(y)
-(x::ZZPolyRingElem, y::Integer) = x - flintify(y)

*(x::ZZPolyRingElem, y::Integer) = FlintInt(y)*x
*(x::ZZPolyRingElem, y::Integer) = flintify(y)*x

###############################################################################
#
Expand Down Expand Up @@ -943,7 +943,7 @@ function (a::ZZPolyRing)()
end

function (a::ZZPolyRing)(b::IntegerUnion)
z = ZZPolyRingElem(FlintInt(b))
z = ZZPolyRingElem(flintify(b))
z.parent = a
return z
end
Expand Down

0 comments on commit 05d75a0

Please sign in to comment.