From 03e705a44d1d8588621ac3f9c094b90ad01b4e5a Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 27 Jun 2024 11:52:56 +0200 Subject: [PATCH] Move more code out of src/Hecke*.jl (#1804) --- src/HeckeMiscInteger.jl | 2 - src/HeckeMiscMatrix.jl | 55 -------- src/HeckeMoreStuff.jl | 260 ------------------------------------- src/Nemo.jl | 5 + src/antic/nf_elem.jl | 120 +++++++++++++++++ src/flint/fmpq.jl | 5 + src/flint/fmpq_mpoly.jl | 6 + src/flint/fmpq_poly.jl | 2 + src/flint/fmpz.jl | 14 ++ src/flint/fmpz_mat.jl | 58 ++++++++- src/flint/fmpz_mod.jl | 22 ++++ src/flint/fmpz_poly.jl | 2 +- src/flint/gfp_elem.jl | 30 +++++ src/flint/gfp_fmpz_elem.jl | 11 ++ src/flint/nmod.jl | 22 ++++ src/flint/nmod_mat.jl | 5 + src/julia/Float.jl | 4 + src/julia/Integer.jl | 24 ++++ src/julia/Rational.jl | 1 + 19 files changed, 329 insertions(+), 319 deletions(-) create mode 100644 src/julia/Float.jl create mode 100644 src/julia/Integer.jl create mode 100644 src/julia/Rational.jl diff --git a/src/HeckeMiscInteger.jl b/src/HeckeMiscInteger.jl index e76cf5282..4887ecbd9 100644 --- a/src/HeckeMiscInteger.jl +++ b/src/HeckeMiscInteger.jl @@ -1,5 +1,3 @@ -clog(a::Int, b::Int) = clog(ZZRingElem(a), b) - function Float64(a::QQFieldElem) b = a * ZZRingElem(2)^53 Float64(div(numerator(b), denominator(b))) / (Float64(2)^53) #CF 2^53 is bad in 32bit diff --git a/src/HeckeMiscMatrix.jl b/src/HeckeMiscMatrix.jl index fbf2cc672..b6df9b592 100644 --- a/src/HeckeMiscMatrix.jl +++ b/src/HeckeMiscMatrix.jl @@ -29,61 +29,6 @@ function Array(a::ZZMatrix; S::Type{T}=ZZRingElem) where {T} return A end -################################################################################ -# -################################################################################ - -function maximum(f::typeof(abs), a::ZZMatrix) - r = ZZRingElem() - GC.@preserve a r begin - m = mat_entry_ptr(a, 1, 1) - for i = 1:nrows(a) - for j = 1:ncols(a) - z = mat_entry_ptr(a, i, j) - if ccall((:fmpz_cmpabs, libflint), Cint, (Ptr{ZZRingElem}, Ptr{ZZRingElem}), m, z) < 0 - m = z - end - end - end - ccall((:fmpz_abs, libflint), Nothing, (Ref{ZZRingElem}, Ptr{ZZRingElem}), r, m) - end - return r -end - -function maximum(a::ZZMatrix) - r = ZZRingElem() - GC.@preserve a r begin - m = mat_entry_ptr(a, 1, 1) - for i = 1:nrows(a) - for j = 1:ncols(a) - z = mat_entry_ptr(a, i, j) - if ccall((:fmpz_cmp, libflint), Cint, (Ptr{ZZRingElem}, Ptr{ZZRingElem}), m, z) < 0 - m = z - end - end - end - set!(r, m) - end - return r -end - -function minimum(a::ZZMatrix) - r = ZZRingElem() - GC.@preserve a r begin - m = mat_entry_ptr(a, 1, 1) - for i = 1:nrows(a) - for j = 1:ncols(a) - z = mat_entry_ptr(a, i, j) - if ccall((:fmpz_cmp, libflint), Cint, (Ptr{ZZRingElem}, Ptr{ZZRingElem}), m, z) > 0 - m = z - end - end - end - set!(r, m) - end - return r -end - ################################################################################ # # Lift of matrices to overrings diff --git a/src/HeckeMoreStuff.jl b/src/HeckeMoreStuff.jl index 7d9e83472..ddecbdb90 100644 --- a/src/HeckeMoreStuff.jl +++ b/src/HeckeMoreStuff.jl @@ -1,7 +1,3 @@ -function Base.copy(a::ZZRingElem) - return deepcopy(a) -end - function QQMatrix(x::ZZMatrix) z = zero_matrix(QQ, nrows(x), ncols(x)) ccall((:fmpq_mat_set_fmpz_mat, libflint), Nothing, (Ref{QQMatrix}, Ref{ZZMatrix}), z, x) @@ -140,17 +136,6 @@ function sub!(z::Vector{QQFieldElem}, x::Vector{QQFieldElem}, y::Vector{ZZRingEl return z end -function valuation(a::UInt, b::UInt) - return ccall((:n_remove, libflint), Int, (Ref{UInt}, UInt), a, b) -end - -fits(::Type{Int}, a::Int) = true - -function fits(::Type{Int}, a::Integer) - #TODO: possibly not optimal? - return a % Int == a -end - function (Zx::ZZPolyRing)(a::AbsSimpleNumFieldElem) b = Zx() @assert denominator(a) == 1 @@ -207,15 +192,6 @@ function Base.hash(f::zzModMPolyRingElem, h::UInt) return UInt(1) # TODO: enhance or throw error end -#to make the MPoly module happy, divrem needs it... -function Base.div(a::AbsSimpleNumFieldElem, b::AbsSimpleNumFieldElem) - return a // b -end - -function rem(a::AbsSimpleNumFieldElem, b::AbsSimpleNumFieldElem) - return parent(a)(0) -end - function AbstractAlgebra.map_coefficients(F::fpField, f::QQMPolyRingElem; parent=polynomial_ring(F, nvars(parent(f)), cached=false)[1]) dF = denominator(f) d = F(dF) @@ -259,115 +235,11 @@ function is_squarefree(x::Generic.Poly{AbsSimpleNumFieldElem}) return isone(gcd(x, derivative(x), true)) end -function degree(a::AbsSimpleNumFieldElem) - return degree(minpoly(a)) -end - -################################################################################ -# -# Characteristic polynomial -# -################################################################################ - -function charpoly(Qx::QQPolyRing, a::AbsSimpleNumFieldElem) - f = charpoly(Qx, representation_matrix(a)) - return f -end - -function charpoly(a::AbsSimpleNumFieldElem) - f = charpoly(parent(parent(a).pol), a) - return f -end - -function charpoly(a::AbsSimpleNumFieldElem, ::QQField) - return charpoly(a) -end - -function charpoly(Zx::ZZPolyRing, a::AbsSimpleNumFieldElem) - f = charpoly(a) - if !isone(denominator(f)) - error("Element is not integral") - end - return Zx(f) -end - -function charpoly(a::AbsSimpleNumFieldElem, Z::ZZRing) - return charpoly(polynomial_ring(Z, cached=false)[1], a) -end - -################################################################################ -# -# Minimal polynomial -# -################################################################################ - -@doc raw""" - minpoly(a::AbsSimpleNumFieldElem) -> QQPolyRingElem - -The minimal polynomial of $a$. -""" -function minpoly(Qx::QQPolyRing, a::AbsSimpleNumFieldElem) - f = minpoly(Qx, representation_matrix(a)) - return f -end - -function minpoly(a::AbsSimpleNumFieldElem) - f = minpoly(parent(parent(a).pol), a) - return f -end - -function minpoly(a::AbsSimpleNumFieldElem, ::QQField) - return minpoly(a) -end - -function minpoly(a::AbsSimpleNumFieldElem, ZZ::ZZRing) - return minpoly(polynomial_ring(ZZ, cached=false)[1], a) -end - -function minpoly(Zx::ZZPolyRing, a::AbsSimpleNumFieldElem) - f = minpoly(a) - if !isone(denominator(f)) - error("Element is not integral") - end - return Zx(f) -end - ### -function one!(a::QQMPolyRingElem) - ccall((:fmpq_mpoly_one, libflint), Nothing, - (Ref{QQMPolyRingElem}, Ref{QQMPolyRing}), a, parent(a)) - return a -end - (::QQField)(a::AbsSimpleNumFieldElem) = (is_rational(a) && return coeff(a, 0)) || error("not a rational") (::ZZRing)(a::AbsSimpleNumFieldElem) = (is_integer(a) && return numerator(coeff(a, 0))) || error("not an integer") -function Base.:(^)(a::AbsSimpleNumFieldElem, e::UInt) - b = parent(a)() - ccall((:nf_elem_pow, libflint), Nothing, - (Ref{AbsSimpleNumFieldElem}, Ref{AbsSimpleNumFieldElem}, UInt, Ref{AbsSimpleNumField}), - b, a, e, parent(a)) - return b -end - -Base.copy(f::QQPolyRingElem) = parent(f)(f) - -function basis(K::AbsSimpleNumField) - n = degree(K) - g = gen(K) - d = Array{typeof(g)}(undef, n) - b = K(1) - for i = 1:n-1 - d[i] = b - b *= g - end - d[n] = b - return d -end - -base_field(_::AbsSimpleNumField) = QQ - ################################################################################ # # Base case for dot products @@ -430,10 +302,6 @@ function Base.setprecision(x::BigFloat, p::Int) end end -function setprecision!(x::BigFloat, p::Int) - ccall((:mpfr_prec_round, :libmpfr), Nothing, (Ref{BigFloat}, Clong, Int32), x, p, Base.MPFR.ROUNDING_MODE[]) -end - function evaluate(f::QQPolyRingElem, r::T) where {T<:RingElem} R = parent(r) if iszero(f) @@ -447,18 +315,6 @@ function evaluate(f::QQPolyRingElem, r::T) where {T<:RingElem} return s end -function neg!(w::ZZMatrix) - ccall((:fmpz_mat_neg, libflint), Nothing, (Ref{ZZMatrix}, Ref{ZZMatrix}), w, w) - return w -end - -divexact!(z::Rational{Int}, x::Rational{Int}, y::Rational{Int}) = divexact(x, y) - -@inline function divexact!(z::QQFieldElem, a::QQFieldElem, b::QQFieldElem) - ccall((:fmpq_div, libflint), Nothing, (Ref{QQFieldElem}, Ref{QQFieldElem}, Ref{QQFieldElem}), z, a, b) - return z -end - function mod!(f::ZZPolyRingElem, p::ZZRingElem) for i = 0:degree(f) setcoeff!(f, i, mod(coeff(f, i), p)) @@ -532,13 +388,6 @@ function sub!(a::AbsSimpleNumFieldElem, b::AbsSimpleNumFieldElem, c::AbsSimpleNu a, b, c, a.parent) end -Base.copy(d::AbsSimpleNumFieldElem) = deepcopy(d) - -function addmul!(A::fpMatrix, B::fpMatrix, C::fpFieldElem, D::fpMatrix) - ccall((:nmod_mat_scalar_addmul_ui, libflint), Nothing, (Ref{fpMatrix}, Ref{fpMatrix}, Ref{fpMatrix}, UInt), A, B, D, C.data) - return A -end - function lift(R::ZZAbsPowerSeriesRing, f::ZZModAbsPowerSeriesRingElem) r = R() for i = 0:length(f)-1 @@ -660,12 +509,6 @@ function invmod(f::ZZModPolyRingElem, M::ZZModPolyRingElem) return g end -function divexact!(a::ZZRingElem, b::ZZRingElem) - ccall((:fmpz_divexact, libflint), Nothing, - (Ref{ZZRingElem}, Ref{ZZRingElem}, Ref{ZZRingElem}), a, a, b) - return a -end - function round!(z::ArbFieldElem, x::ArbFieldElem, p::Int) ccall((:arb_set_round, libflint), Nothing, (Ref{ArbFieldElem}, Ref{ArbFieldElem}, Int), z, x, p) z.parent = ArbField(p, cached=false) @@ -694,64 +537,6 @@ function bits(x::AcbFieldElem) return ccall((:acb_bits, libflint), Int, (Ref{AcbFieldElem},), x) end -function Base.Int128(x::ZZRingElem) - return Base.Int128(BigInt(x)) -end - -## Make zzModRing iterable - -Base.iterate(R::zzModRing) = (zero(R), zero(UInt)) - -function Base.iterate(R::zzModRing, st::UInt) - if st == R.n - 1 - return nothing - end - - return R(st + 1), st + 1 -end - -Base.IteratorEltype(::Type{zzModRing}) = Base.HasEltype() -Base.eltype(::Type{zzModRing}) = zzModRingElem - -Base.IteratorSize(::Type{zzModRing}) = Base.HasLength() -Base.length(R::zzModRing) = R.n - -## Make ZZModRing iterable - -Base.iterate(R::ZZModRing) = (zero(R), zero(ZZRingElem)) - -function Base.iterate(R::ZZModRing, st::ZZRingElem) - if st == R.n - 1 - return nothing - end - - return R(st + 1), st + 1 -end - -Base.IteratorEltype(::Type{ZZModRing}) = Base.HasEltype() -Base.eltype(::Type{ZZModRing}) = ZZModRingElem - -Base.IteratorSize(::Type{ZZModRing}) = Base.HasLength() -Base.length(R::ZZModRing) = Integer(R.n) - -## Make fpField iterable - -Base.iterate(R::fpField) = (zero(R), zero(UInt)) - -function Base.iterate(R::fpField, st::UInt) - if st == R.n - 1 - return nothing - end - - return R(st + 1), st + 1 -end - -Base.IteratorEltype(::Type{fpField}) = Base.HasEltype() -Base.eltype(::Type{fpField}) = fpFieldElem - -Base.IteratorSize(::Type{fpField}) = Base.HasLength() -Base.length(R::fpField) = R.n - function order(x::EuclideanRingResidueRingElem{ZZRingElem}, fp::Dict{ZZRingElem,Int64}) error("missing") end @@ -759,20 +544,6 @@ end fit!(::QQRelPowerSeriesRingElem, Int) = nothing fit!(::QQAbsPowerSeriesRingElem, Int) = nothing -function setcoeff!(z::ZZPolyRingElem, n::Int, x::Ptr{ZZRingElem}) - ccall((:fmpz_poly_set_coeff_fmpz, libflint), Nothing, - (Ref{ZZPolyRingElem}, Int, Ptr{ZZRingElem}), z, n, x) - return z -end - -function mul!(a::Ref{ZZRingElem}, b::Ref{ZZRingElem}, c::ZZRingElem) - ccall((:fmpz_mul, libflint), Nothing, (Ref{ZZRingElem}, Ref{ZZRingElem}, Ref{ZZRingElem}), a, b, c) -end - -function iszero(a::Ref{ZZRingElem}) - return unsafe_load(reinterpret(Ptr{Int}, a)) == 0 -end - function gen(R::Union{EuclideanRingResidueRing{fqPolyRepPolyRingElem},EuclideanRingResidueField{fqPolyRepPolyRingElem}}) ## this is not covered by above return R(gen(base_ring(R))) ## and I don't know why end @@ -932,18 +703,6 @@ end characteristic(F::EuclideanRingResidueField{ZZRingElem}) = abs(F.modulus) -function is_prime(x::Integer) - return is_prime(ZZRingElem(x)) -end - -function next_prime(x::BigInt, proved::Bool=true) - return BigInt(next_prime(ZZRingElem(x), proved)) -end - -function next_prime(x::T, proved::Bool=true) where {T<:Integer} - return T(next_prime(BigInt(x), proved)) -end - function mul!(res::QQMPolyRingElem, a::QQMPolyRingElem, c::ZZRingElem) ccall((:fmpq_mpoly_scalar_mul_fmpz, libflint), Nothing, (Ref{QQMPolyRingElem}, Ref{QQMPolyRingElem}, Ref{ZZRingElem}, Ref{QQMPolyRing}), res, a, c, parent(a)) @@ -1041,25 +800,6 @@ function evaluate(f::QQPolyRingElem, a::AbsSimpleNumFieldElem) return s end -function mul!(z::fpFieldElem, x::fpFieldElem, y::ZZRingElem) - R = parent(x) - d = ccall((:fmpz_fdiv_ui, libflint), UInt, (Ref{ZZRingElem}, UInt), y, R.n) - r = mulmod(x.data, d, R.n, R.ninv) - z.data = r - return z -end - -function mul!(z::FpFieldElem, x::FpFieldElem, y::ZZRingElem) - R = parent(x) - ccall((:fmpz_mod, libflint), Nothing, (Ref{ZZRingElem}, Ref{ZZRingElem}, Ref{ZZRingElem}), - z.data, y, R.n) - - ccall((:fmpz_mod_mul, libflint), Nothing, - (Ref{ZZRingElem}, Ref{ZZRingElem}, Ref{ZZRingElem}, Ref{fmpz_mod_ctx_struct}), - z.data, x.data, z.data, R.ninv) - return z -end - function rem!(z::fpPolyRingElem, a::fpPolyRingElem, b::fpPolyRingElem) ccall((:nmod_poly_rem, libflint), Nothing, (Ref{fpPolyRingElem}, Ref{fpPolyRingElem}, Ref{fpPolyRingElem}, Ptr{Nothing}), diff --git a/src/Nemo.jl b/src/Nemo.jl index 913ba5350..8f4f736d9 100644 --- a/src/Nemo.jl +++ b/src/Nemo.jl @@ -460,6 +460,11 @@ include("HeckeMiscMatrix.jl") include("HeckeMiscPoly.jl") include("HeckeMoreStuff.jl") +# More functionality for Julia types +include("julia/Integer.jl") +include("julia/Rational.jl") +include("julia/Float.jl") + ############################################################################### # # satellite functionality diff --git a/src/antic/nf_elem.jl b/src/antic/nf_elem.jl index 4b28193fb..6ddf4fe20 100644 --- a/src/antic/nf_elem.jl +++ b/src/antic/nf_elem.jl @@ -222,6 +222,8 @@ function deepcopy_internal(d::AbsSimpleNumFieldElem, dict::IdDict) return z end +Base.copy(d::AbsSimpleNumFieldElem) = deepcopy(d) + function is_cyclo_type(K::AbsSimpleNumField) return has_attribute(K, :cyclo) end @@ -626,6 +628,21 @@ divexact(a::ZZRingElem, b::AbsSimpleNumFieldElem; check::Bool=true) = inv(b)*a divexact(a::QQFieldElem, b::AbsSimpleNumFieldElem; check::Bool=true) = inv(b)*a +############################################################################### +# +# Ad hoc division +# +############################################################################### + +#to make the MPoly module happy, divrem needs it... +function Base.div(a::AbsSimpleNumFieldElem, b::AbsSimpleNumFieldElem) + return a // b +end + +function rem(a::AbsSimpleNumFieldElem, b::AbsSimpleNumFieldElem) + return parent(a)(0) +end + ############################################################################### # # Removal and valuation @@ -1259,3 +1276,106 @@ function preimage(f::Generic.EuclideanRingResidueMap{QQPolyRing, AbsSimpleNumFie parent(x) !== codomain(f) && error("Not an element of the codomain") return domain(f)(x) end + +################################################################################ +# +# Characteristic polynomial +# +################################################################################ + +function charpoly(Qx::QQPolyRing, a::AbsSimpleNumFieldElem) + f = charpoly(Qx, representation_matrix(a)) + return f +end + +function charpoly(a::AbsSimpleNumFieldElem) + f = charpoly(parent(parent(a).pol), a) + return f +end + +function charpoly(a::AbsSimpleNumFieldElem, ::QQField) + return charpoly(a) +end + +function charpoly(Zx::ZZPolyRing, a::AbsSimpleNumFieldElem) + f = charpoly(a) + if !isone(denominator(f)) + error("Element is not integral") + end + return Zx(f) +end + +function charpoly(a::AbsSimpleNumFieldElem, Z::ZZRing) + return charpoly(polynomial_ring(Z, cached=false)[1], a) +end + +################################################################################ +# +# Minimal polynomial +# +################################################################################ + +@doc raw""" + minpoly(a::AbsSimpleNumFieldElem) -> QQPolyRingElem + +The minimal polynomial of $a$. +""" +function minpoly(Qx::QQPolyRing, a::AbsSimpleNumFieldElem) + f = minpoly(Qx, representation_matrix(a)) + return f +end + +function minpoly(a::AbsSimpleNumFieldElem) + f = minpoly(parent(parent(a).pol), a) + return f +end + +function minpoly(a::AbsSimpleNumFieldElem, ::QQField) + return minpoly(a) +end + +function minpoly(a::AbsSimpleNumFieldElem, ZZ::ZZRing) + return minpoly(polynomial_ring(ZZ, cached=false)[1], a) +end + +function minpoly(Zx::ZZPolyRing, a::AbsSimpleNumFieldElem) + f = minpoly(a) + if !isone(denominator(f)) + error("Element is not integral") + end + return Zx(f) +end + +################################################################################ +# +# Miscellaneous +# +################################################################################ + +function degree(a::AbsSimpleNumFieldElem) + return degree(minpoly(a)) +end + + +function Base.:(^)(a::AbsSimpleNumFieldElem, e::UInt) + b = parent(a)() + ccall((:nf_elem_pow, libflint), Nothing, + (Ref{AbsSimpleNumFieldElem}, Ref{AbsSimpleNumFieldElem}, UInt, Ref{AbsSimpleNumField}), + b, a, e, parent(a)) + return b +end + +function basis(K::AbsSimpleNumField) + n = degree(K) + g = gen(K) + d = Array{typeof(g)}(undef, n) + b = K(1) + for i = 1:n-1 + d[i] = b + b *= g + end + d[n] = b + return d +end + +base_field(::AbsSimpleNumField) = QQ diff --git a/src/flint/fmpq.jl b/src/flint/fmpq.jl index b52cb494d..73d0616f2 100644 --- a/src/flint/fmpq.jl +++ b/src/flint/fmpq.jl @@ -1212,6 +1212,11 @@ end return z end +@inline function divexact!(z::QQFieldElem, a::QQFieldElem, b::QQFieldElem) + ccall((:fmpq_div, libflint), Nothing, (Ref{QQFieldElem}, Ref{QQFieldElem}, Ref{QQFieldElem}), z, a, b) + return z +end + ############################################################################### # # Parent object call overloads diff --git a/src/flint/fmpq_mpoly.jl b/src/flint/fmpq_mpoly.jl index f0344f06a..37bc581a5 100644 --- a/src/flint/fmpq_mpoly.jl +++ b/src/flint/fmpq_mpoly.jl @@ -825,6 +825,12 @@ function zero!(a::QQMPolyRingElem) return a end +function one!(a::QQMPolyRingElem) + ccall((:fmpq_mpoly_one, libflint), Nothing, + (Ref{QQMPolyRingElem}, Ref{QQMPolyRing}), a, parent(a)) + return a +end + function add!(a::QQMPolyRingElem, b::QQMPolyRingElem, c::QQMPolyRingElem) ccall((:fmpq_mpoly_add, libflint), Nothing, (Ref{QQMPolyRingElem}, Ref{QQMPolyRingElem}, diff --git a/src/flint/fmpq_poly.jl b/src/flint/fmpq_poly.jl index 7dff39333..0945538d1 100644 --- a/src/flint/fmpq_poly.jl +++ b/src/flint/fmpq_poly.jl @@ -73,6 +73,8 @@ function deepcopy_internal(a::QQPolyRingElem, dict::IdDict) return z end +Base.copy(f::QQPolyRingElem) = parent(f)(f) + ############################################################################### # # Similar diff --git a/src/flint/fmpz.jl b/src/flint/fmpz.jl index d9c477c2f..1d0def6cd 100644 --- a/src/flint/fmpz.jl +++ b/src/flint/fmpz.jl @@ -188,6 +188,8 @@ function deepcopy_internal(a::ZZRingElem, dict::IdDict) return z end +Base.copy(a::ZZRingElem) = deepcopy(a) + characteristic(R::ZZRing) = 0 one(::ZZRing) = ZZRingElem(1) @@ -251,6 +253,10 @@ is_unit(a::ZZRingElem) = ccall((:fmpz_is_pm1, libflint), Bool, (Ref{ZZRingElem}, iszero(a::ZZRingElem) = ccall((:fmpz_is_zero, libflint), Bool, (Ref{ZZRingElem},), a) +function iszero(a::Ref{ZZRingElem}) + return unsafe_load(reinterpret(Ptr{Int}, a)) == 0 +end + isone(a::ZZRingElem) = ccall((:fmpz_is_one, libflint), Bool, (Ref{ZZRingElem},), a) isinteger(::ZZRingElem) = true @@ -2712,6 +2718,10 @@ function mul!(z::ZZRingElem, x::ZZRingElem, y::ZZRingElem) return z end +function mul!(a::Ref{ZZRingElem}, b::Ref{ZZRingElem}, c::ZZRingElem) + ccall((:fmpz_mul, libflint), Nothing, (Ref{ZZRingElem}, Ref{ZZRingElem}, Ref{ZZRingElem}), a, b, c) +end + function mul!(z::ZZRingElem, x::ZZRingElem, y::Int) ccall((:fmpz_mul_si, libflint), Nothing, (Ref{ZZRingElem}, Ref{ZZRingElem}, Int), z, x, y) @@ -2794,6 +2804,8 @@ function divexact!(z::ZZRingElem, a::ZZRingElem, b::ZZRingElem) return z end +divexact!(z::ZZRingElem, b::ZZRingElem) = divexact!(z, z, b) + function pow!(z::ZZRingElem, a::ZZRingElem, b::Union{Int, UInt}) ccall((:fmpz_pow_ui, libflint), Nothing, (Ref{ZZRingElem}, Ref{ZZRingElem}, UInt), @@ -3050,6 +3062,8 @@ end (::Type{T})(a::ZZRingElem) where T <: Union{UInt8, UInt16, UInt32} = T(UInt(a)) +(::Type{Int128})(a::ZZRingElem) = Int128(BigInt(a)) + convert(::Type{T}, a::ZZRingElem) where T <: Integer = T(a) function (::Type{Float64})(n::ZZRingElem) diff --git a/src/flint/fmpz_mat.jl b/src/flint/fmpz_mat.jl index 3da58311d..3b821069a 100644 --- a/src/flint/fmpz_mat.jl +++ b/src/flint/fmpz_mat.jl @@ -823,7 +823,7 @@ function hadamard_bound2(M::ZZMatrix) return H end -function Base.maximum(::typeof(nbits), M::ZZMatrix) +function maximum(::typeof(nbits), M::ZZMatrix) mx = 0 n = nrows(M) m = ncols(M) @@ -845,6 +845,57 @@ function Base.maximum(::typeof(nbits), M::ZZMatrix) return Int(mx) end +function maximum(f::typeof(abs), a::ZZMatrix) + r = ZZRingElem() + GC.@preserve a r begin + m = mat_entry_ptr(a, 1, 1) + for i = 1:nrows(a) + for j = 1:ncols(a) + z = mat_entry_ptr(a, i, j) + if ccall((:fmpz_cmpabs, libflint), Cint, (Ptr{ZZRingElem}, Ptr{ZZRingElem}), m, z) < 0 + m = z + end + end + end + ccall((:fmpz_abs, libflint), Nothing, (Ref{ZZRingElem}, Ptr{ZZRingElem}), r, m) + end + return r +end + +function maximum(a::ZZMatrix) + r = ZZRingElem() + GC.@preserve a r begin + m = mat_entry_ptr(a, 1, 1) + for i = 1:nrows(a) + for j = 1:ncols(a) + z = mat_entry_ptr(a, i, j) + if ccall((:fmpz_cmp, libflint), Cint, (Ptr{ZZRingElem}, Ptr{ZZRingElem}), m, z) < 0 + m = z + end + end + end + set!(r, m) + end + return r +end + +function minimum(a::ZZMatrix) + r = ZZRingElem() + GC.@preserve a r begin + m = mat_entry_ptr(a, 1, 1) + for i = 1:nrows(a) + for j = 1:ncols(a) + z = mat_entry_ptr(a, i, j) + if ccall((:fmpz_cmp, libflint), Cint, (Ptr{ZZRingElem}, Ptr{ZZRingElem}), m, z) > 0 + m = z + end + end + end + set!(r, m) + end + return r +end + ############################################################################### # # Gram matrix @@ -1884,6 +1935,11 @@ function zero!(z::ZZMatrix) return z end +function neg!(w::ZZMatrix) + ccall((:fmpz_mat_neg, libflint), Nothing, (Ref{ZZMatrix}, Ref{ZZMatrix}), w, w) + return w +end + function mul!(z::Vector{ZZRingElem}, a::ZZMatrix, b::Vector{ZZRingElem}) ccall((:fmpz_mat_mul_fmpz_vec_ptr, libflint), Nothing, (Ptr{Ref{ZZRingElem}}, Ref{ZZMatrix}, Ptr{Ref{ZZRingElem}}, Int), diff --git a/src/flint/fmpz_mod.jl b/src/flint/fmpz_mod.jl index 9f5a8f84a..c184cb514 100644 --- a/src/flint/fmpz_mod.jl +++ b/src/flint/fmpz_mod.jl @@ -458,3 +458,25 @@ end function residue_ring(R::ZZRing, n::Integer; cached::Bool=true) return residue_ring(R, ZZRingElem(n)) end + +############################################################################### +# +# Iterator interface +# +############################################################################### + +Base.iterate(R::ZZModRing) = (zero(R), zero(ZZRingElem)) + +function Base.iterate(R::ZZModRing, st::ZZRingElem) + if st == R.n - 1 + return nothing + end + + return R(st + 1), st + 1 +end + +Base.IteratorEltype(::Type{ZZModRing}) = Base.HasEltype() +Base.eltype(::Type{ZZModRing}) = ZZModRingElem + +Base.IteratorSize(::Type{ZZModRing}) = Base.HasLength() +Base.length(R::ZZModRing) = Integer(R.n) diff --git a/src/flint/fmpz_poly.jl b/src/flint/fmpz_poly.jl index b77511298..56666298e 100644 --- a/src/flint/fmpz_poly.jl +++ b/src/flint/fmpz_poly.jl @@ -868,7 +868,7 @@ function fit!(z::ZZPolyRingElem, n::Int) return nothing end -function setcoeff!(z::ZZPolyRingElem, n::Int, x::ZZRingElem) +function setcoeff!(z::ZZPolyRingElem, n::Int, x::ZZRingElemOrPtr) ccall((:fmpz_poly_set_coeff_fmpz, libflint), Nothing, (Ref{ZZPolyRingElem}, Int, Ref{ZZRingElem}), z, n, x) return z diff --git a/src/flint/gfp_elem.jl b/src/flint/gfp_elem.jl index e0692effe..fa316e2be 100644 --- a/src/flint/gfp_elem.jl +++ b/src/flint/gfp_elem.jl @@ -348,6 +348,14 @@ function mul!(z::fpFieldElem, x::fpFieldElem, y::fpFieldElem) return x*y end +function mul!(z::fpFieldElem, x::fpFieldElem, y::ZZRingElem) + R = parent(x) + d = ccall((:fmpz_fdiv_ui, libflint), UInt, (Ref{ZZRingElem}, UInt), y, R.n) + r = mulmod(x.data, d, R.n, R.ninv) + z.data = r + return z +end + function addeq!(z::fpFieldElem, x::fpFieldElem) return z + x end @@ -480,3 +488,25 @@ end function representation_matrix(a::fpFieldElem) return matrix(parent(a), 1, 1, [a]) end + +############################################################################### +# +# Iterator interface +# +############################################################################### + +Base.iterate(R::fpField) = (zero(R), zero(UInt)) + +function Base.iterate(R::fpField, st::UInt) + if st == R.n - 1 + return nothing + end + + return R(st + 1), st + 1 +end + +Base.IteratorEltype(::Type{fpField}) = Base.HasEltype() +Base.eltype(::Type{fpField}) = fpFieldElem + +Base.IteratorSize(::Type{fpField}) = Base.HasLength() +Base.length(R::fpField) = R.n diff --git a/src/flint/gfp_fmpz_elem.jl b/src/flint/gfp_fmpz_elem.jl index a24adee62..b4a6de68f 100644 --- a/src/flint/gfp_fmpz_elem.jl +++ b/src/flint/gfp_fmpz_elem.jl @@ -362,6 +362,17 @@ function mul!(z::FpFieldElem, x::FpFieldElem, y::FpFieldElem) return z end +function mul!(z::FpFieldElem, x::FpFieldElem, y::ZZRingElem) + R = parent(x) + ccall((:fmpz_mod, libflint), Nothing, (Ref{ZZRingElem}, Ref{ZZRingElem}, Ref{ZZRingElem}), + z.data, y, R.n) + + ccall((:fmpz_mod_mul, libflint), Nothing, + (Ref{ZZRingElem}, Ref{ZZRingElem}, Ref{ZZRingElem}, Ref{fmpz_mod_ctx_struct}), + z.data, x.data, z.data, R.ninv) + return z +end + function addeq!(z::FpFieldElem, x::FpFieldElem) R = parent(z) ccall((:fmpz_mod_add, libflint), Nothing, diff --git a/src/flint/nmod.jl b/src/flint/nmod.jl index 3c3248108..ecd242fc5 100644 --- a/src/flint/nmod.jl +++ b/src/flint/nmod.jl @@ -482,3 +482,25 @@ function residue_ring(R::ZZRing, n::UInt; cached::Bool=true) f = Generic.EuclideanRingResidueMap(R, S) return S, f end + +############################################################################### +# +# Iterator interface +# +############################################################################### + +Base.iterate(R::zzModRing) = (zero(R), zero(UInt)) + +function Base.iterate(R::zzModRing, st::UInt) + if st == R.n - 1 + return nothing + end + + return R(st + 1), st + 1 +end + +Base.IteratorEltype(::Type{zzModRing}) = Base.HasEltype() +Base.eltype(::Type{zzModRing}) = zzModRingElem + +Base.IteratorSize(::Type{zzModRing}) = Base.HasLength() +Base.length(R::zzModRing) = R.n diff --git a/src/flint/nmod_mat.jl b/src/flint/nmod_mat.jl index 9c0f1e4af..f6bfa87d2 100644 --- a/src/flint/nmod_mat.jl +++ b/src/flint/nmod_mat.jl @@ -298,6 +298,11 @@ function mul!(A::fpMatrix, B::fpFieldElem, D::fpMatrix) return A end +function addmul!(A::fpMatrix, B::fpMatrix, C::fpFieldElem, D::fpMatrix) + ccall((:nmod_mat_scalar_addmul_ui, libflint), Nothing, (Ref{fpMatrix}, Ref{fpMatrix}, Ref{fpMatrix}, UInt), A, B, D, C.data) + return A +end + function Generic.add_one!(a::T, i::Int, j::Int) where T <: Zmodn_mat @boundscheck _checkbounds(a, i, j) x = getindex_raw(a, i, j) diff --git a/src/julia/Float.jl b/src/julia/Float.jl new file mode 100644 index 000000000..5737183cb --- /dev/null +++ b/src/julia/Float.jl @@ -0,0 +1,4 @@ +function setprecision!(x::BigFloat, p::Int) + ccall((:mpfr_prec_round, :libmpfr), Nothing, (Ref{BigFloat}, Clong, Int32), x, p, Base.MPFR.ROUNDING_MODE[]) +end + diff --git a/src/julia/Integer.jl b/src/julia/Integer.jl new file mode 100644 index 000000000..99c9912a3 --- /dev/null +++ b/src/julia/Integer.jl @@ -0,0 +1,24 @@ +function is_prime(x::Integer) + return is_prime(ZZRingElem(x)) +end + +function next_prime(x::BigInt, proved::Bool=true) + return BigInt(next_prime(ZZRingElem(x), proved)) +end + +function next_prime(x::T, proved::Bool=true) where {T<:Integer} + return T(next_prime(BigInt(x), proved)) +end + +function valuation(a::UInt, b::UInt) + return ccall((:n_remove, libflint), Int, (Ref{UInt}, UInt), a, b) +end + +fits(::Type{Int}, a::Int) = true + +function fits(::Type{Int}, a::Integer) + #TODO: possibly not optimal? + return a % Int == a +end + +clog(a::Int, b::Int) = clog(ZZRingElem(a), b) diff --git a/src/julia/Rational.jl b/src/julia/Rational.jl new file mode 100644 index 000000000..889ee4b0a --- /dev/null +++ b/src/julia/Rational.jl @@ -0,0 +1 @@ +divexact!(z::Rational{Int}, x::Rational{Int}, y::Rational{Int}) = divexact(x, y)