Skip to content

Commit

Permalink
Use more FLINT methods for fmpz_mod_mat (#1966)
Browse files Browse the repository at this point in the history
Co-authored-by: Tommy Hofmann <thofma@gmail.com>
  • Loading branch information
fingolfin and thofma authored Dec 11, 2024
1 parent ea3fb30 commit defef89
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 71 deletions.
98 changes: 27 additions & 71 deletions src/flint/fmpz_mod_mat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -376,35 +376,27 @@ end
#
################################################################################

#= Not implemented in Flint yet
function det(a::ZZModMatrix)
!is_square(a) && error("Matrix must be a square matrix")
if is_prime(a.n)
r = @ccall libflint.fmpz_mod_mat_det(a::Ref{ZZModMatrix})::UInt
return base_ring(a)(r)
else
try
return AbstractAlgebra.det_fflu(a)
catch
return AbstractAlgebra.det_df(a)
end
end
!is_square(a) && error("Matrix must be a square matrix")
z = ZZRingElem()
r = @ccall libflint.fmpz_mod_mat_det(z::Ref{ZZRingElem}, a::Ref{ZZModMatrix}, base_ring(a).ninv::Ref{fmpz_mod_ctx_struct})::Nothing
return base_ring(a)(z)
end

=#

################################################################################
#
# Rank
#
################################################################################

#= Not implemented in Flint yet
#= There are some doubts whether fmpz_mod_mat_rank is what we want: there are
several non-equivalent ways to define the rank of a matrix over a ring with
zero divisors. FLINT does not seem to document what exactly fmpz_mod_mat_rank
computes...
function rank(a::T) where T <: Zmod_fmpz_mat
r = @ccall libflint.fmpz_mod_mat_rank(a::Ref{T})::Int
return r
r = @ccall libflint.fmpz_mod_mat_rank(a::Ref{T}, base_ring(a).ninv::Ref{fmpz_mod_ctx_struct})::Int
return r
end
=#
Expand Down Expand Up @@ -434,18 +426,14 @@ function inv(a::ZZModMatrix)
end
end

#= Not implemented in Flint yet
function inv(a::T) where T <: Zmod_fmpz_mat
!is_square(a) && error("Matrix must be a square matrix")
z = similar(a)
r = @ccall libflint.fmpz_mod_mat_inv(z::Ref{T}, a::Ref{T})::Int
!Bool(r) && error("Matrix not invertible")
return z
!is_square(a) && error("Matrix must be a square matrix")
z = similar(a)
r = @ccall libflint.fmpz_mod_mat_inv(z::Ref{T}, a::Ref{T}, base_ring(a).ninv::Ref{fmpz_mod_ctx_struct})::Int
!Bool(r) && error("Matrix not invertible")
return z
end

=#

################################################################################
#
# Linear solving
Expand Down Expand Up @@ -599,45 +587,20 @@ end
#
################################################################################

#= Not implemented in Flint yet
@doc raw"""
lift(a::T) where {T <: Zmod_fmpz_mat}
Return a lift of the matrix $a$ to a matrix over $\mathbb{Z}$, i.e. where the
entries of the returned matrix are those of $a$ lifted to $\mathbb{Z}$.
"""
function lift(a::T) where {T <: Zmod_fmpz_mat}
z = ZZMatrix(nrows(a), ncols(a))
@ccall libflint.fmpz_mat_set_fmpz_mod_mat(z::Ref{ZZMatrix}, a::Ref{T})::Nothing
return z
end
function lift!(z::ZZMatrix, a::T) where T <: Zmod_fmpz_mat
@ccall libflint.fmpz_mat_set_fmpz_mod_mat(z::Ref{ZZMatrix}, a::Ref{T})::Nothing
return z
@ccall libflint.fmpz_mod_mat_get_fmpz_mat(z::Ref{ZZMatrix}, a::Ref{T})::Nothing
return z
end

=#

@doc raw"""
lift(a::T) where {T <: Zmod_fmpz_mat}
Return a lift of the matrix $a$ to a matrix over $\mathbb{Z}$, i.e. where the
entries of the returned matrix are those of $a$ lifted to $\mathbb{Z}$.
"""
function lift(a::Zmod_fmpz_mat)
z = zero_matrix(ZZ, nrows(a), ncols(a))
GC.@preserve a z begin
for i in 1:nrows(a)
for j in 1:ncols(a)
m = mat_entry_ptr(z, i, j)
n = mat_entry_ptr(a, i, j)
set!(m, n)
end
end
end
return z
z = ZZMatrix(nrows(a), ncols(a))
return lift!(z, a)
end

################################################################################
Expand All @@ -646,33 +609,26 @@ end
#
################################################################################

#= Not implemented in Flint yet
function charpoly(R::ZZModPolyRing, a::ZZModMatrix)
m = deepcopy(a)
p = R()
@ccall libflint.fmpz_mod_mat_charpoly(p::Ref{ZZModPolyRingElem}, m::Ref{ZZModMatrix})::Nothing
return p
@req base_ring(R) == base_ring(a) "base rings don't match'"
m = deepcopy(a)
p = R()
@ccall libflint.fmpz_mod_mat_charpoly(p::Ref{ZZModPolyRingElem}, m::Ref{ZZModMatrix}, base_ring(a).ninv::Ref{fmpz_mod_ctx_struct})::Nothing
return p
end

=#

################################################################################
#
# Minimal polynomial
#
################################################################################

#= Not implemented in Flint yet
function minpoly(R::ZZModPolyRing, a::ZZModMatrix)
p = R()
@ccall libflint.fmpz_mod_mat_minpoly(p::Ref{ZZModPolyRingElem}, a::Ref{ZZModMatrix})::Nothing
return p
p = R()
@ccall libflint.fmpz_mod_mat_minpoly(p::Ref{ZZModPolyRingElem}, a::Ref{ZZModMatrix}, base_ring(a).ninv::Ref{fmpz_mod_ctx_struct})::Nothing
return p
end

=#

###############################################################################
#
# Promotion rules
Expand Down
11 changes: 11 additions & 0 deletions src/flint/gfp_fmpz_mat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,17 @@ function lu(x::FpMatrix, P = SymmetricGroup(nrows(x)))
return rank, p, L, U
end

################################################################################
#
# Rank
#
################################################################################

function rank(a::FpMatrix)
r = @ccall libflint.fmpz_mod_mat_rank(a::Ref{FpMatrix}, base_ring(a).ninv::Ref{fmpz_mod_ctx_struct})::Int
return r
end

################################################################################
#
# Entry pointers
Expand Down
7 changes: 7 additions & 0 deletions test/flint/fmpz_mod_mat-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,13 @@ end
R, = residue_ring(ZZ, 3^5)
a = R[1;]
@test @inferred isone(det(a))

for n in 2:12
R, = residue_ring(ZZ, ZZ(n))
a = matrix(R, [ 1 2 3 ; 4 5 6; 0 42 9])
@test det(a) == det(lift(a)) % modulus(R)
@test tr(a) == tr(lift(a)) % modulus(R)
end
end

@testset "ZZModMatrix.rank" begin
Expand Down

0 comments on commit defef89

Please sign in to comment.