Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mh/mod ZZMatrix ZZRingElem #1982

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions docs/src/matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,25 +169,6 @@ reduce_mod(::ZZMatrix, ::Integer)
reduce_mod(::ZZMatrix, ::ZZRingElem)
```

**Examples**

```jldoctest
julia> A = ZZ[2 3 5; 1 4 7; 9 2 2]
[2 3 5]
[1 4 7]
[9 2 2]

julia> reduce_mod(A, ZZ(5))
[2 3 0]
[1 4 2]
[4 2 2]

julia> reduce_mod(A, 2)
[0 1 1]
[1 0 1]
[1 0 0]
```

### Lifting

```@docs
Expand Down
43 changes: 0 additions & 43 deletions src/HeckeMoreStuff.jl
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,6 @@ function is_squarefree(x::Generic.Poly{AbsSimpleNumFieldElem})
return isone(gcd(x, derivative(x), true))
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")

################################################################################
#
# Base case for dot products
Expand Down Expand Up @@ -317,16 +312,6 @@ function numerator(a::AbsSimpleNumFieldElem)
return z
end

function divexact!(z::AbsSimpleNumFieldElem, x::AbsSimpleNumFieldElem, y::ZZRingElem)
@ccall libflint.nf_elem_scalar_div_fmpz(z::Ref{AbsSimpleNumFieldElem}, x::Ref{AbsSimpleNumFieldElem}, y::Ref{ZZRingElem}, parent(x)::Ref{AbsSimpleNumField})::Nothing
return z
end

function sub!(a::AbsSimpleNumFieldElem, b::AbsSimpleNumFieldElem, c::AbsSimpleNumFieldElem)
@ccall libflint.nf_elem_sub(a::Ref{AbsSimpleNumFieldElem}, b::Ref{AbsSimpleNumFieldElem}, c::Ref{AbsSimpleNumFieldElem}, a.parent::Ref{AbsSimpleNumField})::Nothing
return a
end

function lift(R::ZZAbsPowerSeriesRing, f::ZZModAbsPowerSeriesRingElem)
r = R()
for i = 0:length(f)-1
Expand Down Expand Up @@ -707,11 +692,6 @@ function evaluate(f::QQPolyRingElem, a::AbsSimpleNumFieldElem)
return s
end

function rem!(z::fpPolyRingElem, a::fpPolyRingElem, b::fpPolyRingElem)
@ccall libflint.nmod_poly_rem(z::Ref{fpPolyRingElem}, a::Ref{fpPolyRingElem}, b::Ref{fpPolyRingElem}, (pointer_from_objref(base_ring(z)) + sizeof(ZZRingElem))::Ptr{Nothing})::Nothing
return z
end

function preimage(M::Map{D,C}, a) where {D,C}
if isdefined(M.header, :preimage)
p = M.header.preimage(a)::elem_type(D)
Expand Down Expand Up @@ -837,24 +817,6 @@ function (R::QQPolyRing)(a::Generic.RationalFunctionFieldElem{QQFieldElem})
return R(numerator(a))
end

function Base.divrem(a::ZZModRingElem, b::ZZModRingElem)
R = parent(a)
r = rem(a, b)
return divexact(a - r, b), r
end

function Base.div(a::ZZModRingElem, b::ZZModRingElem)
R = parent(a)
r = rem(a, b)
return divexact(a - r, b)
end

function Base.rem(a::ZZModRingElem, b::ZZModRingElem)
R = parent(a)
r = R(rem(lift(a), gcd(modulus(R), lift(b))))
return r
end

