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

Add some ring / field conformance tests #1707

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions src/Hecke.jl
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,8 @@ order_type(T::DataType) = throw(MethodError(order_type, (T,)))
embedding_type(x) = embedding_type(typeof(x))
embedding_type(T::DataType) = throw(MethodError(embedding_type, (T,)))

base_field_type(x) = base_field_type(typeof(x))
base_field_type(T::DataType) = throw(MethodError(base_field_type, (T,)))

################################################################################
#
Expand Down
14 changes: 8 additions & 6 deletions src/LocalField/LocalField.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,20 @@ prime(K::LocalField) = prime(base_field(K))
#
################################################################################

base_field_type(K::LocalField{S, T}) where {S <: FieldElem, T <: LocalFieldParameter} = parent_type(S)
base_ring_type(::Type{LocalField{S, T}}) where {S <: FieldElem, T <: LocalFieldParameter} = parent_type(S)

base_field_type(::Type{LocalField{S, T}}) where {S <: FieldElem, T <: LocalFieldParameter} = parent_type(S)

elem_type(::Type{LocalField{S, T}}) where {S <: FieldElem, T <: LocalFieldParameter} = LocalFieldElem{S, T}

dense_poly_type(K::LocalField{S, T}) where {S <: FieldElem, T <: LocalFieldParameter} = Generic.Poly{LocalFieldElem{S, T}}
dense_poly_type(::Type{LocalField{S, T}}) where {S <: FieldElem, T <: LocalFieldParameter} = Generic.Poly{LocalFieldElem{S, T}}

################################################################################
#
# Basic predicates
#
################################################################################

is_domain_type(::Type{S}) where S <: LocalField = true
is_exact_type(::Type{S}) where S <: LocalField = false
is_domain_type(::Type{<: LocalFieldElem}) = true
is_exact_type(::Type{<: LocalFieldElem}) = false
isfinite(K::LocalField) = isfinite(base_field(K))

################################################################################
Expand Down Expand Up @@ -134,6 +132,10 @@ end
#
################################################################################

function base_ring(L::LocalField)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be base_ring(L::LocalField) = base_field(L) instead?
But base_ring was never (intended to be) part of any useful interface, it was just indicating, in recursively defined rings, the previous step. Strictly here, base_ring might even have been the polynomial ring...
base_field, coefficient_ring/field were intended to be more useful

return base_ring(defining_polynomial(L))
end

function base_field(L::LocalField)
return base_ring(defining_polynomial(L))
end
Expand Down
8 changes: 2 additions & 6 deletions src/Map/NumField.jl
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,9 @@ end
#
################################################################################

base_field_type(::AbsSimpleNumField) = QQField
base_field_type(::Type{AbsSimpleNumField}) = QQField

base_field_type(::AbsNonSimpleNumField) = QQField

base_field_type(::RelSimpleNumField{T}) where {T} = parent_type(T)

base_field_type(::RelNonSimpleNumField{T}) where {T} = parent_type(T)
base_field_type(::Type{AbsNonSimpleNumField}) = QQField

base_field_type(::Type{RelNonSimpleNumField{T}}) where {T} = parent_type(T)

Expand Down
10 changes: 9 additions & 1 deletion src/Misc/RelFiniteField.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,13 @@ function defining_polynomial(F::RelFinField{T}) where T
return F.defining_polynomial::dense_poly_type(T)
end

base_field(F::RelFinField{S}) where S= base_ring(F.defining_polynomial)::parent_type(S)
base_field_type(::Type{RelFinField{S}}) where S = parent_type(S)

base_field(F::RelFinField{S}) where S = base_ring(F.defining_polynomial)::parent_type(S)

base_ring_type(::Type{RelFinField{S}}) where S = parent_type(S)

base_ring(F::RelFinField{S}) where S = base_ring(F.defining_polynomial)::parent_type(S)

characteristic(F::RelFinField) = characteristic(base_field(F))

Expand Down Expand Up @@ -139,6 +145,8 @@ iszero(x::RelFinFieldElem) = iszero(x.data)
isone(x::RelFinFieldElem) = isone(x.data)
is_unit(x::RelFinFieldElem) = !iszero(x)

hash(x::RelFinFieldElem, h::UInt) = hash(x.data, h)

==(x::RelFinFieldElem{S, T}, y::RelFinFieldElem{S, T}) where {S, T} = x.data == y.data

coeff(a::RelFinFieldElem, i::Int) = coeff(a.data, i)
Expand Down
2 changes: 2 additions & 0 deletions src/NumField/Embedded.jl
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ base_ring_type(::Type{<:EmbeddedNumField}) = QQField

