diff --git a/src/NumField/Elem.jl b/src/NumField/Elem.jl index 111de92d32..9e425ed9a9 100644 --- a/src/NumField/Elem.jl +++ b/src/NumField/Elem.jl @@ -658,3 +658,18 @@ absolute_minpoly(a::nf_elem) = minpoly(a) absolute_minpoly(a::NfAbsNS) = minpoly(a) absolute_minpoly(a::T) where T <: Union{NfRelNSElem, NfRelElem} = minpoly(a, FlintQQ) + +################################################################################ +# +# Integral multiplicator +# +################################################################################ + +function _integral_multiplicator(a::Union{PolyElem, MPolyElem}) + return lcm(ZZRingElem[_integral_multiplicator(c) for c in coefficients(a)]) +end + +function _integral_multiplicator(a::NumFieldElem) + f = minpoly(a) + return _integral_multiplicator(f) +end diff --git a/src/NumField/NfAbs/Elem.jl b/src/NumField/NfAbs/Elem.jl index 31420267b3..ffbb961e5b 100644 --- a/src/NumField/NfAbs/Elem.jl +++ b/src/NumField/NfAbs/Elem.jl @@ -950,3 +950,13 @@ function complex_conjugate(a::nf_elem) end error("Not implemented yet: element must be in an at most quadratic field") end + +################################################################################ +# +# Integral multiplicator +# +################################################################################ + +_integral_multiplicator(a::nf_elem) = denominator(minpoly(a)) + +_integral_multiplicator(a::QQPolyRingElem) = denominator(a) diff --git a/src/NumField/NfRel/NfRel.jl b/src/NumField/NfRel/NfRel.jl index 9c954c767b..c7026292f6 100644 --- a/src/NumField/NfRel/NfRel.jl +++ b/src/NumField/NfRel/NfRel.jl @@ -926,3 +926,13 @@ function cyclotomic_field_as_cm_extension(n::Int; cached::Bool = true) return E, b end +################################################################################# +## +## Integral multiple +## +################################################################################# +# +#function _integral_multiplicator(a::NfRelElem) +# f = minpoly(a) +# return lcm(ZZRingElem[_integral_multiplicator(c) for c in coefficients(f)]) +#end diff --git a/src/NumField/NfRel/NfRelNS.jl b/src/NumField/NfRel/NfRelNS.jl index 99fc4fecba..e607638761 100644 --- a/src/NumField/NfRel/NfRelNS.jl +++ b/src/NumField/NfRel/NfRelNS.jl @@ -822,3 +822,14 @@ function is_rational(a::NfRelNSElem) d = data(a) return is_constant(d) && is_rational(constant_coefficient(d)) end +# +################################################################################# +## +## Integral multiplicator +## +################################################################################# +# +#function _integral_multiplicator(a::NfRelNSElem) +# f = minpoly(a) +# return lcm(ZZRingElem[_integral_multiplicator(c) for c in coefficients(f)]) +#end diff --git a/src/NumFieldOrd/NfOrd/Ideal/Prime.jl b/src/NumFieldOrd/NfOrd/Ideal/Prime.jl index a038cd23d7..c63fa0743d 100644 --- a/src/NumFieldOrd/NfOrd/Ideal/Prime.jl +++ b/src/NumFieldOrd/NfOrd/Ideal/Prime.jl @@ -904,6 +904,9 @@ end function _prefactorization(I::NfOrdIdl) @assert has_2_elem(I) + if !is_defining_polynomial_nice(nf(I)) + return __prefactorization(I) + end n = I.gen_one if has_minimum(I) n = minimum(I) @@ -919,6 +922,10 @@ function _prefactorization(I::NfOrdIdl) end function _prefactorization(I::NfAbsOrdIdl) + return __prefactorization(I) +end + +function __prefactorization(I::NfAbsOrdIdl) return coprime_base(ZZRingElem[I.gen_one, norm(I), minimum(I)]) end diff --git a/src/NumFieldOrd/NfOrd/NfOrd.jl b/src/NumFieldOrd/NfOrd/NfOrd.jl index f77a92bae2..71ea9e448b 100644 --- a/src/NumFieldOrd/NfOrd/NfOrd.jl +++ b/src/NumFieldOrd/NfOrd/NfOrd.jl @@ -882,10 +882,15 @@ function any_order(K::AnticNumberField) end function any_order(K::NfAbsNS) - normalized_gens = Vector{NfAbsNSElem}(undef, degree(K)) + normalized_gens = Vector{NfAbsNSElem}(undef, ngens(K)) g = gens(K) for i in 1:ngens(K) f = denominator(K.pol[i]) * K.pol[i] + @show f + @show isone(coeff(f, 1)) + @show coeff(f, 1) + @show typeof(f) + @show g[i] if isone(coeff(f, 1)) normalized_gens[i] = g[i] else @@ -893,6 +898,8 @@ function any_order(K::NfAbsNS) end end + @show normalized_gens + b = Vector{NfAbsNSElem}(undef, degree(K)) ind = 1 it = cartesian_product_iterator([1:degrees(K)[i] for i in 1:ngens(K)], inplace = true) diff --git a/src/NumFieldOrd/NfOrd/ResidueField.jl b/src/NumFieldOrd/NfOrd/ResidueField.jl index 0c07565651..454922c542 100644 --- a/src/NumFieldOrd/NfOrd/ResidueField.jl +++ b/src/NumFieldOrd/NfOrd/ResidueField.jl @@ -197,7 +197,7 @@ function residue_field(O::NfOrd, P::NfOrdIdl, check::Bool = true) if check !is_prime(P) && error("Ideal must be prime") end - if !is_maximal_known(O) || !is_maximal(O) + if !is_maximal_known(O) || !is_maximal(O) || !is_defining_polynomial_nice(nf(O)) return _residue_field_generic_fq_default(O, P) end if !is_index_divisor(O, minimum(P)) && has_2_elem(P) diff --git a/src/NumFieldOrd/NfRelOrd/NfRelOrd.jl b/src/NumFieldOrd/NfRelOrd/NfRelOrd.jl index f5796f8442..6480895f25 100644 --- a/src/NumFieldOrd/NfRelOrd/NfRelOrd.jl +++ b/src/NumFieldOrd/NfRelOrd/NfRelOrd.jl @@ -506,7 +506,52 @@ function EquationOrder(L::NumField) return O end +function any_order(K::NfRel) + f = defining_polynomial(K) + de = _integral_multiplicator(f) + g = f * de + if is_monic(g) + return equation_order(K) + else + d = degree(g) + M = zero_matrix(base_field(K), d, d) + M[1, 1] = 1 + for i in 2:d + for j in i:-1:2 + M[i, j] = coeff(g, d - (i - j)) + end + end + B = pseudo_hnf(pseudo_matrix(M), :lowerleft) + return Order(K, B) + end +end + +function any_order(K::NfRelNS) + normalized_gens = Vector{elem_type(K)}(undef, ngens(K)) + g = gens(K) + pols = defining_polynomials(K) + for i in 1:ngens(K) + f = _integral_multiplicator(K.pol[i]) * K.pol[i] + if isone(coeff(f, 1)) + normalized_gens[i] = g[i] + else + normalized_gens[i] = coeff(f, 1) * g[i] + end + end + + b = Vector{elem_type(K)}(undef, degree(K)) + ind = 1 + it = cartesian_product_iterator([1:degrees(K)[i] for i in 1:ngens(K)], inplace = true) + for i in it + b[ind] = prod(normalized_gens[j]^(i[j] - 1) for j=1:length(i)) + ind += 1 + end + return Order(K, basis_matrix(b)) +end + function EquationOrder(L::NfRel{nf_elem}) + a = gen(L) + @req is_integral(a) "Generator of must be integral" M = identity_matrix(base_field(L), degree(L)) PM = pseudo_matrix(M) O = Order(L, PM) diff --git a/test/NfRel/NfRelOrd.jl b/test/NfRel/NfRelOrd.jl index 56ffb61291..670e588efa 100644 --- a/test/NfRel/NfRelOrd.jl +++ b/test/NfRel/NfRelOrd.jl @@ -212,3 +212,19 @@ K, a = quadratic_field(5) Kt, t = K["t"] L, b = number_field(polynomial(K, [-2, 0, 0, 1]), "b"); @test_throws Hecke.NotImplemented extend(equation_order(L), [b]) + +# Towards non-nice equations + +begin + Qx, x = QQ["x"] + K, a = number_field(x - 1) + Kt, t = K["t"] + L, b = number_field(t^2 + 1//2) + c = Hecke._integral_multiplicator(b) + @test is_integral(c * b) + O = any_order(L) + @test nf(O) === L + L, b = number_field([t^2 + 1//2]) + O = any_order(L) + @test nf(O) === L +end