@doc raw"""
zeros(f::ZZPolyRingElem) -> Vector{ZZRingElem}

Expand Down Expand Up @@ -1086,11 +1048,6 @@ function (R::FqPolyRepField)(x::FpPolyRingElem)
return z
end

@inline function rem!(a::ZZRingElem, b::ZZRingElem, c::ZZRingElem)
@ccall libflint.fmpz_mod(a::Ref{ZZRingElem}, b::Ref{ZZRingElem}, c::Ref{ZZRingElem})::Nothing
return a
end

function rem!(a::ZZModPolyRingElem, b::ZZModPolyRingElem, c::ZZModPolyRingElem)
@ccall libflint.fmpz_mod_poly_rem(a::Ref{ZZModPolyRingElem}, b::Ref{ZZModPolyRingElem}, c::Ref{ZZModPolyRingElem}, a.parent.base_ring.ninv::Ref{fmpz_mod_ctx_struct})::Nothing
return a
Expand Down
35 changes: 29 additions & 6 deletions src/antic/nf_elem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -262,24 +262,21 @@ function +(a::AbsSimpleNumFieldElem, b::AbsSimpleNumFieldElem)
parent(a) == parent(b) || return force_op(+, a, b)::AbsSimpleNumFieldElem
check_parent(a, b)
r = a.parent()
@ccall libflint.nf_elem_add(r::Ref{AbsSimpleNumFieldElem}, a::Ref{AbsSimpleNumFieldElem}, b::Ref{AbsSimpleNumFieldElem}, a.parent::Ref{AbsSimpleNumField})::Nothing
return r
return add!(r, a, b)
end

function -(a::AbsSimpleNumFieldElem, b::AbsSimpleNumFieldElem)
parent(a) == parent(b) || return force_op(-, a, b)::AbsSimpleNumFieldElem
check_parent(a, b)
r = a.parent()
@ccall libflint.nf_elem_sub(r::Ref{AbsSimpleNumFieldElem}, a::Ref{AbsSimpleNumFieldElem}, b::Ref{AbsSimpleNumFieldElem}, a.parent::Ref{AbsSimpleNumField})::Nothing
return r
return sub!(r, a, b)
end

function *(a::AbsSimpleNumFieldElem, b::AbsSimpleNumFieldElem)
parent(a) == parent(b) || return force_op(*, a, b)::AbsSimpleNumFieldElem
check_parent(a, b)
r = a.parent()
@ccall libflint.nf_elem_mul(r::Ref{AbsSimpleNumFieldElem}, a::Ref{AbsSimpleNumFieldElem}, b::Ref{AbsSimpleNumFieldElem}, a.parent::Ref{AbsSimpleNumField})::Nothing
return r
return mul!(r, a, b)
end

###############################################################################
Expand Down Expand Up @@ -724,6 +721,11 @@ end

add!(c::AbsSimpleNumFieldElem, a::AbsSimpleNumFieldElem, b::Integer) = add!(c, a, flintify(b))

function sub!(a::AbsSimpleNumFieldElem, b::AbsSimpleNumFieldElem, c::AbsSimpleNumFieldElem)
@ccall libflint.nf_elem_sub(a::Ref{AbsSimpleNumFieldElem}, b::Ref{AbsSimpleNumFieldElem}, c::Ref{AbsSimpleNumFieldElem}, a.parent::Ref{AbsSimpleNumField})::Nothing
return a
end

function sub!(c::AbsSimpleNumFieldElem, a::AbsSimpleNumFieldElem, b::QQFieldElem)
@ccall libflint.nf_elem_sub_fmpq(c::Ref{AbsSimpleNumFieldElem}, a::Ref{AbsSimpleNumFieldElem}, b::Ref{QQFieldElem}, a.parent::Ref{AbsSimpleNumField})::Nothing
return c
Expand Down Expand Up @@ -775,6 +777,23 @@ end

mul!(c::AbsSimpleNumFieldElem, a::AbsSimpleNumFieldElem, b::Integer) = mul!(c, a, flintify(b))

function divexact!(z::AbsSimpleNumFieldElem, x::AbsSimpleNumFieldElem, y::Int)
@ccall libflint.nf_elem_scalar_div_si(r::Ref{AbsSimpleNumFieldElem}, a::Ref{AbsSimpleNumFieldElem}, b::Int, parent(x)::Ref{AbsSimpleNumField})::Nothing
return z
end

function divexact!(z::AbsSimpleNumFieldElem, x::AbsSimpleNumFieldElem, y::ZZRingElem)
@ccall libflint.nf_elem_scalar_div_fmpz(z::Ref{AbsSimpleNumFieldElem}, x::Ref{AbsSimpleNumFieldElem}, y::Ref{ZZRingElem}, parent(x)::Ref{AbsSimpleNumField})::Nothing
return z
end

function divexact!(z::AbsSimpleNumFieldElem, x::AbsSimpleNumFieldElem, y::QQFieldElem)
@ccall libflint.nf_elem_scalar_div_fmpq(z::Ref{AbsSimpleNumFieldElem}, x::Ref{AbsSimpleNumFieldElem}, y::Ref{QQFieldElem}, parent(x)::Ref{AbsSimpleNumField})::Nothing
return z
end

divexact!(z::AbsSimpleNumFieldElem, x::AbsSimpleNumFieldElem, y::RationalUnion) = divexact!(z, x, flintify(y))

###############################################################################
#
# Speedups for polynomials over number fields
Expand Down Expand Up @@ -1016,6 +1035,10 @@ function (a::QQPolyRing)(b::AbsSimpleNumFieldElem)
return r
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")

###############################################################################
#
# Random generation
Expand Down
11 changes: 10 additions & 1 deletion src/flint/fmpz.jl
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ function rem(x::ZZRingElemOrPtr, ::Type{UInt64})
end

function rem(x::ZZRingElem, c::ZZRingElem)
# FIXME: it seems `rem` and `rem!` for `ZZRingElem` do different things?
q, r = Base.divrem(x, c)
return r
end
Expand Down Expand Up @@ -951,7 +952,7 @@ end
#
###############################################################################

function mod!(r::ZZRingElem, x::ZZRingElem, y::ZZRingElem)
function mod!(r::ZZRingElemOrPtr, x::ZZRingElemOrPtr, y::ZZRingElemOrPtr)
@ccall libflint.fmpz_fdiv_r(r::Ref{ZZRingElem}, x::Ref{ZZRingElem}, y::Ref{ZZRingElem})::Nothing
return r
end
Expand Down Expand Up @@ -2609,6 +2610,14 @@ divexact!(z::ZZRingElemOrPtr, a::ZZRingElemOrPtr, b::Integer) = divexact!(z, a,

#

function rem!(a::ZZRingElem, b::ZZRingElem, c::ZZRingElem)
# FIXME: it seems `rem` and `rem!` for `ZZRingElem` do different things?
@ccall libflint.fmpz_mod(a::Ref{ZZRingElem}, b::Ref{ZZRingElem}, c::Ref{ZZRingElem})::Nothing
return a
end

#

function pow!(z::ZZRingElemOrPtr, a::ZZRingElemOrPtr, b::Integer)
@ccall libflint.fmpz_pow_ui(z::Ref{ZZRingElem}, a::Ref{ZZRingElem}, UInt(b)::UInt)::Nothing
return z
Expand Down
57 changes: 33 additions & 24 deletions src/flint/fmpz_mat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -502,61 +502,70 @@ end

@doc raw"""
reduce_mod(x::ZZMatrix, y::ZZRingElem)
reduce_mod(x::ZZMatrix, y::Integer)

