From 560cbc786fe3f0638836a4e52d8762b2ca568147 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 10 Aug 2022 22:48:43 +0800 Subject: [PATCH 01/42] 34212: clean version --- src/sage/rings/number_field/number_field.py | 67 +++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 58463d570d4..3b1bb23205b 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -153,6 +153,10 @@ from collections import Counter from builtins import zip +from sage.categories.homset import Hom +from sage.categories.sets_cat import Sets +from sage.modules.free_module import VectorSpace +from sage.modules.free_module_element import vector _NumberFields = NumberFields() @@ -9297,6 +9301,69 @@ def minkowski_embedding(self, B=None, prec=None): return sage.matrix.all.matrix(d) + def logarithmic_embedding(self, prec=53): + """ + Return the morphism of ``self`` under the logarithmic embedding + in the category Set. + + The logarithmic embedding is defined as a map from the number field ``self`` to `\RR^n`. + + It is defined under Definition 4.9.6 in [Cohen1993]_. + + INPUT: + + - ``prec`` -- desired floating point precision. + + OUTPUT: + + - a tuple of real numbers. + + EXAMPLES:: + + sage: CF. = CyclotomicField(97) + sage: f = CF.logarithmic_embedding() + sage: f(0) + (-1) + sage: f(7) + (1.94591014905531) + + :: + + sage: K. = NumberField(x^3 + 5) + sage: f = K.logarithmic_embedding() + sage: f(0) + (-1) + sage: f(7) + (1.94591014905531) + """ + def closure_map(x, prec=53): + """ + The function closure of the logarithmic embedding. + """ + K = self.base_ring() + K_embeddings = K.places(prec) + r1, r2 = K.signature() + r = r1 + r2 - 1 + + from sage.rings.all import RealField + Reals = RealField(prec) + + if x == 0: + return vector([-1 for _ in range(r + 1)]) + + x_logs = [] + for i in range(r1): + sigma = K_embeddings[i] + x_logs.append(Reals(abs(sigma(x))).log()) + for i in range(r1, r + 1): + tau = K_embeddings[i] + x_logs.append(2 * Reals(abs(tau(x))).log()) + + return vector(x_logs) + + log_map = closure_map(self(0), prec) + return Hom(self, VectorSpace(QQ, len(log_map)), Sets()) + def places(self, all_complex=False, prec=None): r""" Return the collection of all infinite places of self. From 2ad46295eef275961547bc0e68a8cae5abb25df5 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 11 Aug 2022 14:00:41 +0800 Subject: [PATCH 02/42] 34212: fix doc --- src/sage/rings/number_field/number_field.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 3b1bb23205b..c5a591de1ff 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -157,6 +157,7 @@ from sage.categories.sets_cat import Sets from sage.modules.free_module import VectorSpace from sage.modules.free_module_element import vector +from sage.rings.real_mpfr import RR _NumberFields = NumberFields() @@ -9302,7 +9303,7 @@ def minkowski_embedding(self, B=None, prec=None): return sage.matrix.all.matrix(d) def logarithmic_embedding(self, prec=53): - """ + r""" Return the morphism of ``self`` under the logarithmic embedding in the category Set. @@ -9362,7 +9363,8 @@ def closure_map(x, prec=53): return vector(x_logs) log_map = closure_map(self(0), prec) - return Hom(self, VectorSpace(QQ, len(log_map)), Sets()) + hom = Hom(self, VectorSpace(RR, len(log_map)), Sets()) + return hom(log_map) def places(self, all_complex=False, prec=None): r""" From 6bff6a6e28b8ee186fc6bc800acb692a6c7eb967 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 11 Aug 2022 16:43:53 +0800 Subject: [PATCH 03/42] 34212: fix doc and code --- src/sage/rings/number_field/number_field.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index c5a591de1ff..0d2f56a1dc7 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -9317,31 +9317,31 @@ def logarithmic_embedding(self, prec=53): OUTPUT: - - a tuple of real numbers. + - the morphism of ``self`` under the logarithmic embedding in the category Set. EXAMPLES:: - sage: CF. = CyclotomicField(97) + sage: CF. = CyclotomicField(5) sage: f = CF.logarithmic_embedding() sage: f(0) - (-1) + (-1, -1) sage: f(7) - (1.94591014905531) + (3.89182029811063, 3.89182029811063) :: sage: K. = NumberField(x^3 + 5) sage: f = K.logarithmic_embedding() sage: f(0) - (-1) + (-1, -1) sage: f(7) - (1.94591014905531) + (1.94591014905531, 3.89182029811063) """ def closure_map(x, prec=53): """ The function closure of the logarithmic embedding. """ - K = self.base_ring() + K = self K_embeddings = K.places(prec) r1, r2 = K.signature() r = r1 + r2 - 1 @@ -9362,9 +9362,8 @@ def closure_map(x, prec=53): return vector(x_logs) - log_map = closure_map(self(0), prec) - hom = Hom(self, VectorSpace(RR, len(log_map)), Sets()) - return hom(log_map) + hom = Hom(self, VectorSpace(RR, len(closure_map(self(0), prec))), Sets()) + return hom(closure_map) def places(self, all_complex=False, prec=None): r""" From 15cb0846b3348e3fc7baf3175deea6fc9e625691 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 1 Sep 2022 13:35:39 +0800 Subject: [PATCH 04/42] 34212: Correct doc and add an example --- src/sage/rings/number_field/number_field.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 0d2f56a1dc7..edfa01cd232 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -9309,7 +9309,7 @@ def logarithmic_embedding(self, prec=53): The logarithmic embedding is defined as a map from the number field ``self`` to `\RR^n`. - It is defined under Definition 4.9.6 in [Cohen1993]_. + It is defined under Definition 4.9.6 in [Coh1993]_. INPUT: @@ -9336,6 +9336,15 @@ def logarithmic_embedding(self, prec=53): (-1, -1) sage: f(7) (1.94591014905531, 3.89182029811063) + + :: + + sage: K. = NumberField(x^4 - 8*x^2 + 3) + sage: f = logarithmic_embedding(K) + sage: f(0) + (-1, -1, -1, -1) + sage: f(7) + (3.89182029811063, 3.89182029811063, 3.89182029811063, 3.89182029811063) """ def closure_map(x, prec=53): """ From 89d2c29e89e8cacd90d85bab0b7cbe9556e8614d Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 1 Sep 2022 13:42:27 +0800 Subject: [PATCH 05/42] 34212: log embedding for relative number field --- .../rings/number_field/number_field_rel.py | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index d33980c4b10..499a89161a6 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -2062,6 +2062,75 @@ def automorphisms(self): check=False, universe=self.Hom(self)) return self.__automorphisms + def logarithmic_embedding(self, prec=53): + r""" + Return the morphism of ``self`` under the logarithmic embedding + in the category Set. + + The logarithmic embedding is defined as a map from the relative number field ``self`` to `\RR^n`. + + It is defined under Definition 4.9.6 in [Coh1993]_. + + INPUT: + + - ``prec`` -- desired floating point precision. + + OUTPUT: + + - the morphism of ``self`` under the logarithmic embedding in the category Set. + + EXAMPLES:: + + sage: K. = CyclotomicField(3) + sage: R. = K[] + sage: L. = K.extension(x^5 + 5) + sage: f = logarithmic_embedding(L) + sage: f(0) + (-1, -1, -1, -1, -1) + sage: f(5) + (3.21887582486820, 3.21887582486820, 3.21887582486820, + 3.21887582486820, 3.21887582486820) + + :: + + sage: K. = NumberField(x^2 + 1) + sage: t = K['t'].gen() + sage: L. = K.extension(t^4 - i) + sage: f = logarithmic_embedding(L) + sage: f(0) + (-1, -1, -1, -1, -1, -1, -1, -1) + sage: f(3) + (2.19722457733622, 2.19722457733622, 2.19722457733622, 2.19722457733622, + 2.19722457733622, 2.19722457733622, 2.19722457733622, 2.19722457733622) + """ + def closure_map(x, prec=53): + """ + The function closure of the logarithmic embedding. + """ + K = self + K_embeddings = K.places(prec) + r1, r2 = K.signature() + r = r1 + r2 - 1 + + from sage.rings.all import RealField + Reals = RealField(prec) + + if x == 0: + return vector([-1 for _ in range(r + 1)]) + + x_logs = [] + for i in range(r1): + sigma = K_embeddings[i] + x_logs.append(Reals(abs(sigma(x))).log()) + for i in range(r1, r + 1): + tau = K_embeddings[i] + x_logs.append(2 * Reals(abs(tau(x))).log()) + + return vector(x_logs) + + hom = Hom(self, VectorSpace(RR, len(closure_map(self(0), prec))), Sets()) + return hom(closure_map) + def places(self, all_complex=False, prec=None): """ Return the collection of all infinite places of self. From 2fd483097aaa8d2a849bcb6785fc7f967ef73909 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 1 Sep 2022 14:51:33 +0800 Subject: [PATCH 06/42] 34212: correct examples --- src/sage/rings/number_field/number_field.py | 6 +++--- src/sage/rings/number_field/number_field_rel.py | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index edfa01cd232..118386623c3 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -9339,12 +9339,12 @@ def logarithmic_embedding(self, prec=53): :: - sage: K. = NumberField(x^4 - 8*x^2 + 3) - sage: f = logarithmic_embedding(K) + sage: F. = NumberField(x^4 - 8*x^2 + 3) + sage: f = F.logarithmic_embedding() sage: f(0) (-1, -1, -1, -1) sage: f(7) - (3.89182029811063, 3.89182029811063, 3.89182029811063, 3.89182029811063) + (1.94591014905531, 1.94591014905531, 1.94591014905531, 1.94591014905531) """ def closure_map(x, prec=53): """ diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index 499a89161a6..9e80ef1e3c1 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -99,8 +99,12 @@ from sage.rings.number_field.morphism import RelativeNumberFieldHomomorphism_from_abs from sage.libs.pari.all import pari_gen -from sage.rings.rational_field import QQ -from sage.rings.integer_ring import ZZ +from sage.categories.homset import Hom +from sage.categories.sets_cat import Sets +from sage.modules.free_module import VectorSpace +from sage.modules.free_module_element import vector + +from sage.rings.all import RR, QQ, ZZ def is_RelativeNumberField(x): @@ -2084,7 +2088,7 @@ def logarithmic_embedding(self, prec=53): sage: K. = CyclotomicField(3) sage: R. = K[] sage: L. = K.extension(x^5 + 5) - sage: f = logarithmic_embedding(L) + sage: f = L.logarithmic_embedding() sage: f(0) (-1, -1, -1, -1, -1) sage: f(5) @@ -2096,7 +2100,7 @@ def logarithmic_embedding(self, prec=53): sage: K. = NumberField(x^2 + 1) sage: t = K['t'].gen() sage: L. = K.extension(t^4 - i) - sage: f = logarithmic_embedding(L) + sage: f = L.logarithmic_embedding() sage: f(0) (-1, -1, -1, -1, -1, -1, -1, -1) sage: f(3) From 7a12ff3327a209bc6065fb0d8ea9b939f1d91c5f Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 13:28:09 +0800 Subject: [PATCH 07/42] points --- src/doc/en/reference/references/index.rst | 4 + .../schemes/projective/proj_bdd_height.py | 189 ++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 src/sage/schemes/projective/proj_bdd_height.py diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 1dbd6f036e7..010654f683a 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -3668,6 +3668,10 @@ REFERENCES: and its use for certified homotopy continuation of systems of plane algebraic curves, :arxiv:`1505.03432` +.. [Krumm2016] Daid Krumm, *Computing Points of Bounded Height in Projective Space over a Number Field*, + MATHEMATICS OF COMPUTATION, Volume 85, Number 297, January 2016, Pages 423–447. + http://dx.doi.org/10.1090/mcom/2984 + .. [KR2001] \J. Kahane and A. Ryba. *The hexad game*, Electronic Journal of Combinatorics, **8** (2001). http://www.combinatorics.org/Volume_8/Abstracts/v8i2r11.html diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py new file mode 100644 index 00000000000..8da3d90297f --- /dev/null +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -0,0 +1,189 @@ +r""" +Points of bounded height in projective spaces + +This module defines sunctions to compute points of bounded height of a given +number field with height less than a specified bound in projective spaces. + +Sage functions to list all elements of a given number field with height less +than a specified bound. + +AUTHORS: + +- Jing Guo (2022): initial version based on David Krumm's code + +REFERENCES: + +- [Krumm2016] + +""" + +import itertools + +def QQ_points_of_bounded_height(dim, bound): + r""" + ... + """ + if bound < 1: + return + PN = ProjectiveSpace(QQ, dim) + unit_tuples = list(itertools.product([-1, 1], repeat=dim)) + increasing_tuples = itertools.combinations_with_replacement(range(bound + 1), dim + 1) + for t in increasing_tuples: + if gcd(t) == 1: + for p in itertools.permutations(t): + for u in unit_tuples: + new_point = [a*b for a, b in zip(u, p)] + [p[dim]] + yield PN(new_point) + +def points_of_bounded_height(K, dim, bound, prec=53): + r""" + ... + """ + if bound < 1: + return + + r1, r2 = K.signature() + r = r1 + r2 - 1 + K_degree = K.degree() + K_embeddings = K.places(prec=prec) + roots_of_unity = K.roots_of_unity() + unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) + + PN = ProjectiveSpace(K, dim) + + Reals = RealField(prec) + logB = Reals(bound).log() + + class_group_ideals = [c.ideal() for c in K.class_group()] + class_number = len(class_group_ideals) + class_group_ideal_norms = [a.norm() for a in class_group_ideals] + norm_bound = bound*max(class_group_ideal_norms) + fundamental_units = UnitGroup(K).fundamental_units() + fund_unit_logs = map(log_map, fundamental_units) # TODO log map + + test_matrix = column_matrix(fund_unit_logs) + try: + test_matrix.change_ring(QQ) + except ValueError: + raise ValueError('prec too low.') + + cut_fund_unit_logs = column_matrix(fund_unit_logs).delete_rows([r]) + lll_fund_units = [] + for c in pari(cut_fund_unit_logs).qflll().python().columns(): + new_unit = 1 + for i in range(r): + new_unit *= fundamental_units[i]**c[i] + lll_fund_units.append(new_unit) + fundamental_units = lll_fund_units + fund_unit_logs = map(log_map, fundamental_units) + + possible_norm_set = set([]) + for i in range(class_number): + for k in range(1, bound + 1): + possible_norm_set.add(k*class_group_ideal_norms[i]) + + principal_ideal_gens = dict() + negative_norm_units = K.elements_of_norm(-1) + if len(negative_norm_units) == 0: + for m in possible_norm_set: + principal_ideal_gens[m] = K.elements_of_norm(m) + K.elements_of_norm(-m) + else: + for m in possible_norm_set: + principal_ideal_gens[m] = K.elements_of_norm(m) + + pr_ideal_gen_logs = dict() + for key in principal_ideal_gens: + for y in principal_ideal_gens[key]: + pr_ideal_gen_logs[y] = log_map(y) + + fund_parallelotope_vertices = [] + for coefficient_tuple in itertools.product([-1/2, 1/2], repeat=r): + vertex = sum([coefficient_tuple[i]*fund_unit_logs[i] for i in range(r)]) + fund_parallelotope_vertices.append(vertex) + + D_numbers = [] + for v in range(r + 1): + D_numbers.append(max([vertex[v] for vertex in fund_parallelotope_vertices])) + + A_numbers = [] + for v in range(r + 1): + A_numbers.append(min([pr_ideal_gen_logs[y][v] for y in pr_ideal_gen_logs])) + + aux_constant = (1/K_degree)*Reals(norm_bound).log() + + L_numbers = [] + for v in range(r1): + L_numbers.append(aux_constant + D_numbers[v] - A_numbers[v]) + for v in range(r1, r + 1): + L_numbers.append(2*aux_constant + D_numbers[v] - A_numbers[v]) + L_numbers = vector(L_numbers).change_ring(QQ) + + T = column_matrix(fund_unit_logs).delete_rows([r]).change_ring(QQ) + + M = ((-1)*matrix.identity(r)).insert_row(r, [1 for i in range(r)]) + M = M.transpose().insert_row(0, [0 for i in range(r + 1)]).transpose() + M = M.change_ring(QQ) + M.set_column(0, L_numbers) + vertices = map(vector, Polyhedron(ieqs=list(M)).vertices()) + + T_it = T.inverse().transpose() + unit_polytope = Polyhedron([v*T_it for v in vertices]) + + coordinate_space = dict() + coordinate_space[0] = [[K(0), log_map(0)]] + int_points = unit_polytope.integral_points() + + units_with_logs = dict() + for n in int_points: + new_unit = 1 + for j in range(r): + new_unit *= fundamental_units[j]**n[j] + new_unit_log = sum([n[j]*fund_unit_logs[j] for j in range(r)]) + units_with_logs[n] = [new_unit, new_unit_log] + + for norm in principal_ideal_gens: + coordinate_list = [] + for y in principal_ideal_gens[norm]: + for n in int_points: + unit, unit_log = units_with_logs[n] + y_log = pr_ideal_gen_logs[y] + g_log = unit_log + y_log + bool1 = all(g_log[i] <= aux_constant + D_numbers[i] for i in range(r1)) + bool2 = all(g_log[j] <= 2*aux_constant + D_numbers[j] for j in range(r1, r + 1)) + if bool1 and bool2: + g = unit*y + coordinate_list.append([g, g_log]) + if len(coordinate_list) > 0: + coordinate_space[norm] = coordinate_list + + for m in range(class_number): + a = class_group_ideals[m] + a_norm = class_group_ideal_norms[m] + log_a_norm = Reals(a_norm).log() + a_const = (logB + log_a_norm)/K_degree + a_coordinates = [] + + for k in range(bound + 1): + norm = k*a_norm + if coordinate_space.has_key(norm): + for pair in coordinate_space[norm]: + g, g_log = pair + if g in a: + bool1 = all(g_log[i] <= a_const + D_numbers[i] for i in range(r1)) + bool2 = all(g_log[j] <= 2*a_const + D_numbers[j] for j in range(r1, r + 1)) + if bool1 and bool2: + a_coordinates.append(pair) + + t = len(a_coordinates) - 1 + points_in_class_a = set([]) + increasing_tuples = itertools.combinations_with_replacement(range(t + 1), dim + 1) + log_arch_height_bound = logB + log_a_norm + for index_tuple in increasing_tuples: + point_coordinates = [a_coordinates[i][0] for i in index_tuple] + point_coordinate_logs = [a_coordinates[i][1] for i in index_tuple] + log_arch_height = sum([max([x[i] for x in point_coordinate_logs]) for i in range(r + 1)]) + if log_arch_height <= log_arch_height_bound and a == K.ideal(point_coordinates): + for p in itertools.permutations(point_coordinates): + for u in unit_tuples: + new_point = [i*j for i, j in zip(u, p)] + [p[dim]] + yield PN(new_point) From 2ed790e656bfe439dd7cdfe49c4c5ad45488b5f5 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 15:50:20 +0800 Subject: [PATCH 08/42] clean --- .../schemes/projective/projective_space.py | 74 ++++++------------- 1 file changed, 24 insertions(+), 50 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index ed44ebcd6aa..55a2f7e6a5b 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1852,18 +1852,12 @@ def _morphism(self, *args, **kwds): def points_of_bounded_height(self, **kwds): r""" - Returns an iterator of the points in self of absolute height of at most the given bound. + Return an iterator of the points in ``self`` of absolute height of + at most the given bound. - Bound check is strict for the rational field. Requires self to be projective space - over a number field. Uses the - Doyle-Krumm algorithm 4 (algorithm 5 for imaginary quadratic) for - computing algebraic numbers up to a given height [DK2013]_. + ALGORITHM: - The algorithm requires floating point arithmetic, so the user is - allowed to specify the precision for such calculations. - Additionally, due to floating point issues, points - slightly larger than the bound may be returned. This can be controlled - by lowering the tolerance. + This is an implementation of Algorithm 6 in [Krumm2016]_. INPUT: @@ -1871,13 +1865,11 @@ def points_of_bounded_height(self, **kwds): - ``bound`` - a real number - - ``tolerance`` - a rational number in (0,1] used in doyle-krumm algorithm-4 - - - ``precision`` - the precision to use for computing the elements of bounded height of number fields. + - ``precision`` - (default: 53) a positive integer OUTPUT: - - an iterator of points in this space + - an iterator of points of bounded height EXAMPLES:: @@ -1897,48 +1889,30 @@ def points_of_bounded_height(self, **kwds): sage: len(list(P.points_of_bounded_height(bound=1.5, tolerance=0.1))) 57 """ - if is_RationalField(self.base_ring()): - ftype = False # stores whether the field is a number field or the rational field - elif self.base_ring() in NumberFields(): # true for rational field as well, so check is_RationalField first - ftype = True + from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, points_of_bounded_height + + R = self.base_ring() + + # whether the field is a number field or the rational field + if is_RationalField(R): + field_type = False + elif R in NumberFields(): + # true for rational field as well, so check is_RationalField first + field_type = True else: raise NotImplementedError("self must be projective space over a number field") bound = kwds.pop('bound') B = bound**(self.base_ring().absolute_degree()) # convert to relative height - n = self.dimension_relative() - R = self.base_ring() - if ftype: - zero = R.zero() - i = n - while not i < 0: - P = [zero for _ in range(i)] + [R.one()] - P += [zero for _ in range(n - i)] - yield self(P) - tol = kwds.pop('tolerance', 1e-2) - prec = kwds.pop('precision', 53) - iters = [R.elements_of_bounded_height(bound=B, tolerance=tol, precision=prec) for _ in range(i)] - for x in iters: - next(x) # put at zero - j = 0 - while j < i: - try: - P[j] = next(iters[j]) - yield self(P) - j = 0 - except StopIteration: - iters[j] = R.elements_of_bounded_height(bound=B, tolerance=tol, precision=prec) # reset - next(iters[j]) # put at zero - P[j] = zero - j += 1 - i -= 1 - else: # base ring QQ - zero = (0,) * (n + 1) - for c in cartesian_product_iterator([srange(-B, B + 1) - for _ in range(n + 1)]): - if gcd(c) == 1 and c > zero: - yield self.point(c, check=False) + prec = kwds.pop('precision', 53) + + dim = self.dimension_relative() + + if field_type: + return points_of_bounded_height(dim, B) + else: + return QQ_points_of_bounded_height(R, dim, B, prec) def subscheme_from_Chow_form(self, Ch, dim): r""" From b1b8a28be151beff6455102b2fb0e0f4b564bde8 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 16:10:09 +0800 Subject: [PATCH 09/42] clean --- .../schemes/projective/proj_bdd_height.py | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 8da3d90297f..866453ba2a7 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -18,10 +18,23 @@ """ import itertools +from sage.schemes.projective.projective_space import ProjectiveSpace + def QQ_points_of_bounded_height(dim, bound): r""" - ... + Return an iterator of the points in ``self`` of absolute height of + at most the given bound in the rational field. + + INPUT: + + - ``dim`` -- a positive interger + + - ``bound`` -- a real number + + OUTPUT: + + - an iterator of points of bounded height """ if bound < 1: return @@ -37,7 +50,26 @@ def QQ_points_of_bounded_height(dim, bound): def points_of_bounded_height(K, dim, bound, prec=53): r""" - ... + Return an iterator of the points in ``self`` of absolute height of + at most the given bound. + + ALGORITHM: + + This is an implementation of Algorithm 6 in [Krumm2016]_. + + INPUT: + + - ``K`` -- a number field + + - ``dim`` -- a positive interger + + - ``bound`` -- a real number + + - ``prec`` -- (default: 53) a positive integer + + OUTPUT: + + - an iterator of points of bounded height """ if bound < 1: return From 76dab1c5ae1a007e5fd4e02301269ea6c46d237a Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 17:25:07 +0800 Subject: [PATCH 10/42] rational --- .../schemes/projective/proj_bdd_height.py | 27 +++++++++++++++---- .../schemes/projective/projective_space.py | 23 +++++----------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 866453ba2a7..1b37bb9724b 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -19,34 +19,51 @@ import itertools from sage.schemes.projective.projective_space import ProjectiveSpace - +from sage.rings.rational_field import QQ +from sage.arith.all import gcd def QQ_points_of_bounded_height(dim, bound): r""" Return an iterator of the points in ``self`` of absolute height of - at most the given bound in the rational field. + at most ``bound`` in the rational field. INPUT: - - ``dim`` -- a positive interger + - ``dim`` -- a positive integer - ``bound`` -- a real number OUTPUT: - an iterator of points of bounded height + + EXAMPLES: + + sage: from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height + sage: list(QQ_points_of_bounded_height(1, 1)) + [(0 : 1), (1 : 0), (1 : 1), (-1 : 1)] + sage: len(list(QQ_points_of_bounded_height(1, 5))) + 40 + + There are no points of negative height:: + + sage: from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height + sage: list(QQ_points_of_bounded_height(1, -3)) + [] """ if bound < 1: - return + return iter(set([])) PN = ProjectiveSpace(QQ, dim) unit_tuples = list(itertools.product([-1, 1], repeat=dim)) + points_of_bounded_height = set([]) increasing_tuples = itertools.combinations_with_replacement(range(bound + 1), dim + 1) for t in increasing_tuples: if gcd(t) == 1: for p in itertools.permutations(t): for u in unit_tuples: new_point = [a*b for a, b in zip(u, p)] + [p[dim]] - yield PN(new_point) + points_of_bounded_height.add(PN(new_point)) + return iter(points_of_bounded_height) def points_of_bounded_height(K, dim, bound, prec=53): r""" diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 55a2f7e6a5b..93b8d8c7b8a 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1874,20 +1874,11 @@ def points_of_bounded_height(self, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(QQ, 1) - sage: sorted(list(P.points_of_bounded_height(bound=5))) - [(0 : 1), (1 : -5), (1 : -4), (1 : -3), (1 : -2), (1 : -1), (1 : 0), - (1 : 1), (1 : 2), (1 : 3), (1 : 4), (1 : 5), (2 : -5), (2 : -3), - (2 : -1), (2 : 1), (2 : 3), (2 : 5), (3 : -5), (3 : -4), (3 : -2), - (3 : -1), (3 : 1), (3 : 2), (3 : 4), (3 : 5), (4 : -5), (4 : -3), - (4 : -1), (4 : 1), (4 : 3), (4 : 5), (5 : -4), (5 : -3), (5 : -2), - (5 : -1), (5 : 1), (5 : 2), (5 : 3), (5 : 4)] - - :: - - sage: u = QQ['u'].0 - sage: P. = ProjectiveSpace(NumberField(u^2 - 2, 'v'), 2) - sage: len(list(P.points_of_bounded_height(bound=1.5, tolerance=0.1))) - 57 + sage: sorted(list(P.points_of_bounded_height(bound=3))) + [(-3 : 1), (-2 : 1), (-3/2 : 1), (-1 : 1), + (-2/3 : 1), (-1/2 : 1), (-1/3 : 1), (0 : 1), + (1/3 : 1), (1/2 : 1), (2/3 : 1), (1 : 0), + (1 : 1), (3/2 : 1), (2 : 1), (3 : 1)] """ from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, points_of_bounded_height @@ -1910,9 +1901,9 @@ def points_of_bounded_height(self, **kwds): dim = self.dimension_relative() if field_type: - return points_of_bounded_height(dim, B) + return points_of_bounded_height(R, dim, B, prec) else: - return QQ_points_of_bounded_height(R, dim, B, prec) + return QQ_points_of_bounded_height(dim, B) def subscheme_from_Chow_form(self, Ch, dim): r""" From 706e514ae198f296bf29808785cbc2add3b89c5b Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 17:43:39 +0800 Subject: [PATCH 11/42] import --- src/sage/schemes/projective/proj_bdd_height.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 1b37bb9724b..5f637d98f9b 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -20,6 +20,8 @@ import itertools from sage.schemes.projective.projective_space import ProjectiveSpace from sage.rings.rational_field import QQ +from sage.rings.all import RealField +from sage.rings.number_field.unit_group import UnitGroup from sage.arith.all import gcd def QQ_points_of_bounded_height(dim, bound): From 3e5f25f3015a452b6da3669753b5336457e4b8b7 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 18:05:42 +0800 Subject: [PATCH 12/42] number fields --- src/sage/schemes/projective/proj_bdd_height.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 5f637d98f9b..07ce8d5f959 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -23,6 +23,7 @@ from sage.rings.all import RealField from sage.rings.number_field.unit_group import UnitGroup from sage.arith.all import gcd +from sage.rings.number_field.number_field import logarithmic_embedding def QQ_points_of_bounded_height(dim, bound): r""" @@ -110,7 +111,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): class_group_ideal_norms = [a.norm() for a in class_group_ideals] norm_bound = bound*max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() - fund_unit_logs = map(log_map, fundamental_units) # TODO log map + fund_unit_logs = map(logarithmic_embedding, fundamental_units) test_matrix = column_matrix(fund_unit_logs) try: @@ -126,7 +127,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): new_unit *= fundamental_units[i]**c[i] lll_fund_units.append(new_unit) fundamental_units = lll_fund_units - fund_unit_logs = map(log_map, fundamental_units) + fund_unit_logs = map(logarithmic_embedding, fundamental_units) possible_norm_set = set([]) for i in range(class_number): @@ -145,7 +146,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): pr_ideal_gen_logs = dict() for key in principal_ideal_gens: for y in principal_ideal_gens[key]: - pr_ideal_gen_logs[y] = log_map(y) + pr_ideal_gen_logs[y] = logarithmic_embedding(y) fund_parallelotope_vertices = [] for coefficient_tuple in itertools.product([-1/2, 1/2], repeat=r): @@ -181,7 +182,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): unit_polytope = Polyhedron([v*T_it for v in vertices]) coordinate_space = dict() - coordinate_space[0] = [[K(0), log_map(0)]] + coordinate_space[0] = [[K(0), logarithmic_embedding(0)]] int_points = unit_polytope.integral_points() units_with_logs = dict() From 4d10b14e3ddbdaef3d1e2306b4e34a4255242f81 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 19:28:41 +0800 Subject: [PATCH 13/42] log embed --- src/sage/schemes/projective/proj_bdd_height.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 07ce8d5f959..8b2713e19da 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -23,7 +23,7 @@ from sage.rings.all import RealField from sage.rings.number_field.unit_group import UnitGroup from sage.arith.all import gcd -from sage.rings.number_field.number_field import logarithmic_embedding +from sage.matrix.constructor import column_matrix def QQ_points_of_bounded_height(dim, bound): r""" @@ -102,6 +102,8 @@ def points_of_bounded_height(K, dim, bound, prec=53): unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) PN = ProjectiveSpace(K, dim) + #R = K.base_ring() + log_embed = K.logarithmic_embedding() Reals = RealField(prec) logB = Reals(bound).log() @@ -111,7 +113,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): class_group_ideal_norms = [a.norm() for a in class_group_ideals] norm_bound = bound*max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() - fund_unit_logs = map(logarithmic_embedding, fundamental_units) + fund_unit_logs = map(log_embed, fundamental_units) test_matrix = column_matrix(fund_unit_logs) try: @@ -127,7 +129,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): new_unit *= fundamental_units[i]**c[i] lll_fund_units.append(new_unit) fundamental_units = lll_fund_units - fund_unit_logs = map(logarithmic_embedding, fundamental_units) + fund_unit_logs = map(log_embed, fundamental_units) possible_norm_set = set([]) for i in range(class_number): @@ -146,7 +148,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): pr_ideal_gen_logs = dict() for key in principal_ideal_gens: for y in principal_ideal_gens[key]: - pr_ideal_gen_logs[y] = logarithmic_embedding(y) + pr_ideal_gen_logs[y] = log_embed(y) fund_parallelotope_vertices = [] for coefficient_tuple in itertools.product([-1/2, 1/2], repeat=r): @@ -182,7 +184,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): unit_polytope = Polyhedron([v*T_it for v in vertices]) coordinate_space = dict() - coordinate_space[0] = [[K(0), logarithmic_embedding(0)]] + coordinate_space[0] = [[K(0), log_embed(0)]] int_points = unit_polytope.integral_points() units_with_logs = dict() From 21c8ec68f09eb6e375c1a16a6bdbcc0507dd6fda Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Mon, 29 Aug 2022 11:25:55 +0800 Subject: [PATCH 14/42] doc --- src/sage/schemes/projective/proj_bdd_height.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 8b2713e19da..602dd056bf1 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -70,8 +70,8 @@ def QQ_points_of_bounded_height(dim, bound): def points_of_bounded_height(K, dim, bound, prec=53): r""" - Return an iterator of the points in ``self`` of absolute height of - at most the given bound. + Return an iterator of the points in ``K`` with dimension ``dim`` of + absolute height of at most ``bound``. ALGORITHM: @@ -102,7 +102,6 @@ def points_of_bounded_height(K, dim, bound, prec=53): unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) PN = ProjectiveSpace(K, dim) - #R = K.base_ring() log_embed = K.logarithmic_embedding() Reals = RealField(prec) From 2711a1d38a637cf42e1cf0a12f09a2f4f42f4a9e Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Mon, 29 Aug 2022 12:10:32 +0800 Subject: [PATCH 15/42] indent --- .../schemes/projective/proj_bdd_height.py | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 602dd056bf1..8ad4fb6f101 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -92,11 +92,11 @@ def points_of_bounded_height(K, dim, bound, prec=53): - an iterator of points of bounded height """ if bound < 1: - return + return [] r1, r2 = K.signature() r = r1 + r2 - 1 - K_degree = K.degree() + K_degree = K.degree() K_embeddings = K.places(prec=prec) roots_of_unity = K.roots_of_unity() unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) @@ -134,7 +134,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): for i in range(class_number): for k in range(1, bound + 1): possible_norm_set.add(k*class_group_ideal_norms[i]) - + principal_ideal_gens = dict() negative_norm_units = K.elements_of_norm(-1) if len(negative_norm_units) == 0: @@ -148,22 +148,22 @@ def points_of_bounded_height(K, dim, bound, prec=53): for key in principal_ideal_gens: for y in principal_ideal_gens[key]: pr_ideal_gen_logs[y] = log_embed(y) - + fund_parallelotope_vertices = [] for coefficient_tuple in itertools.product([-1/2, 1/2], repeat=r): vertex = sum([coefficient_tuple[i]*fund_unit_logs[i] for i in range(r)]) fund_parallelotope_vertices.append(vertex) - + D_numbers = [] for v in range(r + 1): D_numbers.append(max([vertex[v] for vertex in fund_parallelotope_vertices])) - + A_numbers = [] for v in range(r + 1): A_numbers.append(min([pr_ideal_gen_logs[y][v] for y in pr_ideal_gen_logs])) - + aux_constant = (1/K_degree)*Reals(norm_bound).log() - + L_numbers = [] for v in range(r1): L_numbers.append(aux_constant + D_numbers[v] - A_numbers[v]) @@ -225,7 +225,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): bool1 = all(g_log[i] <= a_const + D_numbers[i] for i in range(r1)) bool2 = all(g_log[j] <= 2*a_const + D_numbers[j] for j in range(r1, r + 1)) if bool1 and bool2: - a_coordinates.append(pair) + a_coordinates.append(pair) t = len(a_coordinates) - 1 points_in_class_a = set([]) @@ -239,4 +239,6 @@ def points_of_bounded_height(K, dim, bound, prec=53): for p in itertools.permutations(point_coordinates): for u in unit_tuples: new_point = [i*j for i, j in zip(u, p)] + [p[dim]] - yield PN(new_point) + points_in_class_a.add(PN(new_point)) + points_of_bdd_height += list(points_in_class_a) + return points_of_bdd_height From 394bf27029bee8d0326999795c8cc06dc860e5bd Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Mon, 29 Aug 2022 13:33:38 +0800 Subject: [PATCH 16/42] python 2 to python 3 --- .../schemes/projective/proj_bdd_height.py | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 8ad4fb6f101..d814371de08 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -23,7 +23,12 @@ from sage.rings.all import RealField from sage.rings.number_field.unit_group import UnitGroup from sage.arith.all import gcd -from sage.matrix.constructor import column_matrix +from sage.matrix.constructor import matrix, column_matrix +from sage.libs.pari.all import pari +from sage.modules.free_module_element import vector +from sage.rings.integer import Integer +from sage.geometry.polyhedron.constructor import Polyhedron + def QQ_points_of_bounded_height(dim, bound): r""" @@ -107,28 +112,33 @@ def points_of_bounded_height(K, dim, bound, prec=53): Reals = RealField(prec) logB = Reals(bound).log() + points_of_bdd_height = [] + class_group_ideals = [c.ideal() for c in K.class_group()] class_number = len(class_group_ideals) class_group_ideal_norms = [a.norm() for a in class_group_ideals] norm_bound = bound*max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() - fund_unit_logs = map(log_embed, fundamental_units) + fund_unit_logs = list(map(log_embed, fundamental_units)) test_matrix = column_matrix(fund_unit_logs) - try: - test_matrix.change_ring(QQ) - except ValueError: - raise ValueError('prec too low.') + #try: + # test_matrix.change_ring(QQ) + #except ValueError: + # raise ValueError('prec too low.') - cut_fund_unit_logs = column_matrix(fund_unit_logs).delete_rows([r]) + cut_fund_unit_logs = test_matrix.delete_rows([r]) lll_fund_units = [] - for c in pari(cut_fund_unit_logs).qflll().python().columns(): + for c in cut_fund_unit_logs.columns(): + #for c in pari(cut_fund_unit_logs).qflll().python().columns(): new_unit = 1 for i in range(r): + print(fundamental_units[i]) + print(c[i]) new_unit *= fundamental_units[i]**c[i] lll_fund_units.append(new_unit) fundamental_units = lll_fund_units - fund_unit_logs = map(log_embed, fundamental_units) + fund_unit_logs = list(map(log_embed, fundamental_units)) possible_norm_set = set([]) for i in range(class_number): @@ -173,8 +183,8 @@ def points_of_bounded_height(K, dim, bound, prec=53): T = column_matrix(fund_unit_logs).delete_rows([r]).change_ring(QQ) - M = ((-1)*matrix.identity(r)).insert_row(r, [1 for i in range(r)]) - M = M.transpose().insert_row(0, [0 for i in range(r + 1)]).transpose() + M = ((-1)*matrix.identity(r)).insert_row(r, [Integer(1) for i in range(r)]) + M = M.transpose().insert_row(0, [Integer(0) for i in range(r + 1)]).transpose() M = M.change_ring(QQ) M.set_column(0, L_numbers) vertices = map(vector, Polyhedron(ieqs=list(M)).vertices()) @@ -218,7 +228,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): for k in range(bound + 1): norm = k*a_norm - if coordinate_space.has_key(norm): + if norm in coordinate_space: for pair in coordinate_space[norm]: g, g_log = pair if g in a: From 2e9df04ae57717bc61f2aff97f1d83490833886f Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Tue, 30 Aug 2022 20:30:33 +0800 Subject: [PATCH 17/42] some small changes --- .../schemes/projective/proj_bdd_height.py | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index d814371de08..e20bf297962 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -116,21 +116,22 @@ def points_of_bounded_height(K, dim, bound, prec=53): class_group_ideals = [c.ideal() for c in K.class_group()] class_number = len(class_group_ideals) - class_group_ideal_norms = [a.norm() for a in class_group_ideals] - norm_bound = bound*max(class_group_ideal_norms) + class_group_ideal_norms = [i.norm() for i in class_group_ideals] + norm_bound = bound * max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() fund_unit_logs = list(map(log_embed, fundamental_units)) + mat = column_matrix(fund_unit_logs) - test_matrix = column_matrix(fund_unit_logs) - #try: - # test_matrix.change_ring(QQ) - #except ValueError: - # raise ValueError('prec too low.') + test_matrix = mat + try: + test_matrix.change_ring(QQ) + except ValueError: + raise ValueError('prec too low.') - cut_fund_unit_logs = test_matrix.delete_rows([r]) + cut_fund_unit_logs = mat.delete_rows([r]) lll_fund_units = [] - for c in cut_fund_unit_logs.columns(): #for c in pari(cut_fund_unit_logs).qflll().python().columns(): + for c in cut_fund_unit_logs.columns(): new_unit = 1 for i in range(r): print(fundamental_units[i]) @@ -172,7 +173,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): for v in range(r + 1): A_numbers.append(min([pr_ideal_gen_logs[y][v] for y in pr_ideal_gen_logs])) - aux_constant = (1/K_degree)*Reals(norm_bound).log() + aux_constant = (1/K_degree) * Reals(norm_bound).log() L_numbers = [] for v in range(r1): @@ -212,9 +213,9 @@ def points_of_bounded_height(K, dim, bound, prec=53): y_log = pr_ideal_gen_logs[y] g_log = unit_log + y_log bool1 = all(g_log[i] <= aux_constant + D_numbers[i] for i in range(r1)) - bool2 = all(g_log[j] <= 2*aux_constant + D_numbers[j] for j in range(r1, r + 1)) + bool2 = all(g_log[j] <= 2 * aux_constant + D_numbers[j] for j in range(r1, r + 1)) if bool1 and bool2: - g = unit*y + g = unit * y coordinate_list.append([g, g_log]) if len(coordinate_list) > 0: coordinate_space[norm] = coordinate_list @@ -227,13 +228,13 @@ def points_of_bounded_height(K, dim, bound, prec=53): a_coordinates = [] for k in range(bound + 1): - norm = k*a_norm + norm = k * a_norm if norm in coordinate_space: for pair in coordinate_space[norm]: g, g_log = pair if g in a: bool1 = all(g_log[i] <= a_const + D_numbers[i] for i in range(r1)) - bool2 = all(g_log[j] <= 2*a_const + D_numbers[j] for j in range(r1, r + 1)) + bool2 = all(g_log[j] <= 2 * a_const + D_numbers[j] for j in range(r1, r + 1)) if bool1 and bool2: a_coordinates.append(pair) From fc09436787030034d389e1e458a5212d9a170c41 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 31 Aug 2022 14:02:10 +0800 Subject: [PATCH 18/42] restore commented line --- src/sage/schemes/projective/proj_bdd_height.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index e20bf297962..b624038cd28 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -130,12 +130,9 @@ def points_of_bounded_height(K, dim, bound, prec=53): cut_fund_unit_logs = mat.delete_rows([r]) lll_fund_units = [] - #for c in pari(cut_fund_unit_logs).qflll().python().columns(): - for c in cut_fund_unit_logs.columns(): + for c in pari(cut_fund_unit_logs).qflll().python(): new_unit = 1 for i in range(r): - print(fundamental_units[i]) - print(c[i]) new_unit *= fundamental_units[i]**c[i] lll_fund_units.append(new_unit) fundamental_units = lll_fund_units From e150af850836823d0c733ab16d345818149b67a5 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 31 Aug 2022 21:29:28 +0800 Subject: [PATCH 19/42] examples --- .../schemes/projective/proj_bdd_height.py | 26 +++++++++++++++++-- .../schemes/projective/projective_space.py | 7 +++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index b624038cd28..01b0a7986e4 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -95,9 +95,29 @@ def points_of_bounded_height(K, dim, bound, prec=53): OUTPUT: - an iterator of points of bounded height + + EXAMPLES: + + sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height + sage: R. = PolynomialRing(QQ) + sage: K. = NumberField(x^3 + 5) + sage: list(points_of_bounded_height(K, 2, -3)) + [] + sage: list(points_of_bounded_height(K, 2, 2)) + [(1 : 0 : 1), (-1 : 0 : 1), (0 : -1 : 1), (0 : 1 : 0), + (1 : 1 : 0), (-1 : 1 : 1), (1 : -1 : 1), (-1 : -1 : 1), + (1 : 0 : 0), (-1 : 1 : 0), (0 : 0 : 1), (1 : 1 : 1), + (0 : 1 : 1)] + + :: + + sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height + sage: K. = QuadraticField(3) + sage: list(points_of_bounded_height(K, 1, 1)) + [(0 : 1), (1 : 0), (1 : 1), (-1 : 1)] """ if bound < 1: - return [] + return iter([]) r1, r2 = K.signature() r = r1 + r2 - 1 @@ -249,4 +269,6 @@ def points_of_bounded_height(K, dim, bound, prec=53): new_point = [i*j for i, j in zip(u, p)] + [p[dim]] points_in_class_a.add(PN(new_point)) points_of_bdd_height += list(points_in_class_a) - return points_of_bdd_height + + return iter(points_of_bdd_height) + diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 93b8d8c7b8a..2adfaafe764 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1879,6 +1879,13 @@ def points_of_bounded_height(self, **kwds): (-2/3 : 1), (-1/2 : 1), (-1/3 : 1), (0 : 1), (1/3 : 1), (1/2 : 1), (2/3 : 1), (1 : 0), (1 : 1), (3/2 : 1), (2 : 1), (3 : 1)] + + :: + + sage: u = QQ['u'].0 + sage: P. = ProjectiveSpace(NumberField(u^2 - 2, 'v'), 2) + sage: len(list(P.points_of_bounded_height(bound=2))) + 265 """ from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, points_of_bounded_height From 1cc7b79098ebff1254eac1eb48e2892ef81e98e6 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 1 Sep 2022 13:03:12 +0800 Subject: [PATCH 20/42] more examples and rel degree --- .../schemes/projective/proj_bdd_height.py | 6 +++- .../schemes/projective/projective_space.py | 28 +++++++++++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 01b0a7986e4..0a033719c6b 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -121,7 +121,11 @@ def points_of_bounded_height(K, dim, bound, prec=53): r1, r2 = K.signature() r = r1 + r2 - 1 - K_degree = K.degree() + + if K.is_relative: + K_degree = K.relative_degree() + else: + K_degree = K.degree() K_embeddings = K.places(prec=prec) roots_of_unity = K.roots_of_unity() unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 2adfaafe764..3374298ceb8 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1863,7 +1863,7 @@ def points_of_bounded_height(self, **kwds): kwds: - - ``bound`` - a real number + - ``bound`` - an integer - ``precision`` - (default: 53) a positive integer @@ -1885,7 +1885,25 @@ def points_of_bounded_height(self, **kwds): sage: u = QQ['u'].0 sage: P. = ProjectiveSpace(NumberField(u^2 - 2, 'v'), 2) sage: len(list(P.points_of_bounded_height(bound=2))) - 265 + 13 + + :: + + sage: CF. = CyclotomicField(5) + sage: R. = CF[] + sage: L. = CF.extension(x^5 + 5) + sage: Q. = ProjectiveSpace(L, 1) + sage: list(Q.points_of_bounded_height(bound=2)) + + :: + + sage: R. = QQ[] + sage: F. = NumberField(x^4 - 8*x^2 + 3) + sage: P. = ProjectiveSpace(F, 2) + sage: all([exp(p.global_height()) <= 1 for p in P.points_of_bounded_height(bound=1)]) + True + sage: all([exp(p.global_height()) <= 3 for p in P.points_of_bounded_height(bound=3)]) + True """ from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, points_of_bounded_height @@ -1901,16 +1919,14 @@ def points_of_bounded_height(self, **kwds): raise NotImplementedError("self must be projective space over a number field") bound = kwds.pop('bound') - B = bound**(self.base_ring().absolute_degree()) # convert to relative height - prec = kwds.pop('precision', 53) dim = self.dimension_relative() if field_type: - return points_of_bounded_height(R, dim, B, prec) + return points_of_bounded_height(R, dim, bound, prec) else: - return QQ_points_of_bounded_height(dim, B) + return QQ_points_of_bounded_height(dim, bound) def subscheme_from_Chow_form(self, Ch, dim): r""" From 26885489d3ebf9650467b7f0d2499c5d3d102b5f Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 1 Sep 2022 15:35:33 +0800 Subject: [PATCH 21/42] 34686: Support for relative number field --- src/sage/schemes/projective/proj_bdd_height.py | 7 +++++-- src/sage/schemes/projective/projective_space.py | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 0a033719c6b..b8f8c472be1 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -122,7 +122,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): r1, r2 = K.signature() r = r1 + r2 - 1 - if K.is_relative: + if K.is_relative(): K_degree = K.relative_degree() else: K_degree = K.degree() @@ -140,7 +140,10 @@ def points_of_bounded_height(K, dim, bound, prec=53): class_group_ideals = [c.ideal() for c in K.class_group()] class_number = len(class_group_ideals) - class_group_ideal_norms = [i.norm() for i in class_group_ideals] + if K.is_relative(): + class_group_ideal_norms = [i.absolute_norm() for i in class_group_ideals] + else: + class_group_ideal_norms = [i.norm() for i in class_group_ideals] norm_bound = bound * max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() fund_unit_logs = list(map(log_embed, fundamental_units)) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 3374298ceb8..7c559eef1af 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1889,11 +1889,13 @@ def points_of_bounded_height(self, **kwds): :: - sage: CF. = CyclotomicField(5) + sage: CF. = CyclotomicField(3) sage: R. = CF[] - sage: L. = CF.extension(x^5 + 5) + sage: L. = CF.extension(x^3 + 2) sage: Q. = ProjectiveSpace(L, 1) sage: list(Q.points_of_bounded_height(bound=2)) + [(0 : 1), (a : 1), (a + 1 : 1), (-a - 1 : 1), + (-a : 1), (-1 : 1), (1 : 1), (1 : 0)] :: From 83f385fc31a129c36389ac91cfd3c66d2d15c920 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sat, 3 Sep 2022 12:52:07 +0800 Subject: [PATCH 22/42] 32686: points_of_bounded_height for imaginary quadraitc field --- .../schemes/projective/proj_bdd_height.py | 104 ++++++++++++------ 1 file changed, 71 insertions(+), 33 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index b8f8c472be1..b5b1cf865d9 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -18,6 +18,7 @@ """ import itertools + from sage.schemes.projective.projective_space import ProjectiveSpace from sage.rings.rational_field import QQ from sage.rings.all import RealField @@ -61,6 +62,7 @@ def QQ_points_of_bounded_height(dim, bound): """ if bound < 1: return iter(set([])) + PN = ProjectiveSpace(QQ, dim) unit_tuples = list(itertools.product([-1, 1], repeat=dim)) points_of_bounded_height = set([]) @@ -71,6 +73,71 @@ def QQ_points_of_bounded_height(dim, bound): for u in unit_tuples: new_point = [a*b for a, b in zip(u, p)] + [p[dim]] points_of_bounded_height.add(PN(new_point)) + + return iter(points_of_bounded_height) + +def IQ_points_of_bounded_height(K, dim, bound): + r""" + Return an iterator of the points in ``self`` of absolute height of + at most ``bound`` in the imaginary quadratic field ``K``. + + INPUT: + + - ``K`` -- a number field + + - ``dim`` -- a positive interger + + - ``bound`` -- a real number + + OUTPUT: + + - an iterator of points of bounded height + """ + if bound < 1: + return iter(set([])) + + PN = ProjectiveSpace(K, dim) + unit_tuples = list(itertools.product(K.roots_of_unity(), repeat=dim)) + points_of_bounded_height = [] + + class_group_ideals = [c.ideal() for c in K.class_group()] + class_group_ideal_norms = [i.norm() for i in class_group_ideals] + class_number = len(class_group_ideals) + + possible_norm_set = set([]) + for i in range(class_number): + for k in range(1, bound + 1): + possible_norm_set.add(k*class_group_ideal_norms[i]) + + coordinate_space = dict() + coordinate_space[0] = [K(0)] + for m in possible_norm_set: + coordinate_space[m] = K.elements_of_norm(m) + + for i in range(class_number): + a = class_group_ideals[i] + a_norm = class_group_ideal_norms[i] + a_norm_bound = bound * a_norm + a_coordinates = [] + + for m in coordinate_space: + if m <= a_norm_bound: + for x in coordinate_space[m]: + if x in a: + a_coordinates.append(x) + + points_in_class_a = set([]) + t = len(a_coordinates) - 1 + increasing_tuples = itertools.combinations_with_replacement(range(t + 1), dim + 1) + for index_tuple in increasing_tuples: + point_coordinates = [a_coordinates[i] for i in index_tuple] + if a == K.ideal(point_coordinates): + for p in itertools.permutations(point_coordinates): + for u in unit_tuples: + new_point = [i*j for i, j in zip(u, p)] + [p[dim]] + points_in_class_a.add(PN(new_point)) + points_of_bounded_height += list(points_in_class_a) + return iter(points_of_bounded_height) def points_of_bounded_height(K, dim, bound, prec=53): @@ -95,37 +162,13 @@ def points_of_bounded_height(K, dim, bound, prec=53): OUTPUT: - an iterator of points of bounded height - - EXAMPLES: - - sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height - sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^3 + 5) - sage: list(points_of_bounded_height(K, 2, -3)) - [] - sage: list(points_of_bounded_height(K, 2, 2)) - [(1 : 0 : 1), (-1 : 0 : 1), (0 : -1 : 1), (0 : 1 : 0), - (1 : 1 : 0), (-1 : 1 : 1), (1 : -1 : 1), (-1 : -1 : 1), - (1 : 0 : 0), (-1 : 1 : 0), (0 : 0 : 1), (1 : 1 : 1), - (0 : 1 : 1)] - - :: - - sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height - sage: K. = QuadraticField(3) - sage: list(points_of_bounded_height(K, 1, 1)) - [(0 : 1), (1 : 0), (1 : 1), (-1 : 1)] """ if bound < 1: - return iter([]) + return [] r1, r2 = K.signature() r = r1 + r2 - 1 - - if K.is_relative(): - K_degree = K.relative_degree() - else: - K_degree = K.degree() + K_degree = K.degree() K_embeddings = K.places(prec=prec) roots_of_unity = K.roots_of_unity() unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) @@ -140,10 +183,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): class_group_ideals = [c.ideal() for c in K.class_group()] class_number = len(class_group_ideals) - if K.is_relative(): - class_group_ideal_norms = [i.absolute_norm() for i in class_group_ideals] - else: - class_group_ideal_norms = [i.norm() for i in class_group_ideals] + class_group_ideal_norms = [i.norm() for i in class_group_ideals] norm_bound = bound * max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() fund_unit_logs = list(map(log_embed, fundamental_units)) @@ -276,6 +316,4 @@ def points_of_bounded_height(K, dim, bound, prec=53): new_point = [i*j for i, j in zip(u, p)] + [p[dim]] points_in_class_a.add(PN(new_point)) points_of_bdd_height += list(points_in_class_a) - - return iter(points_of_bdd_height) - + return points_of_bdd_height From 2a67e06550a8d0b271c879194ee1d9b2010c0ab1 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sat, 3 Sep 2022 14:11:19 +0800 Subject: [PATCH 23/42] 32686: Support for imaginary quadratic field --- .../schemes/projective/proj_bdd_height.py | 38 ++++++++++++++++--- .../schemes/projective/projective_space.py | 21 +++++++++- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index b5b1cf865d9..f4f7a831db7 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -92,9 +92,18 @@ def IQ_points_of_bounded_height(K, dim, bound): OUTPUT: - an iterator of points of bounded height + + EXAMPLES: + + sage: from sage.schemes.projective.proj_bdd_height import IQ_points_of_bounded_height + sage: CF. = CyclotomicField(3) + sage: len(list(IQ_points_of_bounded_height(CF, 2, -1))) + 0 + sage: len(list(IQ_points_of_bounded_height(CF, 2, 1))) + 57 """ if bound < 1: - return iter(set([])) + return iter([]) PN = ProjectiveSpace(K, dim) unit_tuples = list(itertools.product(K.roots_of_unity(), repeat=dim)) @@ -162,13 +171,25 @@ def points_of_bounded_height(K, dim, bound, prec=53): OUTPUT: - an iterator of points of bounded height + + EXAMPLES: + + sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height + sage: K. = NumberField(x^3 - 7) + sage: len(list(points_of_bounded_height(K, 2, 1))) + 13 """ if bound < 1: - return [] + return iter([]) r1, r2 = K.signature() r = r1 + r2 - 1 - K_degree = K.degree() + + if K.is_relative(): + K_degree = K.relative_degree() + else: + K_degree = K.degree() + K_embeddings = K.places(prec=prec) roots_of_unity = K.roots_of_unity() unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) @@ -183,7 +204,12 @@ def points_of_bounded_height(K, dim, bound, prec=53): class_group_ideals = [c.ideal() for c in K.class_group()] class_number = len(class_group_ideals) - class_group_ideal_norms = [i.norm() for i in class_group_ideals] + + if K.is_relative(): + class_group_ideal_norms = [i.absolute_norm() for i in class_group_ideals] + else: + class_group_ideal_norms = [i.norm() for i in class_group_ideals] + norm_bound = bound * max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() fund_unit_logs = list(map(log_embed, fundamental_units)) @@ -316,4 +342,6 @@ def points_of_bounded_height(K, dim, bound, prec=53): new_point = [i*j for i, j in zip(u, p)] + [p[dim]] points_in_class_a.add(PN(new_point)) points_of_bdd_height += list(points_in_class_a) - return points_of_bdd_height + + return iter(points_of_bdd_height) + diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 7c559eef1af..03158bb1627 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1906,8 +1906,15 @@ def points_of_bounded_height(self, **kwds): True sage: all([exp(p.global_height()) <= 3 for p in P.points_of_bounded_height(bound=3)]) True + + :: + + sage: K. = CyclotomicField(3) + sage: P. = ProjectiveSpace(K, 2) + sage: len(list(P.points_of_bounded_height(bound=1))) + 57 """ - from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, points_of_bounded_height + from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, IQ_points_of_bounded_height, points_of_bounded_height R = self.base_ring() @@ -1926,6 +1933,18 @@ def points_of_bounded_height(self, **kwds): dim = self.dimension_relative() if field_type: + # for imaginary quadratic field + r1, r2 = R.signature() + r = r1 + r2 - 1 + + if R.is_relative(): + deg = R.relative_degree() + else: + deg = R.degree() + + if deg == 2 and r == 0: + return IQ_points_of_bounded_height(R, dim, bound) + return points_of_bounded_height(R, dim, bound, prec) else: return QQ_points_of_bounded_height(dim, bound) From f4e99ee347bd6ac2aec981e281aab08873b38230 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sat, 3 Sep 2022 15:04:56 +0800 Subject: [PATCH 24/42] 32686: Raise degree to absolute degree --- .../schemes/projective/projective_space.py | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 03158bb1627..15d319b8f57 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1874,18 +1874,16 @@ def points_of_bounded_height(self, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(QQ, 1) - sage: sorted(list(P.points_of_bounded_height(bound=3))) - [(-3 : 1), (-2 : 1), (-3/2 : 1), (-1 : 1), - (-2/3 : 1), (-1/2 : 1), (-1/3 : 1), (0 : 1), - (1/3 : 1), (1/2 : 1), (2/3 : 1), (1 : 0), - (1 : 1), (3/2 : 1), (2 : 1), (3 : 1)] + sage: sorted(list(P.points_of_bounded_height(bound=2))) + [(-2 : 1), (-1 : 1), (-1/2 : 1), (0 : 1), + (1/2 : 1), (1 : 0), (1 : 1), (2 : 1)] :: sage: u = QQ['u'].0 sage: P. = ProjectiveSpace(NumberField(u^2 - 2, 'v'), 2) sage: len(list(P.points_of_bounded_height(bound=2))) - 13 + 265 :: @@ -1893,9 +1891,9 @@ def points_of_bounded_height(self, **kwds): sage: R. = CF[] sage: L. = CF.extension(x^3 + 2) sage: Q. = ProjectiveSpace(L, 1) - sage: list(Q.points_of_bounded_height(bound=2)) + sage: sorted(list(Q.points_of_bounded_height(bound=1))) [(0 : 1), (a : 1), (a + 1 : 1), (-a - 1 : 1), - (-a : 1), (-1 : 1), (1 : 1), (1 : 0)] + (-a : 1), (-1 : 1), (1 : 1), (1 : 0)] :: @@ -1913,6 +1911,22 @@ def points_of_bounded_height(self, **kwds): sage: P. = ProjectiveSpace(K, 2) sage: len(list(P.points_of_bounded_height(bound=1))) 57 + + :: + + sage: u = QQ['u'].0 + sage: K. = NumberField(u^2 - 2) + sage: P. = ProjectiveSpace(K, 1) + sage: len(list(P.points_of_bounded_height(bound=2))) + 24 + + :: + + sage: R. = QQ[] + sage: K. = NumberField(x^4 - 8*x^2 + 3) + sage: P. = ProjectiveSpace(K, 1) + sage: len(list(P.points_of_bounded_height(bound=2))) + 108 """ from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, IQ_points_of_bounded_height, points_of_bounded_height @@ -1930,6 +1944,8 @@ def points_of_bounded_height(self, **kwds): bound = kwds.pop('bound') prec = kwds.pop('precision', 53) + bound = bound**R.absolute_degree() + dim = self.dimension_relative() if field_type: From 34f1439986bcd5acccb2809d0a14e62d2173c7b3 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 4 Sep 2022 12:21:22 +0800 Subject: [PATCH 25/42] 32686: Correct typo, add doc, and remove an unnecessary example --- src/sage/schemes/projective/proj_bdd_height.py | 6 +++--- src/sage/schemes/projective/projective_space.py | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index f4f7a831db7..a3a213246dc 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -1,7 +1,7 @@ r""" Points of bounded height in projective spaces -This module defines sunctions to compute points of bounded height of a given +This module defines functions to compute points of bounded height of a given number field with height less than a specified bound in projective spaces. Sage functions to list all elements of a given number field with height less @@ -108,7 +108,7 @@ def IQ_points_of_bounded_height(K, dim, bound): PN = ProjectiveSpace(K, dim) unit_tuples = list(itertools.product(K.roots_of_unity(), repeat=dim)) points_of_bounded_height = [] - + class_group_ideals = [c.ideal() for c in K.class_group()] class_group_ideal_norms = [i.norm() for i in class_group_ideals] class_number = len(class_group_ideals) @@ -117,7 +117,7 @@ def IQ_points_of_bounded_height(K, dim, bound): for i in range(class_number): for k in range(1, bound + 1): possible_norm_set.add(k*class_group_ideal_norms[i]) - + coordinate_space = dict() coordinate_space[0] = [K(0)] for m in possible_norm_set: diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 15d319b8f57..acaf6683143 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1902,8 +1902,6 @@ def points_of_bounded_height(self, **kwds): sage: P. = ProjectiveSpace(F, 2) sage: all([exp(p.global_height()) <= 1 for p in P.points_of_bounded_height(bound=1)]) True - sage: all([exp(p.global_height()) <= 3 for p in P.points_of_bounded_height(bound=3)]) - True :: @@ -1944,6 +1942,7 @@ def points_of_bounded_height(self, **kwds): bound = kwds.pop('bound') prec = kwds.pop('precision', 53) + # Convert between absolute and relative height for calling Krumm's algorithm bound = bound**R.absolute_degree() dim = self.dimension_relative() From 10c681c87c0de40448777a11dfc5c9e62774591c Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 4 Sep 2022 12:58:50 +0800 Subject: [PATCH 26/42] 32686: Correct some examples in hyperplane_transformation_matrix --- .../schemes/projective/projective_space.py | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index acaf6683143..06da4cc06e0 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1547,8 +1547,8 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x) sage: plane2 = P.subscheme(y) sage: m = P.hyperplane_transformation_matrix(plane1, plane2); m - [-1 -1] - [ 1 0] + [0 1] + [1 0] sage: plane2(m*P((0,1))) (1 : 0) @@ -1558,10 +1558,10 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + 2*y + z) sage: plane2 = P.subscheme(2*x + y + z) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [ -3 0 0 0] - [ 9 6 0 0] - [-3/2 -3 3/2 0] - [-1/2 -1 -1/2 1] + [ 1/2 0 0 0] + [-1/2 1 0 0] + [ 0 0 1/2 0] + [ 0 0 0 1] :: @@ -1569,8 +1569,8 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + y) sage: plane2 = P.subscheme(y) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [ 1 0] - [-1 -1] + [1 0] + [1 1] :: @@ -1580,9 +1580,9 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane2 = P.subscheme(x + v*y + v*z) sage: m = P.hyperplane_transformation_matrix(plane1, plane2) sage: m - [ -6/7*v - 2/7 0 0] - [ 2/7*v + 10/7 -4/7*v + 8/7 0] - [ -4/7*v + 1/7 -10/7*v - 8/7 1] + [-4/21*v + 23/21 10/21*v + 16/21 8/21*v + 1/7] + [ 8/21*v + 8/7 -8/21*v - 8/7 -8/21*v - 8/7] + [ 4/21*v + 5/21 -2/21*v + 8/21 1] :: @@ -1592,10 +1592,10 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(k*x + 2*k*y + z) sage: plane2 = P.subscheme(7*k*x + y + 9*z) sage: m = P.hyperplane_transformation_matrix(plane1, plane2); m - [ 297/410*k + 279/410 0 0 0] - [-3609/410*k + 4437/410 -1656/205*k + 2358/205 0 0] - [ 511/410*k - 24/205 511/205*k - 48/205 -107/205*k + 327/410 0] - [ 83/410*k - 107/205 83/205*k - 214/205 107/205*k + 83/410 1] + [ -4/65*k - 1/130 0 0 0] + [ -25/52*k - 21/52 -139/130*k + 7/130 137/260*k - 121/260 0] + [ 0 0 -4/65*k - 1/130 0] + [ 139/260*k + 123/260 139/130*k + 123/130 -123/260*k + 139/260 1] :: @@ -1627,9 +1627,9 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + 9*t*y + z) sage: plane2 = P.subscheme(x + z) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [ -1/9*t -t^2 0] - [ -t^2 + 1/9*t 0 0] - [ 1/81 1/9*t -1/9*t + 1/81] + [ -1/81 -1/9*t -1/9*t] + [-1/9*t - 1/81 t^2 + 1/9*t 1/9*t + 1/81] + [ -1/9*t -t^2 -1/81] TESTS:: From 2c4d407b911c42fdc26377ad9b418ecc4af40cfc Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 4 Sep 2022 13:15:28 +0800 Subject: [PATCH 27/42] 32686: mention Trac ticket 11328 for insert_row --- src/sage/schemes/projective/proj_bdd_height.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index a3a213246dc..31b376f96bb 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -274,6 +274,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): T = column_matrix(fund_unit_logs).delete_rows([r]).change_ring(QQ) + # insert_row only takes integers, see https://trac.sagemath.org/ticket/11328 M = ((-1)*matrix.identity(r)).insert_row(r, [Integer(1) for i in range(r)]) M = M.transpose().insert_row(0, [Integer(0) for i in range(r + 1)]).transpose() M = M.change_ring(QQ) From ac41c06e9e163d3e6ae1fd51b19f393289c779f3 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Fri, 9 Sep 2022 23:09:44 +0800 Subject: [PATCH 28/42] 32686: `bound` allows real numbers and `yield` instead of returning a list for points_of_bounded_height --- .../schemes/projective/proj_bdd_height.py | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 31b376f96bb..1f1ca0e5e1e 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -19,6 +19,8 @@ import itertools +from math import floor + from sage.schemes.projective.projective_space import ProjectiveSpace from sage.rings.rational_field import QQ from sage.rings.all import RealField @@ -66,15 +68,15 @@ def QQ_points_of_bounded_height(dim, bound): PN = ProjectiveSpace(QQ, dim) unit_tuples = list(itertools.product([-1, 1], repeat=dim)) points_of_bounded_height = set([]) - increasing_tuples = itertools.combinations_with_replacement(range(bound + 1), dim + 1) + increasing_tuples = itertools.combinations_with_replacement(range(floor(bound + 1)), dim + 1) for t in increasing_tuples: if gcd(t) == 1: for p in itertools.permutations(t): for u in unit_tuples: - new_point = [a*b for a, b in zip(u, p)] + [p[dim]] - points_of_bounded_height.add(PN(new_point)) - - return iter(points_of_bounded_height) + PN_point = PN([a*b for a, b in zip(u, p)] + [p[dim]]) + if PN_point not in points_of_bounded_height: + points_of_bounded_height.add(PN_point) + yield PN_point def IQ_points_of_bounded_height(K, dim, bound): r""" @@ -107,7 +109,6 @@ def IQ_points_of_bounded_height(K, dim, bound): PN = ProjectiveSpace(K, dim) unit_tuples = list(itertools.product(K.roots_of_unity(), repeat=dim)) - points_of_bounded_height = [] class_group_ideals = [c.ideal() for c in K.class_group()] class_group_ideal_norms = [i.norm() for i in class_group_ideals] @@ -115,7 +116,7 @@ def IQ_points_of_bounded_height(K, dim, bound): possible_norm_set = set([]) for i in range(class_number): - for k in range(1, bound + 1): + for k in range(1, ): possible_norm_set.add(k*class_group_ideal_norms[i]) coordinate_space = dict() @@ -142,12 +143,10 @@ def IQ_points_of_bounded_height(K, dim, bound): point_coordinates = [a_coordinates[i] for i in index_tuple] if a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): - for u in unit_tuples: - new_point = [i*j for i, j in zip(u, p)] + [p[dim]] - points_in_class_a.add(PN(new_point)) - points_of_bounded_height += list(points_in_class_a) - - return iter(points_of_bounded_height) + PN_point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) + if PN_point not in points_in_class_a: + points_in_class_a.add(PN_point) + yield PN_point def points_of_bounded_height(K, dim, bound, prec=53): r""" @@ -233,7 +232,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): possible_norm_set = set([]) for i in range(class_number): - for k in range(1, bound + 1): + for k in range(1, floor(bound + 1)): possible_norm_set.add(k*class_group_ideal_norms[i]) principal_ideal_gens = dict() @@ -318,7 +317,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): a_const = (logB + log_a_norm)/K_degree a_coordinates = [] - for k in range(bound + 1): + for k in range(floor(bound + 1)): norm = k * a_norm if norm in coordinate_space: for pair in coordinate_space[norm]: @@ -340,9 +339,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): if log_arch_height <= log_arch_height_bound and a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - new_point = [i*j for i, j in zip(u, p)] + [p[dim]] - points_in_class_a.add(PN(new_point)) - points_of_bdd_height += list(points_in_class_a) - - return iter(points_of_bdd_height) - + PN_point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) + if PN_point not in points_in_class_a: + points_in_class_a.add(PN_point) + yield PN_point From 37f2d72672a9ce36772ab583fb6684ac0ea775d9 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Tue, 6 Sep 2022 10:33:15 +0800 Subject: [PATCH 29/42] 32686: Change ring when no common parent --- src/sage/schemes/projective/projective_space.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 06da4cc06e0..4d7c55e5fdd 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1616,8 +1616,8 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + y + z) sage: plane2 = P.subscheme(z) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [1 0 0] - [1 1 0] + [0 1 1] + [0 0 1] [1 1 1] :: @@ -1698,7 +1698,7 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): source_points.append(self(point)) base_list = [list(s) for s in source_points] elif len(source_points) == N + 1: - Ms = matrix(base_list + [point]) + Ms = matrix(base_list + [point.change_ring(self.base_ring())]) if not any([m == 0 for m in Ms.minors(N + 1)]): source_points.append(self(point)) break From 31d0587e058db1053850c52c8dc76be59159a9a2 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sat, 10 Sep 2022 00:14:14 +0800 Subject: [PATCH 30/42] 32686: Change some example outputs --- src/sage/schemes/projective/proj_bdd_height.py | 4 ++-- src/sage/schemes/projective/projective_space.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 1f1ca0e5e1e..fcd8557f459 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -51,8 +51,8 @@ def QQ_points_of_bounded_height(dim, bound): EXAMPLES: sage: from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height - sage: list(QQ_points_of_bounded_height(1, 1)) - [(0 : 1), (1 : 0), (1 : 1), (-1 : 1)] + sage: sorted(list(QQ_points_of_bounded_height(1, 1))) + [(-1 : 1), (0 : 1), (1 : 0), (1 : 1)] sage: len(list(QQ_points_of_bounded_height(1, 5))) 40 diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 4d7c55e5fdd..806386b7151 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1892,8 +1892,8 @@ def points_of_bounded_height(self, **kwds): sage: L. = CF.extension(x^3 + 2) sage: Q. = ProjectiveSpace(L, 1) sage: sorted(list(Q.points_of_bounded_height(bound=1))) - [(0 : 1), (a : 1), (a + 1 : 1), (-a - 1 : 1), - (-a : 1), (-1 : 1), (1 : 1), (1 : 0)] + [(0 : 1), (1 : 0), (a + 1 : 1), (a : 1), + (-1 : 1), (-a - 1 : 1), (-a : 1), (1 : 1)] :: From 8afc292bef6d28bba6bd2fc6d6347ef0f3565f7b Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sat, 10 Sep 2022 12:36:46 +0800 Subject: [PATCH 31/42] 32686: Debug `IQ_points_of_bounded_height` --- src/sage/schemes/projective/proj_bdd_height.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index fcd8557f459..8b0f04aaaa8 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -116,7 +116,7 @@ def IQ_points_of_bounded_height(K, dim, bound): possible_norm_set = set([]) for i in range(class_number): - for k in range(1, ): + for k in range(1, floor(bound + 1)): possible_norm_set.add(k*class_group_ideal_norms[i]) coordinate_space = dict() @@ -143,10 +143,11 @@ def IQ_points_of_bounded_height(K, dim, bound): point_coordinates = [a_coordinates[i] for i in index_tuple] if a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): - PN_point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) - if PN_point not in points_in_class_a: - points_in_class_a.add(PN_point) - yield PN_point + for u in unit_tuples: + PN_point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) + if PN_point not in points_in_class_a: + points_in_class_a.add(PN_point) + yield PN_point def points_of_bounded_height(K, dim, bound, prec=53): r""" From b3b05c8d3a852ab14fbb01a092002eacf225d0bd Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sat, 10 Sep 2022 12:51:51 +0800 Subject: [PATCH 32/42] 32686: Change example outputs --- .../schemes/projective/projective_space.py | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 806386b7151..9d60f748799 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1558,10 +1558,10 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + 2*y + z) sage: plane2 = P.subscheme(2*x + y + z) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [ 1/2 0 0 0] - [-1/2 1 0 0] - [ 0 0 1/2 0] - [ 0 0 0 1] + [1 0 0 0] + [0 4 0 0] + [0 0 2 0] + [0 0 0 1] :: @@ -1569,8 +1569,8 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + y) sage: plane2 = P.subscheme(y) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [1 0] - [1 1] + [-1 0] + [ 1 1] :: @@ -1580,9 +1580,9 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane2 = P.subscheme(x + v*y + v*z) sage: m = P.hyperplane_transformation_matrix(plane1, plane2) sage: m - [-4/21*v + 23/21 10/21*v + 16/21 8/21*v + 1/7] - [ 8/21*v + 8/7 -8/21*v - 8/7 -8/21*v - 8/7] - [ 4/21*v + 5/21 -2/21*v + 8/21 1] + [ v 0 0] + [ 0 -2*v 0] + [ 0 0 1] :: @@ -1592,10 +1592,10 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(k*x + 2*k*y + z) sage: plane2 = P.subscheme(7*k*x + y + 9*z) sage: m = P.hyperplane_transformation_matrix(plane1, plane2); m - [ -4/65*k - 1/130 0 0 0] - [ -25/52*k - 21/52 -139/130*k + 7/130 137/260*k - 121/260 0] - [ 0 0 -4/65*k - 1/130 0] - [ 139/260*k + 123/260 139/130*k + 123/130 -123/260*k + 139/260 1] + [ 1 0 0 0] + [ 0 14*k 0 0] + [ 0 0 7/9 0] + [ 0 0 0 1] :: @@ -1616,8 +1616,8 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + y + z) sage: plane2 = P.subscheme(z) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [0 1 1] - [0 0 1] + [1 0 0] + [1 1 0] [1 1 1] :: @@ -1627,9 +1627,9 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + 9*t*y + z) sage: plane2 = P.subscheme(x + z) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [ -1/81 -1/9*t -1/9*t] - [-1/9*t - 1/81 t^2 + 1/9*t 1/9*t + 1/81] - [ -1/9*t -t^2 -1/81] + [ 1 9*t 0] + [ 1 0 0] + [ 0 0 1] TESTS:: From 5958fc6c65d31535b9580837ef4e614d3432a0cb Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 14 Sep 2022 11:35:59 +0800 Subject: [PATCH 33/42] 32686: Improve doc and return points in `self` --- .../schemes/projective/proj_bdd_height.py | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 8b0f04aaaa8..421fe48381a 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -35,8 +35,8 @@ def QQ_points_of_bounded_height(dim, bound): r""" - Return an iterator of the points in ``self`` of absolute height of - at most ``bound`` in the rational field. + Return an iterator of the points in ``self`` of absolute multiplicative + height of at most ``bound`` in the rational field. INPUT: @@ -65,7 +65,6 @@ def QQ_points_of_bounded_height(dim, bound): if bound < 1: return iter(set([])) - PN = ProjectiveSpace(QQ, dim) unit_tuples = list(itertools.product([-1, 1], repeat=dim)) points_of_bounded_height = set([]) increasing_tuples = itertools.combinations_with_replacement(range(floor(bound + 1)), dim + 1) @@ -73,15 +72,15 @@ def QQ_points_of_bounded_height(dim, bound): if gcd(t) == 1: for p in itertools.permutations(t): for u in unit_tuples: - PN_point = PN([a*b for a, b in zip(u, p)] + [p[dim]]) - if PN_point not in points_of_bounded_height: - points_of_bounded_height.add(PN_point) - yield PN_point + point = self([a*b for a, b in zip(u, p)] + [p[dim]]) + if point not in points_of_bounded_height: + points_of_bounded_height.add(point) + yield point def IQ_points_of_bounded_height(K, dim, bound): r""" - Return an iterator of the points in ``self`` of absolute height of - at most ``bound`` in the imaginary quadratic field ``K``. + Return an iterator of the points in ``self`` of absolute multiplicative + height of at most ``bound`` in the imaginary quadratic field ``K``. INPUT: @@ -107,7 +106,6 @@ def IQ_points_of_bounded_height(K, dim, bound): if bound < 1: return iter([]) - PN = ProjectiveSpace(K, dim) unit_tuples = list(itertools.product(K.roots_of_unity(), repeat=dim)) class_group_ideals = [c.ideal() for c in K.class_group()] @@ -144,15 +142,15 @@ def IQ_points_of_bounded_height(K, dim, bound): if a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - PN_point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) - if PN_point not in points_in_class_a: - points_in_class_a.add(PN_point) - yield PN_point + point = self([i*j for i, j in zip(u, p)] + [p[dim]]) + if point not in points_in_class_a: + points_in_class_a.add(point) + yield point def points_of_bounded_height(K, dim, bound, prec=53): r""" Return an iterator of the points in ``K`` with dimension ``dim`` of - absolute height of at most ``bound``. + absolute multiplicative height of at most ``bound``. ALGORITHM: @@ -194,7 +192,6 @@ def points_of_bounded_height(K, dim, bound, prec=53): roots_of_unity = K.roots_of_unity() unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) - PN = ProjectiveSpace(K, dim) log_embed = K.logarithmic_embedding() Reals = RealField(prec) @@ -340,7 +337,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): if log_arch_height <= log_arch_height_bound and a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - PN_point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) - if PN_point not in points_in_class_a: - points_in_class_a.add(PN_point) - yield PN_point + point = self([i*j for i, j in zip(u, p)] + [p[dim]]) + if point not in points_in_class_a: + points_in_class_a.add(point) + yield point From 1c80864f268e410aa7dfcc3598a9036579b0be7b Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 14 Sep 2022 11:52:40 +0800 Subject: [PATCH 34/42] 32686: Change `self` to `K` in non-rational points_of_bounded_height --- src/sage/schemes/projective/proj_bdd_height.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 421fe48381a..b48625b58e3 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -65,6 +65,7 @@ def QQ_points_of_bounded_height(dim, bound): if bound < 1: return iter(set([])) + PN = ProjectiveSpace(QQ, dim) unit_tuples = list(itertools.product([-1, 1], repeat=dim)) points_of_bounded_height = set([]) increasing_tuples = itertools.combinations_with_replacement(range(floor(bound + 1)), dim + 1) @@ -72,7 +73,7 @@ def QQ_points_of_bounded_height(dim, bound): if gcd(t) == 1: for p in itertools.permutations(t): for u in unit_tuples: - point = self([a*b for a, b in zip(u, p)] + [p[dim]]) + point = PN([a*b for a, b in zip(u, p)] + [p[dim]]) if point not in points_of_bounded_height: points_of_bounded_height.add(point) yield point @@ -142,7 +143,7 @@ def IQ_points_of_bounded_height(K, dim, bound): if a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - point = self([i*j for i, j in zip(u, p)] + [p[dim]]) + point = K([i*j for i, j in zip(u, p)] + [p[dim]]) if point not in points_in_class_a: points_in_class_a.add(point) yield point @@ -337,7 +338,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): if log_arch_height <= log_arch_height_bound and a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - point = self([i*j for i, j in zip(u, p)] + [p[dim]]) + point = K([i*j for i, j in zip(u, p)] + [p[dim]]) if point not in points_in_class_a: points_in_class_a.add(point) yield point From 5ec496e2a408c0d59f935252b32e4f91d6992740 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 14 Sep 2022 12:03:27 +0800 Subject: [PATCH 35/42] 32686: Add `PN` to args of non-rational points_bdd --- src/sage/schemes/projective/proj_bdd_height.py | 16 +++++++++++----- src/sage/schemes/projective/projective_space.py | 4 ++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index b48625b58e3..5f0bac1d35f 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -78,13 +78,15 @@ def QQ_points_of_bounded_height(dim, bound): points_of_bounded_height.add(point) yield point -def IQ_points_of_bounded_height(K, dim, bound): +def IQ_points_of_bounded_height(PN, K, dim, bound): r""" Return an iterator of the points in ``self`` of absolute multiplicative height of at most ``bound`` in the imaginary quadratic field ``K``. INPUT: + - ``PN`` -- a projective space + - ``K`` -- a number field - ``dim`` -- a positive interger @@ -99,7 +101,8 @@ def IQ_points_of_bounded_height(K, dim, bound): sage: from sage.schemes.projective.proj_bdd_height import IQ_points_of_bounded_height sage: CF. = CyclotomicField(3) - sage: len(list(IQ_points_of_bounded_height(CF, 2, -1))) + sage: P. = ProjectiveSpace(CF, 2) + sage: len(list(IQ_points_of_bounded_height(P, CF, 2, -1))) 0 sage: len(list(IQ_points_of_bounded_height(CF, 2, 1))) 57 @@ -143,12 +146,12 @@ def IQ_points_of_bounded_height(K, dim, bound): if a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - point = K([i*j for i, j in zip(u, p)] + [p[dim]]) + point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) if point not in points_in_class_a: points_in_class_a.add(point) yield point -def points_of_bounded_height(K, dim, bound, prec=53): +def points_of_bounded_height(PN, K, dim, bound, prec=53): r""" Return an iterator of the points in ``K`` with dimension ``dim`` of absolute multiplicative height of at most ``bound``. @@ -159,6 +162,8 @@ def points_of_bounded_height(K, dim, bound, prec=53): INPUT: + - ``PN`` -- a projective space + - ``K`` -- a number field - ``dim`` -- a positive interger @@ -175,6 +180,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height sage: K. = NumberField(x^3 - 7) + sage: P. = ProjectiveSpace(K, 2) sage: len(list(points_of_bounded_height(K, 2, 1))) 13 """ @@ -338,7 +344,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): if log_arch_height <= log_arch_height_bound and a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - point = K([i*j for i, j in zip(u, p)] + [p[dim]]) + point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) if point not in points_in_class_a: points_in_class_a.add(point) yield point diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 9d60f748799..b882767edbe 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1958,9 +1958,9 @@ def points_of_bounded_height(self, **kwds): deg = R.degree() if deg == 2 and r == 0: - return IQ_points_of_bounded_height(R, dim, bound) + return IQ_points_of_bounded_height(self, R, dim, bound) - return points_of_bounded_height(R, dim, bound, prec) + return points_of_bounded_height(self, R, dim, bound, prec) else: return QQ_points_of_bounded_height(dim, bound) From 2adb101bc163c52a029181a7df3ad91acc0c41ed Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 14 Sep 2022 12:10:26 +0800 Subject: [PATCH 36/42] 32686: Correct tests --- src/sage/schemes/projective/proj_bdd_height.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 5f0bac1d35f..0cc57507158 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -104,7 +104,7 @@ def IQ_points_of_bounded_height(PN, K, dim, bound): sage: P. = ProjectiveSpace(CF, 2) sage: len(list(IQ_points_of_bounded_height(P, CF, 2, -1))) 0 - sage: len(list(IQ_points_of_bounded_height(CF, 2, 1))) + sage: len(list(IQ_points_of_bounded_height(P, CF, 2, 1))) 57 """ if bound < 1: @@ -181,7 +181,7 @@ def points_of_bounded_height(PN, K, dim, bound, prec=53): sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height sage: K. = NumberField(x^3 - 7) sage: P. = ProjectiveSpace(K, 2) - sage: len(list(points_of_bounded_height(K, 2, 1))) + sage: len(list(points_of_bounded_height(P, K, 2, 1))) 13 """ if bound < 1: From a23735269b76390cc7dde97c500d0d9974510ff7 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 14 Sep 2022 12:17:04 +0800 Subject: [PATCH 37/42] 32686: Improve doc --- src/sage/schemes/projective/projective_space.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index b882767edbe..c68157714eb 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1852,8 +1852,8 @@ def _morphism(self, *args, **kwds): def points_of_bounded_height(self, **kwds): r""" - Return an iterator of the points in ``self`` of absolute height of - at most the given bound. + Return an iterator of the points in ``self`` of absolute multiplicative + height of at most the given bound. ALGORITHM: From 00af5c7d5f07ce95060549ef74ac1a2439f1cc13 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 22 Sep 2022 14:37:48 +0800 Subject: [PATCH 38/42] 32686: Correct doc and add an example --- src/sage/schemes/projective/projective_space.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index c68157714eb..7facb20875f 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1863,7 +1863,7 @@ def points_of_bounded_height(self, **kwds): kwds: - - ``bound`` - an integer + - ``bound`` - a real number - ``precision`` - (default: 53) a positive integer @@ -1925,6 +1925,14 @@ def points_of_bounded_height(self, **kwds): sage: P. = ProjectiveSpace(K, 1) sage: len(list(P.points_of_bounded_height(bound=2))) 108 + + :: + + R. = QQ[] + K. = NumberField(x^5 + x^3 + 1) + P. = ProjectiveSpace(K, 2) + L = P.points_of_bounded_height(bound=1.2) + 0 """ from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, IQ_points_of_bounded_height, points_of_bounded_height From 98a467602c4f4959cb847963ad08ade3334841b9 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 22 Sep 2022 15:16:57 +0800 Subject: [PATCH 39/42] 32686: Correct example --- src/sage/schemes/projective/projective_space.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 7facb20875f..117e071a67b 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1928,11 +1928,12 @@ def points_of_bounded_height(self, **kwds): :: - R. = QQ[] - K. = NumberField(x^5 + x^3 + 1) - P. = ProjectiveSpace(K, 2) - L = P.points_of_bounded_height(bound=1.2) - 0 + sage: R. = QQ[] + sage: K. = NumberField(x^5 + x^3 + 1) + sage: P. = ProjectiveSpace(K, 2) + sage: L = P.points_of_bounded_height(bound=1.2) + sage: len(list(L)) + 109 """ from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, IQ_points_of_bounded_height, points_of_bounded_height From c4aab9f9dc11d787945fad21be16beee4b025456 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 6 Oct 2022 12:14:43 +0800 Subject: [PATCH 40/42] 32686: Remove unused imports and variables --- src/sage/schemes/projective/proj_bdd_height.py | 3 --- src/sage/schemes/projective/projective_space.py | 1 - 2 files changed, 4 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 0cc57507158..c36ca173fd9 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -195,7 +195,6 @@ def points_of_bounded_height(PN, K, dim, bound, prec=53): else: K_degree = K.degree() - K_embeddings = K.places(prec=prec) roots_of_unity = K.roots_of_unity() unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) @@ -204,8 +203,6 @@ def points_of_bounded_height(PN, K, dim, bound, prec=53): Reals = RealField(prec) logB = Reals(bound).log() - points_of_bdd_height = [] - class_group_ideals = [c.ideal() for c in K.class_group()] class_number = len(class_group_ideals) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 117e071a67b..e4d100caa1e 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -80,7 +80,6 @@ # **************************************************************************** from sage.arith.misc import gcd, binomial -from sage.arith.srange import srange from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.rings.integer import Integer From 10df9a648550ddf79315e9a6c9843eed01415d08 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Fri, 7 Oct 2022 14:41:46 +0800 Subject: [PATCH 41/42] 32686: Correct example outputs in various files --- .../arithmetic_dynamics/projective_ds.py | 26 ++++++++++--------- .../schemes/projective/projective_homset.py | 2 +- .../projective/projective_rational_point.py | 3 +-- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index cdfc11a9e52..f6d811f972a 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -3072,13 +3072,18 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): sage: g = f.affine_preperiodic_model(0, 1); g Dynamical System of Projective Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x : y : z) to - (-x^2 : 2*x^2 + 2*x*y + y^2 : 2*x^2 + 2*x*y + 2*y^2 - 2*y*z + z^2) + (-x^2 : -2*x^2 + 2*x*y - y^2 : 2*x^2 - 2*x*y + 2*y^2 + 2*y*z + z^2) We can check that ``g`` has affine fixed points:: sage: g.periodic_points(1) - [(-1 : 1 : 1), (-1/2 : 1/2 : 1), (-1/2 : 1 : 1), (-1/3 : 2/3 : 1), (0 : 0 : 1), - (0 : 1/2 : 1), (0 : 1 : 1)] + [(-1 : -1 : 1), + (-1/2 : -1 : 1), + (-1/2 : -1/2 : 1), + (-1/3 : -2/3 : 1), + (0 : -1 : 1), + (0 : -1/2 : 1), + (0 : 0 : 1)] :: @@ -3087,8 +3092,8 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): sage: f.affine_preperiodic_model(0, 1) Dynamical System of Projective Space of dimension 2 over Finite Field in z2 of size 3^2 Defn: Defined on coordinates by sending (x : y : z) to - ((z2 + 1)*x^2 : (z2 + 1)*x^2 + (z2 + 1)*x*y + (-z2 - 1)*y^2 : - (z2 - 1)*x^2 + (z2 - 1)*x*y - y^2 + (-z2)*y*z + z^2) + ((-z2)*x^2 : z2*x^2 + (-z2)*x*y + (-z2)*y^2 : + (-z2)*x^2 + z2*x*y + (z2 + 1)*y^2 - y*z + z^2) :: @@ -3099,9 +3104,8 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): Dynamical System of Projective Space of dimension 2 over Univariate Polynomial Ring in c over Finite Field of size 3 Defn: Defined on coordinates by sending (x : y : z) to - ((2*c^4 + c^3)*x^2 : (2*c^4 + c^3)*x^2 + (2*c^4 + c^3)*x*y + (c^4 + 2*c^3)*y^2 : - c^3*x^2 + c^3*x*y + (2*c^3 + 2*c^2)*y^2 + (c^3 + 2*c^2)*y*z + (2*c^4 + 2*c^3 + - 2*c^2)*z^2) + (2*c^3*x^2 : c^3*x^2 + 2*c^3*x*y + 2*c^3*y^2 : + 2*c^3*x^2 + c^3*x*y + (c^3 + c^2)*y^2 + 2*c^2*y*z + c^2*z^2) :: @@ -3112,8 +3116,7 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): Dynamical System of Projective Space of dimension 2 over Cyclotomic Field of order 3 and degree 2 Defn: Defined on coordinates by sending (x : y : z) to - (x^2 + y^2 + (-k + 2)*x*z - 2*y*z + (-k + 3)*z^2 : - -2*x^2 + (k - 4)*x*z + (k - 3)*z^2 : -x^2 + (k - 2)*x*z + (k - 2)*z^2) + (-y^2 : x^2 : x^2 + (-k)*x*z + z^2) :: @@ -3132,8 +3135,7 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): Dynamical System of Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: 2*y - z Defn: Defined on coordinates by sending (x : y : z) to - (2*x^2 + y^2 + 4*x*z - 2*y*z + 4*z^2 : -x^2 - y^2 - 2*x*z + 2*y*z - 3*z^2 : - -x^2 - 2*x*z - 2*z^2) + (-x^2 - y^2 : y^2 : x^2 + z^2) TESTS:: diff --git a/src/sage/schemes/projective/projective_homset.py b/src/sage/schemes/projective/projective_homset.py index 0f7b6abce52..f9a8e69bd4b 100644 --- a/src/sage/schemes/projective/projective_homset.py +++ b/src/sage/schemes/projective/projective_homset.py @@ -124,7 +124,7 @@ def points(self, **kwds): sage: K. = NumberField(u^2 + 3) sage: P. = ProjectiveSpace(K,2) sage: len(P(K).points(bound=1.8)) - 381 + 309 :: diff --git a/src/sage/schemes/projective/projective_rational_point.py b/src/sage/schemes/projective/projective_rational_point.py index 93789be8d65..cb12e30c873 100644 --- a/src/sage/schemes/projective/projective_rational_point.py +++ b/src/sage/schemes/projective/projective_rational_point.py @@ -191,8 +191,7 @@ def enum_projective_number_field(X, **kwds): sage: P. = ProjectiveSpace(K, 2) sage: X = P.subscheme([x - y]) sage: enum_projective_number_field(X(K), bound=RR(5^(1/3)), prec=2^10) - [(0 : 0 : 1), (-1 : -1 : 1), (1 : 1 : 1), (-1/5*v^2 : -1/5*v^2 : 1), (-v : -v : 1), - (1/5*v^2 : 1/5*v^2 : 1), (v : v : 1), (1 : 1 : 0)] + [(0 : 0 : 1), (1 : 1 : 0), (-1 : -1 : 1), (1 : 1 : 1)] :: From c053c2ac5367b08f553d6dd3d4fa86dec14bc09d Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Fri, 7 Oct 2022 18:42:27 +0800 Subject: [PATCH 42/42] 32686: Format according to lint result --- src/sage/schemes/projective/proj_bdd_height.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index c36ca173fd9..33d5ec1d3bc 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -78,6 +78,7 @@ def QQ_points_of_bounded_height(dim, bound): points_of_bounded_height.add(point) yield point + def IQ_points_of_bounded_height(PN, K, dim, bound): r""" Return an iterator of the points in ``self`` of absolute multiplicative @@ -151,6 +152,7 @@ def IQ_points_of_bounded_height(PN, K, dim, bound): points_in_class_a.add(point) yield point + def points_of_bounded_height(PN, K, dim, bound, prec=53): r""" Return an iterator of the points in ``K`` with dimension ``dim`` of @@ -218,9 +220,9 @@ def points_of_bounded_height(PN, K, dim, bound, prec=53): test_matrix = mat try: - test_matrix.change_ring(QQ) + test_matrix.change_ring(QQ) except ValueError: - raise ValueError('prec too low.') + raise ValueError('prec too low.') cut_fund_unit_logs = mat.delete_rows([r]) lll_fund_units = []