@@ -747,9 +747,8 @@ checked by computing minimal polynomials. If `isbasis` is set, then elements are
747
747
assumed to form a $\m athbf{Z}$-basis. If `cached` is set, then the constructed
748
748
order is cached for future use.
749
749
"""
750
- function Order (:: S , a:: Vector{T} ; check:: Bool = true , isbasis:: Bool = false ,
750
+ function Order (K :: S , a:: Vector{T} ; check:: Bool = true , isbasis:: Bool = false ,
751
751
cached:: Bool = false ) where {S <: NumField{QQFieldElem} , T <: NumFieldElem{QQFieldElem} }
752
- K = parent (a[1 ])
753
752
@assert all (x-> K == parent (x), a)
754
753
if isbasis
755
754
if check
769
768
770
769
function Order (K, a:: Vector ; check:: Bool = true , isbasis:: Bool = false ,
771
770
cached:: Bool = true )
772
- local b
771
+ local b:: Vector{elem_type(K)}
773
772
try
774
773
b = map (K, a)
774
+ b = convert (Vector{elem_type (K)}, b)
775
775
catch
776
776
error (" Cannot coerce elements from array into the number field" )
777
777
end
@@ -886,20 +886,13 @@ function any_order(K::NfAbsNS)
886
886
g = gens (K)
887
887
for i in 1 : ngens (K)
888
888
f = denominator (K. pol[i]) * K. pol[i]
889
- @show f
890
- @show isone (coeff (f, 1 ))
891
- @show coeff (f, 1 )
892
- @show typeof (f)
893
- @show g[i]
894
889
if isone (coeff (f, 1 ))
895
890
normalized_gens[i] = g[i]
896
891
else
897
892
normalized_gens[i] = coeff (f, 1 ) * g[i]
898
893
end
899
894
end
900
895
901
- @show normalized_gens
902
-
903
896
b = Vector {NfAbsNSElem} (undef, degree (K))
904
897
ind = 1
905
898
it = cartesian_product_iterator ([1 : degrees (K)[i] for i in 1 : ngens (K)], inplace = true )
@@ -999,114 +992,116 @@ The equation order of the number field.
999
992
"""
1000
993
equation_order (M:: NfAbsOrd ) = equation_order (nf (M))
1001
994
995
+ # Construct the smallest order of K containing the elements in elt.
996
+ # If check == true, it is checked whether the given elements in elt are integral
997
+ # and whether the constructed order is actually an order.
998
+ # Via extends one may supply an order which will then be extended by the elements
999
+ # in elt.
1002
1000
function _order (K:: S , elt:: Vector{T} ; cached:: Bool = true , check:: Bool = true , extends = nothing ) where {S <: NumField{QQFieldElem} , T}
1003
- #=
1004
- check == true: the elements are known to be integral
1005
- extends !== nothing: then extends is an order, which we are extending
1006
- =#
1001
+ elt = unique (elt)
1007
1002
n = degree (K)
1008
1003
1009
- extending = false
1010
-
1011
- local B:: FakeFmpqMat = FakeFmpqMat ()
1012
-
1013
1004
if extends != = nothing
1014
1005
extended_order:: order_type (K) = extends
1015
1006
@assert K === nf (extended_order)
1016
- extend = true
1017
1007
1018
1008
if is_maximal_known_and_maximal (extended_order) || length (elt) == 0
1019
1009
return extended_order
1020
1010
end
1021
- # in this case we can start with phase 2 directly as we have mult. closed
1022
- # module to start with, so set everything up for it...
1023
1011
B = basis_matrix (extended_order)
1024
1012
bas = basis (extended_order, K)
1025
- phase = 2
1013
+ full_rank = true
1014
+ m = _det_triangular (numerator (B, copy = false ))// denominator (B, copy = false )
1026
1015
else
1016
+ if isempty (elt)
1017
+ elt = elem_type (K)[one (K)]
1018
+ end
1027
1019
bas = elem_type (K)[one (K)]
1028
- phase = 1
1020
+ B = basis_matrix (bas, FakeFmpqMat) # trivially in lower-left HNF
1021
+ full_rank = false
1029
1022
end
1030
1023
1024
+ dummy_vector = elem_type (K)[K ()]
1025
+ function in_span_of_B (x:: T )
1026
+ if mod (denominator (B, copy = false ), denominator (x)) == 0
1027
+ dummy_vector[1 ] = x
1028
+ C = basis_matrix (dummy_vector, FakeFmpqMat)
1029
+ return is_zero_mod_hnf! (div (denominator (B, copy = false ), denominator (x))* numerator (C, copy = false ), numerator (B, copy = false ))
1030
+ end
1031
+ return false
1032
+ end
1031
1033
1032
1034
for e in elt
1033
- # @show findall(isequal(e), elt)
1034
- if phase == 2
1035
- if denominator (B) % denominator (e) == 0
1036
- C = basis_matrix ([e], FakeFmpqMat)
1037
- fl, _ = can_solve_with_solution (B. num, div (B. den, denominator (e))* C. num, side = :left )
1038
- # fl && println("elt known:", :e)
1039
- fl && continue
1040
- end
1041
- end
1035
+ # Check if e is already in the multiplicatively closed module generated by
1036
+ # the previous elements of elt
1037
+ in_span_of_B (e) && continue
1038
+
1039
+ # Multiply powers of e to the existing basis elements
1042
1040
if check
1043
1041
f = minpoly (e)
1044
- isone (denominator (f)) || error (" data does not define an order, $e is non-integral" )
1045
- df = degree (f)- 1
1042
+ isone (denominator (f)) || error (" The elements do not define an order: $e is non-integral" )
1043
+ df = degree (f) - 1
1046
1044
else
1047
- df = n- 1
1045
+ df = n - 1
1048
1046
end
1049
- f = one (K)
1050
- for i= 1 : df
1051
- mul! (f, f, e)
1052
- if phase == 2 # don't understand this part
1053
- if denominator (B) % denominator (f) == 0
1054
- C = basis_matrix (elem_type (K)[f], FakeFmpqMat)
1055
- fl = is_zero_mod_hnf! (div (B. den, denominator (f))* C. num, B. num)
1056
- # fl && println("inner abort: ", :e, " ^ ", i)
1057
- fl && break
1058
- end
1059
- end
1060
- if phase == 1
1061
- # [1] -> [1, e] -> [1, e, e, e^2] -> ... otherwise
1062
- push! (bas, deepcopy (f))
1063
- else
1064
- b = elem_type (K)[e* x for x in bas]
1065
- append! (bas, b)
1047
+
1048
+ start = 1
1049
+ # We only multiply the elements of index start:length(bas) by e .
1050
+ # Example: bas = [a_1, ..., a_k] with a_1 = 1. Then
1051
+ # new_bas := [e, e*a_2, ..., e*a_k] and we append this to bas and set
1052
+ # start := k + 1. In the next iteration, we then have
1053
+ # new_bas := [e^2, e^2*a_2, ..., e^2*a_k] (assuming that there was no
1054
+ # reduction of the basis in between).
1055
+ for i in 1 : df
1056
+ new_bas = elem_type (K)[]
1057
+ for j in start: length (bas)
1058
+ t = e* bas[j]
1059
+ in_span_of_B (t) && continue
1060
+ push! (new_bas, t)
1066
1061
end
1062
+ isempty (new_bas) && break
1063
+ start = length (bas) + 1
1064
+ append! (bas, new_bas)
1065
+
1067
1066
if length (bas) >= n
1067
+ # HNF reduce the basis we have so far, if B is already of full rank,
1068
+ # we can do this with the modular algorithm
1068
1069
B = basis_matrix (bas, FakeFmpqMat)
1069
- if extending
1070
- # We are extending extended_order, which has basis matrix M/d
1071
- # Thus we know that B.den/d * M \subseteq <B.num>
1072
- # So we can take B.den/d * largest_elementary_divisor(M) as the modulus
1073
- B = hnf_modular_eldiv (B, B. den, shape = :lowerleft )
1070
+ if full_rank
1071
+ # We have M \subseteq B, where M is a former incarnation of B.
1072
+ # So we have B.den * M.num/M.den \subseteq B.num \subseteq Z^n, so
1073
+ # M.d divides B.den and we can choose (B.den/M.den)*det(M.num) as
1074
+ # modulus for the HNF of B.num.
1075
+ mm = ZZ (m* denominator (B, copy = false ))
1076
+ hnf_modular_eldiv! (B, mm, shape = :lowerleft )
1077
+ B = sub (B, nrows (B) - n + 1 : nrows (B), 1 : n)
1078
+
1079
+ # Check if we have a better modulus
1080
+ new_m = _det_triangular (numerator (B, copy = false ))// denominator (B, copy = false )
1081
+ if new_m < m
1082
+ m = new_m
1083
+ end
1074
1084
else
1075
1085
hnf! (B)
1086
+ k = findfirst (k -> ! is_zero_row (B, k), nrows (B) - n + 1 : nrows (B))
1087
+ B = sub (B, nrows (B) - n + k: nrows (B), 1 : n)
1088
+ if nrows (B) == n
1089
+ full_rank = true
1090
+ m = _det_triangular (numerator (B, copy = false ))// denominator (B, copy = false )
1091
+ end
1076
1092
end
1077
- rk = nrows (B) - n + 1
1078
- while is_zero_row (B, rk)
1079
- rk += 1
1080
- end
1081
- B = sub (B, rk: nrows (B), 1 : n)
1082
- phase = 2
1083
- bas = elem_type (K)[ elem_from_mat_row (K, B. num, i, B. den) for i = 1 : nrows (B) ]
1093
+ bas = elem_type (K)[ elem_from_mat_row (K, numerator (B, copy = false ), i, denominator (B, copy = false )) for i = 1 : nrows (B) ]
1094
+ start = 1
1084
1095
if check
1085
1096
@assert isone (bas[1 ])
1086
1097
end
1087
1098
end
1088
1099
end
1089
1100
end
1090
-
1091
- if length (bas) > n # == n can only happen here after an hnf was computed
1092
- # above. Don't quite see how > n can happen here either
1093
- B = basis_matrix (bas, FakeFmpqMat)
1094
- hnf! (B)
1095
- rk = nrows (B) - n + 1
1096
- if is_zero_row (B. num, rk)
1097
- error (" data does not define an order: dimension to small" )
1098
- end
1099
- B = sub (B, rk: nrows (B), 1 : n)
1100
- bas = elem_type (K)[ elem_from_mat_row (K, B. num, i, B. den) for i = 1 : nrows (B) ]
1101
- end
1102
-
1103
- if ! isdefined (B, :num )
1104
- error (" data does not define an order: dimension to small" )
1101
+ if length (bas) < n
1102
+ error (" The elements do not define an order: rank too small" )
1105
1103
end
1106
-
1107
- # Make an explicit check
1108
- @hassert :NfOrd 1 defines_order (K, B)[1 ]
1109
- return Order (K, B, cached = cached, check = check)
1104
+ return Order (K, B, cached = cached, check = check):: order_type (K)
1110
1105
end
1111
1106
1112
1107
# ###############################################################################
0 commit comments