Reduce the entries of $x$ modulo $y$ and return the result.

# Examples
```jldoctest
julia> A = ZZ[2 3 5; 1 4 7; 9 2 2]
[2 3 5]
[1 4 7]
[9 2 2]

julia> reduce_mod(A, ZZ(5))
[2 3 0]
[1 4 2]
[4 2 2]

julia> reduce_mod(A, 2)
[0 1 1]
[1 0 1]
[1 0 0]
```
"""
function reduce_mod(x::ZZMatrix, y::ZZRingElem)
z = similar(x)
@ccall libflint.fmpz_mat_scalar_mod_fmpz(z::Ref{ZZMatrix}, x::Ref{ZZMatrix}, y::Ref{ZZRingElem})::Nothing
return z
end

@doc raw"""
reduce_mod(x::ZZMatrix, y::Integer)

Reduce the entries of $x$ modulo $y$ and return the result.
"""
reduce_mod(x::ZZMatrix, y::Integer) = reduce_mod(x, ZZRingElem(y))

@doc raw"""
mod!(M::ZZMatrix, p::ZZRingElem)

Reduces every entry modulo $p$ in-place, i.e. applies the mod function to every entry.
Positive residue system.
"""
function mod!(M::ZZMatrix, p::ZZRingElem)
GC.@preserve M begin
function mod!(A::ZZMatrix, M::ZZMatrix, p::ZZRingElem)
GC.@preserve A M begin
for i = 1:nrows(M)
for j = 1:ncols(M)
z = mat_entry_ptr(M, i, j)
@ccall libflint.fmpz_mod(z::Ptr{ZZRingElem}, z::Ptr{ZZRingElem}, p::Ref{ZZRingElem})::Nothing
x = mat_entry_ptr(M, i, j)
z = mat_entry_ptr(A, i, j)
mod!(z, x, p)
end
end
end
return nothing
return A
end

@doc raw"""
mod(M::ZZMatrix, p::ZZRingElem) -> ZZMatrix

