Skip to content

Commit

Permalink
Division with remainder for power series (#1545)
Browse files Browse the repository at this point in the history
* `divrem` for power series

* Add test for HNF/SNF of power series
  • Loading branch information
joschmitt authored Jan 9, 2024
1 parent ebcaa0d commit 1c96bca
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/AbsSeries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,25 @@ function Base.inv(a::AbsPowerSeriesRingElem{T}) where T <: FieldElement
return x
end

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

function Base.divrem(a::AbsPowerSeriesRingElem{T}, b::AbsPowerSeriesRingElem{T}) where {T <: FieldElement}
check_parent(a, b)
if length(b) == 0
throw(DivideError())
end
if valuation(a) < valuation(b)
return zero(parent(a)), a
end
# valuation(a) >= valuation(b), so the exact division works
q = divexact(a, b)
return q, a - q*b
end

###############################################################################
#
# Composition
Expand Down
19 changes: 19 additions & 0 deletions src/RelSeries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,25 @@ function Base.inv(a::RelPowerSeriesRingElem{T}) where T <: FieldElement
return x
end

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

function Base.divrem(a::RelPowerSeriesRingElem{T}, b::RelPowerSeriesRingElem{T}) where {T <: FieldElement}
check_parent(a, b)
if pol_length(b) == 0
throw(DivideError())
end
if valuation(a) < valuation(b)
return zero(parent(a)), a
end
# valuation(a) >= valuation(b), so the exact division works
q = divexact(a, b)
return q, a - q*b
end

###############################################################################
#
# Composition
Expand Down
34 changes: 34 additions & 0 deletions test/generic/AbsSeries-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1247,3 +1247,37 @@ end
@test isequal(h, R())
end
end

@testset "Generic.AbsSeries.euclidean" begin
R, x = power_series_ring(QQ, 20, "x", model = :capped_absolute)
S, y = power_series_ring(GF(5), 20, "y", model = :capped_absolute)

T, z = power_series_ring(GF(7), 20, "z", model = :capped_absolute)
@test_throws ErrorException divrem(y, z)

for (T, t) in [ (R, x), (S, y) ]
@test divrem(t^2, t) == (t, zero(T))
@test divrem(t + 1, t) == (zero(T), t + 1)
@test_throws DivideError divrem(t, zero(T))

@test gcd(t^2*(t - 1), t^2) == t^2
@test gcd((t + 1)*(t - 1), t + 1) == one(T)
@test gcdx(t^2*(t - 1), t^2) == (t^2, zero(T), one(T))
g, u, v = gcdx((t + 1)*(t - 1), t + 1)
@test u*(t + 1)*(t - 1) + v*(t + 1) == g

M = matrix(T, 4, 3, [ 0 0 0; t^3 + 1 t^2 0; 0 t^2 t^5; t^4 + 1 t^2 t^5 + t^3 ])
@test is_hnf(hnf(M))
H, U = hnf_with_transform(M)
@test is_hnf(H)
@test U*M == H
@test is_unit(det(U))

@test is_snf(snf(M))
S, U, V = snf_with_transform(M)
@test is_snf(S)
@test U*M*V == S
@test is_unit(det(U))
@test is_unit(det(V))
end
end
34 changes: 34 additions & 0 deletions test/generic/RelSeries-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1283,3 +1283,37 @@ end
@test isequal(h, R())
end
end

@testset "Generic.RelSeries.euclidean" begin
R, x = power_series_ring(QQ, 20, "x", model = :capped_relative)
S, y = power_series_ring(GF(5), 20, "y", model = :capped_relative)

T, z = power_series_ring(GF(7), 20, "z", model = :capped_relative)
@test_throws ErrorException divrem(y, z)

for (T, t) in [ (R, x), (S, y) ]
@test divrem(t^2, t) == (t, zero(T))
@test divrem(t + 1, t) == (zero(T), t + 1)
@test_throws DivideError divrem(t, zero(T))

@test gcd(t^2*(t - 1), t^2) == t^2
@test gcd((t + 1)*(t - 1), t + 1) == one(T)
@test gcdx(t^2*(t - 1), t^2) == (t^2, zero(T), one(T))
g, u, v = gcdx((t + 1)*(t - 1), t + 1)
@test u*(t + 1)*(t - 1) + v*(t + 1) == g

M = matrix(T, 4, 3, [ 0 0 0; t^3 + 1 t^2 0; 0 t^2 t^5; t^4 + 1 t^2 t^5 + t^3 ])
@test is_hnf(hnf(M))
H, U = hnf_with_transform(M)
@test is_hnf(H)
@test U*M == H
@test is_unit(det(U))

@test is_snf(snf(M))
S, U, V = snf_with_transform(M)
@test is_snf(S)
@test U*M*V == S
@test is_unit(det(U))
@test is_unit(det(V))
end
end

0 comments on commit 1c96bca

Please sign in to comment.