data(x::EmbeddedNumFieldElem) = x.element

characteristic(::EmbeddedNumField) = 0

function embedded_field(K::SimpleNumField, i::NumFieldEmb)
@assert number_field(i) === K
E = EmbeddedNumField(K, i)
Expand Down
4 changes: 4 additions & 0 deletions src/NumField/NfRel/NfRel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ order_type(::Type{RelSimpleNumField{T}}) where {T} = RelNumFieldOrder{T, fractio

@inline base_field(a::RelSimpleNumField{T}) where {T} = a.base_ring::parent_type(T)

base_ring(a::RelSimpleNumField{T}) where {T} = a.base_ring::parent_type(T)

base_ring_type(::Type{RelSimpleNumField{T}}) where {T} = parent_type(T)

@inline data(a::RelSimpleNumFieldElem) = a.data

@inline parent(a::RelSimpleNumFieldElem{T}) where {T} = a.parent::RelSimpleNumField{T}
Expand Down
22 changes: 22 additions & 0 deletions test/LocalField/LocalField.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# the following is copied from the `random_elem` function
function test_elem(L::Union{QadicField, Hecke.LocalField})
b = basis(L)
n = degree(L)
r = [rand(1:5*n) for i in 1:n] # Choose small coordinates
return sum( [r[i]*b[i] for i in 1:n])
end

# TODO/FIXME: implement isapprox so we can get rid of the following HACK:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why? From the docs:

Approximation (floating point and ball arithmetic only)

isapprox(f::MyElem, g::MyElem; atol::Real=sqrt(eps()))

so it is not part of the normal ring/field interface I'd say

function equality(a::T, b::T) where {T <: Union{QadicFieldElem, Hecke.LocalFieldElem}}
return a == b
end

@testset "LocalField" begin

@testset "Creation" begin
Expand All @@ -8,6 +21,9 @@
@test characteristic(K) == 0
@test prime(K) == 2

test_Field_interface(K)
#test_Field_interface_recursive(K) # TODO/FIXME: does not work due to missing isapprox

Kt, t = polynomial_ring(K, "t")
g = t^2+2
L, b = local_field(g, "b", Hecke.EisensteinLocalField, check = false)
Expand Down Expand Up @@ -40,8 +56,14 @@

@testset "Norm" begin
K = qadic_field(3, 4, precision = 10)[1]
test_Field_interface(K)
#test_Field_interface_recursive(K) # TODO/FIXME: does not work due to missing isapprox

Kx, x = polynomial_ring(K, "x")
L = eisenstein_extension(x^20+3)[1]
test_Field_interface(L)
#test_Field_interface_recursive(L) # TODO/FIXME: does not work due to missing isapprox

b = @inferred basis(L)
for i = 1:10
r = 1+2*uniformizer(L)^i * sum([rand(1:10)*b[i] for i in 1:5])
Expand Down
7 changes: 7 additions & 0 deletions test/Misc/RelFinField.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
@testset "RelFinField" begin

@testset "conformance" begin
F = Native.finite_field(3, 3, cached = false)[1]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thofma I thought we'd rather get rid of the RelFinField?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only replaced the ones in the prime decomposition of relative number fields. They might be used somewhere else still.

x = polynomial_ring(F, "x", cached = false)[2]
K, gK = @inferred Native.finite_field(x^2+1, :a)
test_Field_interface_recursive(K)
end

@testset "Basic properties" begin
F = Native.finite_field(3, 3, cached = false)[1]
x = polynomial_ring(F, "x", cached = false)[2]
Expand Down
16 changes: 16 additions & 0 deletions test/NfRel/NfRel.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
function test_elem(K::RelSimpleNumField)
return rand(K, -10:10)
end

@testset "RelSimpleNumField" begin

@testset "conformance" begin
Qx, x = QQ["x"]
f = x^2 + 12x - 92
K, a = number_field(f, "a")
Ky, y = K["y"]

L, b = number_field(y^2 + y + 1, "b")

test_Field_interface_recursive(L)
end

@testset "is_subfield" begin
Qx, x = QQ["x"]
f = x^2 + 12x - 92
Expand Down
2 changes: 1 addition & 1 deletion test/NumField/Embedded.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ test_elem(E::Hecke.EmbeddedNumField) = E(rand(number_field(E), -10:10))
@test sprint(show, a) isa String
@test sprint(show, "text/plain", a) isa String
@test E([1, 2]) == 1 + 2*a
test_Ring_interface(E)
test_Field_interface(E)
# trigger expressify
Et, t = E["t"]
@test sprint(show, a * t) isa String
Expand Down
Loading