Reduces every entry modulo $p$, i.e. applies the mod function to every entry.
"""
function mod(M::ZZMatrix, p::ZZRingElem)
N = deepcopy(M)
mod!(N, p)
return N
end
mod(M::ZZMatrix, p::ZZRingElem) = mod!(similar(M), M, p)

@doc raw"""
mod_sym!(N::ZZMatrix, M::ZZMatrix, p::ZZRingElem)
mod_sym!(M::ZZMatrix, p::ZZRingElem)

Reduces every entry modulo $p$ in-place, into the symmetric residue system.
"""
function mod_sym!(M::ZZMatrix, B::ZZRingElem)
function mod_sym!(N::ZZMatrix, M::ZZMatrix, B::ZZRingElem)
println("foo")
@assert !iszero(B)
@ccall libflint.fmpz_mat_scalar_smod(M::Ref{ZZMatrix}, M::Ref{ZZMatrix}, B::Ref{ZZRingElem})::Nothing
@ccall libflint.fmpz_mat_scalar_smod(N::Ref{ZZMatrix}, M::Ref{ZZMatrix}, B::Ref{ZZRingElem})::Nothing
return N
end
mod_sym!(M::ZZMatrix, B::Integer) = mod_sym!(M, ZZRingElem(B))
mod_sym!(N::ZZMatrix, M::ZZMatrix, B::Integer) = mod_sym!(M, ZZRingElem(B))
mod_sym!(M::ZZMatrix, B::IntegerUnion) = mod_sym!(M, M, B)

@doc raw"""
mod_sym(M::ZZMatrix, p::ZZRingElem) -> ZZMatrix
Expand Down
24 changes: 24 additions & 0 deletions src/flint/fmpz_mod.jl
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,30 @@ function divides(a::ZZModRingElem, b::ZZModRingElem)
return true, rr
end

###############################################################################
#
# Division with remainder
#
###############################################################################

function Base.divrem(a::ZZModRingElem, b::ZZModRingElem)
R = parent(a)
r = rem(a, b)
return divexact(a - r, b), r
end

function Base.div(a::ZZModRingElem, b::ZZModRingElem)
R = parent(a)
r = rem(a, b)
return divexact(a - r, b)
end

function Base.rem(a::ZZModRingElem, b::ZZModRingElem)
R = parent(a)
r = R(rem(lift(a), gcd(modulus(R), lift(b))))
return r
end

###############################################################################
#
# GCD
Expand Down
8 changes: 6 additions & 2 deletions src/flint/gfp_poly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,16 @@ end
#
################################################################################

function rem!(z::fpPolyRingElem, x::fpPolyRingElem, y::fpPolyRingElem)
@ccall libflint.nmod_poly_rem(z::Ref{fpPolyRingElem}, x::Ref{fpPolyRingElem}, y::Ref{fpPolyRingElem})::Nothing
return z
end

function rem(x::fpPolyRingElem, y::fpPolyRingElem)
check_parent(x,y)
iszero(y) && throw(DivideError())
z = parent(x)()
@ccall libflint.nmod_poly_rem(z::Ref{fpPolyRingElem}, x::Ref{fpPolyRingElem}, y::Ref{fpPolyRingElem})::Nothing
return z
return rem!(z, x, y)
end

################################################################################
Expand Down
Loading