From 701c58cdbdc2f1a1c6f165a6e20153f34a040ddb Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 8 Oct 2024 11:38:11 +0200 Subject: [PATCH 1/2] Introduce low-level analogs for Flint structs --- src/flint/CTypes.jl | 255 ++++++++++++++++++++++++++++++++++++++++ src/flint/FlintTypes.jl | 33 ++---- src/flint/fmpq_poly.jl | 4 +- src/flint/nmod_poly.jl | 6 +- 4 files changed, 273 insertions(+), 25 deletions(-) create mode 100644 src/flint/CTypes.jl diff --git a/src/flint/CTypes.jl b/src/flint/CTypes.jl new file mode 100644 index 000000000..e120e6360 --- /dev/null +++ b/src/flint/CTypes.jl @@ -0,0 +1,255 @@ +############################################################################### +# +# Flint C types +# +############################################################################### + +module Flint + +# +# C types (names provided to ease automatic conversion of struct definitions) +# +const int = Cint +const char = Cchar + +# +# from flint.h +# +const ulong = Culong +const slong = Clong + +const flint_bitcnt_t = ulong +const nn_ptr = Ptr{ulong} + +const fmpz = Clong + +const fmpz_t = Ptr{fmpz} + +struct fmpq + num::fmpz + den::fmpz +end + +const fmpq_t = Ptr{fmpq} + +struct nmod_t + n::ulong + ninv::ulong + norm::flint_bitcnt_t +end + +# +# from limb_types.h +# + +const FLINT_MAX_FACTORS_IN_LIMB = 15 + +struct n_factor_t + num::int + exp::NTuple{FLINT_MAX_FACTORS_IN_LIMB, int} + p::NTuple{FLINT_MAX_FACTORS_IN_LIMB, ulong} +end + +struct n_primes_struct + small_i::slong + small_num::slong + small_primes::Ptr{Cuint} + + sieve_a::ulong + sieve_b::ulong + sieve_i::slong + sieve_num::slong + sieve::Ptr{char} +end + +# +# from fmpz_types.h +# + +struct zz_struct + alloc::int + size::int + ptr::nn_ptr +end + +const zz_ptr = Ptr{zz_struct} + +struct fmpz_factor_struct + sign::int + p::Ptr{fmpz} + exp::Ptr{ulong} + alloc::slong + num::slong +end + +struct fmpz_preinvn_struct + dinv::nn_ptr + n::slong + norm::flint_bitcnt_t +end + +struct fmpz_poly_struct + coeffs::Ptr{fmpz} + alloc::slong + length::slong +end + +struct fmpz_poly_factor_struct + c::fmpz + p::Ptr{fmpz_poly_struct} + exp::Ptr{slong} + num::slong + alloc::slong +end + +struct fmpz_mat_struct + entries::Ptr{fmpz} + r::slong + c::slong + rows::Ptr{Ptr{fmpz}} +end + +struct fmpz_poly_mat_struct + entries::Ptr{fmpz_poly_struct} + r::slong + c::slong + rows::Ptr{Ptr{fmpz_poly_struct}} +end + +struct fmpz_mpoly_struct + coeffs::Ptr{fmpz} + exps::Ptr{ulong} + alloc::slong + length::slong + bits::flint_bitcnt_t +end + +struct fmpz_mpoly_factor_struct + constant::fmpz_t + constant_den::fmpz_t + poly::Ptr{fmpz_mpoly_struct} + exp::Ptr{fmpz} + num::slong + alloc::slong +end + +struct fmpz_poly_q_struct + num::Ptr{fmpz_poly_struct} + den::Ptr{fmpz_poly_struct} +end + +struct fmpz_mpoly_q_struct + num::fmpz_mpoly_struct + den::fmpz_mpoly_struct +end + +struct fmpzi_struct + a::fmpz + b::fmpz +end + + +# +# from nmod_types.h +# +struct nmod_mat_struct + entries::Ptr{ulong} + r::slong + c::slong + rows::Ptr{Ptr{ulong}} + mod::nmod_t +end + +struct nmod_poly_struct + coeffs::nn_ptr + alloc::slong + length::slong + mod::nmod_t +end + +const nmod_poly_t = Ptr{nmod_poly_struct} + +struct nmod_poly_factor_struct + p::Ptr{nmod_poly_struct} + exp::Ptr{slong} + num::slong + alloc::slong +end + +struct nmod_poly_mat_struct + entries::Ptr{nmod_poly_struct} + r::slong + c::slong + rows::Ptr{Ptr{nmod_poly_struct}} + modulus::ulong +end + +struct nmod_mpoly_struct + coeffs::Ptr{ulong} + exps::Ptr{ulong} + length::slong + bits::flint_bitcnt_t + coeffs_alloc::slong + exps_alloc::slong +end + +struct nmod_mpoly_factor_struct + constant::ulong + poly::Ptr{nmod_mpoly_struct} + exp::Ptr{fmpz} + num::slong + alloc::slong +end + +# +# from fq_nmod_types.h +# + +const fq_nmod_struct = nmod_poly_struct + +struct fq_nmod_ctx_struct + mod::nmod_t + + sparse_modulus::int + is_conway::int + + a::Ptr{ulong} + j::Ptr{slong} + len::slong + + modulus::nmod_poly_t + inv::nmod_poly_t + + var::Ptr{char} +end + +struct fq_nmod_mat_struct + entries::Ptr{fq_nmod_struct} + r::slong + c::slong + rows::Ptr{Ptr{fq_nmod_struct}} +end + +struct fq_nmod_poly_struct + coeffs::Ptr{fq_nmod_struct} + alloc::slong + length::slong +end + +struct fq_nmod_poly_factor_struct + poly::Ptr{fq_nmod_poly_struct} + exp::Ptr{slong} + num::slong + alloc::slong +end + +struct fq_nmod_mpoly_struct + coeffs::Ptr{ulong} + exps::Ptr{ulong} + length::slong + bits::flint_bitcnt_t + coeffs_alloc::slong + exps_alloc::slong +end + +end diff --git a/src/flint/FlintTypes.jl b/src/flint/FlintTypes.jl index 92c7e8faa..84d2c6ef0 100644 --- a/src/flint/FlintTypes.jl +++ b/src/flint/FlintTypes.jl @@ -6,6 +6,8 @@ const _err_dim_negative = ErrorException("Dimensions must be non-negative") +include("CTypes.jl") + ############################################################################### # # ZZRing / ZZRingElem @@ -42,7 +44,7 @@ integer_ring() = ZZRing() @doc zz_ring_doc mutable struct ZZRingElem <: RingElem - d::Int + d::Flint.fmpz function ZZRingElem() z = new() @@ -92,11 +94,7 @@ function _fmpz_clear_fn(a::ZZRingElem) end mutable struct fmpz_factor - sign::Cint - p::Ptr{Nothing} # Array of fmpz_struct's - exp::Ptr{UInt} - alloc::Int - num::Int + data::Flint.fmpz_factor_struct function fmpz_factor() z = new() @@ -241,9 +239,7 @@ end const FmpzPolyID = CacheDictType{Symbol, ZZPolyRing}() mutable struct ZZPolyRingElem <: PolyRingElem{ZZRingElem} - coeffs::Ptr{Nothing} - alloc::Int - length::Int + data::Flint.fmpz_poly_struct parent::ZZPolyRing function ZZPolyRingElem() @@ -291,11 +287,7 @@ function _fmpz_poly_clear_fn(a::ZZPolyRingElem) end mutable struct fmpz_poly_factor - d::Int # ZZRingElem - p::Ptr{ZZPolyRingElem} # array of flint fmpz_poly_struct's - exp::Ptr{Int} - num::Int - alloc::Int + data::Flint.fmpz_poly_factor_struct function fmpz_poly_factor() z = new() @@ -591,12 +583,7 @@ end const NmodPolyRingID = CacheDictType{Tuple{zzModRing, Symbol}, zzModPolyRing}() mutable struct zzModPolyRingElem <: PolyRingElem{zzModRingElem} - coeffs::Ptr{Nothing} - alloc::Int - length::Int - mod_n::UInt - mod_ninv::UInt - mod_norm::UInt + data::Flint.nmod_poly_struct parent::zzModPolyRing function zzModPolyRingElem(n::UInt) @@ -736,6 +723,8 @@ mutable struct fpPolyRingElem <: PolyRingElem{fpFieldElem} mod_n::UInt mod_ninv::UInt mod_norm::UInt + # end of flint struct + parent::fpPolyRing function fpPolyRingElem(n::UInt) @@ -3453,6 +3442,8 @@ mutable struct fpRelPowerSeriesRingElem <: RelPowerSeriesRingElem{fpFieldElem} mod_n::UInt mod_ninv::UInt mod_norm::UInt + # end of flint struct + prec::Int val::Int parent::fpRelPowerSeriesRing @@ -3554,6 +3545,8 @@ mutable struct zzModRelPowerSeriesRingElem <: RelPowerSeriesRingElem{zzModRingEl mod_n::UInt mod_ninv::UInt mod_norm::UInt + # end of flint struct + prec::Int val::Int parent::zzModRelPowerSeriesRing diff --git a/src/flint/fmpq_poly.jl b/src/flint/fmpq_poly.jl index 621873fe4..1cd59e45b 100644 --- a/src/flint/fmpq_poly.jl +++ b/src/flint/fmpq_poly.jl @@ -706,10 +706,10 @@ for (factor_fn, factor_fn_inner, flint_fn) in ccall((:fmpz_poly_factor_get_fmpz, libflint), Nothing, (Ref{ZZRingElem}, Ref{fmpz_poly_factor}), z, fac) f = ZZPolyRingElem() - for i in 1:fac.num + for i in 1:fac.data.num ccall((:fmpz_poly_factor_get_fmpz_poly, libflint), Nothing, (Ref{ZZPolyRingElem}, Ref{fmpz_poly_factor}, Int), f, fac, i - 1) - e = unsafe_load(fac.exp, i) + e = unsafe_load(fac.data.exp, i) res[parent(x)(f)] = e end return res, QQFieldElem(z, denominator(x)) diff --git a/src/flint/nmod_poly.jl b/src/flint/nmod_poly.jl index 074c43107..c5f00fb8b 100644 --- a/src/flint/nmod_poly.jl +++ b/src/flint/nmod_poly.jl @@ -708,7 +708,7 @@ end function _factor(x::zzModPolyRingElem) !is_prime(modulus(x)) && error("Modulus not prime in factor") - fac = nmod_poly_factor(x.mod_n) + fac = nmod_poly_factor(x.data.mod.n) z = ccall((:nmod_poly_factor, libflint), UInt, (Ref{nmod_poly_factor}, Ref{zzModPolyRingElem}), fac, x) res = Dict{zzModPolyRingElem,Int}() @@ -729,7 +729,7 @@ function factor_squarefree(x::zzModPolyRingElem) end function _factor_squarefree(x::zzModPolyRingElem) - fac = nmod_poly_factor(x.mod_n) + fac = nmod_poly_factor(x.data.mod.n) ccall((:nmod_poly_factor_squarefree, libflint), UInt, (Ref{nmod_poly_factor}, Ref{zzModPolyRingElem}), fac, x) res = Dict{zzModPolyRingElem,Int}() @@ -753,7 +753,7 @@ function factor_distinct_deg(x::zzModPolyRingElem) !is_prime(modulus(x)) && error("Modulus not prime in factor_distinct_deg") degs = Vector{Int}(undef, degree(x)) degss = [ pointer(degs) ] - fac = nmod_poly_factor(x.mod_n) + fac = nmod_poly_factor(x.data.mod.n) ccall((:nmod_poly_factor_distinct_deg, libflint), UInt, (Ref{nmod_poly_factor}, Ref{zzModPolyRingElem}, Ptr{Ptr{Int}}), fac, x, degss) From 67df4ba0aed8f3cd513262dc32fac091f00fadff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Mon, 21 Oct 2024 17:12:44 +0200 Subject: [PATCH 2/2] some fixes --- src/flint/FlintTypes.jl | 4 +--- src/flint/fmpz.jl | 4 ++-- src/flint/fmpz_factor.jl | 12 ++++++------ src/flint/fmpz_poly.jl | 4 ++-- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/flint/FlintTypes.jl b/src/flint/FlintTypes.jl index 84d2c6ef0..67bdb7007 100644 --- a/src/flint/FlintTypes.jl +++ b/src/flint/FlintTypes.jl @@ -122,9 +122,7 @@ end ############################################################################### mutable struct n_factor - num::Cint - exp::NTuple{15, Cint} - p::NTuple{15, UInt} + data::Flint.n_factor_t function n_factor() z = new() diff --git a/src/flint/fmpz.jl b/src/flint/fmpz.jl index 889871d7b..58a6303d0 100644 --- a/src/flint/fmpz.jl +++ b/src/flint/fmpz.jl @@ -1621,11 +1621,11 @@ function _factor_trial_range(N::ZZRingElem, start::Int = 0, np::Int = 10^5) ccall((:fmpz_factor_trial_range, libflint), Nothing, (Ref{fmpz_factor}, Ref{ZZRingElem}, UInt, UInt), F, N, start, np) res = Dict{ZZRingElem, Int}() - for i in 1:F.num + for i in 1:F.data.num z = ZZRingElem() ccall((:fmpz_factor_get_fmpz, libflint), Nothing, (Ref{ZZRingElem}, Ref{fmpz_factor}, Int), z, F, i - 1) - res[z] = unsafe_load(F.exp, i) + res[z] = unsafe_load(F.data.exp, i) end return res, canonical_unit(N) end diff --git a/src/flint/fmpz_factor.jl b/src/flint/fmpz_factor.jl index e446c44c4..db57b6233 100644 --- a/src/flint/fmpz_factor.jl +++ b/src/flint/fmpz_factor.jl @@ -9,7 +9,7 @@ function _factor(a::ZZRingElem) F = fmpz_factor() ccall((:fmpz_factor, libflint), Nothing, (Ref{fmpz_factor}, Ref{ZZRingElem}), F, a) res = Dict{ZZRingElem, Int}() - for i in 1:F.num + for i in 1:F.data.num z = ZZRingElem() ccall((:fmpz_factor_get_fmpz, libflint), Nothing, (Ref{ZZRingElem}, Ref{fmpz_factor}, Int), z, F, i - 1) @@ -25,9 +25,9 @@ function factor(a::T) where T <: Union{Int, UInt} F = n_factor() ccall((:n_factor, libflint), Nothing, (Ref{n_factor}, UInt), F, a) res = Dict{T, Int}() - for i in 1:F.num - z = F.p[i] - res[z] = F.exp[i] + for i in 1:F.data.num + z = F.data.p[i] + res[z] = F.data.exp[i] end return Fac(u, res) end @@ -186,11 +186,11 @@ function factor_trial_range(N::ZZRingElem, start::Int=0, np::Int=10^5) F = fmpz_factor() ccall((:fmpz_factor_trial_range, libflint), Nothing, (Ref{fmpz_factor}, Ref{ZZRingElem}, UInt, UInt), F, N, start, np) res = Dict{ZZRingElem,Int}() - for i in 1:F.num + for i in 1:F.data.num z = ZZRingElem() ccall((:fmpz_factor_get_fmpz, libflint), Nothing, (Ref{ZZRingElem}, Ref{fmpz_factor}, Int), z, F, i - 1) - res[z] = unsafe_load(F.exp, i) + res[z] = unsafe_load(F.data.exp, i) end return res, canonical_unit(N) end diff --git a/src/flint/fmpz_poly.jl b/src/flint/fmpz_poly.jl index 3934948b7..5dc6cd9f1 100644 --- a/src/flint/fmpz_poly.jl +++ b/src/flint/fmpz_poly.jl @@ -712,11 +712,11 @@ for (factor_fn, factor_fn_inner, flint_fn) in z = ZZRingElem() ccall((:fmpz_poly_factor_get_fmpz, libflint), Nothing, (Ref{ZZRingElem}, Ref{fmpz_poly_factor}), z, fac) - for i in 1:fac.num + for i in 1:fac.data.num f = parent(x)() ccall((:fmpz_poly_factor_get_fmpz_poly, libflint), Nothing, (Ref{ZZPolyRingElem}, Ref{fmpz_poly_factor}, Int), f, fac, i - 1) - e = unsafe_load(fac.exp, i) + e = unsafe_load(fac.data.exp, i) res[f] = e end return res, z