diff --git a/Project.toml b/Project.toml index c200bf474b..f3d791c102 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "Hecke" uuid = "3e1990a7-5d81-5526-99ce-9ba3ff248f21" -version = "0.22.8" +version = "0.23.0" [deps] AbstractAlgebra = "c3fe647b-3220-5bb0-a1ea-a7954cac585d" @@ -28,7 +28,7 @@ GAPExt = "GAP" PolymakeExt = "Polymake" [compat] -AbstractAlgebra = "0.34" +AbstractAlgebra = "^0.34.4" Dates = "1.6" Distributed = "1.6" GAP = "0.9.6, 0.10" @@ -37,7 +37,7 @@ LazyArtifacts = "1.6" Libdl = "1.6" LinearAlgebra = "1.6" Markdown = "1.6" -Nemo = "0.38" +Nemo = "^0.38.2" Pkg = "1.6" Polymake = "0.10, 0.11" Printf = "1.6" diff --git a/README.md b/README.md index 55ef39463c..019627ae04 100644 --- a/README.md +++ b/README.md @@ -69,28 +69,32 @@ Here is a quick example of using Hecke: ```julia julia> using Hecke -... Welcome to - _ _ _ - | | | | | | - | |__| | ___ ___| | _____ - | __ |/ _ \/ __| |/ / _ \ - | | | | __/ (__| < __/ - |_| |_|\___|\___|_|\_\___| + _ _ _ + | | | | | | + | |__| | ___ ___| | _____ + | __ |/ _ \/ __| |/ / _ \ + | | | | __/ (__| < __/ + |_| |_|\___|\___|_|\_\___| + +Version 0.22.8... + ... which comes with absolutely no warranty whatsoever +(c) 2015-2023 by Claus Fieker, Tommy Hofmann and Carlo Sircana -Version 0.10.12... - ... which comes with absolutely no warrant whatsoever -(c) 2015-2019 by Claus Fieker, Tommy Hofmann and Carlo Sircana julia> Qx, x = polynomial_ring(FlintQQ, "x"); + julia> f = x^3 + 2; + julia> K, a = number_field(f, "a"); + julia> O = maximal_order(K); + julia> O -Maximal order of Number field over Rational Field with defining polynomial x^3 + 2 -with basis [1,a,a^2] +Maximal order of Number field of degree 3 over QQ +with basis nf_elem[1, a, a^2] ``` ## Documentation diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 4ae13b44e9..16ad9fcf95 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -114,6 +114,7 @@ nav: - Misc: misc.md - Extra features: - Macros: features/macros.md + - Multi-sets: features/mset.md - References: 'references.md' - Examples: 'examples.md' - Developer: diff --git a/docs/src/index.md b/docs/src/index.md index 60fe71ddb0..7c765b0662 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -42,40 +42,48 @@ Here is a quick example of using Hecke: ```julia julia> using Hecke -... Welcome to - _ _ _ - | | | | | | - | |__| | ___ ___| | _____ - | __ |/ _ \/ __| |/ / _ \ - | | | | __/ (__| < __/ - |_| |_|\___|\___|_|\_\___| + _ _ _ + | | | | | | + | |__| | ___ ___| | _____ + | __ |/ _ \/ __| |/ / _ \ + | | | | __/ (__| < __/ + |_| |_|\___|\___|_|\_\___| -Version 0.9.0 ... +Version 0.22.8... ... which comes with absolutely no warranty whatsoever -(c) 2015-2018 by Claus Fieker, Tommy Hofmann and Carlo Sircana +(c) 2015-2023 by Claus Fieker, Tommy Hofmann and Carlo Sircana + julia> Qx, x = polynomial_ring(FlintQQ, "x"); + julia> f = x^3 + 2; + julia> K, a = number_field(f, "a"); + julia> O = maximal_order(K); + julia> O -Maximal order of Number field over Rational Field with defining polynomial x^3 + 2 -with basis [1,a,a^2] +Maximal order of Number field of degree 3 over QQ +with basis nf_elem[1, a, a^2] ``` The documentation of the single functions can also be accessed at the julia prompt. Here is an example: ``` -help?> signature -search: signature +help?> absolute_degree +search: absolute_degree absolute_inertia_degree absolute_coordinates is_absolutely_irreducible + + absolute_degree(a::FqField) + + Return the degree of the given finite field over the prime field. - ---------------------------------------------------------------------------- + ───────────────────────────────────────────────────────────────────────────────────────────────── - signature(O::NfMaximalOrder) -> Tuple{Int, Int} + absolute_degree(L::NumField) -> Int - | Returns the signature of the ambient number field of \mathcal O. + Given a number field L/K, this function returns the degree of L over \mathbf Q. ``` diff --git a/docs/src/quad_forms/basics.md b/docs/src/quad_forms/basics.md index 4cd5cef002..de5501d752 100644 --- a/docs/src/quad_forms/basics.md +++ b/docs/src/quad_forms/basics.md @@ -21,7 +21,7 @@ following spaces for the rest of this section: ```@repl 2 using Hecke # hide -K, a = CyclotomicRealSubfield(7); +K, a = cyclotomic_real_subfield(7); Kt, t = K["t"]; E, b = number_field(t^2-a*t+1, "b"); Q = quadratic_space(K, K[0 1; 1 0]) @@ -59,7 +59,7 @@ space $H$: ```@repl 2 using Hecke # hide -K, a = CyclotomicRealSubfield(7); +K, a = cyclotomic_real_subfield(7); Kt, t = K["t"]; E, b = number_field(t^2-a*t+1, "b"); H = hermitian_space(E, 3); @@ -96,7 +96,7 @@ Note that the `is_hermitian` function tests whether the space is non-quadratic. ```@repl 2 using Hecke # hide -K, a = CyclotomicRealSubfield(7); +K, a = cyclotomic_real_subfield(7); Kt, t = K["t"]; E, b = number_field(t^2-a*t+1, "b"); Q = quadratic_space(K, K[0 1; 1 0]); @@ -123,7 +123,7 @@ restrict_scalars(::AbstractSpace, ::QQField, ::FieldElem) ```@repl 2 using Hecke # hide -K, a = CyclotomicRealSubfield(7); +K, a = cyclotomic_real_subfield(7); Kt, t = K["t"]; E, b = number_field(t^2-a*t+1, "b"); Q = quadratic_space(K, K[0 1; 1 0]); @@ -160,7 +160,7 @@ of $O_K$ above $7$, one can get: ```@repl 2 using Hecke # hide -K, a = CyclotomicRealSubfield(7); +K, a = cyclotomic_real_subfield(7); Q = quadratic_space(K, K[0 1; 1 0]); OK = maximal_order(K); p = prime_decomposition(OK, 7)[1][1]; @@ -196,7 +196,7 @@ embed respectively locally or globally into $Q$ or $H$: ```@repl 2 using Hecke # hide -K, a = CyclotomicRealSubfield(7); +K, a = cyclotomic_real_subfield(7); Kt, t = K["t"]; E, b = number_field(t^2-a*t+1, "b"); Q = quadratic_space(K, K[0 1; 1 0]); @@ -247,7 +247,7 @@ orthogonal_projection(::AbstractSpace, ::MatElem) ```@repl 2 using Hecke # hide -K, a = CyclotomicRealSubfield(7); +K, a = cyclotomic_real_subfield(7); Kt, t = K["t"]; Q = quadratic_space(K, K[0 1; 1 0]); orthogonal_complement(Q, matrix(K, 1, 2, [1 0])) @@ -268,7 +268,7 @@ is_isotropic(::AbstractSpace, p) ```@repl 2 using Hecke # hide -K, a = CyclotomicRealSubfield(7); +K, a = cyclotomic_real_subfield(7); Kt, t = K["t"]; E, b = number_field(t^2-a*t+1, "b"); H = hermitian_space(E, 3); @@ -295,7 +295,7 @@ is_locally_hyperbolic(::HermSpace, ::NfOrdIdl) ```@repl 2 using Hecke # hide -K, a = CyclotomicRealSubfield(7); +K, a = cyclotomic_real_subfield(7); Kt, t = K["t"]; E, b = number_field(t^2-a*t+1, "b"); H = hermitian_space(E, 3); diff --git a/docs/src/quad_forms/genusherm.md b/docs/src/quad_forms/genusherm.md index 9055d7b7ad..63f9bc448a 100644 --- a/docs/src/quad_forms/genusherm.md +++ b/docs/src/quad_forms/genusherm.md @@ -473,7 +473,7 @@ hermitian_genera(::Hecke.NfRel, ::Int, ::Dict{InfPlc, Int}, ::Union{Hecke.NfRelO ```@repl 2 using Hecke # hide -K, a = CyclotomicRealSubfield(8, "a"); +K, a = cyclotomic_real_subfield(8, "a"); Kt, t = K["t"]; E, b = number_field(t^2 - a * t + 1); p = prime_decomposition(maximal_order(K), 2)[1][1]; diff --git a/examples/NFDB.jl b/examples/NFDB.jl index 46c8a3c62b..1b90534fbf 100644 --- a/examples/NFDB.jl +++ b/examples/NFDB.jl @@ -1175,9 +1175,10 @@ function _p_adic_regulator(K, p) end C, mC = completion(K, P, prec) Rmat = zero_matrix(C, r, r) + D = Dict{nf_elem, LocalFieldElem{qadic, EisensteinLocalField}}() for i in 1:r for j in 1:r - Rmat[i, j] = _evaluate_log_of_fac_elem(mC, P, mA(A[i])(mU(U[j + 1]))) # j + 1, because the fundamental units correspond to U[2],..,U[r + 1] + Rmat[i, j] = _evaluate_log_of_fac_elem(mC, P, mA(A[i])(mU(U[j + 1])), D) # j + 1, because the fundamental units correspond to U[2],..,U[r + 1] end end z = _det(Rmat) @@ -1189,14 +1190,26 @@ function _p_adic_regulator(K, p) end end -function _evaluate_log_of_fac_elem(mC, P, e) +function _evaluate_log_of_fac_elem(mC, P, e::FacElem{nf_elem, AnticNumberField}, D = Dict{nf_elem, LocalFieldElem{qadic, EisensteinLocalField}}()) C = codomain(mC) K = base_ring(e) pi = K(uniformizer(P)) - # at the moment log() works only for valuation == 0, + # We want to compute + # sum(n * log(mC(pi^(-valuation(b, P)) * b)) for (b, n) in e; init = zero(C)) + # but we cache the result of the individual log(), since the elements we look + # at have large intersection for their bases. + # + # At the moment log() works only for valuation == 0, # but since we have a unit, we can just scale in every factor - l = sum(n * log(mC(pi^(-valuation(b, P)) * b)) for (b, n) in e; init = zero(C)) - return l + res = zero(C) + for (b, n) in e + l = get!(D, b) do + bb = mC(pi^(-valuation(b, P)) * b) + return log(bb) + end + res = res + n * l + end + return res end function _padic_regulator_non_normal(K, p) diff --git a/src/AlgAss/AlgMat.jl b/src/AlgAss/AlgMat.jl index 4547ecefbb..270561330a 100644 --- a/src/AlgAss/AlgMat.jl +++ b/src/AlgAss/AlgMat.jl @@ -18,8 +18,6 @@ basis(A::AlgMat) = A.basis has_one(A::AlgMat) = true -elem_type(A::AlgMat{T, S}) where { T, S } = AlgMatElem{T, AlgMat{T, S}, S} - elem_type(::Type{AlgMat{T, S}}) where { T, S } = AlgMatElem{T, AlgMat{T, S}, S} order_type(::AlgMat{QQFieldElem, S}) where { S } = AlgAssAbsOrd{AlgMat{QQFieldElem, S}, elem_type(AlgMat{QQFieldElem, S})} diff --git a/src/AlgAss/AlgQuat.jl b/src/AlgAss/AlgQuat.jl index 2bd820beef..2d8c1f253d 100644 --- a/src/AlgAss/AlgQuat.jl +++ b/src/AlgAss/AlgQuat.jl @@ -53,8 +53,6 @@ standard_form(A::AlgQuat) = A.std has_one(A::AlgQuat) = true -elem_type(A::AlgQuat{T}) where {T} = AlgAssElem{T, AlgQuat{T}} - elem_type(::Type{AlgQuat{T}}) where {T} = AlgAssElem{T, AlgQuat{T}} is_commutative(A::AlgQuat) = false diff --git a/src/AlgAssAbsOrd/Elem.jl b/src/AlgAssAbsOrd/Elem.jl index b7bc607121..3c58be1a52 100644 --- a/src/AlgAssAbsOrd/Elem.jl +++ b/src/AlgAssAbsOrd/Elem.jl @@ -2,8 +2,6 @@ export elem_in_algebra parent_type(::Type{AlgAssAbsOrdElem{S, T}}) where {S, T} = AlgAssAbsOrd{S, T} -parent_type(::AlgAssAbsOrdElem{S, T}) where {S, T} = AlgAssAbsOrd{S, T} - @inline parent(x::AlgAssAbsOrdElem) = x.parent Base.hash(x::AlgAssAbsOrdElem, h::UInt) = hash(elem_in_algebra(x, copy = false), h) diff --git a/src/AlgAssAbsOrd/Ideal.jl b/src/AlgAssAbsOrd/Ideal.jl index 9aff85cc76..1f87bb9240 100644 --- a/src/AlgAssAbsOrd/Ideal.jl +++ b/src/AlgAssAbsOrd/Ideal.jl @@ -1447,8 +1447,6 @@ FracIdealSet(O::AlgAssAbsOrd) = IdealSet(O) elem_type(::Type{AlgAssAbsOrdIdlSet{S, T}}) where {S, T} = AlgAssAbsOrdIdl{S, T} -elem_type(::AlgAssAbsOrdIdlSet{S, T}) where {S, T} = AlgAssAbsOrdIdl{S, T} - parent_type(::Type{AlgAssAbsOrdIdl{S, T}}) where {S, T} = AlgAssAbsOrdIdlSet{S, T} function Base.one(S::AlgAssAbsOrdIdlSet) diff --git a/src/AlgAssAbsOrd/Order.jl b/src/AlgAssAbsOrd/Order.jl index 8e5d8e3101..4b010b5953 100644 --- a/src/AlgAssAbsOrd/Order.jl +++ b/src/AlgAssAbsOrd/Order.jl @@ -1,10 +1,8 @@ -export algebra, integral_group_ring +export algebra, ideal_type, integral_group_ring add_assertion_scope(:AlgAssOrd) add_verbosity_scope(:AlgAssOrd) -elem_type(::AlgAssAbsOrd{S, T}) where {S, T} = AlgAssAbsOrdElem{S, T} - elem_type(::Type{AlgAssAbsOrd{S, T}}) where {S, T} = AlgAssAbsOrdElem{S, T} ideal_type(::AlgAssAbsOrd{S, T}) where {S, T} = AlgAssAbsOrdIdl{S, T} diff --git a/src/AlgAssRelOrd/Elem.jl b/src/AlgAssRelOrd/Elem.jl index 1701f60fbb..f87a2f1b88 100644 --- a/src/AlgAssRelOrd/Elem.jl +++ b/src/AlgAssRelOrd/Elem.jl @@ -4,8 +4,6 @@ export trred parent_type(::Type{AlgAssRelOrdElem{S, T, U}}) where {S, T, U} = AlgAssRelOrd{S, T, U} -parent_type(::AlgAssRelOrdElem{S, T, U}) where {S, T, U} = AlgAssRelOrd{S, T, U} - @doc raw""" parent(x::AlgAssRelOrdElem) -> AlgAssRelOrd diff --git a/src/AlgAssRelOrd/Order.jl b/src/AlgAssRelOrd/Order.jl index cb59b86d07..f08d2b2caa 100644 --- a/src/AlgAssRelOrd/Order.jl +++ b/src/AlgAssRelOrd/Order.jl @@ -1,6 +1,4 @@ -export is_commutative, trred_matrix, any_order, pmaximal_overorder, phereditary_overorder, is_maximal - -elem_type(::AlgAssRelOrd{S, T, U}) where {S, T, U} = AlgAssRelOrdElem{S, T, U} +export is_commutative, trred_matrix, any_order, pmaximal_overorder, phereditary_overorder, is_maximal, ideal_type elem_type(::Type{AlgAssRelOrd{S, T, U}}) where {S, T, U} = AlgAssRelOrdElem{S, T, U} diff --git a/src/EllCrv/EllCrv.jl b/src/EllCrv/EllCrv.jl index c9e88b081b..7317fca9e5 100644 --- a/src/EllCrv/EllCrv.jl +++ b/src/EllCrv/EllCrv.jl @@ -775,10 +775,6 @@ end # ################################################################################ -function elem_type(E::EllCrv{T}) where T - return EllCrvPt{T} -end - function elem_type(::Type{EllCrv{T}}) where T return EllCrvPt{T} end diff --git a/src/FunField/HessQR.jl b/src/FunField/HessQR.jl index 1b5643f385..cfaac14d37 100644 --- a/src/FunField/HessQR.jl +++ b/src/FunField/HessQR.jl @@ -143,9 +143,7 @@ function Hecke.denominator(a::Generic.RationalFunctionFieldElem, S::HessQR) return integral_split(a, S)[2] end -Nemo.elem_type(::HessQR) = HessQRElem Nemo.elem_type(::Type{HessQR}) = HessQRElem -Nemo.parent_type(::HessQRElem) = HessQR Nemo.parent_type(::Type{HessQRElem}) = HessQR Nemo.is_domain_type(::Type{HessQRElem}) = true diff --git a/src/GenOrd/GenOrd.jl b/src/GenOrd/GenOrd.jl index df909c9522..5d74ca4243 100644 --- a/src/GenOrd/GenOrd.jl +++ b/src/GenOrd/GenOrd.jl @@ -46,14 +46,10 @@ function elem_type(::Type{GenOrd{S, T}}) where {S, T} return GenOrdElem{elem_type(S), elem_type(T)} end -elem_type(::O) where {O <: GenOrd} = elem_type(O) - function parent_type(::Type{GenOrdElem{S, T}}) where {S, T} return GenOrd{parent_type(S), parent_type(T)} end -parent_type(::OE) where {OE <: GenOrdElem} = parent_type(OE) - # prepare for algebras, which are not domains is_domain_type(::Type{GenOrdElem{S, T}}) where {S, T} = is_domain_type(S) diff --git a/src/Grp/GenGrp.jl b/src/Grp/GenGrp.jl index c774d5e72e..2563385e78 100644 --- a/src/Grp/GenGrp.jl +++ b/src/Grp/GenGrp.jl @@ -181,8 +181,6 @@ end elem_type(::Type{GrpGen}) = GrpGenElem -elem_type(::GrpGen) = GrpGenElem - Base.hash(G::GrpGenElem, h::UInt) = Base.hash(G.i, h) Base.hash(G::GrpGen, h::UInt) = UInt(0) diff --git a/src/GrpAb/GrpAbFinGen.jl b/src/GrpAb/GrpAbFinGen.jl index ce848085f8..84bbf97170 100644 --- a/src/GrpAb/GrpAbFinGen.jl +++ b/src/GrpAb/GrpAbFinGen.jl @@ -48,8 +48,6 @@ import Base.+, Nemo.snf, Nemo.parent, Base.rand, Nemo.is_snf # ################################################################################ -elem_type(G::GrpAbFinGen) = GrpAbFinGenElem - elem_type(::Type{GrpAbFinGen}) = GrpAbFinGenElem parent_type(::Type{GrpAbFinGenElem}) = GrpAbFinGen @@ -882,7 +880,6 @@ function show(io::IO, P::TupleParent{T}) where {T} end elem_type(::Type{TupleParent{T}}) where {T} = T -elem_type(::TupleParent{T}) where {T} = T parent(t::Tuple) = TupleParent(t) diff --git a/src/GrpAb/Lattice.jl b/src/GrpAb/Lattice.jl index 556d1ca994..6a1813d090 100644 --- a/src/GrpAb/Lattice.jl +++ b/src/GrpAb/Lattice.jl @@ -517,6 +517,10 @@ end # "overgroup" M. If so, the second return value is M and the third and fourth # return values describe the map from G to M and H to M respectively. function can_map_into_overstructure(L::RelLattice{T, D}, G::T, H::T) where {T, D} + if G === H + return true, G, L.make_id(G)::D, L.make_id(G)::D + end + if !(G in keys(L.weak_vertices) && H in keys(L.weak_vertices)) return false, G, L.zero, L.zero end diff --git a/src/HeckeTypes.jl b/src/HeckeTypes.jl index 51c6e51e77..25a76f510b 100644 --- a/src/HeckeTypes.jl +++ b/src/HeckeTypes.jl @@ -1993,8 +1993,6 @@ end elem_type(::Type{NfRel{T}}) where {T} = NfRelElem{T} -elem_type(::NfRel{T}) where {T} = NfRelElem{T} - parent_type(::Type{NfRelElem{T}}) where {T} = NfRel{T} diff --git a/src/HypellCrv/HypellCrv.jl b/src/HypellCrv/HypellCrv.jl index 2e0d39833d..b805e8698b 100644 --- a/src/HypellCrv/HypellCrv.jl +++ b/src/HypellCrv/HypellCrv.jl @@ -460,10 +460,6 @@ end # ################################################################################ -function elem_type(C::HypellCrv{T}) where T - return HypellCrvPt{T} -end - function elem_type(::Type{HypellCrv{T}}) where T return HypellCrvPt{T} end diff --git a/src/LargeField/misc2.jl b/src/LargeField/misc2.jl index c04fbc128f..a4efee0fd4 100644 --- a/src/LargeField/misc2.jl +++ b/src/LargeField/misc2.jl @@ -388,7 +388,7 @@ end #= Qx,x = polynomial_ring(FlintQQ, "a") -K, a = CyclotomicRealSubfield(1024, "a"); +K, a = cyclotomic_real_subfield(1024, "a"); @time fb_int = Hecke.int_fb_max_real(1024, 2^20); h = Hecke.auto_of_maximal_real(K, 3); b = [K(1), a] @@ -398,7 +398,7 @@ fb_int = FactorBase(ZZRingElem[x for x = vcat(fb_int[1], fb_int[2], fb_int[3])]) @time Hecke.basis_rels_5(b, 600, 10, 5, fb_int) Qx,x = polynomial_ring(FlintQQ, "a") -K, a = CyclotomicRealSubfield(512, "a"); +K, a = cyclotomic_real_subfield(512, "a"); @time fb_int = Hecke.int_fb_max_real(512, 2^18); h = Hecke.auto_of_maximal_real(K, 3); b = [K(1), a] diff --git a/src/LinearAlgebra/LatEnum.jl b/src/LinearAlgebra/LatEnum.jl index e17109f524..d26cb0740d 100644 --- a/src/LinearAlgebra/LatEnum.jl +++ b/src/LinearAlgebra/LatEnum.jl @@ -183,6 +183,8 @@ function enum_ctx_start(E::enum_ctx{A,B,C}, c::ZZRingElem) where {A,B,C} E.cnt = 0 end +#start enumeration at the element x, the bound on the length +#is the length of x * eps function enum_ctx_start(E::enum_ctx{A,B,C}, x::ZZMatrix; eps::Float64=1.0) where {A,B,C} E.x = x for i=E.limit-1:-1:1 @@ -202,33 +204,54 @@ function enum_ctx_start(E::enum_ctx{A,B,C}, x::ZZMatrix; eps::Float64=1.0) where E.last_non_zero = maximum(findall(i->E.x[1, i] != 0, 1:E.limit))+1 end -#for pol-red-abs we need s.th. else I think -# +#start enumeration at the first element having a 1 at position i (and zeros +#for all j>i. +#the length is going to be the length of the i-th unit vector * eps +#(the actual vector might be shorter) +function enum_ctx_start(E::enum_ctx{A,B,C}, i::Int; eps::Float64=1.0) where {A,B,C} + for j=1:E.limit + if j == i + E.x[1, j] = 1 + else + E.x[1, j] = 0 + end + end + E.last_non_zero = i+1 + + for k=E.limit-1:-1:1 + E.tail[k] = sum(E.C[k, j]*C(E.x[1,j]) for j=k+1:E.limit) + end + b = sum(E.C[j,j]*(C(E.x[1,j]) + E.tail[j])^2 for j=1:E.limit) #curr. length + #@show b, C((x*E.G*x')[1,1]) + #@assert b == C((x*E.G*x')[1,1]) + E.c = ceil(ZZRingElem, b*C(E.d)*eps) + E.l[E.limit] = C(E.c//E.d) + for j=E.limit-1:-1:1 + E.l[j] = E.l[j+1] - E.C[j+1,j+1]*(C(E.x[1,j+1]) + E.tail[j+1])^2 + end + for j=E.limit:-1:1 + E.L[j], E.U[j] = enum_ctx_local_bound(-E.tail[j], E.l[j]/E.C[j,j]) + if j < i + E.x[1, j] = A(Base.ceil((E.L[j] +E.U[j])/2)) + E.tail[j] = sum(E.C[j, k]*C(E.x[1,k]) for k=j+1:E.limit) + E.l[j] = E.l[j+1] - E.C[j+1,j+1]*(C(E.x[1,j+1]) + E.tail[j+1])^2 + end + end +end + # #missing: lower bound # reference vector (eventually) # length # proper lattice type -@inline function fmpz_mat_entry(a::ZZMatrix, r::Int, c::Int) - return ccall((:fmpz_mat_entry, libflint), Ptr{ZZRingElem}, - (Ref{ZZMatrix}, Int, Int), a, r - 1, c - 1) -#@inline function fmpz_mat_entry(a::ZZMatrix, r::Int, c::Int) - #return unsafe_load(reinterpret(Ptr{Ptr{ZZRingElem}}, a.rows), r)+(c-1)*sizeof(Ptr) -end - @inline function fmpz_mat_entry_incref!(a::ZZMatrix, r::Int, c::Int) - z = ccall((:fmpz_mat_entry, libflint), Ptr{ZZRingElem}, - (Ref{ZZMatrix}, Int, Int), a, r - 1, c - 1) + z = Nemo.mat_entry_ptr(a, r, c) ccall((:fmpz_add_ui, libflint), Nothing, (Ptr{ZZRingElem}, Ptr{ZZRingElem}, Int), z, z, 1) - #z = fmpz_mat_entry(a, r, c) - #unsafe_store!(reinterpret(Ptr{Int}, z), unsafe_load(reinterpret(Ptr{Int}, z), 1)+1, 1) - ##ccall((:fmpz_add_ui, libflint), Nothing, (Ptr{ZZRingElem}, Ptr{ZZRingElem}, Int), z, z, 1) end function fmpz_mat_entry_add_ui!(a::ZZMatrix, r::Int, c::Int, v::UInt) - z = ccall((:fmpz_mat_entry, libflint), Ptr{ZZRingElem}, - (Ref{ZZMatrix}, Int, Int), a, r - 1, c - 1) + z = Nemo.mat_entry_ptr(a, r, c) ccall((:fmpz_add_ui, libflint), Nothing, (Ptr{ZZRingElem}, Ptr{ZZRingElem}, Int), z, z, v) end diff --git a/src/LocalField/Elem.jl b/src/LocalField/Elem.jl index 7d7c54720f..a200e3be73 100644 --- a/src/LocalField/Elem.jl +++ b/src/LocalField/Elem.jl @@ -87,7 +87,6 @@ end parent(a::LocalFieldElem) = a.parent -parent_type(a::LocalFieldElem{S, T}) where {S <: FieldElem, T <: LocalFieldParameter} = LocalField{S, T} parent_type(::Type{LocalFieldElem{S, T}}) where {S <: FieldElem, T <: LocalFieldParameter} = LocalField{S, T} ################################################################################ diff --git a/src/LocalField/LocalField.jl b/src/LocalField/LocalField.jl index bce7e6303c..5c4fc00f50 100644 --- a/src/LocalField/LocalField.jl +++ b/src/LocalField/LocalField.jl @@ -40,12 +40,8 @@ prime(K::LocalField) = prime(base_field(K)) base_field_type(K::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(K::LocalField{S, T}) where {S <: FieldElem, T <: LocalFieldParameter} = LocalFieldElem{S, T} elem_type(::Type{LocalField{S, T}}) where {S <: FieldElem, T <: LocalFieldParameter} = LocalFieldElem{S, T} -dense_matrix_type(K::LocalField{S, T}) where {S <: FieldElem, T <: LocalFieldParameter} = Generic.MatSpaceElem{LocalFieldElem{S, T}} -dense_matrix_type(::Type{LocalField{S, T}}) where {S <: FieldElem, T <: LocalFieldParameter} = Generic.MatSpaceElem{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}} diff --git a/src/Map/NumField.jl b/src/Map/NumField.jl index 0a9af45464..5071616d47 100644 --- a/src/Map/NumField.jl +++ b/src/Map/NumField.jl @@ -199,14 +199,10 @@ base_field_type(::Type{NfRel{T}}) where {T} = parent_type(T) elem_type(::Type{NfRelNS{T}}) where {T} = NfRelNSElem{T} -elem_type(::NfRelNS{T}) where {T} = NfRelNSElem{T} - parent_type(::Type{NfRelNSElem{T}}) where {T} = NfRelNS{T} elem_type(::Type{NfAbsNS}) = NfAbsNSElem -elem_type(::NfAbsNS) = NfAbsNSElem - parent_type(::Type{NfAbsNSElem}) = NfAbsNS ################################################################################ diff --git a/src/Map/NumberField.jl b/src/Map/NumberField.jl index dc5995ea37..6be2b752c5 100644 --- a/src/Map/NumberField.jl +++ b/src/Map/NumberField.jl @@ -8,10 +8,6 @@ function elem_type(::Type{NfMorSet{T}}) where {T} return morphism_type(T, T) end -function elem_type(::NfMorSet{T}) where {T} - return elem_type(NfMorSet{T}) -end - function show(io::IO, S::NfMorSet{T}) where {T} print(io, "Set of automorphisms of ", S.field) end diff --git a/src/Misc/FiniteField.jl b/src/Misc/FiniteField.jl index de8144a31b..4915b4751f 100644 --- a/src/Misc/FiniteField.jl +++ b/src/Misc/FiniteField.jl @@ -254,10 +254,10 @@ end mutable struct VeryBad - entries::Ptr{Nothing} + entries::Ptr{UInt} r::Int c::Int - rows::Ptr{Nothing} + rows::Ptr{Ptr{UInt}} n::UInt ninv::UInt norm::UInt @@ -268,23 +268,23 @@ mutable struct VeryBad r.ninv = ninv r.norm = norm r.r = 1 - r.rr = [reinterpret(Ptr{Nothing}, 0)] - r.rows = Base.unsafe_convert(Ptr{Nothing}, r.rr) + r.rr = [reinterpret(Ptr{UInt}, 0)] + r.rows = pointer(r.rr) return r end - rr::Vector{Ptr{Nothing}} + rr::Vector{Ptr{UInt}} end function VeryBad!(V::VeryBad, a::fqPolyRepFieldElem) V.c = a.length - V.entries = a.coeffs + V.entries = reinterpret(Ptr{UInt}, a.coeffs) V.rr[1] = a.coeffs # V.rows = Base.unsafe_convert(Ptr{Nothing}, [a.coeffs]) end function clear!(V::VeryBad) - V.entries = reinterpret(Ptr{Nothing}, 0) + V.entries = reinterpret(Ptr{Ptr{UInt}}, 0) # V.rows = reinterpret(Ptr{Nothing}, 0) end diff --git a/src/Misc/Poly.jl b/src/Misc/Poly.jl index 355b5b7f1a..1f937ddbd6 100644 --- a/src/Misc/Poly.jl +++ b/src/Misc/Poly.jl @@ -418,7 +418,7 @@ function n_positive_roots(f::ZZPolyRingElem; multiplicities::Bool = false) if !multiplicities ffp = derivative(ff) g = gcd(ff, ffp) - if isconstant(g) + if is_constant(g) return _n_positive_roots_sf(f) else return n_positive_roots(divexact(ff, g))::Int @@ -446,7 +446,7 @@ function _n_positive_roots_sf(f::ZZPolyRingElem) # Here a = 0 _, f = remove(f, gen(parent(f))) - if isconstant(f) + if is_constant(f) # f = x^n * a, so no positive root return 0 end @@ -465,7 +465,7 @@ function n_real_roots(f::ZZPolyRingElem) ff = Hecke.Globals.Qx(f) ffp = derivative(ff) g = gcd(ff, ffp) - if isconstant(g) + if is_constant(g) return _n_real_roots_sf(f) else return n_real_roots(divexact(ff, g))::Int diff --git a/src/Misc/RelFiniteField.jl b/src/Misc/RelFiniteField.jl index 3a93c9da5e..6f9a8c1bb4 100644 --- a/src/Misc/RelFiniteField.jl +++ b/src/Misc/RelFiniteField.jl @@ -152,10 +152,8 @@ function zero!(x::RelFinFieldElem) return x end -elem_type(F::RelFinField{T}) where T = RelFinFieldElem{RelFinField{T}, dense_poly_type(T)} -elem_type(::Type{RelFinField{T}}) where T = RelFinFieldElem{RelFinField{T}, dense_poly_type(T)} +elem_type(::Type{RelFinField{T}}) where T = RelFinFieldElem{RelFinField{T}, dense_poly_type(T)} -parent_type(::RelFinFieldElem{S, T}) where {S, T} = S parent_type(::Type{RelFinFieldElem{S, T}}) where {S, T} = S gen(F::RelFinField) = F(gen(parent(defining_polynomial(F)))) diff --git a/src/ModAlgAss/Lattices/Morphisms.jl b/src/ModAlgAss/Lattices/Morphisms.jl index 6823072465..0cd8aee943 100644 --- a/src/ModAlgAss/Lattices/Morphisms.jl +++ b/src/ModAlgAss/Lattices/Morphisms.jl @@ -191,8 +191,12 @@ end # ################################################################################ -function _is_isomorphic_with_isomorphism_same_ambient_module(L::ModAlgAssLat, M::ModAlgAssLat) +function _is_isomorphic_with_isomorphism_same_ambient_module(L::ModAlgAssLat, M::ModAlgAssLat; strategy = :default) E, f, O, I = _hom_space_as_ideal(L, M) + if strategy == :s1 + fl = __isprincipal_s1(O, I, :right) + return fl, zero_map(L.V, M.V) + end fl, beta = __isprincipal(O, I, :right) if !fl return false, zero_map(L.V, M.V) @@ -204,7 +208,7 @@ function _is_isomorphic_with_isomorphism_same_ambient_module(L::ModAlgAssLat, M: end end -function is_isomorphic_with_isomorphism(L::ModAlgAssLat, M::ModAlgAssLat) +function is_isomorphic_with_isomorphism(L::ModAlgAssLat, M::ModAlgAssLat; strategy = :s1) # the hom_space function wants L and M sitting inside the same ambient space # there is some choice we can make # we try to choose the order, where we already computed the endomorphism @@ -216,10 +220,12 @@ function is_isomorphic_with_isomorphism(L::ModAlgAssLat, M::ModAlgAssLat) return false, zero_map(L.V, M.V) end MM = iso(M) - fl, LtoMM = _is_isomorphic_with_isomorphism_same_ambient_module(L, MM) + fl, LtoMM = _is_isomorphic_with_isomorphism_same_ambient_module(L, MM; strategy = strategy) if fl _iso = LtoMM * inv(iso) - @assert _iso(L) == M + if !is_zero(LtoMM.matrix) + @assert _iso(L) == M + end return true, _iso else return false, zero_map(L.V, M.V) @@ -230,7 +236,7 @@ function is_isomorphic_with_isomorphism(L::ModAlgAssLat, M::ModAlgAssLat) return false, zero_map(L.V, M.V) end LL = iso(L) - fl, LLtoM = _is_isomorphic_with_isomorphism_same_ambient_module(LL, M) + fl, LLtoM = _is_isomorphic_with_isomorphism_same_ambient_module(LL, M; strategy = strategy) if fl _iso = iso * LLtoM @assert _iso(L) == M @@ -241,8 +247,8 @@ function is_isomorphic_with_isomorphism(L::ModAlgAssLat, M::ModAlgAssLat) end end -function is_isomorphic(L::ModAlgAssLat, M::ModAlgAssLat) - return is_isomorphic_with_isomorphism(L, M)[1] +function is_isomorphic(L::ModAlgAssLat, M::ModAlgAssLat; strategy = :default) + return is_isomorphic_with_isomorphism(L, M; strategy = strategy)[1] end ################################################################################ @@ -313,16 +319,25 @@ end # ################################################################################ -function is_aut_isomorphic(L::ModAlgAssLat, M::ModAlgAssLat) +# Take a Z[G]-lattice L and Z[H]-lattice M with G isomorhic to H +# Check if there is an isomorphism G -> H, such that +# L and M are isomorphic +# If G === H, this is the test for Aut(G)-isomorphism +function is_aut_isomorphic(L::ModAlgAssLat, M::ModAlgAssLat; strategy = :default) + G = group(algebra(L.base_ring)) + H = group(algebra(M.base_ring)) + if G !== H + M = _make_compatible(L, M) + end + for T in _twists(M) - if is_isomorphic(L, T) + if is_isomorphic(L, T; strategy = strategy) return true end end return false end - function _make_compatible(L::ModAlgAssLat, M::ModAlgAssLat) G = group(algebra(L.base_ring)) H = group(algebra(M.base_ring)) diff --git a/src/ModAlgAss/ModAlgAss.jl b/src/ModAlgAss/ModAlgAss.jl index b281fb3df4..26a89f3c2d 100644 --- a/src/ModAlgAss/ModAlgAss.jl +++ b/src/ModAlgAss/ModAlgAss.jl @@ -674,7 +674,7 @@ function _twists(V::ModAlgAss) A = outer_automorphisms(G) res = typeof(V)[] for a in A - push!(res, _twist(V, a)) + push!(res, _twist(V, hom(a))) end return res end @@ -683,7 +683,7 @@ function _twist(V::ModAlgAss, a::Map) A = algebra(V) @req A isa AlgGrp "Algebra must be a group algebra" G = group(A) - @req domain(a) == G == codomain(G) "Map must be an endomorphism of the group" + @req domain(a) == G == codomain(a) "Map must be an endomorphism of the group" B = basis(A) rep2 = QQMatrix[] for i in 1:length(B) @@ -693,3 +693,21 @@ function _twist(V::ModAlgAss, a::Map) end W = Amodule(A, rep2) end + +function _change_group(V::ModAlgAss, a::Map; algebra = nothing) + A = Hecke.algebra(V) + @req A isa AlgGrp "Algebra must be a group algebra" + G = group(A) + @req G == codomain(a) "Map must be an endomorphism of the group" + @assert algebra !== nothing + H = domain(a) + QH = group_algebra(base_field(A), H) + B = basis(A) + rep2 = QQMatrix[] + for i in 1:length(B) + g = A.base_to_group[i] + push!(rep2, action(V, A(a(g)))) + end + W = Amodule(QH, rep2) + return W +end diff --git a/src/NumField/Embedded.jl b/src/NumField/Embedded.jl index 0b61a02362..dd99b31e36 100644 --- a/src/NumField/Embedded.jl +++ b/src/NumField/Embedded.jl @@ -55,12 +55,8 @@ parent(x::EmbeddedElem{T}) where {T} = x.parent::parent_type(x) elem_type(::Type{EmbeddedField{S, E}}) where {S, E} = EmbeddedElem{elem_type(S)} -elem_type(K::EmbeddedField{S, E}) where {S, E} = elem_type(EmbeddedField{S, E}) - parent_type(::Type{EmbeddedElem{T}}) where {T} = EmbeddedField{parent_type(T), embedding_type(parent_type(T))} -parent_type(x::EmbeddedElem{T}) where {T} = parent_type(EmbeddedElem{T}) - data(x::EmbeddedElem) = x.element function embedded_field(K::SimpleNumField, i::NumFieldEmb) diff --git a/src/NumField/NfAbs/Cyclotomic.jl b/src/NumField/NfAbs/Cyclotomic.jl index e30b64a522..2fe7fea55a 100644 --- a/src/NumField/NfAbs/Cyclotomic.jl +++ b/src/NumField/NfAbs/Cyclotomic.jl @@ -10,7 +10,7 @@ conductor, return a generating set for the cyclotomic units of $K$. # Examples ```jldoctest -julia> K, a = CyclotomicRealSubfield(7); +julia> K, a = cyclotomic_real_subfield(7); julia> cyclotomic_units_totally_real(K) 3-element Vector{nf_elem}: @@ -150,7 +150,7 @@ function cyclotomic_regulator(n::Int, prec::Int; maximal_totally_real::Bool = fa # If we only care about regulators, this is not a problem, as we # just have to scale appropriately. if is_prime(n) - K, = CyclotomicRealSubfield(n, cached = false) + K, = cyclotomic_real_subfield(n, cached = false) if degree(K) == 1 return regulator(nf_elem[], prec) end @@ -163,7 +163,7 @@ function cyclotomic_regulator(n::Int, prec::Int; maximal_totally_real::Bool = fa end else @assert is_prime_power(n) - K, = CyclotomicRealSubfield(n, cached = false) + K, = cyclotomic_real_subfield(n, cached = false) cyc = _cyclotomic_units_totally_real_prime_power_conductor(K, n, true) # cyc is in K(zeta_n) reg = regulator(cyc[2:end], prec) diff --git a/src/NumField/NfAbs/Simplify.jl b/src/NumField/NfAbs/Simplify.jl index 99222479ab..0fab8aa6cd 100644 --- a/src/NumField/NfAbs/Simplify.jl +++ b/src/NumField/NfAbs/Simplify.jl @@ -393,11 +393,10 @@ function polredabs(K::AnticNumberField) end end - l = zeros(FlintZZ, n) - l[i] = 1 - scale = 1.0 - enum_ctx_start(E, matrix(FlintZZ, 1, n, l), eps = 1.01) + enum_ctx_start(E, i, eps = 1.01) #start at the 1st vector having + # a 1 at position i, it's pointless to start earlier + #as none of the elements can be primitive. a = gen(K) all_a = nf_elem[a] @@ -410,7 +409,6 @@ function polredabs(K::AnticNumberField) while !found_pe while first || enum_ctx_next(E) first = false -# @show E.x M = E.x*E.t q = elem_from_mat_row(K, M, 1, E.t_den) bb = _block(q, rt, ap) @@ -442,7 +440,7 @@ function polredabs(K::AnticNumberField) end end scale *= 2 - enum_ctx_start(E, matrix(FlintZZ, 1, n, l), eps = scale) + enum_ctx_start(E, i, eps = scale) first = true Ec = BigFloat(E.c//E.d) end diff --git a/src/NumField/NfRel/NfRel.jl b/src/NumField/NfRel/NfRel.jl index 1e32782053..9e0c294d7d 100644 --- a/src/NumField/NfRel/NfRel.jl +++ b/src/NumField/NfRel/NfRel.jl @@ -915,7 +915,7 @@ Number field with defining polynomial $ - 1 ``` """ function cyclotomic_field_as_cm_extension(n::Int; cached::Bool = true) - K, a = CyclotomicRealSubfield(n, Symbol("(z_$n + 1//z_$n)"), cached = cached) + K, a = cyclotomic_real_subfield(n, Symbol("(z_$n + 1//z_$n)"), cached = cached) Kt, t = polynomial_ring(K, "t", cached = false) E, b = number_field(t^2-a*t+1, "z_$n", cached = cached) set_attribute!(E, :cyclo, n) diff --git a/src/NumFieldOrd/NfOrd/FracIdeal.jl b/src/NumFieldOrd/NfOrd/FracIdeal.jl index d6e63b6429..7e1a13c1d3 100644 --- a/src/NumFieldOrd/NfOrd/FracIdeal.jl +++ b/src/NumFieldOrd/NfOrd/FracIdeal.jl @@ -52,7 +52,7 @@ end ################################################################################ function iszero(x::NfAbsOrdFracIdl) - return iszero(numerator(x)) + return iszero(numerator(x, copy = false)) end ################################################################################# @@ -202,8 +202,6 @@ end elem_type(::Type{NfAbsOrdFracIdlSet{S, T}}) where {S, T} = NfAbsOrdFracIdl{S, T} -elem_type(::NfAbsOrdFracIdlSet{S, T}) where {S, T} = NfAbsOrdFracIdl{S, T} - parent_type(::Type{NfAbsOrdFracIdl{S, T}}) where {S, T} = NfAbsOrdFracIdlSet{S, T} ==(a::NfAbsOrdFracIdlSet, b::NfAbsOrdFracIdlSet) = order(a) === order(b) @@ -234,12 +232,14 @@ order(a::NfAbsOrdFracIdl) = a.order Returns the inverse of the basis matrix of $I$. """ -function basis_mat_inv(a::NfAbsOrdFracIdl) - if isdefined(a, :basis_mat_inv) - return deepcopy(a.basis_mat_inv) - else +function basis_mat_inv(a::NfAbsOrdFracIdl; copy::Bool = true) + if !isdefined(a, :basis_mat_inv) a.basis_mat_inv = inv(basis_matrix(a)) + end + if copy return deepcopy(a.basis_mat_inv) + else + return a.basis_mat_inv end end @@ -627,7 +627,7 @@ function +(A::NfAbsOrdIdl{S, T}, B::NfAbsOrdFracIdl{S, T}) where {S <: NumField, return fractional_ideal(order(A), A) end n1 = A*denominator(B) - n = n1 + numerator(B) + n = n1 + numerator(B, copy = false) return n//denominator(B) end @@ -645,7 +645,7 @@ function +(A::NfAbsOrdFracIdl{S, T}, B::Hecke.NfAbsOrdFracIdl{S, T}) where {S <: d = lcm(denominator(A), denominator(B)) ma = div(d, denominator(A)) mb = div(d, denominator(B)) - return (numerator(A)*ma + numerator(B)*mb)//d + return (numerator(A, copy = false)*ma + numerator(B, copy = false)*mb)//d end function *(x::T, y::NfAbsOrd{S, T}) where {S <: NumField, T <: NumFieldElem} @@ -792,7 +792,7 @@ function in(x::nf_elem, y::NfOrdFracIdl) M = zero_matrix(FlintZZ, 1, degree(O)) t = FakeFmpqMat(M) elem_to_mat_row!(t.num, 1, t.den, x) - v = t*basis_mat_inv(O) + v = t*basis_mat_inv(O, copy = false) v = v*B return v.den == 1 diff --git a/src/NumFieldOrd/NfOrd/Ideal/Ideal.jl b/src/NumFieldOrd/NfOrd/Ideal/Ideal.jl index e8769e9c8f..dc307e4b26 100644 --- a/src/NumFieldOrd/NfOrd/Ideal/Ideal.jl +++ b/src/NumFieldOrd/NfOrd/Ideal/Ideal.jl @@ -99,8 +99,6 @@ end elem_type(::Type{NfOrdIdlSet}) = NfOrdIdl -elem_type(::NfOrdIdlSet) = NfOrdIdl - parent_type(::Type{NfOrdIdl}) = NfOrdIdlSet ################################################################################ @@ -268,23 +266,20 @@ checked whether $M$ defines an ideal (expensive). If `M_in_hnf` is set, then it that $M$ is already in lower left HNF. """ function ideal(O::NfAbsOrd, M::ZZMatrix; check::Bool = false, M_in_hnf::Bool = false) - !M_in_hnf ? x = _hnf(M, :lowerleft) : nothing #sub-optimal, but == relies on the basis being thus - #_trace_call(;print = true) - I = NfAbsOrdIdl(O, M) + x = !M_in_hnf ? _hnf(M, :lowerleft) : M #sub-optimal, but == relies on the basis being thus + I = NfAbsOrdIdl(O, x) # The compiler stopped liking this recursion?? # if check # J = ideal(O, basis(I)) # @assert J == I # end - return I end function _ideal(O::NfAbsOrd, M::ZZMatrix, M_in_hnf::Bool = false) - !M_in_hnf ? x = _hnf(M, :lowerleft) : nothing #sub-optimal, but == relies on the basis being thus + x = !M_in_hnf ? _hnf(M, :lowerleft) : M #sub-optimal, but == relies on the basis being thus #_trace_call(;print = true) - I = NfAbsOrdIdl(O, M) - + I = NfAbsOrdIdl(O, x) return I end diff --git a/src/NumFieldOrd/NfOrd/NfOrd.jl b/src/NumFieldOrd/NfOrd/NfOrd.jl index dfe4a51574..ce0c352bd8 100644 --- a/src/NumFieldOrd/NfOrd/NfOrd.jl +++ b/src/NumFieldOrd/NfOrd/NfOrd.jl @@ -37,7 +37,7 @@ export ==, +, basis, basis_matrix, basis_mat_inv, contains_equation_order, is_equation_order, is_index_divisor, lll, lll_basis, nf, minkowski_matrix, norm_change_const, Order, parent, different, signature, trace_matrix, codifferent, ramified_primes, - reduced_discriminant + reduced_discriminant, ideal_type ################################################################################ # @@ -47,8 +47,6 @@ export ==, +, basis, basis_matrix, basis_mat_inv, contains_equation_order, Nemo.parent_type(::Type{NfAbsOrdElem{S, T}}) where {S, T} = NfAbsOrd{S, T} -Nemo.elem_type(::NfAbsOrd{S, T}) where {S, T} = NfAbsOrdElem{S, T} - Nemo.elem_type(::Type{NfAbsOrd{S, T}}) where {S, T} = NfAbsOrdElem{S, T} ideal_type(::NfAbsOrd{S, T}) where {S, T} = NfAbsOrdIdl{S, T} diff --git a/src/NumFieldOrd/NfOrd/RayClassGrp.jl b/src/NumFieldOrd/NfOrd/RayClassGrp.jl index f7c724717a..8da47a8085 100644 --- a/src/NumFieldOrd/NfOrd/RayClassGrp.jl +++ b/src/NumFieldOrd/NfOrd/RayClassGrp.jl @@ -197,6 +197,7 @@ function class_as_ray_class(C::GrpAbFinGen, mC::MapClassGrp, exp_class::Function local expo_map let mQ = mQ, exp_class = exp_class function expo_map(el::GrpAbFinGenElem) + @assert parent(el) === codomain(mQ) return exp_class(mQ\el) end end @@ -237,8 +238,9 @@ function empty_ray_class(m::NfOrdIdl) X = abelian_group(Int[]) local exp - let O = O + let O = O, X = X function exp(a::GrpAbFinGenElem) + @assert parent(a) === X return FacElem(Dict(ideal(O,1) => ZZRingElem(1))) end end @@ -478,8 +480,9 @@ function n_part_class_group(mC::Hecke.MapClassGrp, n::Integer) if is_coprime(exponent(C), n) G = abelian_group(ZZRingElem[]) local exp1 - let O = O + let O = O, G = G function exp1(a::GrpAbFinGenElem) + @assert parent(a) === G return ideal(O, one(O)) end end @@ -507,6 +510,7 @@ function n_part_class_group(mC::Hecke.MapClassGrp, n::Integer) local exp2 let O = O, G = G function exp2(a::GrpAbFinGenElem) + @assert parent(a) === G new_coeff = zero_matrix(FlintZZ, 1, ngens(C)) for i = 1:ngens(G) new_coeff[1, i+ind-1] = a[i]*diff @@ -909,6 +913,7 @@ function ray_class_group(m::NfOrdIdl, inf_plc::Vector{<:InfPlc} = Vector{InfPlc{ local expo let C = C, O = O, groups_and_maps = groups_and_maps, exp_class = exp_class, eH = eH, H = H, K = K, Dgens = Dgens, X = X, p = p function expo(a::GrpAbFinGenElem) + @assert parent(a) === X b = GrpAbFinGenElem(C, sub(a.coeff, 1:1, 1:ngens(C))) res = exp_class(b) for i = 1:nG @@ -978,6 +983,7 @@ function ray_class_groupQQ(O::NfOrd, modulus::Int, inf_plc::Bool, n_quo::Int) end function expon1(a::GrpAbFinGenElem) + @assert parent(a) === domain(mU) x=mU(a) return FacElem(Dict{NfOrdIdl, ZZRingElem}(ideal(O,lift(x)) => 1)) end @@ -997,6 +1003,7 @@ function ray_class_groupQQ(O::NfOrd, modulus::Int, inf_plc::Bool, n_quo::Int) end function expon2(a::GrpAbFinGenElem) + @assert parent(a) === domain(mU) x=mU(a) return FacElem(Dict{NfOrdIdl, ZZRingElem}(ideal(O,lift(x)) => 1)) end @@ -1016,6 +1023,7 @@ function ray_class_groupQQ(O::NfOrd, modulus::Int, inf_plc::Bool, n_quo::Int) end function expon(a::GrpAbFinGenElem) + @assert parent(a) === codomain(mQ) x=mU(mQ\a) return FacElem(Dict{NfOrdIdl, ZZRingElem}(ideal(O,x) => 1)) end diff --git a/src/NumFieldOrd/NfOrd/ResidueRing.jl b/src/NumFieldOrd/NfOrd/ResidueRing.jl index de8d280c14..e7a4f5fb3f 100644 --- a/src/NumFieldOrd/NfOrd/ResidueRing.jl +++ b/src/NumFieldOrd/NfOrd/ResidueRing.jl @@ -55,11 +55,6 @@ function elem_type(::Type{AbsOrdQuoRing{S, T}}) where {S, T} return AbsOrdQuoRingElem{S, T, U} end -function elem_type(::AbsOrdQuoRing{S, T}) where {S, T} - U = elem_type(S) - return AbsOrdQuoRingElem{S, T, U} -end - base_ring(Q::AbsOrdQuoRing) = Q.base_ring ideal(Q::AbsOrdQuoRing) = Q.ideal diff --git a/src/NumFieldOrd/NfRelOrd/NfRelOrd.jl b/src/NumFieldOrd/NfRelOrd/NfRelOrd.jl index 6480895f25..513455b5ce 100644 --- a/src/NumFieldOrd/NfRelOrd/NfRelOrd.jl +++ b/src/NumFieldOrd/NfRelOrd/NfRelOrd.jl @@ -22,8 +22,6 @@ parent(O::NfRelOrd) = O.parent base_ring(O::NfRelOrd) = order(pseudo_basis(O, copy = false)[1][2]) -elem_type(::NfRelOrd{T, S, U}) where {T, S, U} = NfRelOrdElem{T, U} - elem_type(::Type{NfRelOrd{T, S, U}}) where {T, S, U} = NfRelOrdElem{T, U} ideal_type(::NfRelOrd{T, S, U}) where {T, S, U} = NfRelOrdIdl{T, S, U} diff --git a/src/NumFieldOrd/NfRelOrd/OrdElem.jl b/src/NumFieldOrd/NfRelOrd/OrdElem.jl index 55e31fffc0..b7849eb12a 100644 --- a/src/NumFieldOrd/NfRelOrd/OrdElem.jl +++ b/src/NumFieldOrd/NfRelOrd/OrdElem.jl @@ -1,4 +1,3 @@ -parent_type(::NfRelOrdElem{T, U}) where {T, U} = NfRelOrd{T, fractional_ideal_type(order_type(parent_type(T))), U} parent_type(::Type{NfRelOrdElem{T, U}}) where {T, U} = NfRelOrd{T, fractional_ideal_type(order_type(parent_type(T))), U} ################################################################################ diff --git a/src/NumFieldOrd/NfRelOrd/ResidueRing.jl b/src/NumFieldOrd/NfRelOrd/ResidueRing.jl index 404434b55f..7d9a4629b0 100644 --- a/src/NumFieldOrd/NfRelOrd/ResidueRing.jl +++ b/src/NumFieldOrd/NfRelOrd/ResidueRing.jl @@ -9,11 +9,6 @@ function elem_type(::Type{RelOrdQuoRing{T1, T2, T3}}) where { T1, T2, T3 } return RelOrdQuoRingElem{T1, T2, T3, S} end -function elem_type(::RelOrdQuoRing{T1, T2, T3}) where { T1, T2, T3 } - S = elem_type(T1) - return RelOrdQuoRingElem{T1, T2, T3, S} -end - base_ring(Q::RelOrdQuoRing) = Q.base_ring ideal(Q::RelOrdQuoRing) = Q.ideal diff --git a/src/QuadForm/Herm/Lattices.jl b/src/QuadForm/Herm/Lattices.jl index 1d34b1ba52..da7ce1a94c 100644 --- a/src/QuadForm/Herm/Lattices.jl +++ b/src/QuadForm/Herm/Lattices.jl @@ -680,12 +680,13 @@ function _maximal_integral_lattice(L::HermLat, p, minimal = true) end function is_maximal_integral(L::HermLat, p) + @req order(p) == fixed_ring(L) "The ideal does not belong to the fixed ring of the lattice" valuation(norm(L), p) < 0 && return false, L return _maximal_integral_lattice(L, p, true) end function is_maximal_integral(L::HermLat) - !is_integral(norm(L)) && error("The lattice is not integral") + !is_integral(norm(L)) && return false, L S = base_ring(L) f = factor(discriminant(S)) ff = factor(norm(volume(L))) @@ -703,6 +704,8 @@ function is_maximal_integral(L::HermLat) end function is_maximal(L::HermLat, p) + @req order(p) == fixed_ring(L) "The ideal does not belong to the fixed ring of the lattice" + @req valuation(norm(L), p) >= 0 "The norm of the lattice is not locally integral" #iszero(L) && error("The lattice must be non-zero") v = valuation(norm(L), p) x = elem_in_nf(p_uniformizer(p))^(-v) @@ -715,7 +718,7 @@ function is_maximal(L::HermLat, p) end function maximal_integral_lattice(L::HermLat) - !is_integral(norm(L)) && error("The lattice is not integral") + @req is_integral(norm(L)) "The norm of the lattice is not integral" S = base_ring(L) f = factor(discriminant(S)) ff = factor(norm(volume(L))) @@ -730,7 +733,8 @@ function maximal_integral_lattice(L::HermLat) end function maximal_integral_lattice(L::HermLat, p) - valuation(norm(L), p) < 0 && error("Lattice is not locally integral") + @req order(p) == fixed_ring(L) "The ideal does not belong to the fixed ring of the lattice" + @req valuation(norm(L), p) >= 0 "The norm of the lattice is not locally integral" _, L = _maximal_integral_lattice(L, p, false) return L end diff --git a/src/QuadForm/Lattices.jl b/src/QuadForm/Lattices.jl index e8c00bf291..703e86d8ec 100644 --- a/src/QuadForm/Lattices.jl +++ b/src/QuadForm/Lattices.jl @@ -1989,17 +1989,25 @@ end is_maximal_integral(L::AbstractLat, p::NfOrdIdl) -> Bool, AbstractLat Given a lattice `L` and a prime ideal `p` of the fixed ring $\mathcal O_K$ of -`L`, return whether the completion of `L` at `p` is maximal integral. If it is -not the case, the second returned value is a lattice in the ambient space of `L` -whose completion at `p` is a minimal overlattice of $L_p$. +`L`, return whether the completion of `L` at `p` has integral norm and that `L` has no +proper overlattice satisfying this property. + +If the norm of `L` is not integral at `p`, the second output is `L` by default. +Otherwise, either `L` is maximal at `p` and the second output is `L`, or the +second output is a lattice `M` in the ambient space of `L` whose completion +at `p` is a minimal overlattice of $L_p$ with integral norm. """ is_maximal_integral(::AbstractLat, p) @doc raw""" is_maximal_integral(L::AbstractLat) -> Bool, AbstractLat -Given a lattice `L`, return whether `L` is maximal integral. If it is not, -the second returned value is a minimal overlattice of `L` with integral norm. +Given a lattice `L`, return whether `L` has integral norm and has no proper +overlattice satisfying this property. + +If the norm of `L` is not integral, the second output is `L` by default. +Otherwise, either `L` is maximal and the second output is `L`, or the second +output is a minimal overlattice `M` of `L` with integral norm. """ is_maximal_integral(::AbstractLat) @@ -2007,10 +2015,12 @@ is_maximal_integral(::AbstractLat) is_maximal(L::AbstractLat, p::NfOrdIdl) -> Bool, AbstractLat Given a lattice `L` and a prime ideal `p` in the fixed ring $\mathcal O_K$ of -`L`, check whether the norm of $L_p$ is integral and return whether `L` is maximal -at `p`. If it is locally integral but not locally maximal, the second returned value -is a lattice in the same ambient space of `L` whose completion at `p` has integral norm -and is a proper overlattice of $L_p$. +`L` such that the norm of $L_p$ is integral, return whether `L` is maximal +integral at `p`. + +If `L` is locally maximal at `p`, the second output is `L`, otherwise it is +a lattice `M` in the same ambient space of `L` whose completion at `p` has +integral norm and is a proper overlattice of $L_p$. """ is_maximal(::AbstractLat, p) @@ -2018,16 +2028,17 @@ is_maximal(::AbstractLat, p) maximal_integral_lattice(L::AbstractLat, p::NfOrdIdl) -> AbstractLat Given a lattice `L` and a prime ideal `p` of the fixed ring $\mathcal O_K$ of -`L`, return a lattice `M` in the ambient space of `L` which is maximal integral -at `p` and which agrees with `L` locally at all the places different from `p`. +`L` such that the norm of $L_p$ is integral, return a lattice `M` in the +ambient space of `L` which is maximal integral at `p` and which agrees +with `L` locally at all the places different from `p`. """ maximal_integral_lattice(::AbstractLat, p) @doc raw""" maximal_integral_lattice(L::AbstractLat) -> AbstractLat -Given a lattice `L`, return a lattice `M` in the ambient space of `L` which -is maximal integral and which contains `L`. +Given a lattice `L` with integral norm, return a maximal integral overlattice +`M` of `L`. """ maximal_integral_lattice(::AbstractLat) diff --git a/src/QuadForm/Quad/Lattices.jl b/src/QuadForm/Quad/Lattices.jl index 0ef68f1ec2..950a2a42c4 100644 --- a/src/QuadForm/Quad/Lattices.jl +++ b/src/QuadForm/Quad/Lattices.jl @@ -440,7 +440,7 @@ function guess_max_det(L::QuadLat, p) end function is_maximal_integral(L::QuadLat, p) - @req order(p) == base_ring(L) "Rings do not match" + @req order(p) == base_ring(L) "The ideal does not belong to the base ring of the lattice" #if iszero(L) # return true, L #end @@ -532,8 +532,8 @@ function is_maximal_integral(L::QuadLat) end function maximal_integral_lattice(L::QuadLat, p) - @req base_ring(L) == order(p) "Second argument must be an ideal of the base ring of L" - @req valuation(norm(L), p) >= 0 "The normal of the lattice must be locally integral" + @req base_ring(L) == order(p) "The ideal does not belong to the base ring of the lattice" + @req valuation(norm(L), p) >= 0 "The norm of the lattice is not locally integral" ok, LL = is_maximal_integral(L, p) while !ok @@ -544,7 +544,8 @@ function maximal_integral_lattice(L::QuadLat, p) end function is_maximal(L::QuadLat, p) - @req order(p) == base_ring(L) "Asdsads" + @req order(p) == base_ring(L) "The ideal does not belong to the base ring of the lattice" + @req valuation(norm(L), p) >= 0 "The norm of the lattice is not locally integral" #if iszero(L) # return true, L #end @@ -576,7 +577,7 @@ function maximal_integral_lattice(V::QuadSpace) end function maximal_integral_lattice(L::QuadLat) - @req is_integral(norm(L)) "Lattice must be integral" + @req is_integral(norm(L)) "The norm of the lattice is not integral" for p in bad_primes(L; even = true) L = maximal_integral_lattice(L, p) end diff --git a/src/QuadForm/Quad/ZLattices.jl b/src/QuadForm/Quad/ZLattices.jl index 2fb7bbd852..c5126f8556 100644 --- a/src/QuadForm/Quad/ZLattices.jl +++ b/src/QuadForm/Quad/ZLattices.jl @@ -1142,14 +1142,13 @@ function _maximal_integral_lattice(L::ZZLat) end @doc raw""" - maximal_even_lattice(L::ZZLat, p) -> ZZLat + maximal_even_lattice(L::ZZLat, p::IntegerUnion) -> ZZLat -Given an even lattice `L` and a prime number `p` return an overlattice of `M` -which is maximal at `p` and agrees locally with `L` at all other places. - -Recall that $L$ is called even if $\Phi(x,x) \in 2 \mathbb Z$ for all $x in L$. +Given an integer lattice `L` with integral scale and a prime number `p` such that +$L_p$ is even, return an overlattice `M` of `L` which is maximal even at `p` and +which agrees locally with `L` at all other places. """ -function maximal_even_lattice(L::ZZLat, p) +function maximal_even_lattice(L::ZZLat, p::IntegerUnion) while true ok, L = is_maximal_even(L, p) if ok @@ -1161,10 +1160,7 @@ end @doc raw""" maximal_even_lattice(L::ZZLat) -> ZZLat -Return a maximal even overlattice `M` of the even lattice `L`. - -Recall that $L$ is called even if $\Phi(x,x) \in 2 \mathbb Z$ for all $x in L$. -Note that the genus of `M` is uniquely determined by the genus of `L`. +Given an even integer lattice `L`, return a maximal even overlattice `M` of `L`. """ function maximal_even_lattice(L::ZZLat) @req iseven(L) "The lattice must be even" @@ -1175,7 +1171,7 @@ function maximal_even_lattice(L::ZZLat) end function maximal_integral_lattice(L::ZZLat) - @req denominator(norm(L)) == 1 "The quadratic form is not integral" + @req denominator(norm(L)) == 1 "The norm of the lattice is not integral" L2 = rescale(L, 2) LL2 = maximal_even_lattice(L2) return rescale(LL2, QQ(1//2)) @@ -1183,21 +1179,23 @@ end @doc raw""" - is_maximal_even(L::ZZLat, p) -> Bool, ZZLat + is_maximal_even(L::ZZLat, p::IntegerUnion) -> Bool, ZZLat -Return if the (`p`-locally) even lattice `L` is maximal at `p` and an even overlattice `M` -of `L` with $[M:L]=p$ if `L` is not maximal and $1$ else. +Given an integer lattice `L` with integral scale and a prime number `p`, +return whether $L_p$ is even and has no proper overlattice satisfying this +property. -Recall that $L$ is called even if $\Phi(x,x) \in 2 \mathbb{Z}$ for all $x in L$. +If $L_p$ is not even, the second output is `L` by default. Otherwise, either +`L` is maximal at `p` and the second output is `L`, or the second output is +an overlattice `M` of `L` such that $M_p$ is even and $[M:L] = p$. """ - -function is_maximal_even(L::ZZLat, p) +function is_maximal_even(L::ZZLat, p::IntegerUnion) @req denominator(scale(L)) == 1 "The bilinear form is not integral" - @req p != 2 || mod(ZZ(norm(L)),2) == 0 "The bilinear form is not even" + p != 2 || mod(ZZ(norm(L)), 2) == 0 || return false, L # o-maximal lattices are classified # see Kirschmer Lemma 3.5.3 - if valuation(det(L), p)<= 1 + if valuation(det(L), p) <= 1 return true, L end G = change_base_ring(ZZ, gram_matrix(L)) diff --git a/test/GrpAb/Lattice.jl b/test/GrpAb/Lattice.jl index 43ec173f35..c8d1c8d901 100644 --- a/test/GrpAb/Lattice.jl +++ b/test/GrpAb/Lattice.jl @@ -138,5 +138,9 @@ Q2, mQ2 = quo(G, [G[1]], true, L) b, GG, MHHH, MHH = @inferred Hecke.can_map_into_overstructure(L, Q, Q2) @test !b + + b, GG, _, _ = @inferred Hecke.can_map_into_overstructure(L, Q, Q) + @test b + @test GG === Q end end diff --git a/test/NfOrd/Ideal.jl b/test/NfOrd/Ideal.jl index b4c85cc634..1ede5829e2 100644 --- a/test/NfOrd/Ideal.jl +++ b/test/NfOrd/Ideal.jl @@ -276,5 +276,11 @@ Hecke.assure_2_normal(I) @test isdefined(I, :gen_two) + # Some issue with ideal(O, M) + K, a = quadratic_field(-1) + O = maximal_order(K) + @test basis_matrix(ideal(O, representation_matrix(O(a)))) == identity_matrix(ZZ, 2) + include("Ideal/Prime.jl") + end diff --git a/test/NfOrd/LinearAlgebra.jl b/test/NfOrd/LinearAlgebra.jl index 5d1b3b7ea7..4a3fd7f41b 100644 --- a/test/NfOrd/LinearAlgebra.jl +++ b/test/NfOrd/LinearAlgebra.jl @@ -179,7 +179,7 @@ @test Hecke._spans_subset_of_pseudohnf(pm, pm, :lowerleft) # issue 1112 - K, a = CyclotomicRealSubfield(8, "a"); + K, a = cyclotomic_real_subfield(8, "a"); Kt, t = K["t"]; E, b = number_field(t^2 - a * t + 1, "b"); V = hermitian_space(E, gram_matrix(root_lattice(:E, 8))); diff --git a/test/NumField/Hilbert.jl b/test/NumField/Hilbert.jl index 84b10c5183..bb5607256f 100644 --- a/test/NumField/Hilbert.jl +++ b/test/NumField/Hilbert.jl @@ -36,7 +36,7 @@ @test quadratic_defect(QQ(1//9),ZZ(3)) == PosInf() # Test where Magma div(x, y) differs from julia div(x, y) (internally) - K, a = CyclotomicRealSubfield(8, "a") # x^2 - 2 + K, a = cyclotomic_real_subfield(8, "a") # x^2 - 2 z = 9278908160780559301//4*a+6561375391013480455//2 w = K(-2) p = prime_decomposition(maximal_order(K), 2)[1][1] diff --git a/test/NumField/NfAbs/Cyclotomic.jl b/test/NumField/NfAbs/Cyclotomic.jl index 93c49fb9f7..5fbd897dcd 100644 --- a/test/NumField/NfAbs/Cyclotomic.jl +++ b/test/NumField/NfAbs/Cyclotomic.jl @@ -1,11 +1,11 @@ @testset "Cyclotomic" begin for q in [7, 7^2, 2^2, 2^3, 2^4] - K, a = CyclotomicRealSubfield(q) + K, a = cyclotomic_real_subfield(q) v = cyclotomic_units_totally_real(K) @test length(v) == degree(K) # = unit rank + 1 end - K, a = CyclotomicRealSubfield(7) + K, a = cyclotomic_real_subfield(7) v = cyclotomic_units_totally_real(K) # Class number of Q(zeta_7)^+ is one, so the cyclotomic units are the units @test overlaps(regulator(maximal_order(K)), regulator(v[2:end])) diff --git a/test/NumField/NfAbs/NfAbs.jl b/test/NumField/NfAbs/NfAbs.jl index b1cd78c557..7bdc3b0a0c 100644 --- a/test/NumField/NfAbs/NfAbs.jl +++ b/test/NumField/NfAbs/NfAbs.jl @@ -60,6 +60,15 @@ end @test simplify(number_field(h)[1], canonical = true)[1].pol == g end +@testset "simplify-Fabian" begin + Qx, x = polynomial_ring(FlintQQ, "x") + f = x^8 + 4*x^7 - 56*x^6 - 168*x^5 + 758*x^4 + 2412*x^3 - 1656*x^2 - 9508*x - 6828 + g = x^8 - 4*x^7 - 30*x^6 + 44*x^5 + 298*x^4 + 108*x^3 - 614*x^2 - 680*x - 199 + @test simplify(number_field(f)[1], canonical = true)[1].pol == g + @test simplify(number_field(g)[1], canonical = true)[1].pol == g +end + + @testset "factor-van-Hoeij" begin Qx, x = polynomial_ring(FlintQQ, "x") f = x^12 + 4*x^10 + 11*x^8 + 4*x^6 - 41*x^4 - 8*x^2 + 37 diff --git a/test/QuadForm/Herm/Genus.jl b/test/QuadForm/Herm/Genus.jl index 31b5d2761d..1a99d8b99b 100644 --- a/test/QuadForm/Herm/Genus.jl +++ b/test/QuadForm/Herm/Genus.jl @@ -421,7 +421,7 @@ # ############################################################################# - K, a = CyclotomicRealSubfield(8, "a") + K, a = cyclotomic_real_subfield(8, "a") Kt, t = polynomial_ring(K, "t") L, b = number_field(t^2 - a * t + 1) @@ -461,7 +461,7 @@ @test (@inferred representative(G[i])) in G[i] end - K, a = CyclotomicRealSubfield(8, "a") + K, a = cyclotomic_real_subfield(8, "a") Kt, t = K["t"] L, b = number_field(t^2 - a * t + 1) p = prime_decomposition(maximal_order(K), 2)[1][1] @@ -486,7 +486,7 @@ @test all(x -> x in Gs, myG) @test all(x -> x in myG, Gs) - K, a = CyclotomicRealSubfield(8, "a") + K, a = cyclotomic_real_subfield(8, "a") Kt, t = K["t"] L, b = number_field(t^2 - a * t + 1) rlp = real_places(K) diff --git a/test/QuadForm/Lattices.jl b/test/QuadForm/Lattices.jl index 3e0145eb0c..90216feb5c 100644 --- a/test/QuadForm/Lattices.jl +++ b/test/QuadForm/Lattices.jl @@ -110,7 +110,7 @@ M = @inferred Hecke.maximal_integral_lattice(V) @test Hecke.genus(M, p) == genus(HermLat, L, p, [(-2, 2, 1, 0), (0, 1, 1, 0)]) - K, a = CyclotomicRealSubfield(8, "a") + K, a = cyclotomic_real_subfield(8, "a") Kt, t = K["t"] E, b = number_field(t^2 - a * t + 1, "b") p = prime_decomposition(maximal_order(K), 2)[1][1] @@ -148,7 +148,7 @@ L = Hecke._to_number_field_lattice(E8) @test L == dual(L) - K, a = CyclotomicRealSubfield(8, "a") + K, a = cyclotomic_real_subfield(8, "a") Kt, t = K["t"] E, b = number_field(t^2 - a * t + 1, "b") V = hermitian_space(E, gram_matrix(root_lattice(:E, 8)))