diff --git a/src/sage/schemes/affine/affine_homset.py b/src/sage/schemes/affine/affine_homset.py index 914e54f7148..5a75d699c52 100644 --- a/src/sage/schemes/affine/affine_homset.py +++ b/src/sage/schemes/affine/affine_homset.py @@ -210,14 +210,14 @@ def points(self, **kwds): EXAMPLES: The bug reported at #11526 is fixed:: sage: A2 = AffineSpace(ZZ, 2) - sage: F = GF(3) - sage: A2(F).points() + sage: F = GF(3) # optional - sage.rings.finite_rings + sage: A2(F).points() # optional - sage.rings.finite_rings [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] :: sage: A. = ZZ[] - sage: I = A.ideal(x^2-y^2-1) + sage: I = A.ideal(x^2 - y^2 - 1) sage: V = AffineSpace(ZZ, 2) sage: X = V.subscheme(I) sage: M = X(ZZ) @@ -227,9 +227,9 @@ def points(self, **kwds): :: sage: u = QQ['u'].0 - sage: K. = NumberField(u^2 + 3) - sage: A. = AffineSpace(K, 2) - sage: len(A(K).points(bound=2)) + sage: K. = NumberField(u^2 + 3) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: len(A(K).points(bound=2)) # optional - sage.rings.number_field 1849 :: @@ -244,16 +244,20 @@ def points(self, **kwds): sage: A. = AffineSpace(CC, 2) sage: E = A.subscheme([y^3 - x^3 - x^2, x*y]) sage: E(A.base_ring()).points() - verbose 0 (...: affine_homset.py, points) Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly. + verbose 0 (...: affine_homset.py, points) + Warning: computations in the numerical fields are inexact;points + may be computed partially or incorrectly. [(-1.00000000000000, 0.000000000000000), - (0.000000000000000, 0.000000000000000)] + (0.000000000000000, 0.000000000000000)] :: sage: A. = AffineSpace(CDF, 2) sage: E = A.subscheme([x1^2 + x2^2 + x1*x2, x1 + x2]) sage: E(A.base_ring()).points() - verbose 0 (...: affine_homset.py, points) Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly. + verbose 0 (...: affine_homset.py, points) + Warning: computations in the numerical fields are inexact;points + may be computed partially or incorrectly. [(0.0, 0.0)] """ from sage.schemes.affine.affine_space import is_AffineSpace @@ -388,14 +392,14 @@ def numerical_points(self, F=None, **kwds): EXAMPLES:: - sage: K. = QuadraticField(3) - sage: A. = AffineSpace(K, 2) - sage: X = A.subscheme([x^3 - v^2*y, y - v*x^2 + 3]) - sage: L = X(K).numerical_points(F=RR); L # abs tol 1e-14 + sage: K. = QuadraticField(3) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: X = A.subscheme([x^3 - v^2*y, y - v*x^2 + 3]) # optional - sage.rings.number_field + sage: L = X(K).numerical_points(F=RR); L # abs tol 1e-14 # optional - sage.rings.number_field [(-1.18738247880014, -0.558021142104134), (1.57693558184861, 1.30713548084184), (4.80659931965815, 37.0162574656220)] - sage: L[0].codomain() + sage: L[0].codomain() # optional - sage.rings.number_field Affine Space of dimension 2 over Real Field with 53 bits of precision :: diff --git a/src/sage/schemes/affine/affine_morphism.py b/src/sage/schemes/affine/affine_morphism.py index b61b011f979..ed82a6d52bf 100644 --- a/src/sage/schemes/affine/affine_morphism.py +++ b/src/sage/schemes/affine/affine_morphism.py @@ -13,14 +13,12 @@ sage: P2. = ProjectiveSpace(QQ, 2) sage: A2.hom([x, x + y], A2) Scheme endomorphism of Affine Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (x, x + y) + Defn: Defined on coordinates by sending (x, y) to (x, x + y) sage: A2.hom([1, x, x + y], P2) Scheme morphism: From: Affine Space of dimension 2 over Rational Field To: Projective Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (1 : x : x + y) + Defn: Defined on coordinates by sending (x, y) to (1 : x : x + y) AUTHORS: @@ -95,8 +93,7 @@ class SchemeMorphism_polynomial_affine_space(SchemeMorphism_polynomial): Scheme morphism: From: Affine Space of dimension 2 over Rational Field To: Projective Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (x : y : 1) + Defn: Defined on coordinates by sending (x, y) to (x : y : 1) """ def __init__(self, parent, polys, check=True): r""" @@ -134,20 +131,17 @@ def __init__(self, parent, polys, check=True): sage: H = Hom(A, A) sage: H([3/2*x^2, y^2]) Scheme endomorphism of Affine Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (3/2*x^2, y^2) + Defn: Defined on coordinates by sending (x, y) to (3/2*x^2, y^2) :: sage: A. = AffineSpace(QQ, 2) - sage: X = A.subscheme([x-y^2]) + sage: X = A.subscheme([x - y^2]) sage: H = Hom(X, X) sage: H([9/4*x^2, 3/2*y]) Scheme endomorphism of Closed subscheme of Affine Space of dimension 2 - over Rational Field defined by: - -y^2 + x - Defn: Defined on coordinates by sending (x, y) to - (9/4*x^2, 3/2*y) + over Rational Field defined by: -y^2 + x + Defn: Defined on coordinates by sending (x, y) to (9/4*x^2, 3/2*y) sage: P. = ProjectiveSpace(ZZ, 2) sage: H = Hom(P, P) @@ -160,21 +154,19 @@ def __init__(self, parent, polys, check=True): If you pass in quotient ring elements, they are reduced:: sage: A. = AffineSpace(QQ, 3) - sage: X = A.subscheme([x-y]) - sage: H = Hom(X,X) + sage: X = A.subscheme([x - y]) + sage: H = Hom(X, X) sage: u,v,w = X.coordinate_ring().gens() - sage: H([u, v, u+v]) + sage: H([u, v, u + v]) Scheme endomorphism of Closed subscheme of Affine Space of dimension 3 - over Rational Field defined by: - x - y - Defn: Defined on coordinates by sending (x, y, z) to - (y, y, 2*y) + over Rational Field defined by: x - y + Defn: Defined on coordinates by sending (x, y, z) to (y, y, 2*y) You must use the ambient space variables to create rational functions:: sage: A. = AffineSpace(QQ, 3) - sage: X = A.subscheme([x^2-y^2]) - sage: H = Hom(X,X) + sage: X = A.subscheme([x^2 - y^2]) + sage: H = Hom(X, X) sage: u,v,w = X.coordinate_ring().gens() sage: H([u, v, (u+1)/v]) Traceback (most recent call last): @@ -182,7 +174,7 @@ def __init__(self, parent, polys, check=True): ArithmeticError: Division failed. The numerator is not a multiple of the denominator. sage: H([x, y, (x+1)/y]) Scheme endomorphism of Closed subscheme of Affine Space of dimension 3 - over Rational Field defined by: + over Rational Field defined by: x^2 - y^2 Defn: Defined on coordinates by sending (x, y, z) to (x, y, (x + 1)/y) @@ -191,11 +183,11 @@ def __init__(self, parent, polys, check=True): sage: R. = PolynomialRing(QQ) sage: A. = AffineSpace(R, 3) - sage: X = A.subscheme(x^2-y^2) + sage: X = A.subscheme(x^2 - y^2) sage: H = End(X) sage: H([x^2/(t*y), t*y^2, x*z]) Scheme endomorphism of Closed subscheme of Affine Space of dimension 3 - over Univariate Polynomial Ring in t over Rational Field defined by: + over Univariate Polynomial Ring in t over Rational Field defined by: x^2 - y^2 Defn: Defined on coordinates by sending (x, y, z) to (x^2/(t*y), t*y^2, x*z) @@ -239,7 +231,7 @@ def __call__(self, x, check=True): sage: P. = AffineSpace(QQ, 3) sage: H = Hom(P, P) - sage: f = H([x^2+y^2, y^2, z^2 + y*z]) + sage: f = H([x^2 + y^2, y^2, z^2 + y*z]) sage: f(P([1, 1, 1])) (2, 1, 2) @@ -256,13 +248,13 @@ def __call__(self, x, check=True): Defn: Defined on coordinates by sending (u, v) to (u + v, u*v) - sage: F. = GF(4) - sage: P = T(F)(1, a) - sage: h(P) + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: P = T(F)(1, a) # optional - sage.rings.finite_rings + sage: h(P) # optional - sage.rings.finite_rings (a + 1, a) - sage: h(P).domain() + sage: h(P).domain() # optional - sage.rings.finite_rings Spectrum of Finite Field in a of size 2^2 - sage: h.change_ring(F)(P) + sage: h.change_ring(F)(P) # optional - sage.rings.finite_rings (a + 1, a) """ from sage.schemes.affine.affine_point import SchemeMorphism_point_affine @@ -334,7 +326,7 @@ def __ne__(self, right): sage: A. = AffineSpace(RR, 2) sage: H = End(A) sage: f = H([x^2 - y, y^2]) - sage: g = H([x^3-x*y, x*y^2]) + sage: g = H([x^3 - x*y, x*y^2]) sage: f != g True sage: f != f @@ -355,7 +347,7 @@ def _fastpolys(self): sage: P. = AffineSpace(QQ, 2) sage: H = Hom(P, P) - sage: f = H([x^2+y^2, y^2/(1+x)]) + sage: f = H([x^2 + y^2, y^2/(1+x)]) sage: [t.op_list() for g in f._fastpolys for t in g] [[('load_const', 0), ('load_const', 1), ('load_arg', ...), ('ipow', 2), 'mul', 'add', ('load_const', 1), ('load_arg', ...), ('ipow', 2), 'mul', @@ -410,7 +402,7 @@ def _fast_eval(self, x): sage: P. = AffineSpace(QQ, 3) sage: H = Hom(P, P) - sage: f = H([x^2+y^2, y^2, z^2 + y*z]) + sage: f = H([x^2 + y^2, y^2, z^2 + y*z]) sage: f._fast_eval([1, 1, 1]) [2, 1, 2] @@ -464,58 +456,56 @@ def homogenize(self, n): sage: A. = AffineSpace(CC, 2) sage: H = Hom(A, A) - sage: f = H([(x^2-2)/(x*y), y^2-x]) + sage: f = H([(x^2-2)/(x*y), y^2 - x]) sage: f.homogenize((2, 0)) Scheme endomorphism of Projective Space of dimension 2 - over Complex Field with 53 bits of precision - Defn: Defined on coordinates by sending (x0 : x1 : x2) to - (x0*x1*x2^2 : x0^2*x2^2 + (-2.00000000000000)*x2^4 : x0*x1^3 - x0^2*x1*x2) + over Complex Field with 53 bits of precision + Defn: Defined on coordinates by sending (x0 : x1 : x2) to + (x0*x1*x2^2 : x0^2*x2^2 + (-2.00000000000000)*x2^4 : x0*x1^3 - x0^2*x1*x2) :: sage: A. = AffineSpace(ZZ, 2) - sage: X = A.subscheme([x-y^2]) + sage: X = A.subscheme([x - y^2]) sage: H = Hom(X, X) sage: f = H([9*y^2, 3*y]) sage: f.homogenize(2) Scheme endomorphism of Closed subscheme of Projective Space - of dimension 2 over Integer Ring defined by: - x1^2 - x0*x2 - Defn: Defined on coordinates by sending (x0 : x1 : x2) to - (9*x1^2 : 3*x1*x2 : x2^2) + of dimension 2 over Integer Ring defined by: x1^2 - x0*x2 + Defn: Defined on coordinates by sending (x0 : x1 : x2) to + (9*x1^2 : 3*x1*x2 : x2^2) :: sage: R. = PolynomialRing(ZZ) sage: A. = AffineSpace(R, 2) sage: H = Hom(A, A) - sage: f = H([(x^2-2)/y, y^2-x]) + sage: f = H([(x^2-2)/y, y^2 - x]) sage: f.homogenize((2, 0)) Scheme endomorphism of Projective Space of dimension 2 - over Univariate Polynomial Ring in t over Integer Ring - Defn: Defined on coordinates by sending (x0 : x1 : x2) to - (x1*x2^2 : x0^2*x2 + (-2)*x2^3 : x1^3 - x0*x1*x2) + over Univariate Polynomial Ring in t over Integer Ring + Defn: Defined on coordinates by sending (x0 : x1 : x2) to + (x1*x2^2 : x0^2*x2 + (-2)*x2^3 : x1^3 - x0*x1*x2) :: sage: A. = AffineSpace(QQ, 1) sage: H = End(A) - sage: f = H([x^2-1]) + sage: f = H([x^2 - 1]) sage: f.homogenize((1, 0)) - Scheme endomorphism of Projective Space of dimension 1 - over Rational Field - Defn: Defined on coordinates by sending (x0 : x1) to - (x1^2 : x0^2 - x1^2) + Scheme endomorphism of Projective Space of dimension 1 over Rational Field + Defn: Defined on coordinates by sending (x0 : x1) to + (x1^2 : x0^2 - x1^2) :: - sage: R. = PolynomialRing(QQbar) - sage: A. = AffineSpace(R, 2) - sage: H = End(A) - sage: f = H([QQbar(sqrt(2))*x*y, a*x^2]) - sage: f.homogenize(2) - Scheme endomorphism of Projective Space of dimension 2 over Univariate - Polynomial Ring in a over Algebraic Field + sage: R. = PolynomialRing(QQbar) # optional - sage.rings.number_field + sage: A. = AffineSpace(R, 2) # optional - sage.rings.number_field + sage: H = End(A) # optional - sage.rings.number_field + sage: f = H([QQbar(sqrt(2))*x*y, a*x^2]) # optional - sage.rings.number_field sage.symbolic + sage: f.homogenize(2) # optional - sage.rings.number_field sage.symbolic + Scheme endomorphism of Projective Space of dimension 2 + over Univariate Polynomial Ring in a over Algebraic Field Defn: Defined on coordinates by sending (x0 : x1 : x2) to (1.414213562373095?*x0*x1 : a*x0^2 : x2^2) @@ -533,38 +523,39 @@ def homogenize(self, n): sage: A. = AffineSpace(K, 1) sage: f = Hom(A, A)([x^2 + c]) sage: f.homogenize(1) - Scheme endomorphism of Projective Space of - dimension 1 over Rational function field in c over Rational Field + Scheme endomorphism of Projective Space of dimension 1 + over Rational function field in c over Rational Field Defn: Defined on coordinates by sending (x0 : x1) to (x0^2 + c*x1^2 : x1^2) :: - sage: A. = AffineSpace(QQbar, 1) - sage: H = End(A) - sage: f = H([2*z / (z^2 + 2*z + 3)]) - sage: f.homogenize(1) - Scheme endomorphism of Projective Space of dimension 1 over Algebraic - Field - Defn: Defined on coordinates by sending (x0 : x1) to + sage: A. = AffineSpace(QQbar, 1) # optional - sage.rings.number_field + sage: H = End(A) # optional - sage.rings.number_field + sage: f = H([2*z / (z^2 + 2*z + 3)]) # optional - sage.rings.number_field + sage: f.homogenize(1) # optional - sage.rings.number_field + Scheme endomorphism of Projective Space of dimension 1 + over Algebraic Field + Defn: Defined on coordinates by sending (x0 : x1) to (x0*x1 : 1/2*x0^2 + x0*x1 + 3/2*x1^2) :: - sage: R. = QQbar[] - sage: A. = AffineSpace(R, 1) - sage: H = Hom(A, A) - sage: F = H([d*x^2 + c]) - sage: F.homogenize(1) - Scheme endomorphism of Projective Space of dimension 1 over Multivariate Polynomial Ring in c, d over Algebraic Field - Defn: Defined on coordinates by sending (x0 : x1) to - (d*x0^2 + c*x1^2 : x1^2) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: A. = AffineSpace(R, 1) # optional - sage.rings.number_field + sage: H = Hom(A, A) # optional - sage.rings.number_field + sage: F = H([d*x^2 + c]) # optional - sage.rings.number_field + sage: F.homogenize(1) # optional - sage.rings.number_field + Scheme endomorphism of Projective Space of dimension 1 + over Multivariate Polynomial Ring in c, d over Algebraic Field + Defn: Defined on coordinates by sending (x0 : x1) to + (d*x0^2 + c*x1^2 : x1^2) TESTS:: sage: A2. = AffineSpace(QQ, 2) sage: P2. = ProjectiveSpace(QQ, 2) - sage: f = A2.hom([u,v,u*v], P2) + sage: f = A2.hom([u, v, u*v], P2) sage: g = f.homogenize(0) sage: i = A2.projective_embedding(0, g.domain()) sage: g*i == f @@ -652,16 +643,16 @@ def as_dynamical_system(self): sage: A. = AffineSpace(ZZ, 2) sage: H = End(A) - sage: f = H([x^2-y^2, y^2]) + sage: f = H([x^2 - y^2, y^2]) sage: type(f.as_dynamical_system()) :: - sage: A. = AffineSpace(GF(5), 1) - sage: H = End(A) - sage: f = H([x^2]) - sage: type(f.as_dynamical_system()) + sage: A. = AffineSpace(GF(5), 1) # optional - sage.rings.finite_rings + sage: H = End(A) # optional - sage.rings.finite_rings + sage: f = H([x^2]) # optional - sage.rings.finite_rings + sage: type(f.as_dynamical_system()) # optional - sage.rings.finite_rings :: @@ -703,25 +694,25 @@ def global_height(self, prec=None): sage: A. = AffineSpace(QQ, 1) sage: H = Hom(A, A) - sage: f = H([1/1331*x^2 + 4000]); + sage: f = H([1/1331*x^2 + 4000]) sage: f.global_height() 15.4877354584971 :: sage: R. = PolynomialRing(QQ) - sage: k. = NumberField(x^2 + 5) - sage: A. = AffineSpace(k, 2) - sage: H = Hom(A, A) - sage: f = H([13*w*x^2 + 4*y, 1/w*y^2]); - sage: f.global_height(prec=2) + sage: k. = NumberField(x^2 + 5) # optional - sage.rings.number_field + sage: A. = AffineSpace(k, 2) # optional - sage.rings.number_field + sage: H = Hom(A, A) # optional - sage.rings.number_field + sage: f = H([13*w*x^2 + 4*y, 1/w*y^2]) # optional - sage.rings.number_field + sage: f.global_height(prec=2) # optional - sage.rings.number_field 4.0 :: sage: A. = AffineSpace(ZZ, 1) sage: H = Hom(A, A) - sage: f = H([7*x^2 + 1513]); + sage: f = H([7*x^2 + 1513]) sage: f.global_height() 7.32184971378836 @@ -765,7 +756,7 @@ def local_height(self, v, prec=None): sage: P. = AffineSpace(QQ, 2) sage: H = Hom(P, P) - sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y]); + sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y]) sage: f.local_height(1331) 7.19368581839511 @@ -773,7 +764,7 @@ def local_height(self, v, prec=None): sage: P. = AffineSpace(QQ, 3) sage: H = Hom(P, P) - sage: f = H([4*x^2 + 3/100*y^2, 8/210*x*y, 1/10000*z^2]); + sage: f = H([4*x^2 + 3/100*y^2, 8/210*x*y, 1/10000*z^2]) sage: f.local_height(2) 2.77258872223978 @@ -781,18 +772,18 @@ def local_height(self, v, prec=None): sage: P. = AffineSpace(QQ, 3) sage: H = Hom(P, P) - sage: f = H([4*x^2 + 3/100*y^2, 8/210*x*y, 1/10000*z^2]); + sage: f = H([4*x^2 + 3/100*y^2, 8/210*x*y, 1/10000*z^2]) sage: f.local_height(2, prec=2) 3.0 :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(z^2 - 2) - sage: P. = AffineSpace(K, 2) - sage: H = Hom(P, P) - sage: f = H([2*x^2 + w/3*y^2, 1/w*y^2]) - sage: f.local_height(K.ideal(3)) + sage: K. = NumberField(z^2 - 2) # optional - sage.rings.number_field + sage: P. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: H = Hom(P, P) # optional - sage.rings.number_field + sage: f = H([2*x^2 + w/3*y^2, 1/w*y^2]) # optional - sage.rings.number_field + sage: f.local_height(K.ideal(3)) # optional - sage.rings.number_field 1.09861228866811 """ K = FractionField(self.domain().base_ring()) @@ -835,11 +826,11 @@ def local_height_arch(self, i, prec=None): :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(z^2 - 2) - sage: P. = AffineSpace(K, 2) - sage: H = Hom(P, P) - sage: f = H([2*x^2 + w/3*y^2, 1/w*y^2]) - sage: f.local_height_arch(1) + sage: K. = NumberField(z^2 - 2) # optional - sage.rings.number_field + sage: P. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: H = Hom(P, P) # optional - sage.rings.number_field + sage: f = H([2*x^2 + w/3*y^2, 1/w*y^2]) # optional - sage.rings.number_field + sage: f.local_height_arch(1) # optional - sage.rings.number_field 0.6931471805599453094172321214582 """ K = FractionField(self.domain().base_ring()) @@ -855,7 +846,7 @@ def jacobian(self): Return the Jacobian matrix of partial derivative of this map. The `(i, j)` entry of the Jacobian matrix is the partial derivative - `diff(functions[i], variables[j])`. + ``diff(functions[i], variables[j])``. OUTPUT: @@ -916,10 +907,10 @@ def _matrix_times_polymap_(self, mat, h): :: - sage: A1 = AffineSpace(ZZ,1) - sage: A2 = AffineSpace(ZZ,2) + sage: A1 = AffineSpace(ZZ, 1) + sage: A2 = AffineSpace(ZZ, 2) sage: H = Hom(A1, A2) - sage: f = H([x^2+1,x^2-1]) + sage: f = H([x^2 + 1, x^2 - 1]) sage: matrix([[1,2,3], [0,1,2], [0,0,1]]) * f Scheme morphism: From: Affine Space of dimension 1 over Integer Ring @@ -960,10 +951,10 @@ def _polymap_times_matrix_(self, mat, h): :: - sage: A1 = AffineSpace(ZZ,1) - sage: A2 = AffineSpace(ZZ,2) + sage: A1 = AffineSpace(ZZ, 1) + sage: A2 = AffineSpace(ZZ, 2) sage: H = Hom(A1, A2) - sage: f = H([x^2+1,x^2-1]) + sage: f = H([x^2 + 1, x^2 - 1]) sage: f * matrix([[1,2], [0,1]]) Scheme morphism: From: Affine Space of dimension 1 over Integer Ring @@ -974,10 +965,10 @@ def _polymap_times_matrix_(self, mat, h): :: sage: P. = AffineSpace(QQ, 2) - sage: P2. = AffineSpace(QQ,3) + sage: P2. = AffineSpace(QQ, 3) sage: H = Hom(P2, P) sage: f = H([u^2 + v^2, w^2]) - sage: m = matrix([[1,1,1], [1,0,1],[0,0,1]]) + sage: m = matrix([[1,1,1], [1,0,1], [0,0,1]]) sage: m*f Scheme morphism: From: Affine Space of dimension 3 over Rational Field @@ -1057,25 +1048,25 @@ def weil_restriction(self): EXAMPLES:: - sage: K. = QuadraticField(5) - sage: A. = AffineSpace(K, 2) - sage: H = End(A) - sage: f = H([x^2-y^2, y^2]) - sage: f.weil_restriction() + sage: K. = QuadraticField(5) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: H = End(A) # optional - sage.rings.number_field + sage: f = H([x^2 - y^2, y^2]) # optional - sage.rings.number_field + sage: f.weil_restriction() # optional - sage.rings.number_field Scheme endomorphism of Affine Space of dimension 4 over Rational Field Defn: Defined on coordinates by sending (z0, z1, z2, z3) to (z0^2 + 5*z1^2 - z2^2 - 5*z3^2, 2*z0*z1 - 2*z2*z3, z2^2 + 5*z3^2, 2*z2*z3) :: - sage: K. = QuadraticField(5) - sage: PS. = AffineSpace(K, 2) - sage: H = Hom(PS, PS) - sage: f = H([x, y]) - sage: F = f.weil_restriction() - sage: P = PS(2, 1) - sage: Q = P.weil_restriction() - sage: f(P).weil_restriction() == F(Q) + sage: K. = QuadraticField(5) # optional - sage.rings.number_field + sage: PS. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: H = Hom(PS, PS) # optional - sage.rings.number_field + sage: f = H([x, y]) # optional - sage.rings.number_field + sage: F = f.weil_restriction() # optional - sage.rings.number_field + sage: P = PS(2, 1) # optional - sage.rings.number_field + sage: Q = P.weil_restriction() # optional - sage.rings.number_field + sage: f(P).weil_restriction() == F(Q) # optional - sage.rings.number_field True """ if any(isinstance(f, FractionFieldElement) for f in self): @@ -1103,65 +1094,64 @@ def reduce_base_field(self): EXAMPLES:: - sage: K. = GF(5^4) - sage: A. = AffineSpace(K, 1) - sage: A2. = AffineSpace(K, 2) - sage: H = End(A) - sage: H2 = Hom(A,A2) - sage: H3 = Hom(A2,A) - sage: f = H([x^2 + 2*(t^3 + t^2 + t + 3)]) - sage: f.reduce_base_field() - Scheme endomorphism of Affine Space of dimension 1 over Finite Field in t2 of size 5^2 - Defn: Defined on coordinates by sending (x) to - (x^2 + (2*t2)) - sage: f2 = H2([x^2 + 4, 2*x]) - sage: f2.reduce_base_field() + sage: K. = GF(5^4) # optional - sage.rings.finite_rings + sage: A. = AffineSpace(K, 1) # optional - sage.rings.finite_rings + sage: A2. = AffineSpace(K, 2) # optional - sage.rings.finite_rings + sage: H = End(A) # optional - sage.rings.finite_rings + sage: H2 = Hom(A, A2) # optional - sage.rings.finite_rings + sage: H3 = Hom(A2, A) # optional - sage.rings.finite_rings + sage: f = H([x^2 + 2*(t^3 + t^2 + t + 3)]) # optional - sage.rings.finite_rings + sage: f.reduce_base_field() # optional - sage.rings.finite_rings + Scheme endomorphism of Affine Space of dimension 1 + over Finite Field in t2 of size 5^2 + Defn: Defined on coordinates by sending (x) to (x^2 + (2*t2)) + sage: f2 = H2([x^2 + 4, 2*x]) # optional - sage.rings.finite_rings + sage: f2.reduce_base_field() # optional - sage.rings.finite_rings Scheme morphism: From: Affine Space of dimension 1 over Finite Field of size 5 To: Affine Space of dimension 2 over Finite Field of size 5 - Defn: Defined on coordinates by sending (x) to - (x^2 - 1, 2*x) - sage: f3 = H3([a^2 + t*b]) - sage: f3.reduce_base_field() + Defn: Defined on coordinates by sending (x) to (x^2 - 1, 2*x) + sage: f3 = H3([a^2 + t*b]) # optional - sage.rings.finite_rings + sage: f3.reduce_base_field() # optional - sage.rings.finite_rings Scheme morphism: From: Affine Space of dimension 2 over Finite Field in t of size 5^4 To: Affine Space of dimension 1 over Finite Field in t of size 5^4 - Defn: Defined on coordinates by sending (a, b) to - (a^2 + t*b) + Defn: Defined on coordinates by sending (a, b) to (a^2 + t*b) :: - sage: K. = CyclotomicField(4) - sage: A. = AffineSpace(K, 1) - sage: H = End(A) - sage: f = H([x^2 + v]) - sage: g = f.reduce_base_field();g - Scheme endomorphism of Affine Space of dimension 1 over Cyclotomic Field of order 4 and degree 2 - Defn: Defined on coordinates by sending (x) to - (x^2 + v) - sage: g.base_ring() is K + sage: K. = CyclotomicField(4) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 1) # optional - sage.rings.number_field + sage: H = End(A) # optional - sage.rings.number_field + sage: f = H([x^2 + v]) # optional - sage.rings.number_field + sage: g = f.reduce_base_field(); g # optional - sage.rings.number_field + Scheme endomorphism of Affine Space of dimension 1 + over Cyclotomic Field of order 4 and degree 2 + Defn: Defined on coordinates by sending (x) to (x^2 + v) + sage: g.base_ring() is K # optional - sage.rings.number_field True :: - sage: A. = AffineSpace(QQbar, 1) - sage: H = End(A) - sage: f = H([(QQbar(sqrt(2))*x^2 + 1/QQbar(sqrt(3))) / (5*x)]) - sage: f.reduce_base_field() - Scheme endomorphism of Affine Space of dimension 1 over Number Field in a with defining polynomial y^4 - 4*y^2 + 1 with a = ...? + sage: A. = AffineSpace(QQbar, 1) # optional - sage.rings.number_field + sage: H = End(A) # optional - sage.rings.number_field + sage: f = H([(QQbar(sqrt(2))*x^2 + 1/QQbar(sqrt(3))) / (5*x)]) # optional - sage.rings.number_field + sage: f.reduce_base_field() # optional - sage.rings.number_field + Scheme endomorphism of Affine Space of dimension 1 over Number Field in a + with defining polynomial y^4 - 4*y^2 + 1 with a = ...? Defn: Defined on coordinates by sending (x) to (((a^3 - 3*a)*x^2 + (-1/3*a^2 + 2/3))/(5*x)) :: sage: R. = PolynomialRing(QQ) - sage: A. =AffineSpace(QQbar,1) - sage: H = End(A) - sage: f = H([QQbar(3^(1/3))*x^2 + QQbar(sqrt(-2))]) - sage: f.reduce_base_field() + sage: A. = AffineSpace(QQbar, 1) # optional - sage.rings.number_field + sage: H = End(A) # optional - sage.rings.number_field + sage: f = H([QQbar(3^(1/3))*x^2 + QQbar(sqrt(-2))]) # optional - sage.rings.number_field + sage: f.reduce_base_field() # optional - sage.rings.number_field Scheme endomorphism of Affine Space of dimension 1 over Number Field in a with defining polynomial y^6 + 6*y^4 - 6*y^3 + 12*y^2 + 36*y + 17 - with a = 1.442249570307409? + 1.414213562373095?*I + with a = 1.442249570307409? + 1.414213562373095?*I Defn: Defined on coordinates by sending (x) to ((-48/269*a^5 + 27/269*a^4 - 320/269*a^3 + 468/269*a^2 - 772/269*a - 1092/269)*x^2 + (48/269*a^5 - 27/269*a^4 + 320/269*a^3 - 468/269*a^2 @@ -1170,39 +1160,39 @@ def reduce_base_field(self): :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^3-x+1, embedding=(x^3+x+1).roots(ring=CC)[0][0]) - sage: A. = AffineSpace(K,1) - sage: A2. = AffineSpace(K,2) - sage: H = Hom(A, A2) - sage: f = H([x^2 + a*x + 3, 5*x]) - sage: f.reduce_base_field() + sage: K. = NumberField(x^3 - x + 1, # optional - sage.rings.number_field + ....: embedding=(x^3+x+1).roots(ring=CC)[0][0]) + sage: A. = AffineSpace(K, 1) # optional - sage.rings.number_field + sage: A2. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: H = Hom(A, A2) # optional - sage.rings.number_field + sage: f = H([x^2 + a*x + 3, 5*x]) # optional - sage.rings.number_field + sage: f.reduce_base_field() # optional - sage.rings.number_field Scheme morphism: - From: Affine Space of dimension 1 over Number Field in a with - defining polynomial x^3 - x + 1 with a = -1.324717957244746? - To: Affine Space of dimension 2 over Number Field in a with - defining polynomial x^3 - x + 1 with a = -1.324717957244746? - Defn: Defined on coordinates by sending (x) to - (x^2 + a*x + 3, 5*x) + From: Affine Space of dimension 1 over Number Field in a with + defining polynomial x^3 - x + 1 with a = -1.324717957244746? + To: Affine Space of dimension 2 over Number Field in a with + defining polynomial x^3 - x + 1 with a = -1.324717957244746? + Defn: Defined on coordinates by sending (x) to (x^2 + a*x + 3, 5*x) :: - sage: K. = QuadraticField(2) - sage: A. =AffineSpace(K,1) - sage: H = End(A) - sage: f = H([3*x^2 + x + 1]) - sage: f.reduce_base_field() + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 1) # optional - sage.rings.number_field + sage: H = End(A) # optional - sage.rings.number_field + sage: f = H([3*x^2 + x + 1]) # optional - sage.rings.number_field + sage: f.reduce_base_field() # optional - sage.rings.number_field Scheme endomorphism of Affine Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x) to - (3*x^2 + x + 1) + Defn: Defined on coordinates by sending (x) to (3*x^2 + x + 1) :: - sage: K. = GF(5^6) - sage: A. = AffineSpace(K, 1) - sage: H = End(A) - sage: f = H([x^2 + x*(t^3 + 2*t^2 + 4*t) + (t^5 + 3*t^4 + t^2 + 4*t)]) - sage: f.reduce_base_field() - Scheme endomorphism of Affine Space of dimension 1 over Finite Field in t of size 5^6 + sage: K. = GF(5^6) # optional - sage.rings.finite_rings + sage: A. = AffineSpace(K, 1) # optional - sage.rings.finite_rings + sage: H = End(A) # optional - sage.rings.finite_rings + sage: f = H([x^2 + x*(t^3 + 2*t^2 + 4*t) + (t^5 + 3*t^4 + t^2 + 4*t)]) # optional - sage.rings.finite_rings + sage: f.reduce_base_field() # optional - sage.rings.finite_rings + Scheme endomorphism of Affine Space of dimension 1 + over Finite Field in t of size 5^6 Defn: Defined on coordinates by sending (x) to (x^2 + (t^3 + 2*t^2 - t)*x + (t^5 - 2*t^4 + t^2 - t)) """ @@ -1334,18 +1324,18 @@ def _fast_eval(self, x): EXAMPLES:: - sage: P. = AffineSpace(GF(7), 3) - sage: H = Hom(P, P) - sage: f = H([x^2+y^2,y^2, z^2 + y*z]) - sage: f._fast_eval([1, 1, 1]) + sage: P. = AffineSpace(GF(7), 3) # optional - sage.rings.finite_rings + sage: H = Hom(P, P) # optional - sage.rings.finite_rings + sage: f = H([x^2 + y^2,y ^2, z^2 + y*z]) # optional - sage.rings.finite_rings + sage: f._fast_eval([1, 1, 1]) # optional - sage.rings.finite_rings [2, 1, 2] :: - sage: P. = AffineSpace(GF(19), 3) - sage: H = Hom(P, P) - sage: f = H([x/(y+1), y, (z^2 + y^2)/(x^2 + 1)]) - sage: f._fast_eval([2, 1, 3]) + sage: P. = AffineSpace(GF(19), 3) # optional - sage.rings.finite_rings + sage: H = Hom(P, P) # optional - sage.rings.finite_rings + sage: f = H([x/(y+1), y, (z^2 + y^2)/(x^2 + 1)]) # optional - sage.rings.finite_rings + sage: f._fast_eval([2, 1, 3]) # optional - sage.rings.finite_rings [1, 1, 2] """ R = self.domain().ambient_space().coordinate_ring() @@ -1383,11 +1373,10 @@ def representatives(self): sage: f = X.hom([x, x/y], A2) sage: f.representatives() [Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - 0 + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: 0 To: Affine Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (x, x/y)] + Defn: Defined on coordinates by sending (x, y) to (x, x/y)] :: @@ -1397,29 +1386,27 @@ def representatives(self): sage: f = X.hom([x/y], A1) sage: f.representatives() [Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x^2 - y^2 - y To: Affine Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (x/y), Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y + Defn: Defined on coordinates by sending (x, y) to (x/y), + Scheme morphism: + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x^2 - y^2 - y To: Affine Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - ((y + 1)/x)] + Defn: Defined on coordinates by sending (x, y) to ((y + 1)/x)] sage: g = _[1] sage: g.representatives() [Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x^2 - y^2 - y To: Affine Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (x/y), Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y + Defn: Defined on coordinates by sending (x, y) to (x/y), + Scheme morphism: + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x^2 - y^2 - y To: Affine Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - ((y + 1)/x)] + Defn: Defined on coordinates by sending (x, y) to ((y + 1)/x)] :: @@ -1429,16 +1416,16 @@ def representatives(self): sage: f = X.hom([x, y], P1) sage: f.representatives() [Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x^2 - y^2 - y To: Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x, y) to - (x : y), Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y + (x : y), + Scheme morphism: + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x^2 - y^2 - y To: Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (y + 1 : x)] + Defn: Defined on coordinates by sending (x, y) to (y + 1 : x)] """ X = self.domain() Y = self.codomain() diff --git a/src/sage/schemes/affine/affine_point.py b/src/sage/schemes/affine/affine_point.py index d7d50b2d064..d77ccf55ad4 100644 --- a/src/sage/schemes/affine/affine_point.py +++ b/src/sage/schemes/affine/affine_point.py @@ -194,9 +194,9 @@ def global_height(self, prec=None): :: sage: R. = PolynomialRing(QQ) - sage: k. = NumberField(x^2+5) - sage: A = AffineSpace(k, 2, 'z') - sage: A([3, 5*w+1]).global_height(prec=100) + sage: k. = NumberField(x^2 + 5) # optional - sage.rings.number_field + sage: A = AffineSpace(k, 2, 'z') # optional - sage.rings.number_field + sage: A([3, 5*w + 1]).global_height(prec=100) # optional - sage.rings.number_field 2.4181409534757389986565376694 .. TODO:: @@ -289,24 +289,24 @@ def weil_restriction(self): EXAMPLES:: - sage: A. = AffineSpace(GF(5^3, 't'), 3) - sage: X = A.subscheme([y^2-x*z, z^2+y]) - sage: Y = X.weil_restriction() - sage: P = X([1, -1, 1]) - sage: Q = P.weil_restriction();Q + sage: A. = AffineSpace(GF(5^3, 't'), 3) # optional - sage.rings.finite_rings + sage: X = A.subscheme([y^2 - x*z, z^2 + y]) # optional - sage.rings.finite_rings + sage: Y = X.weil_restriction() # optional - sage.rings.finite_rings + sage: P = X([1, -1, 1]) # optional - sage.rings.finite_rings + sage: Q = P.weil_restriction();Q # optional - sage.rings.finite_rings (1, 0, 0, 4, 0, 0, 1, 0, 0) - sage: Q.codomain() == Y + sage: Q.codomain() == Y # optional - sage.rings.finite_rings True :: sage: R. = QQ[] - sage: K. = NumberField(x^5-2) - sage: R. = K[] - sage: L. = K.extension(x^2+w) - sage: A. = AffineSpace(L, 2) - sage: P = A([w^3-v,1+w+w*v]) - sage: P.weil_restriction() + sage: K. = NumberField(x^5 - 2) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: L. = K.extension(x^2 + w) # optional - sage.rings.number_field + sage: A. = AffineSpace(L, 2) # optional - sage.rings.number_field + sage: P = A([w^3 - v, 1 + w + w*v]) # optional - sage.rings.number_field + sage: P.weil_restriction() # optional - sage.rings.number_field (w^3, -1, w + 1, w) """ L = self.codomain().base_ring() @@ -356,14 +356,14 @@ def intersection_multiplicity(self, X): EXAMPLES:: - sage: A. = AffineSpace(GF(17), 2) - sage: X = A.subscheme([y^2 - x^3 + 2*x^2 - x]) - sage: Y = A.subscheme([y - 2*x + 2]) - sage: Q1 = Y([1,0]) - sage: Q1.intersection_multiplicity(X) + sage: A. = AffineSpace(GF(17), 2) # optional - sage.rings.finite_rings + sage: X = A.subscheme([y^2 - x^3 + 2*x^2 - x]) # optional - sage.rings.finite_rings + sage: Y = A.subscheme([y - 2*x + 2]) # optional - sage.rings.finite_rings + sage: Q1 = Y([1,0]) # optional - sage.rings.finite_rings + sage: Q1.intersection_multiplicity(X) # optional - sage.rings.finite_rings 2 - sage: Q2 = X([4,6]) - sage: Q2.intersection_multiplicity(Y) + sage: Q2 = X([4,6]) # optional - sage.rings.finite_rings + sage: Q2.intersection_multiplicity(Y) # optional - sage.rings.finite_rings 1 :: @@ -416,27 +416,27 @@ def __hash__(self): EXAMPLES:: - sage: P. = AffineSpace(GF(5), 3) - sage: hash(P(2, 1, 2)) + sage: P. = AffineSpace(GF(5), 3) # optional - sage.rings.finite_rings + sage: hash(P(2, 1, 2)) # optional - sage.rings.finite_rings 57 :: - sage: P. = AffineSpace(GF(7), 3) - sage: X = P.subscheme(x^2-y^2) - sage: hash(X(1, 1, 2)) + sage: P. = AffineSpace(GF(7), 3) # optional - sage.rings.finite_rings + sage: X = P.subscheme(x^2 - y^2) # optional - sage.rings.finite_rings + sage: hash(X(1, 1, 2)) # optional - sage.rings.finite_rings 106 :: - sage: P. = AffineSpace(GF(13), 2) - sage: hash(P(3, 4)) + sage: P. = AffineSpace(GF(13), 2) # optional - sage.rings.finite_rings + sage: hash(P(3, 4)) # optional - sage.rings.finite_rings 55 :: - sage: P. = AffineSpace(GF(13^3, 't'), 2) - sage: hash(P(3, 4)) + sage: P. = AffineSpace(GF(13^3, 't'), 2) # optional - sage.rings.finite_rings + sage: hash(P(3, 4)) # optional - sage.rings.finite_rings 8791 """ p = self.codomain().base_ring().order() diff --git a/src/sage/schemes/affine/affine_rational_point.py b/src/sage/schemes/affine/affine_rational_point.py index 73a4c7d0ba6..6846935f4f8 100644 --- a/src/sage/schemes/affine/affine_rational_point.py +++ b/src/sage/schemes/affine/affine_rational_point.py @@ -17,7 +17,7 @@ sage: from sage.schemes.affine.affine_rational_point import enum_affine_rational_field sage: A. = AffineSpace(3, QQ) - sage: S = A.subscheme([2*x-3*y]) + sage: S = A.subscheme([2*x - 3*y]) sage: enum_affine_rational_field(S, 2) [(0, 0, -2), (0, 0, -1), (0, 0, -1/2), (0, 0, 0), (0, 0, 1/2), (0, 0, 1), (0, 0, 2)] @@ -25,8 +25,8 @@ Affine over a finite field:: sage: from sage.schemes.affine.affine_rational_point import enum_affine_finite_field - sage: A. = AffineSpace(4, GF(2)) - sage: enum_affine_finite_field(A(GF(2))) + sage: A. = AffineSpace(4, GF(2)) # optional - sage.rings.finite_rings + sage: enum_affine_finite_field(A(GF(2))) # optional - sage.rings.finite_rings [(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 1, 0), (0, 0, 1, 1), (0, 1, 0, 0), (0, 1, 0, 1), (0, 1, 1, 0), (0, 1, 1, 1), (1, 0, 0, 0), (1, 0, 0, 1), (1, 0, 1, 0), (1, 0, 1, 1), (1, 1, 0, 0), (1, 1, 0, 1), (1, 1, 1, 0), @@ -77,15 +77,15 @@ def enum_affine_rational_field(X, B): sage: from sage.schemes.affine.affine_rational_point import enum_affine_rational_field sage: enum_affine_rational_field(A(QQ), 1) [(-1, -1, -1), (-1, -1, 0), (-1, -1, 1), (-1, 0, -1), (-1, 0, 0), (-1, 0, 1), - (-1, 1, -1), (-1, 1, 0), (-1, 1, 1), (0, -1, -1), (0, -1, 0), (0, -1, 1), - (0, 0, -1), (0, 0, 0), (0, 0, 1), (0, 1, -1), (0, 1, 0), (0, 1, 1), (1, -1, -1), - (1, -1, 0), (1, -1, 1), (1, 0, -1), (1, 0, 0), (1, 0, 1), (1, 1, -1), (1, 1, 0), - (1, 1, 1)] + (-1, 1, -1), (-1, 1, 0), (-1, 1, 1), (0, -1, -1), (0, -1, 0), (0, -1, 1), + (0, 0, -1), (0, 0, 0), (0, 0, 1), (0, 1, -1), (0, 1, 0), (0, 1, 1), (1, -1, -1), + (1, -1, 0), (1, -1, 1), (1, 0, -1), (1, 0, 0), (1, 0, 1), (1, 1, -1), (1, 1, 0), + (1, 1, 1)] :: sage: A. = AffineSpace(4, QQ) - sage: S = A.subscheme([x^2-y*z+1, w^3+z+y^2]) + sage: S = A.subscheme([x^2 - y*z + 1, w^3 + z + y^2]) sage: enum_affine_rational_field(S(QQ), 1) [(0, 0, -1, -1)] sage: enum_affine_rational_field(S(QQ), 2) @@ -94,11 +94,11 @@ def enum_affine_rational_field(X, B): :: sage: A. = AffineSpace(2, QQ) - sage: C = Curve(x^2+y-x) + sage: C = Curve(x^2 + y - x) sage: enum_affine_rational_field(C, 10) # long time (3 s) [(-2, -6), (-1, -2), (-2/3, -10/9), (-1/2, -3/4), (-1/3, -4/9), - (0, 0), (1/3, 2/9), (1/2, 1/4), (2/3, 2/9), (1, 0), - (4/3, -4/9), (3/2, -3/4), (5/3, -10/9), (2, -2), (3, -6)] + (0, 0), (1/3, 2/9), (1/2, 1/4), (2/3, 2/9), (1, 0), + (4/3, -4/9), (3/2, -3/4), (5/3, -10/9), (2, -2), (3, -6)] AUTHORS: @@ -183,31 +183,32 @@ def enum_affine_number_field(X, **kwds): OUTPUT: - - a list containing the affine points of ``X`` of absolute height up to ``B``, - sorted. + - a list containing the affine points of ``X`` of absolute height up to ``B``, + sorted. EXAMPLES:: sage: from sage.schemes.affine.affine_rational_point import enum_affine_number_field sage: u = QQ['u'].0 - sage: K = NumberField(u^2 + 2, 'v') - sage: A. = AffineSpace(K, 3) - sage: X = A.subscheme([y^2 - x]) - sage: enum_affine_number_field(X(K), bound=2**0.5) - [(0, 0, -1), (0, 0, -v), (0, 0, -1/2*v), (0, 0, 0), (0, 0, 1/2*v), (0, 0, v), (0, 0, 1), - (1, -1, -1), (1, -1, -v), (1, -1, -1/2*v), (1, -1, 0), (1, -1, 1/2*v), (1, -1, v), (1, -1, 1), - (1, 1, -1), (1, 1, -v), (1, 1, -1/2*v), (1, 1, 0), (1, 1, 1/2*v), (1, 1, v), (1, 1, 1)] + sage: K = NumberField(u^2 + 2, 'v') # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 3) # optional - sage.rings.number_field + sage: X = A.subscheme([y^2 - x]) # optional - sage.rings.number_field + sage: enum_affine_number_field(X(K), bound=2**0.5) # optional - sage.rings.number_field + [(0, 0, -1), (0, 0, -v), (0, 0, -1/2*v), (0, 0, 0), (0, 0, 1/2*v), + (0, 0, v), (0, 0, 1), (1, -1, -1), (1, -1, -v), (1, -1, -1/2*v), + (1, -1, 0), (1, -1, 1/2*v), (1, -1, v), (1, -1, 1), (1, 1, -1), + (1, 1, -v), (1, 1, -1/2*v), (1, 1, 0), (1, 1, 1/2*v), (1, 1, v), (1, 1, 1)] :: - sage: u = QQ['u'].0 - sage: K = NumberField(u^2 + 3, 'v') - sage: A. = AffineSpace(K, 2) - sage: X=A.subscheme(x-y) sage: from sage.schemes.affine.affine_rational_point import enum_affine_number_field - sage: enum_affine_number_field(X, bound=3**0.25) - [(-1, -1), (-1/2*v - 1/2, -1/2*v - 1/2), (1/2*v - 1/2, 1/2*v - 1/2), (0, 0), (-1/2*v + 1/2, -1/2*v + 1/2), - (1/2*v + 1/2, 1/2*v + 1/2), (1, 1)] + sage: u = QQ['u'].0 + sage: K = NumberField(u^2 + 3, 'v') # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: X = A.subscheme(x - y) # optional - sage.rings.number_field + sage: enum_affine_number_field(X, bound=3**0.25) # optional - sage.rings.number_field + [(-1, -1), (-1/2*v - 1/2, -1/2*v - 1/2), (1/2*v - 1/2, 1/2*v - 1/2), + (0, 0), (-1/2*v + 1/2, -1/2*v + 1/2), (1/2*v + 1/2, 1/2*v + 1/2), (1, 1)] """ B = kwds.pop('bound') tol = kwds.pop('tolerance', 1e-2) @@ -248,31 +249,31 @@ def enum_affine_finite_field(X): EXAMPLES:: - sage: F = GF(7) - sage: A. = AffineSpace(4, F) - sage: C = A.subscheme([w^2+x+4, y*z*x-6, z*y+w*x]) sage: from sage.schemes.affine.affine_rational_point import enum_affine_finite_field - sage: enum_affine_finite_field(C(F)) + sage: F = GF(7) # optional - sage.rings.finite_rings + sage: A. = AffineSpace(4, F) # optional - sage.rings.finite_rings + sage: C = A.subscheme([w^2 + x + 4, y*z*x - 6, z*y + w*x]) # optional - sage.rings.finite_rings + sage: enum_affine_finite_field(C(F)) # optional - sage.rings.finite_rings [] - sage: C = A.subscheme([w^2+x+4, y*z*x-6]) - sage: enum_affine_finite_field(C(F)) + sage: C = A.subscheme([w^2 + x + 4, y*z*x - 6]) # optional - sage.rings.finite_rings + sage: enum_affine_finite_field(C(F)) # optional - sage.rings.finite_rings [(0, 3, 1, 2), (0, 3, 2, 1), (0, 3, 3, 3), (0, 3, 4, 4), (0, 3, 5, 6), - (0, 3, 6, 5), (1, 2, 1, 3), (1, 2, 2, 5), (1, 2, 3, 1), (1, 2, 4, 6), - (1, 2, 5, 2), (1, 2, 6, 4), (2, 6, 1, 1), (2, 6, 2, 4), (2, 6, 3, 5), - (2, 6, 4, 2), (2, 6, 5, 3), (2, 6, 6, 6), (3, 1, 1, 6), (3, 1, 2, 3), - (3, 1, 3, 2), (3, 1, 4, 5), (3, 1, 5, 4), (3, 1, 6, 1), (4, 1, 1, 6), - (4, 1, 2, 3), (4, 1, 3, 2), (4, 1, 4, 5), (4, 1, 5, 4), (4, 1, 6, 1), - (5, 6, 1, 1), (5, 6, 2, 4), (5, 6, 3, 5), (5, 6, 4, 2), (5, 6, 5, 3), - (5, 6, 6, 6), (6, 2, 1, 3), (6, 2, 2, 5), (6, 2, 3, 1), (6, 2, 4, 6), - (6, 2, 5, 2), (6, 2, 6, 4)] + (0, 3, 6, 5), (1, 2, 1, 3), (1, 2, 2, 5), (1, 2, 3, 1), (1, 2, 4, 6), + (1, 2, 5, 2), (1, 2, 6, 4), (2, 6, 1, 1), (2, 6, 2, 4), (2, 6, 3, 5), + (2, 6, 4, 2), (2, 6, 5, 3), (2, 6, 6, 6), (3, 1, 1, 6), (3, 1, 2, 3), + (3, 1, 3, 2), (3, 1, 4, 5), (3, 1, 5, 4), (3, 1, 6, 1), (4, 1, 1, 6), + (4, 1, 2, 3), (4, 1, 3, 2), (4, 1, 4, 5), (4, 1, 5, 4), (4, 1, 6, 1), + (5, 6, 1, 1), (5, 6, 2, 4), (5, 6, 3, 5), (5, 6, 4, 2), (5, 6, 5, 3), + (5, 6, 6, 6), (6, 2, 1, 3), (6, 2, 2, 5), (6, 2, 3, 1), (6, 2, 4, 6), + (6, 2, 5, 2), (6, 2, 6, 4)] :: - sage: A. = AffineSpace(3, GF(3)) - sage: S = A.subscheme(x+y) - sage: enum_affine_finite_field(S) + sage: A. = AffineSpace(3, GF(3)) # optional - sage.rings.finite_rings + sage: S = A.subscheme(x + y) # optional - sage.rings.finite_rings + sage: enum_affine_finite_field(S) # optional - sage.rings.finite_rings [(0, 0, 0), (0, 0, 1), (0, 0, 2), (1, 2, 0), (1, 2, 1), (1, 2, 2), - (2, 1, 0), (2, 1, 1), (2, 1, 2)] + (2, 1, 0), (2, 1, 1), (2, 1, 2)] ALGORITHM: diff --git a/src/sage/schemes/affine/affine_space.py b/src/sage/schemes/affine/affine_space.py index 52c13b29068..3319950fcbc 100644 --- a/src/sage/schemes/affine/affine_space.py +++ b/src/sage/schemes/affine/affine_space.py @@ -48,7 +48,7 @@ def is_AffineSpace(x): sage: from sage.schemes.affine.affine_space import is_AffineSpace sage: is_AffineSpace(AffineSpace(5, names='x')) True - sage: is_AffineSpace(AffineSpace(5, GF(9, 'alpha'), names='x')) + sage: is_AffineSpace(AffineSpace(5, GF(9, 'alpha'), names='x')) # optional - sage.rings.finite_rings True sage: is_AffineSpace(Spec(ZZ)) False @@ -75,7 +75,7 @@ def AffineSpace(n, R=None, names=None, ambient_projective_space=None, Use the divide operator for base extension:: - sage: AffineSpace(5, names='x')/GF(17) + sage: AffineSpace(5, names='x')/GF(17) # optional - sage.rings.finite_rings Affine Space of dimension 5 over Finite Field of size 17 The default base ring is `\ZZ`:: @@ -85,10 +85,10 @@ def AffineSpace(n, R=None, names=None, ambient_projective_space=None, There is also an affine space associated to each polynomial ring:: - sage: R = GF(7)['x, y, z'] - sage: A = AffineSpace(R); A + sage: R = GF(7)['x, y, z'] # optional - sage.rings.finite_rings + sage: A = AffineSpace(R); A # optional - sage.rings.finite_rings Affine Space of dimension 3 over Finite Field of size 7 - sage: A.coordinate_ring() is R + sage: A.coordinate_ring() is R # optional - sage.rings.finite_rings True TESTS:: @@ -173,7 +173,7 @@ class AffineSpace_generic(AmbientSpace, AffineScheme): sage: AffineSpace(RealField(), 3, 'Z') Affine Space of dimension 3 over Real Field with 53 bits of precision - sage: AffineSpace(Qp(7), 2, 'x') + sage: AffineSpace(Qp(7), 2, 'x') # optional - sage.rings.padics Affine Space of dimension 2 over 7-adic Field with capped relative precision 20 Even 0-dimensional affine spaces are supported:: @@ -185,7 +185,7 @@ def __init__(self, n, R, names, ambient_projective_space, default_embedding_inde """ EXAMPLES:: - sage: AffineSpace(3, Zp(5), 'y') + sage: AffineSpace(3, Zp(5), 'y') # optional - sage.rings.padics Affine Space of dimension 3 over 5-adic Ring with capped relative precision 20 """ AmbientSpace.__init__(self, n, R) @@ -205,15 +205,15 @@ def __iter__(self): EXAMPLES:: - sage: FF = FiniteField(3) - sage: AA = AffineSpace(FF, 0) - sage: [ x for x in AA ] + sage: FF = FiniteField(3) # optional - sage.rings.finite_rings + sage: AA = AffineSpace(FF, 0) # optional - sage.rings.finite_rings + sage: [ x for x in AA ] # optional - sage.rings.finite_rings [()] - sage: AA = AffineSpace(FF, 1, 'Z') - sage: [ x for x in AA ] + sage: AA = AffineSpace(FF, 1, 'Z') # optional - sage.rings.finite_rings + sage: [ x for x in AA ] # optional - sage.rings.finite_rings [(0), (1), (2)] - sage: AA. = AffineSpace(FF, 2) - sage: [ x for x in AA ] + sage: AA. = AffineSpace(FF, 2) # optional - sage.rings.finite_rings + sage: [ x for x in AA ] # optional - sage.rings.finite_rings [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] AUTHOR: @@ -249,13 +249,13 @@ def rational_points(self, F=None): EXAMPLES:: - sage: A = AffineSpace(1, GF(3)) - sage: A.rational_points() + sage: A = AffineSpace(1, GF(3)) # optional - sage.rings.finite_rings + sage: A.rational_points() # optional - sage.rings.finite_rings [(0), (1), (2)] - sage: A.rational_points(GF(3^2, 'b')) + sage: A.rational_points(GF(3^2, 'b')) # optional - sage.rings.finite_rings [(0), (b), (b + 1), (2*b + 1), (2), (2*b), (2*b + 2), (b + 2), (1)] - sage: AffineSpace(2, ZZ).rational_points(GF(2)) + sage: AffineSpace(2, ZZ).rational_points(GF(2)) # optional - sage.rings.finite_rings [(0, 0), (0, 1), (1, 0), (1, 1)] TESTS:: @@ -264,7 +264,7 @@ def rational_points(self, F=None): Traceback (most recent call last): ... TypeError: base ring (= Rational Field) must be a finite field - sage: AffineSpace(1, GF(3)).rational_points(ZZ) + sage: AffineSpace(1, GF(3)).rational_points(ZZ) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: second argument (= Integer Ring) must be a finite field @@ -315,9 +315,9 @@ def __hash__(self): EXAMPLES:: - sage: hash(AffineSpace(QQ,3,'a')) == hash(AffineSpace(ZZ,3,'a')) + sage: hash(AffineSpace(QQ, 3, 'a')) == hash(AffineSpace(ZZ, 3, 'a')) False - sage: hash(AffineSpace(ZZ,1,'a')) == hash(AffineSpace(ZZ,0,'a')) + sage: hash(AffineSpace(ZZ, 1, 'a')) == hash(AffineSpace(ZZ, 0, 'a')) False """ return hash((self.dimension_relative(), self.coordinate_ring())) @@ -333,7 +333,7 @@ def _latex_(self): TESTS:: - sage: AffineSpace(3, Zp(5), 'y')._latex_() + sage: AffineSpace(3, Zp(5), 'y')._latex_() # optional - sage.rings.padics '\\mathbf{A}_{\\Bold{Z}_{5}}^3' """ return "\\mathbf{A}_{%s}^%s"%(latex(self.base_ring()), self.dimension_relative()) @@ -434,7 +434,7 @@ def _repr_(self): TESTS:: - sage: AffineSpace(3, Zp(5), 'y')._repr_() + sage: AffineSpace(3, Zp(5), 'y')._repr_() # optional - sage.rings.padics 'Affine Space of dimension 3 over 5-adic Ring with capped relative precision 20' """ return "Affine Space of dimension %s over %s"%(self.dimension_relative(), self.base_ring()) @@ -450,7 +450,7 @@ def _repr_generic_point(self, polys=None): EXAMPLES:: sage: A. = AffineSpace(2, ZZ) - sage: A._repr_generic_point([y-x^2]) + sage: A._repr_generic_point([y - x^2]) '(-x^2 + y)' sage: A._repr_generic_point() '(x, y)' @@ -470,7 +470,7 @@ def _latex_generic_point(self, v=None): EXAMPLES:: sage: A. = AffineSpace(2, ZZ) - sage: A._latex_generic_point([y-x^2]) + sage: A._latex_generic_point([y - x^2]) '\\left(-x^{2} + y\\right)' sage: A._latex_generic_point() '\\left(x, y\\right)' @@ -619,13 +619,11 @@ def change_ring(self, R): - ``R`` -- commutative ring or morphism. - OUTPUT: - - - affine space over ``R``. + OUTPUT: An affine space over ``R``. .. NOTE:: - There is no need to have any relation between `R` and the base ring + There is no need to have any relation between ``R`` and the base ring of this space, if you want to have such a relation, use ``self.base_extend(R)`` instead. @@ -634,14 +632,14 @@ def change_ring(self, R): sage: A. = AffineSpace(3, ZZ) sage: AQ = A.change_ring(QQ); AQ Affine Space of dimension 3 over Rational Field - sage: AQ.change_ring(GF(5)) + sage: AQ.change_ring(GF(5)) # optional - sage.rings.finite_rings Affine Space of dimension 3 over Finite Field of size 5 :: - sage: K. = QuadraticField(5) - sage: A = AffineSpace(K,2,'t') - sage: A.change_ring(K.embeddings(CC)[1]) + sage: K. = QuadraticField(5) # optional - sage.rings.number_field + sage: A = AffineSpace(K, 2, 't') # optional - sage.rings.number_field + sage: A.change_ring(K.embeddings(CC)[1]) # optional - sage.rings.number_field Affine Space of dimension 2 over Complex Field with 53 bits of precision """ if isinstance(R, Map): @@ -655,9 +653,9 @@ def coordinate_ring(self): EXAMPLES:: - sage: R = AffineSpace(2, GF(9,'alpha'), 'z').coordinate_ring(); R + sage: R = AffineSpace(2, GF(9,'alpha'), 'z').coordinate_ring(); R # optional - sage.rings.finite_rings Multivariate Polynomial Ring in z0, z1 over Finite Field in alpha of size 3^2 - sage: AffineSpace(3, R, 'x').coordinate_ring() + sage: AffineSpace(3, R, 'x').coordinate_ring() # optional - sage.rings.finite_rings Multivariate Polynomial Ring in x0, x1, x2 over Multivariate Polynomial Ring in z0, z1 over Finite Field in alpha of size 3^2 """ @@ -716,8 +714,7 @@ def projective_embedding(self, i=None, PP=None): Scheme morphism: From: Affine Space of dimension 2 over Rational Field To: Projective Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x0, x1) to - (1 : x0 : x1) + Defn: Defined on coordinates by sending (x0, x1) to (1 : x0 : x1) sage: z = AA(3, 4) sage: pi(z) (1/4 : 3/4 : 1) @@ -727,8 +724,7 @@ def projective_embedding(self, i=None, PP=None): Scheme morphism: From: Affine Space of dimension 2 over Rational Field To: Projective Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x0, x1) to - (x0 : 1 : x1) + Defn: Defined on coordinates by sending (x0, x1) to (x0 : 1 : x1) sage: pi(z) (3/4 : 1/4 : 1) sage: pi = AA.projective_embedding(2) @@ -825,10 +821,8 @@ def subscheme(self, X, **kwds): Spectrum of Rational Field sage: X.structure_morphism() Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x, - y^2, - x*y^2 + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x, y^2, x*y^2 To: Spectrum of Rational Field Defn: Structure map sage: X.dimension() @@ -844,7 +838,7 @@ def subscheme(self, X, **kwds): def _an_element_(self): r""" - Return an element of this affine space,used both for illustration and + Return an element of this affine space, used both for illustration and testing purposes. OUTPUT: a point in the affine space @@ -854,7 +848,7 @@ def _an_element_(self): sage: AffineSpace(ZZ, 2, 'x').an_element() (5, 4) - sage: AffineSpace(Qp(5), 2, 'x').an_element() + sage: AffineSpace(Qp(5), 2, 'x').an_element() # optional - sage.rings.padics (5^2 + O(5^22), 4*5 + O(5^21)) """ n = self.dimension_relative() @@ -863,7 +857,7 @@ def _an_element_(self): def chebyshev_polynomial(self, n, kind='first', monic=False): """ - Generates an endomorphism of this affine line by a Chebyshev polynomial. + Generate an endomorphism of this affine line by a Chebyshev polynomial. Chebyshev polynomials are a sequence of recursively defined orthogonal polynomials. Chebyshev of the first kind are defined as `T_0(x) = 1`, @@ -888,16 +882,14 @@ def chebyshev_polynomial(self, n, kind='first', monic=False): sage: A. = AffineSpace(QQ, 1) sage: A.chebyshev_polynomial(5, 'first') Dynamical System of Affine Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x) to - (16*x^5 - 20*x^3 + 5*x) + Defn: Defined on coordinates by sending (x) to (16*x^5 - 20*x^3 + 5*x) :: sage: A. = AffineSpace(QQ, 1) sage: A.chebyshev_polynomial(3, 'second') Dynamical System of Affine Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x) to - (8*x^3 - 4*x) + Defn: Defined on coordinates by sending (x) to (8*x^3 - 4*x) :: @@ -928,17 +920,16 @@ def chebyshev_polynomial(self, n, kind='first', monic=False): sage: A. = AffineSpace(QQ, 1) sage: A.chebyshev_polynomial(7, monic=True) Dynamical System of Affine Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x) to - (x^7 - 7*x^5 + 14*x^3 - 7*x) + Defn: Defined on coordinates by sending (x) to (x^7 - 7*x^5 + 14*x^3 - 7*x) :: sage: F. = FunctionField(QQ) sage: A. = AffineSpace(F,1) sage: A.chebyshev_polynomial(4, monic=True) - Dynamical System of Affine Space of dimension 1 over Rational function field in t over Rational Field - Defn: Defined on coordinates by sending (x) to - (x^4 + (-4)*x^2 + 2) + Dynamical System of Affine Space of dimension 1 + over Rational function field in t over Rational Field + Defn: Defined on coordinates by sending (x) to (x^4 + (-4)*x^2 + 2) """ if self.dimension_relative() != 1: raise TypeError("affine space must be of dimension 1") @@ -990,9 +981,9 @@ def _point(self, *args, **kwds): TESTS:: - sage: P2. = AffineSpace(3, GF(3)) - sage: point_homset = P2._point_homset(Spec(GF(3)), P2) - sage: P2._point(point_homset, [1, 2, 3]) + sage: P2. = AffineSpace(3, GF(3)) # optional - sage.rings.finite_rings + sage: point_homset = P2._point_homset(Spec(GF(3)), P2) # optional - sage.rings.finite_rings + sage: P2._point(point_homset, [1, 2, 3]) # optional - sage.rings.finite_rings (1, 2, 0) """ return SchemeMorphism_point_affine_field(*args, **kwds) @@ -1005,8 +996,8 @@ def _morphism(self, *args, **kwds): TESTS:: - sage: P2. = AffineSpace(3, GF(3)) - sage: P2._morphism(P2.Hom(P2), [x, y, z]) + sage: P2. = AffineSpace(3, GF(3)) # optional - sage.rings.finite_rings + sage: P2._morphism(P2.Hom(P2), [x, y, z]) # optional - sage.rings.finite_rings Scheme endomorphism of Affine Space of dimension 3 over Finite Field of size 3 Defn: Defined on coordinates by sending (x, y, z) to (x, y, z) @@ -1048,18 +1039,18 @@ def points_of_bounded_height(self, **kwds): sage: A. = AffineSpace(QQ, 2) sage: list(A.points_of_bounded_height(bound=3)) [(0, 0), (1, 0), (-1, 0), (1/2, 0), (-1/2, 0), (2, 0), (-2, 0), (0, 1), - (1, 1), (-1, 1), (1/2, 1), (-1/2, 1), (2, 1), (-2, 1), (0, -1), (1, -1), - (-1, -1), (1/2, -1), (-1/2, -1), (2, -1), (-2, -1), (0, 1/2), (1, 1/2), - (-1, 1/2), (1/2, 1/2), (-1/2, 1/2), (2, 1/2), (-2, 1/2), (0, -1/2), (1, -1/2), - (-1, -1/2), (1/2, -1/2), (-1/2, -1/2), (2, -1/2), (-2, -1/2), (0, 2), (1, 2), - (-1, 2), (1/2, 2), (-1/2, 2), (2, 2), (-2, 2), (0, -2), (1, -2), (-1, -2), (1/2, -2), - (-1/2, -2), (2, -2), (-2, -2)] + (1, 1), (-1, 1), (1/2, 1), (-1/2, 1), (2, 1), (-2, 1), (0, -1), (1, -1), + (-1, -1), (1/2, -1), (-1/2, -1), (2, -1), (-2, -1), (0, 1/2), (1, 1/2), + (-1, 1/2), (1/2, 1/2), (-1/2, 1/2), (2, 1/2), (-2, 1/2), (0, -1/2), (1, -1/2), + (-1, -1/2), (1/2, -1/2), (-1/2, -1/2), (2, -1/2), (-2, -1/2), (0, 2), (1, 2), + (-1, 2), (1/2, 2), (-1/2, 2), (2, 2), (-2, 2), (0, -2), (1, -2), (-1, -2), + (1/2, -2), (-1/2, -2), (2, -2), (-2, -2)] :: sage: u = QQ['u'].0 - sage: A. = AffineSpace(NumberField(u^2 - 2, 'v'), 2) - sage: len(list(A.points_of_bounded_height(bound=2, tolerance=0.1))) + sage: A. = AffineSpace(NumberField(u^2 - 2, 'v'), 2) # optional - sage.rings.number_field + sage: len(list(A.points_of_bounded_height(bound=2, tolerance=0.1))) # optional - sage.rings.number_field 529 """ if (is_RationalField(self.base_ring())): @@ -1108,21 +1099,21 @@ def weil_restriction(self): the Weil restriction to the prime subfield. OUTPUT: Affine space of dimension ``d * self.dimension_relative()`` - over the base field of ``self.base_ring()``. + over the base field of ``self.base_ring()``. EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(x^5-2) - sage: AK. = AffineSpace(K, 2) - sage: AK.weil_restriction() + sage: K. = NumberField(x^5 - 2) # optional - sage.rings.number_field + sage: AK. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: AK.weil_restriction() # optional - sage.rings.number_field Affine Space of dimension 10 over Rational Field - sage: R. = K[] - sage: L. = K.extension(x^2+1) - sage: AL. = AffineSpace(L, 2) - sage: AL.weil_restriction() - Affine Space of dimension 4 over Number Field in w with defining - polynomial x^5 - 2 + sage: R. = K[] # optional - sage.rings.number_field + sage: L. = K.extension(x^2 + 1) # optional - sage.rings.number_field + sage: AL. = AffineSpace(L, 2) # optional - sage.rings.number_field + sage: AL.weil_restriction() # optional - sage.rings.number_field + Affine Space of dimension 4 over Number Field in w + with defining polynomial x^5 - 2 """ try: X = self.__weil_restriction @@ -1175,7 +1166,7 @@ def line_through(self, p, q): sage: p2 = A3(4, 5, 6) sage: A3.line_through(p1, p2) Affine Curve over Rational Field defined by -1/6*x + 1/6*y - 1/6, - -1/6*x + 1/6*z - 1/3, -1/6*y + 1/6*z - 1/6, -1/6*x + 1/3*y - 1/6*z + -1/6*x + 1/6*z - 1/3, -1/6*y + 1/6*z - 1/6, -1/6*x + 1/3*y - 1/6*z sage: L = _ sage: L(p1) (1, 2, 3) @@ -1244,9 +1235,9 @@ def _point(self, *args, **kwds): TESTS:: - sage: P2. = AffineSpace(3, GF(3)) - sage: point_homset = P2._point_homset(Spec(GF(3)), P2) - sage: P2._point(point_homset, [1, 2, 3]) + sage: P2. = AffineSpace(3, GF(3)) # optional - sage.rings.finite_rings + sage: point_homset = P2._point_homset(Spec(GF(3)), P2) # optional - sage.rings.finite_rings + sage: P2._point(point_homset, [1, 2, 3]) # optional - sage.rings.finite_rings (1, 2, 0) """ return SchemeMorphism_point_affine_finite_field(*args, **kwds) @@ -1259,8 +1250,8 @@ def _morphism(self, *args, **kwds): TESTS:: - sage: P2. = AffineSpace(3, GF(3)) - sage: P2._morphism(P2.Hom(P2), [x, y, z]) + sage: P2. = AffineSpace(3, GF(3)) # optional - sage.rings.finite_rings + sage: P2._morphism(P2.Hom(P2), [x, y, z]) # optional - sage.rings.finite_rings Scheme endomorphism of Affine Space of dimension 3 over Finite Field of size 3 Defn: Defined on coordinates by sending (x, y, z) to (x, y, z) diff --git a/src/sage/schemes/affine/affine_subscheme.py b/src/sage/schemes/affine/affine_subscheme.py index 0ba77fd2b6d..3b98319527d 100644 --- a/src/sage/schemes/affine/affine_subscheme.py +++ b/src/sage/schemes/affine/affine_subscheme.py @@ -42,14 +42,14 @@ class AlgebraicScheme_subscheme_affine(AlgebraicScheme_subscheme): EXAMPLES:: sage: A3. = AffineSpace(QQ, 3) - sage: A3.subscheme([x^2-y*z]) + sage: A3.subscheme([x^2 - y*z]) Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: x^2 - y*z TESTS:: sage: from sage.schemes.affine.affine_subscheme import AlgebraicScheme_subscheme_affine - sage: AlgebraicScheme_subscheme_affine(A3, [x^2-y*z]) + sage: AlgebraicScheme_subscheme_affine(A3, [x^2 - y*z]) Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: x^2 - y*z """ @@ -151,31 +151,27 @@ def projective_embedding(self, i=None, PP=None): EXAMPLES:: sage: A. = AffineSpace(3, ZZ) - sage: S = A.subscheme([x*y-z]) + sage: S = A.subscheme([x*y - z]) sage: S.projective_embedding() Scheme morphism: - From: Closed subscheme of Affine Space of dimension 3 over Integer Ring defined by: - x*y - z - To: Closed subscheme of Projective Space of dimension 3 over Integer Ring defined by: - x0*x1 - x2*x3 - Defn: Defined on coordinates by sending (x, y, z) to - (x : y : z : 1) + From: Closed subscheme of Affine Space of dimension 3 over Integer Ring + defined by: x*y - z + To: Closed subscheme of Projective Space of dimension 3 over Integer Ring + defined by: x0*x1 - x2*x3 + Defn: Defined on coordinates by sending (x, y, z) to (x : y : z : 1) :: sage: A. = AffineSpace(3, ZZ) - sage: P = ProjectiveSpace(3,ZZ,'u') - sage: S = A.subscheme([x^2-y*z]) - sage: S.projective_embedding(1,P) + sage: P = ProjectiveSpace(3, ZZ, 'u') + sage: S = A.subscheme([x^2 - y*z]) + sage: S.projective_embedding(1, P) Scheme morphism: - From: Closed subscheme of Affine Space of dimension 3 over Integer - Ring defined by: - x^2 - y*z - To: Closed subscheme of Projective Space of dimension 3 over Integer - Ring defined by: - u0^2 - u2*u3 - Defn: Defined on coordinates by sending (x, y, z) to - (x : 1 : y : z) + From: Closed subscheme of Affine Space of dimension 3 over Integer Ring + defined by: x^2 - y*z + To: Closed subscheme of Projective Space of dimension 3 over Integer Ring + defined by: u0^2 - u2*u3 + Defn: Defined on coordinates by sending (x, y, z) to (x : 1 : y : z) :: @@ -183,17 +179,11 @@ def projective_embedding(self, i=None, PP=None): sage: X = A.subscheme([y - x^2, z - x^3]) sage: X.projective_embedding() Scheme morphism: - From: Closed subscheme of Affine Space of dimension 3 over Rational - Field defined by: - -x^2 + y, - -x^3 + z - To: Closed subscheme of Projective Space of dimension 3 over - Rational Field defined by: - x0^2 - x1*x3, - x0*x1 - x2*x3, - x1^2 - x0*x2 - Defn: Defined on coordinates by sending (x, y, z) to - (x : y : z : 1) + From: Closed subscheme of Affine Space of dimension 3 over Rational Field + defined by: -x^2 + y, -x^3 + z + To: Closed subscheme of Projective Space of dimension 3 over Rational Field + defined by: x0^2 - x1*x3, x0*x1 - x2*x3, x1^2 - x0*x2 + Defn: Defined on coordinates by sending (x, y, z) to (x : y : z : 1) When taking a closed subscheme of an affine space with a projective embedding, the subscheme inherits the embedding:: @@ -202,12 +192,11 @@ def projective_embedding(self, i=None, PP=None): sage: X = A.subscheme(u - v) sage: X.projective_embedding() Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - u - v - To: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x0 - x2 - Defn: Defined on coordinates by sending (u, v) to - (u : 1 : v) + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: u - v + To: Closed subscheme of Projective Space of dimension 2 over Rational Field + defined by: x0 - x2 + Defn: Defined on coordinates by sending (u, v) to (u : 1 : v) sage: phi = X.projective_embedding() sage: psi = A.projective_embedding() sage: phi(X(2, 2)) == psi(A(X(2, 2))) @@ -271,11 +260,11 @@ def projective_closure(self, i=None, PP=None): EXAMPLES:: - sage: A. = AffineSpace(QQ,4) + sage: A. = AffineSpace(QQ, 4) sage: X = A.subscheme([x^2 - y, x*y - z, y^2 - w, x*z - w, y*z - x*w, z^2 - y*w]) sage: X.projective_closure() Closed subscheme of Projective Space of dimension 4 over Rational Field - defined by: + defined by: x0^2 - x1*x4, x0*x1 - x2*x4, x1^2 - x3*x4, @@ -310,8 +299,8 @@ def is_smooth(self, point=None): EXAMPLES:: - sage: A2. = AffineSpace(2,QQ) - sage: cuspidal_curve = A2.subscheme([y^2-x^3]) + sage: A2. = AffineSpace(2, QQ) + sage: cuspidal_curve = A2.subscheme([y^2 - x^3]) sage: cuspidal_curve Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: -x^3 + y^2 @@ -374,13 +363,15 @@ def intersection_multiplicity(self, X, P): :: sage: R. = QQ[] - sage: K. = NumberField(a^6 - 3*a^5 + 5*a^4 - 5*a^3 + 5*a^2 - 3*a + 1) - sage: A. = AffineSpace(K, 4) - sage: X = A.subscheme([x*y, y*z + 7, w^3 - x^3]) - sage: Y = A.subscheme([x - z^3 + z + 1]) - sage: Q = A([0, -7*b^5 + 21*b^4 - 28*b^3 + 21*b^2 - 21*b + 14, -b^5 + 2*b^4 - 3*b^3 \ - + 2*b^2 - 2*b, 0]) - sage: X.intersection_multiplicity(Y, Q) + sage: K. = NumberField(a^6 - 3*a^5 + 5*a^4 - 5*a^3 + 5*a^2 - 3*a + 1) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 4) # optional - sage.rings.number_field + sage: X = A.subscheme([x*y, y*z + 7, w^3 - x^3]) # optional - sage.rings.number_field + sage: Y = A.subscheme([x - z^3 + z + 1]) # optional - sage.rings.number_field + sage: Q = A([0, # optional - sage.rings.number_field + ....: -7*b^5 + 21*b^4 - 28*b^3 + 21*b^2 - 21*b + 14, + ....: -b^5 + 2*b^4 - 3*b^3 + 2*b^2 - 2*b, + ....: 0]) + sage: X.intersection_multiplicity(Y, Q) # optional - sage.rings.number_field 3 :: @@ -463,22 +454,22 @@ def multiplicity(self, P): :: - sage: A. = AffineSpace(GF(23), 5) - sage: C = A.curve([x^8 - y, y^7 - z, z^3 - 1, w^5 - v^3]) - sage: Q = A([22,1,1,0,0]) - sage: C.multiplicity(Q) + sage: A. = AffineSpace(GF(23), 5) # optional - sage.rings.finite_rings + sage: C = A.curve([x^8 - y, y^7 - z, z^3 - 1, w^5 - v^3]) # optional - sage.rings.finite_rings + sage: Q = A([22,1,1,0,0]) # optional - sage.rings.finite_rings + sage: C.multiplicity(Q) # optional - sage.rings.finite_rings 3 :: - sage: K. = QuadraticField(-1) - sage: A. = AffineSpace(K, 5) - sage: X = A.subscheme([y^7 - x^2*z^5 + z^3*t^8 - x^2*y^4*z - t^8]) - sage: Q1 = A([1,1,0,1,-1]) - sage: X.multiplicity(Q1) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 5) # optional - sage.rings.number_field + sage: X = A.subscheme([y^7 - x^2*z^5 + z^3*t^8 - x^2*y^4*z - t^8]) # optional - sage.rings.number_field + sage: Q1 = A([1,1,0,1,-1]) # optional - sage.rings.number_field + sage: X.multiplicity(Q1) # optional - sage.rings.number_field 1 - sage: Q2 = A([0,0,0,-a,0]) - sage: X.multiplicity(Q2) + sage: Q2 = A([0,0,0,-a,0]) # optional - sage.rings.number_field + sage: X.multiplicity(Q2) # optional - sage.rings.number_field 7 Check that :trac:`27479` is fixed:: @@ -523,20 +514,18 @@ def _morphism(self, *args, **kwds): sage: H = X.Hom(A2) sage: H([x, x/y]) Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x - y + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x - y To: Affine Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (x, x/y) + Defn: Defined on coordinates by sending (x, y) to (x, x/y) sage: P2 = ProjectiveSpace(QQ, 2) sage: H = X.Hom(P2) sage: H([x*y, x, y]) Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x - y + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x - y To: Projective Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (x*y : x : y) + Defn: Defined on coordinates by sending (x, y) to (x*y : x : y) """ return SchemeMorphism_polynomial_affine_subscheme_field(*args, **kwds) @@ -553,14 +542,14 @@ def tangent_space(self, p): EXAMPLES:: sage: A3. = AffineSpace(3, QQ) - sage: X = A3.subscheme(z-x*y) + sage: X = A3.subscheme(z - x*y) sage: X.tangent_space(A3.origin()) Closed subscheme of Affine Space of dimension 3 over Rational Field - defined by: + defined by: z sage: X.tangent_space(X(1,1,1)) Closed subscheme of Affine Space of dimension 3 over Rational Field - defined by: + defined by: -x - y + z Tangent space at a point may have higher dimension than the dimension @@ -572,14 +561,14 @@ def tangent_space(self, p): sage: p = C(0,0,0) sage: C.tangent_space(p) Closed subscheme of Affine Space of dimension 3 over Rational Field - defined by: + defined by: x + y + z sage: _.dimension() 2 sage: q = C(1,0,-1) sage: C.tangent_space(q) Closed subscheme of Affine Space of dimension 3 over Rational Field - defined by: + defined by: x + y + z, 2*x + 3*z sage: _.dimension() diff --git a/src/sage/schemes/berkovich/berkovich_cp_element.py b/src/sage/schemes/berkovich/berkovich_cp_element.py index 7c922fefb90..4611d396fce 100644 --- a/src/sage/schemes/berkovich/berkovich_cp_element.py +++ b/src/sage/schemes/berkovich/berkovich_cp_element.py @@ -48,7 +48,7 @@ class Berkovich_Element(Element): """ - The parent class for any element of a Berkovich space + The parent class for any element of a Berkovich space. """ pass @@ -62,13 +62,13 @@ class Berkovich_Element_Cp(Berkovich_Element): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: B(2) + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: B(2) # optional - sage.rings.padics Type I point centered at 2 + O(3^20) :: - sage: B(0, 1) + sage: B(0, 1) # optional - sage.rings.padics Type II point centered at 0 of radius 3^0 """ @@ -78,8 +78,8 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= EXAMPLES:: - sage: B = Berkovich_Cp_Affine(5) - sage: B(4) + sage: B = Berkovich_Cp_Affine(5) # optional - sage.rings.padics + sage: B(4) # optional - sage.rings.padics Type I point centered at 4 + O(5^20) """ from sage.rings.function_field.element import is_FunctionFieldElement @@ -426,9 +426,9 @@ def _custom_abs(self, x): :: - sage: B = Berkovich_Cp_Affine(Qp(3)) - sage: Q1 = B(9) - sage: Q1._custom_abs(Q1.center()) + sage: B = Berkovich_Cp_Affine(Qp(3)) # optional - sage.rings.padics + sage: Q1 = B(9) # optional - sage.rings.padics + sage: Q1._custom_abs(Q1.center()) # optional - sage.rings.padics 1/9 """ if self._base_type == 'padic field': @@ -450,15 +450,15 @@ def center_function(self): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(5) - sage: L. = PolynomialRing(Qp(5)) - sage: T = FractionField(L) - sage: f = T(1/t) + sage: B = Berkovich_Cp_Projective(5) # optional - sage.rings.padics + sage: L. = PolynomialRing(Qp(5)) # optional - sage.rings.padics + sage: T = FractionField(L) # optional - sage.rings.padics + sage: f = T(1/t) # optional - sage.rings.padics sage: R. = RR[] sage: Y = FractionField(R) - sage: g = (40*pi)/x - sage: Q1 = B(f, g) - sage: Q1.center_function() + sage: g = (40*pi)/x # optional - sage.symbolic + sage: Q1 = B(f, g) # optional - sage.rings.padics sage.symbolic + sage: Q1.center_function() # optional - sage.rings.padics sage.symbolic (1 + O(5^20))/((1 + O(5^20))*t) """ if self.type_of_point() != 4: @@ -478,15 +478,15 @@ def radius_function(self): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(5) - sage: L. = PolynomialRing(Qp(5)) - sage: T = FractionField(L) - sage: f = T(1/t) + sage: B = Berkovich_Cp_Projective(5) # optional - sage.rings.padics + sage: L. = PolynomialRing(Qp(5)) # optional - sage.rings.padics + sage: T = FractionField(L) # optional - sage.rings.padics + sage: f = T(1/t) # optional - sage.rings.padics sage: R. = RR[] sage: Y = FractionField(R) - sage: g = (40*pi)/x - sage: Q1 = B(f, g) - sage: Q1.radius_function() + sage: g = (40*pi)/x # optional - sage.symbolic + sage: Q1 = B(f, g) # optional - sage.rings.padics sage.symbolic + sage: Q1.radius_function() # optional - sage.rings.padics sage.symbolic 40.0000000000000*pi/x """ if self.type_of_point() != 4: @@ -506,14 +506,14 @@ def precision(self): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(Qp(3)) - sage: d = B([2, 2, 2], [1.761, 1.123, 1.112]) - sage: d.precision() + sage: B = Berkovich_Cp_Affine(Qp(3)) # optional - sage.rings.padics + sage: d = B([2, 2, 2], [1.761, 1.123, 1.112]) # optional - sage.rings.padics + sage: d.precision() # optional - sage.rings.padics 3 TESTS:: - sage: d.precision == d.prec + sage: d.precision == d.prec # optional - sage.rings.padics True """ if self._type in [1, 2, 3]: @@ -537,8 +537,8 @@ def ideal(self): :: - sage: B = Berkovich_Cp_Projective(3) - sage: B(0).ideal() + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: B(0).ideal() # optional - sage.rings.padics """ return self.parent().ideal() @@ -557,15 +557,15 @@ def power(self): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: Q1 = B(1, 9) - sage: Q1.power() + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: Q1 = B(1, 9) # optional - sage.rings.padics + sage: Q1.power() # optional - sage.rings.padics 2 :: - sage: Q2 = B(1, 4) - sage: Q2.power() + sage: Q2 = B(1, 4) # optional - sage.rings.padics + sage: Q2.power() # optional - sage.rings.padics 1.26185950714291 """ if self._type in [1, 4]: @@ -583,15 +583,15 @@ def radius(self): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: Q1 = B(1, 2/5) - sage: Q1.radius() + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: Q1 = B(1, 2/5) # optional - sage.rings.padics + sage: Q1.radius() # optional - sage.rings.padics 0.400000000000000 :: - sage: d = B([2, 2, 2], [1.761, 1.123, 1.112]) - sage: d.radius() + sage: d = B([2, 2, 2], [1.761, 1.123, 1.112]) # optional - sage.rings.padics + sage: d.radius() # optional - sage.rings.padics [1.76100000000000, 1.12300000000000, 1.11200000000000] """ if self._type == 4: @@ -618,38 +618,38 @@ def diameter(self, basepoint=Infinity): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: Q1 = B(3) - sage: Q1.diameter() + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: Q1 = B(3) # optional - sage.rings.padics + sage: Q1.diameter() # optional - sage.rings.padics 0 :: - sage: Q2 = B(1/2, 9) - sage: Q2.diameter() + sage: Q2 = B(1/2, 9) # optional - sage.rings.padics + sage: Q2.diameter() # optional - sage.rings.padics 9.00000000000000 The diameter of a type IV point is the limit of the radii:: - sage: R. = PolynomialRing(Qp(3)) - sage: f = R(2) - sage: S. = PolynomialRing(RR) - sage: S = FractionField(S) - sage: g = (y+1)/y - sage: B(f,g).diameter() + sage: R. = PolynomialRing(Qp(3)) # optional - sage.rings.padics + sage: f = R(2) # optional - sage.rings.padics + sage: S. = PolynomialRing(RR) # optional - sage.rings.padics + sage: S = FractionField(S) # optional - sage.rings.padics + sage: g = (y+1)/y # optional - sage.rings.padics + sage: B(f,g).diameter() # optional - sage.rings.padics 1.0 :: - sage: B = Berkovich_Cp_Affine(3) - sage: Q1 = B(1/81, 1) - sage: Q2 = B(1/3) - sage: Q1.diameter(Q2) + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: Q1 = B(1/81, 1) # optional - sage.rings.padics + sage: Q2 = B(1/3) # optional - sage.rings.padics + sage: Q1.diameter(Q2) # optional - sage.rings.padics 0.00137174211248285 :: - sage: Q2.diameter(Q2) + sage: Q2.diameter(Q2) # optional - sage.rings.padics +infinity """ if basepoint == Infinity: @@ -687,27 +687,27 @@ def path_distance_metric(self, other): INPUT: - - ``other`` -- A point of the same Berkovich space as this point. + - ``other`` -- A point of the same Berkovich space as this point. OUTPUT: A finite or infinite real number. EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: Q1 = B(1/4, 4) - sage: Q2 = B(1/4, 6) - sage: Q1.path_distance_metric(Q2) + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: Q1 = B(1/4, 4) # optional - sage.rings.padics + sage: Q2 = B(1/4, 6) # optional - sage.rings.padics + sage: Q1.path_distance_metric(Q2) # optional - sage.rings.padics 0.369070246428542 :: - sage: Q3 = B(1) - sage: Q3.path_distance_metric(Q1) + sage: Q3 = B(1) # optional - sage.rings.padics + sage: Q3.path_distance_metric(Q1) # optional - sage.rings.padics +infinity :: - sage: Q3.path_distance_metric(Q3) + sage: Q3.path_distance_metric(Q3) # optional - sage.rings.padics 0 """ if not isinstance(other, type(self)): @@ -744,20 +744,20 @@ def Hsia_kernel(self, other, basepoint): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B(2, 9) - sage: Q2 = B(1/27, 1/27) - sage: Q3 = B(1, 1/3) - sage: Q1.Hsia_kernel(Q2, Q3) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B(2, 9) # optional - sage.rings.padics + sage: Q2 = B(1/27, 1/27) # optional - sage.rings.padics + sage: Q3 = B(1, 1/3) # optional - sage.rings.padics + sage: Q1.Hsia_kernel(Q2, Q3) # optional - sage.rings.padics 0.111111111111111 :: - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B(2, 9) - sage: Q2 = B(1/2) - sage: Q3 = B(1/2) - sage: Q1.Hsia_kernel(Q2, Q3) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B(2, 9) # optional - sage.rings.padics + sage: Q2 = B(1/2) # optional - sage.rings.padics + sage: Q3 = B(1/2) # optional - sage.rings.padics + sage: Q1.Hsia_kernel(Q2, Q3) # optional - sage.rings.padics +infinity """ @@ -790,10 +790,10 @@ def small_metric(self, other): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: Q1 = B(1/4, 4) - sage: Q2 = B(1/4, 6) - sage: Q1.small_metric(Q2) + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: Q1 = B(1/4, 4) # optional - sage.rings.padics + sage: Q2 = B(1/4, 6) # optional - sage.rings.padics + sage: Q1.small_metric(Q2) # optional - sage.rings.padics 0.0833333333333333 :: @@ -853,20 +853,20 @@ def potential_kernel(self, other, basepoint): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B(27, 1) - sage: Q2 = B(1/3, 2) - sage: Q3 = B(1/9, 1/2) - sage: Q3.potential_kernel(Q1, Q2) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B(27, 1) # optional - sage.rings.padics + sage: Q2 = B(1/3, 2) # optional - sage.rings.padics + sage: Q3 = B(1/9, 1/2) # optional - sage.rings.padics + sage: Q3.potential_kernel(Q1, Q2) # optional - sage.rings.padics 0.369070246428543 :: - sage: B = Berkovich_Cp_Affine(3) - sage: Q1 = B(27, 1) - sage: Q2 = B(1/3, 2) - sage: Q3 = B(1/9, 1/2) - sage: Q3.potential_kernel(Q1, Q2) + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: Q1 = B(27, 1) # optional - sage.rings.padics + sage: Q2 = B(1/3, 2) # optional - sage.rings.padics + sage: Q3 = B(1/9, 1/2) # optional - sage.rings.padics + sage: Q3.potential_kernel(Q1, Q2) # optional - sage.rings.padics 0.369070246428543 """ if not isinstance(other, type(self)): @@ -895,16 +895,16 @@ def spherical_kernel(self, other): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B(2, 2) - sage: Q2 = B(1/9, 1) - sage: Q1.spherical_kernel(Q2) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B(2, 2) # optional - sage.rings.padics + sage: Q2 = B(1/9, 1) # optional - sage.rings.padics + sage: Q1.spherical_kernel(Q2) # optional - sage.rings.padics 0.500000000000000 :: - sage: Q3 = B(2) - sage: Q3.spherical_kernel(Q3) + sage: Q3 = B(2) # optional - sage.rings.padics + sage: Q3.spherical_kernel(Q3) # optional - sage.rings.padics 0 """ if not isinstance(other, type(self)): @@ -933,21 +933,21 @@ def Hsia_kernel_infinity(self, other): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(Qp(3)) - sage: Q1 = B(1/4, 4) - sage: Q2 = B(1/4, 6) - sage: Q1.Hsia_kernel_infinity(Q2) + sage: B = Berkovich_Cp_Affine(Qp(3)) # optional - sage.rings.padics + sage: Q1 = B(1/4, 4) # optional - sage.rings.padics + sage: Q2 = B(1/4, 6) # optional - sage.rings.padics + sage: Q1.Hsia_kernel_infinity(Q2) # optional - sage.rings.padics 6.00000000000000 :: sage: R. = QQ[] - sage: A. = NumberField(x^3 + 20) - sage: ideal = A.ideal(-1/2*a^2 + a - 3) - sage: B = Berkovich_Cp_Projective(A, ideal) - sage: Q1 = B(4) - sage: Q2 = B(0, 1.5) - sage: Q1.Hsia_kernel_infinity(Q2) + sage: A. = NumberField(x^3 + 20) # optional - sage.rings.number_field + sage: ideal = A.ideal(-1/2*a^2 + a - 3) # optional - sage.rings.number_field + sage: B = Berkovich_Cp_Projective(A, ideal) # optional - sage.rings.number_field + sage: Q1 = B(4) # optional - sage.rings.number_field + sage: Q2 = B(0, 1.5) # optional - sage.rings.number_field + sage: Q1.Hsia_kernel_infinity(Q2) # optional - sage.rings.number_field 1.50000000000000 """ return self.join(other).diameter() @@ -961,23 +961,23 @@ def center(self): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: B(3, 1).center() + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: B(3, 1).center() # optional - sage.rings.padics 3 + O(3^21) :: - sage: C = Berkovich_Cp_Projective(3) - sage: C(3, 1).center() + sage: C = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: C(3, 1).center() # optional - sage.rings.padics (3 + O(3^21) : 1 + O(3^20)) :: sage: R. = QQ[] - sage: A. = NumberField(x^3 + 20) - sage: ideal = A.ideal(-1/2*a^2 + a - 3) - sage: B = Berkovich_Cp_Projective(A, ideal) - sage: B(a^2 + 4).center() + sage: A. = NumberField(x^3 + 20) # optional - sage.rings.number_field + sage: ideal = A.ideal(-1/2*a^2 + a - 3) # optional - sage.rings.number_field + sage: B = Berkovich_Cp_Projective(A, ideal) # optional - sage.rings.number_field + sage: B(a^2 + 4).center() # optional - sage.rings.number_field (a^2 + 4 : 1) """ if self._type == 4: @@ -992,13 +992,13 @@ def type_of_point(self): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: B(1).type_of_point() + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: B(1).type_of_point() # optional - sage.rings.padics 1 :: - sage: B(0, 1).type_of_point() + sage: B(0, 1).type_of_point() # optional - sage.rings.padics 2 """ return ZZ(self._type) @@ -1011,8 +1011,8 @@ def prime(self): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: B(1).prime() + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: B(1).prime() # optional - sage.rings.padics 3 """ return ZZ(self._p) @@ -1023,10 +1023,10 @@ def __ne__(self, other): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: Q1 = B(3, 3**(1/2)) - sage: Q2 = B(3, RR(3**(1/2))) - sage: Q1 != Q2 + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: Q1 = B(3, 3**(1/2)) # optional - sage.rings.padics sage.symbolic + sage: Q2 = B(3, RR(3**(1/2))) # optional - sage.rings.padics sage.symbolic + sage: Q1 != Q2 # optional - sage.rings.padics sage.symbolic False """ return not (self == other) @@ -1037,8 +1037,8 @@ def _repr_(self): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: B(2, 1) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: B(2, 1) # optional - sage.rings.padics Type II point centered at (2 + O(3^20) : 1 + O(3^20)) of radius 3^0 """ if self._type == 1: @@ -1067,8 +1067,8 @@ def _latex_(self): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: latex(B(2, 1)) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: latex(B(2, 1)) # optional - sage.rings.padics \text{type 2 Point of } \text{Projective Berkovich line over } \Bold{C}_{3} \text{equivalent to the disk centered at (2 + O(3^20) : 1 + O(3^20)) of radius 1.00000000000000 in } \Bold{C}_3 @@ -1132,122 +1132,122 @@ class Berkovich_Element_Cp_Affine(Berkovich_Element_Cp): Type I points can be created by specifying the corresponding point of ``Cp``:: - sage: B = Berkovich_Cp_Affine(Qp(3)) - sage: B(4) + sage: B = Berkovich_Cp_Affine(Qp(3)) # optional - sage.rings.padics + sage: B(4) # optional - sage.rings.padics Type I point centered at 1 + 3 + O(3^20) The center of a point can be an element of a finite extension of ``Qp``:: - sage: A. = Qq(27) - sage: B(1 + t) + sage: A. = Qq(27) # optional - sage.rings.padics + sage: B(1 + t) # optional - sage.rings.padics Type I point centered at (t + 1) + O(3^20) Type II and III points can be created by specifying a center and a radius:: - sage: B(2, 3**(1/2)) + sage: B(2, 3**(1/2)) # optional - sage.rings.padics sage.symbolic Type II point centered at 2 + O(3^20) of radius 3^1/2 :: - sage: B(2, 1.6) + sage: B(2, 1.6) # optional - sage.rings.padics Type III point centered at 2 + O(3^20) of radius 1.60000000000000 Some type II points may be mistaken for type III points:: - sage: B(3, 3**0.5) #not tested + sage: B(3, 3**0.5) #not tested # optional - sage.rings.padics Type III point centered at 3 + O(3^21) of radius 1.73205080756888 To avoid these errors, specify the power instead of the radius:: - sage: B(3, power=RR(1/100000)) + sage: B(3, power=RR(1/100000)) # optional - sage.rings.padics Type II point centered at 3 + O(3^21) of radius 3^1/100000 Type IV points can be constructed in a number of ways, the first being from a list of centers and radii used to approximate the point:: - sage: B([Qp(3)(2), Qp(3)(2), Qp(3)(2)], [1.761, 1.123, 1.112]) + sage: B([Qp(3)(2), Qp(3)(2), Qp(3)(2)], [1.761, 1.123, 1.112]) # optional - sage.rings.padics Type IV point of precision 3, approximated by disks centered at [2 + O(3^20), 2 + O(3^20)] ... with radii [1.76100000000000, 1.12300000000000] ... Type IV points can be constructed from univariate functions, with arbitrary precision:: - sage: A. = Qq(27) - sage: R. = PolynomialRing(A) - sage: f = (1 + t)^2*x - sage: S. = PolynomialRing(RR) - sage: S = FractionField(S) - sage: g = (y + 1)/y - sage: d = B(f, g, prec=100); d + sage: A. = Qq(27) # optional - sage.rings.padics + sage: R. = PolynomialRing(A) # optional - sage.rings.padics + sage: f = (1 + t)^2*x # optional - sage.rings.padics + sage: S. = PolynomialRing(RR) # optional - sage.rings.padics + sage: S = FractionField(S) # optional - sage.rings.padics + sage: g = (y + 1)/y # optional - sage.rings.padics + sage: d = B(f, g, prec=100); d # optional - sage.rings.padics Type IV point of precision 100 with centers given by ((t^2 + 2*t + 1) + O(3^20))*x and radii given by (y + 1.00000000000000)/y - For increased performance, error_check can be set to ``False``. WARNING: with error check set + For increased performance, ``error_check`` can be set to ``False``. WARNING: with error check set to ``False``, any error in the input will lead to incorrect results:: - sage: B(f, g, prec=100, error_check=False) + sage: B(f, g, prec=100, error_check=False) # optional - sage.rings.padics Type IV point of precision 100 with centers given by ((t^2 + 2*t + 1) + O(3^20))*x and radii given by (y + 1.00000000000000)/y When creating a Berkovich space backed by a number field, points can be created similarly:: sage: R. = QQ[] - sage: A. = NumberField(x^3 + 20) - sage: ideal = A.prime_above(3) - sage: B = Berkovich_Cp_Projective(A, ideal) - sage: Q1 = B(a); Q1 + sage: A. = NumberField(x^3 + 20) # optional - sage.rings.number_field + sage: ideal = A.prime_above(3) # optional - sage.rings.number_field + sage: B = Berkovich_Cp_Projective(A, ideal) # optional - sage.rings.number_field + sage: Q1 = B(a); Q1 # optional - sage.rings.number_field Type I point centered at (a : 1) :: - sage: B(a + 1, 3) + sage: B(a + 1, 3) # optional - sage.rings.number_field Type II point centered at (a + 1 : 1) of radius 3^1 TESTS:: - sage: A = Berkovich_Cp_Affine(3) - sage: Q1 = A(3, 1); Q1 + sage: A = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: Q1 = A(3, 1); Q1 # optional - sage.rings.padics Type II point centered at 3 + O(3^21) of radius 3^0 - sage: Q2 = A(2.5, 1); Q2 + sage: Q2 = A(2.5, 1); Q2 # optional - sage.rings.padics Type II point centered at 1 + 2*3 + 3^2 + 3^3 + 3^4 + 3^5 + 3^6 + 3^7 + 3^8 + 3^9 + 3^10 + 3^11 + 3^12 + 3^13 + 3^14 + 3^15 + 3^16 + 3^17 + 3^18 + 3^19 + O(3^20) of radius 3^0 - sage: Q5 = A(3, 0); Q5 + sage: Q5 = A(3, 0); Q5 # optional - sage.rings.padics Type I point centered at 3 + O(3^21) - sage: A(Zp(3)(2), 2).center().parent() == A(Qp(3)(2), 2).center().parent() + sage: A(Zp(3)(2), 2).center().parent() == A(Qp(3)(2), 2).center().parent() # optional - sage.rings.padics True - sage: Q1 == Q2 + sage: Q1 == Q2 # optional - sage.rings.padics True - sage: Q1 == Q5 + sage: Q1 == Q5 # optional - sage.rings.padics False - sage: Q3 = A(Qp(3)(3), power=0, error_check=False); Q3 + sage: Q3 = A(Qp(3)(3), power=0, error_check=False); Q3 # optional - sage.rings.padics Type II point centered at 3 + O(3^21) of radius 3^0 - sage: Q4 = A(3, 3**0); Q4 + sage: Q4 = A(3, 3**0); Q4 # optional - sage.rings.padics Type II point centered at 3 + O(3^21) of radius 3^0 - sage: Q5 = A(3, power=1/2); Q5 + sage: Q5 = A(3, power=1/2); Q5 # optional - sage.rings.padics Type II point centered at 3 + O(3^21) of radius 3^1/2 - sage: Q6 = A(3, RR(3**(1/2))); Q6 + sage: Q6 = A(3, RR(3**(1/2))); Q6 # optional - sage.rings.padics sage.symbolic Type III point centered at 3 + O(3^21) of radius 1.73205080756888 - sage: Q5 == Q6 + sage: Q5 == Q6 # optional - sage.rings.padics sage.symbolic True - sage: k = Qp(5) - sage: R. = k[] - sage: l. = k.extension(x^2 - 5) - sage: B = Berkovich_Cp_Affine(5) - sage: B(w, power=1) + sage: k = Qp(5) # optional - sage.rings.padics + sage: R. = k[] # optional - sage.rings.padics + sage: l. = k.extension(x^2 - 5) # optional - sage.rings.padics + sage: B = Berkovich_Cp_Affine(5) # optional - sage.rings.padics + sage: B(w, power=1) # optional - sage.rings.padics Type II point centered at w + O(w^41) of radius 5^1 - sage: TestSuite(Q5).run() + sage: TestSuite(Q5).run() # optional - sage.rings.padics """ def __init__(self, parent, center, radius=None, power=None, prec=20, error_check=True): @@ -1256,8 +1256,8 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, error_check EXAMPLES:: - sage: A = Berkovich_Cp_Affine(17) - sage: A(5, 1) + sage: A = Berkovich_Cp_Affine(17) # optional - sage.rings.padics + sage: A(5, 1) # optional - sage.rings.padics Type II point centered at 5 + O(17^20) of radius 17^0 """ # we call Berkovich_Element_Cp constructor which is shared with projective Berkovich space @@ -1283,25 +1283,25 @@ def as_projective_point(self): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(5) - sage: B(5).as_projective_point() + sage: B = Berkovich_Cp_Affine(5) # optional - sage.rings.padics + sage: B(5).as_projective_point() # optional - sage.rings.padics Type I point centered at (5 + O(5^21) : 1 + O(5^20)) :: - sage: B(0, 1).as_projective_point() + sage: B(0, 1).as_projective_point() # optional - sage.rings.padics Type II point centered at (0 : 1 + O(5^20)) of radius 5^0 :: - sage: L. = PolynomialRing(Qp(5)) - sage: T = FractionField(L) - sage: f = T(1/t) - sage: R. = RR[] - sage: Y = FractionField(R) - sage: g = (40*pi)/x - sage: Q2 = B(f, g) - sage: Q2.as_projective_point() + sage: L. = PolynomialRing(Qp(5)) # optional - sage.rings.padics + sage: T = FractionField(L) # optional - sage.rings.padics + sage: f = T(1/t) # optional - sage.rings.padics + sage: R. = RR[] # optional - sage.rings.padics + sage: Y = FractionField(R) # optional - sage.rings.padics + sage: g = (40*pi)/x # optional - sage.rings.padics sage.symbolic + sage: Q2 = B(f, g) # optional - sage.rings.padics sage.symbolic + sage: Q2.as_projective_point() # optional - sage.rings.padics sage.symbolic Type IV point of precision 20 with centers given by (1 + O(5^20))/((1 + O(5^20))*t) and radii given by 40.0000000000000*pi/x """ @@ -1329,28 +1329,28 @@ def __eq__(self, other): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B(1, RR(3**(1/2))) - sage: Q2 = B(1, 3**(1/2)) - sage: Q1 == Q2 + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B(1, RR(3**(1/2))) # optional - sage.rings.padics sage.symbolic + sage: Q2 = B(1, 3**(1/2)) # optional - sage.rings.padics sage.symbolic + sage: Q1 == Q2 # optional - sage.rings.padics sage.symbolic True :: - sage: Q3 = B(1) - sage: Q4 = B(4) - sage: Q3 == Q4 + sage: Q3 = B(1) # optional - sage.rings.padics + sage: Q4 = B(4) # optional - sage.rings.padics + sage: Q3 == Q4 # optional - sage.rings.padics False :: - sage: Q5 = B(1, 4) - sage: Q1 == Q5 + sage: Q5 = B(1, 4) # optional - sage.rings.padics + sage: Q1 == Q5 # optional - sage.rings.padics sage.symbolic False :: - sage: Q1 == Q3 + sage: Q1 == Q3 # optional - sage.rings.padics sage.symbolic False """ if other is self: @@ -1379,21 +1379,21 @@ def __hash__(self): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: Q1 = B(1, RR(3**(1/2))) - sage: Q2 = B(1, 3**(1/2)) - sage: hash(Q1) == hash(Q2) + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: Q1 = B(1, RR(3**(1/2))) # optional - sage.rings.padics sage.symbolic + sage: Q2 = B(1, 3**(1/2)) # optional - sage.rings.padics sage.symbolic + sage: hash(Q1) == hash(Q2) # optional - sage.rings.padics sage.symbolic True :: sage: R. = QQ[] - sage: A. = NumberField(x^3+20) - sage: ideal = A.ideal(-1/2*a^2 + a - 3) - sage: B = Berkovich_Cp_Projective(A, ideal) - sage: Q1 = B(a^2+1, 2) - sage: Q2 = B(0, 2) - sage: hash(Q1) == hash(Q2) + sage: A. = NumberField(x^3 + 20) # optional - sage.rings.number_field + sage: ideal = A.ideal(-1/2*a^2 + a - 3) # optional - sage.rings.number_field + sage: B = Berkovich_Cp_Projective(A, ideal) # optional - sage.rings.number_field + sage: Q1 = B(a^2 + 1, 2) # optional - sage.rings.number_field + sage: Q2 = B(0, 2) # optional - sage.rings.number_field + sage: hash(Q1) == hash(Q2) # optional - sage.rings.number_field True """ if self.type_of_point() == 1: @@ -1425,40 +1425,40 @@ def lt(self, other): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B(5, 0.5) - sage: Q2 = B(5, 1) - sage: Q1.lt(Q2) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B(5, 0.5) # optional - sage.rings.padics + sage: Q2 = B(5, 1) # optional - sage.rings.padics + sage: Q1.lt(Q2) # optional - sage.rings.padics True :: - sage: Q3 = B(1) - sage: Q1.lt(Q3) + sage: Q3 = B(1) # optional - sage.rings.padics + sage: Q1.lt(Q3) # optional - sage.rings.padics False TESTS:: - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B(5) - sage: Q1.lt(Q1) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B(5) # optional - sage.rings.padics + sage: Q1.lt(Q1) # optional - sage.rings.padics False :: - sage: Q2 = B([4, 1/3], [5, 1]) - sage: Q1.lt(Q2) + sage: Q2 = B([4, 1/3], [5, 1]) # optional - sage.rings.padics + sage: Q1.lt(Q2) # optional - sage.rings.padics False :: - sage: Q4 = B(0, 1) - sage: Q1.lt(Q4) + sage: Q4 = B(0, 1) # optional - sage.rings.padics + sage: Q1.lt(Q4) # optional - sage.rings.padics True :: - sage: Q2.lt(Q4) + sage: Q2.lt(Q4) # optional - sage.rings.padics False """ if not isinstance(other, Berkovich_Element_Cp_Affine): @@ -1569,40 +1569,40 @@ def join(self, other, basepoint=Infinity): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: Q1 = B(2, 1) - sage: Q2 = B(2, 2) - sage: Q1.join(Q2) + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: Q1 = B(2, 1) # optional - sage.rings.padics + sage: Q2 = B(2, 2) # optional - sage.rings.padics + sage: Q1.join(Q2) # optional - sage.rings.padics Type III point centered at 2 + O(3^20) of radius 2.00000000000000 :: - sage: Q3 = B(5) - sage: Q3.join(Q1) + sage: Q3 = B(5) # optional - sage.rings.padics + sage: Q3.join(Q1) # optional - sage.rings.padics Type II point centered at 2 + 3 + O(3^20) of radius 3^0 :: - sage: Q3.join(Q1, basepoint=Q2) + sage: Q3.join(Q1, basepoint=Q2) # optional - sage.rings.padics Type II point centered at 2 + O(3^20) of radius 3^0 TESTS:: - sage: Q4 = B(1/3**8 + 2, 1) - sage: Q2.join(Q4, basepoint = Q1) + sage: Q4 = B(1/3**8 + 2, 1) # optional - sage.rings.padics + sage: Q2.join(Q4, basepoint=Q1) # optional - sage.rings.padics Type III point centered at 2 + O(3^20) of radius 2.00000000000000 :: - sage: Q5 = B(2, 1/9) - sage: Q6 = B(1, 1/27) - sage: Q4.join(Q5, basepoint=Q6) + sage: Q5 = B(2, 1/9) # optional - sage.rings.padics + sage: Q6 = B(1, 1/27) # optional - sage.rings.padics + sage: Q4.join(Q5, basepoint=Q6) # optional - sage.rings.padics Type II point centered at 1 + O(3^20) of radius 3^0 :: - sage: Q7 = B(1/27, 1/27) - sage: Q1.join(Q7, Q2) + sage: Q7 = B(1/27, 1/27) # optional - sage.rings.padics + sage: Q1.join(Q7, Q2) # optional - sage.rings.padics Type III point centered at 2 + O(3^20) of radius 2.00000000000000 """ # we error check and then pass to projective space to do the join @@ -1648,46 +1648,46 @@ def involution_map(self): The involution map is 1/z on type I points:: - sage: B = Berkovich_Cp_Affine(3) - sage: Q1 = B(1/2) - sage: Q1.involution_map() + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: Q1 = B(1/2) # optional - sage.rings.padics + sage: Q1.involution_map() # optional - sage.rings.padics Type I point centered at 2 + O(3^20) :: - sage: Q2 = B(0, 1/3) - sage: Q2.involution_map() + sage: Q2 = B(0, 1/3) # optional - sage.rings.padics + sage: Q2.involution_map() # optional - sage.rings.padics Type II point centered at 0 of radius 3^1 :: - sage: Q3 = B(1/3, 1/3) - sage: Q3.involution_map() + sage: Q3 = B(1/3, 1/3) # optional - sage.rings.padics + sage: Q3.involution_map() # optional - sage.rings.padics Type II point centered at 3 + O(3^21) of radius 3^-3 TESTS:: - sage: B = Berkovich_Cp_Affine(3) - sage: B(0).involution_map() + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: B(0).involution_map() # optional - sage.rings.padics Traceback (most recent call last): ... ValueError: involution map not defined on affine type I point centered at 0 :: - sage: B(1/81, 1.5).involution_map() + sage: B(1/81, 1.5).involution_map() # optional - sage.rings.padics Type III point centered at 3^4 + O(3^24) of radius 0.000228623685413809 :: - sage: B([1, 2], [3, 1]).involution_map() + sage: B([1, 2], [3, 1]).involution_map() # optional - sage.rings.padics Traceback (most recent call last): ... ValueError: precision of type IV is not high enough to define image :: - sage: B([1/81, 10/81], [10, 9]).involution_map() + sage: B([1/81, 10/81], [10, 9]).involution_map() # optional - sage.rings.padics Type IV point of precision 2, approximated by disks centered at [3^4 + O(3^24), 3^4 + 2*3^6 + 2*3^7 + 2*3^10 + 2*3^11 + 2*3^14 + 2*3^15 + 2*3^18 + 2*3^19 + 2*3^22 + 2*3^23 + O(3^24)] ... with radii [0.00152415790275873, 0.00137174211248285] ... @@ -1741,17 +1741,17 @@ def contained_in_interval(self, start, end): EXAMPLES:: - sage: B = Berkovich_Cp_Projective((3)) - sage: Q1 = B(2, 1) - sage: Q2 = B(2, 4) - sage: Q3 = B(1/3) - sage: Q2.contained_in_interval(Q1, Q3.join(Q1)) + sage: B = Berkovich_Cp_Projective((3)) # optional - sage.rings.padics + sage: Q1 = B(2, 1) # optional - sage.rings.padics + sage: Q2 = B(2, 4) # optional - sage.rings.padics + sage: Q3 = B(1/3) # optional - sage.rings.padics + sage: Q2.contained_in_interval(Q1, Q3.join(Q1)) # optional - sage.rings.padics False :: - sage: Q4 = B(1/81, 1) - sage: Q2.contained_in_interval(Q1, Q4.join(Q1)) + sage: Q4 = B(1/81, 1) # optional - sage.rings.padics + sage: Q2.contained_in_interval(Q1, Q4.join(Q1)) # optional - sage.rings.padics True """ if not isinstance(start, Berkovich_Element_Cp_Affine): @@ -1821,39 +1821,39 @@ class Berkovich_Element_Cp_Projective(Berkovich_Element_Cp): Type I points can be created by specifying the corresponding point of `P^1(\CC_p)`:: - sage: S = ProjectiveSpace(Qp(5), 1) - sage: P = Berkovich_Cp_Projective(S); P + sage: S = ProjectiveSpace(Qp(5), 1) # optional - sage.rings.padics + sage: P = Berkovich_Cp_Projective(S); P # optional - sage.rings.padics Projective Berkovich line over Cp(5) of precision 20 :: - sage: a = S(0, 1) - sage: Q1 = P(a); Q1 + sage: a = S(0, 1) # optional - sage.rings.padics + sage: Q1 = P(a); Q1 # optional - sage.rings.padics Type I point centered at (0 : 1 + O(5^20)) :: - sage: Q2 = P((1,0)); Q2 + sage: Q2 = P((1,0)); Q2 # optional - sage.rings.padics Type I point centered at (1 + O(5^20) : 0) Type II and III points can be created by specifying a center and a radius:: - sage: Q3 = P((0,5), 5**(3/2)); Q3 + sage: Q3 = P((0,5), 5**(3/2)); Q3 # optional - sage.rings.padics sage.symbolic Type II point centered at (0 : 1 + O(5^20)) of radius 5^3/2 :: - sage: Q4 = P(0, 3**(3/2)); Q4 + sage: Q4 = P(0, 3**(3/2)); Q4 # optional - sage.rings.padics sage.symbolic Type III point centered at (0 : 1 + O(5^20)) of radius 5.19615242270663 Type IV points can be created from lists of centers and radii:: - sage: b = S((3,2)) #create centers - sage: c = S((4,3)) - sage: d = S((2,3)) - sage: L = [b, c, d] - sage: R = [1.761, 1.123, 1.112] - sage: Q5 = P(L, R); Q5 + sage: b = S((3,2)) # create centers # optional - sage.rings.padics + sage: c = S((4,3)) # optional - sage.rings.padics + sage: d = S((2,3)) # optional - sage.rings.padics + sage: L = [b, c, d] # optional - sage.rings.padics + sage: R = [1.761, 1.123, 1.112] # optional - sage.rings.padics + sage: Q5 = P(L, R); Q5 # optional - sage.rings.padics Type IV point of precision 3, approximated by disks centered at [(4 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + 2*5^7 + 2*5^8 + 2*5^9 + 2*5^10 + 2*5^11 + 2*5^12 + 2*5^13 + 2*5^14 + 2*5^15 + 2*5^16 + 2*5^17 + 2*5^18 + 2*5^19 + O(5^20) : @@ -1865,26 +1865,26 @@ class Berkovich_Element_Cp_Projective(Berkovich_Element_Cp): the sequence of disks can not be the point at infinity in `P^1(\CC_p)`, only functions into `\CC_p` are supported:: - sage: L. = PolynomialRing(Qp(5)) - sage: T = FractionField(L) - sage: f = T(1/t) + sage: L. = PolynomialRing(Qp(5)) # optional - sage.rings.padics + sage: T = FractionField(L) # optional - sage.rings.padics + sage: f = T(1/t) # optional - sage.rings.padics sage: R. = RR[] sage: Y = FractionField(R) - sage: g = (40*pi)/x - sage: Q6 = P(f, g); Q6 + sage: g = (40*pi)/x # optional - sage.rings.padics sage.symbolic + sage: Q6 = P(f, g); Q6 # optional - sage.rings.padics sage.symbolic Type IV point of precision 20 with centers given by (1 + O(5^20))/((1 + O(5^20))*t) and radii given by 40.0000000000000*pi/x TESTS:: - sage: P((1,0), 3) + sage: P((1,0), 3) # optional - sage.rings.padics Traceback (most recent call last): ... ValueError: type II and III points can not be centered at infinity - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B(3) - sage: TestSuite(Q1).run() + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B(3) # optional - sage.rings.padics + sage: TestSuite(Q1).run() # optional - sage.rings.padics """ def __init__(self, parent, center, radius=None, power=None, prec=20, error_check=True): @@ -1893,9 +1893,9 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, error_check EXAMPLES:: - sage: S = ProjectiveSpace(Qp(7), 1) - sage: P = Berkovich_Cp_Projective(S) - sage: P(0,1) + sage: S = ProjectiveSpace(Qp(7), 1) # optional - sage.rings.padics + sage: P = Berkovich_Cp_Projective(S) # optional - sage.rings.padics + sage: P(0,1) # optional - sage.rings.padics Type II point centered at (0 : 1 + O(7^20)) of radius 7^0 """ # if we are given a point of Affine Berkovich Space, we do the conversion @@ -1921,27 +1921,27 @@ def as_affine_point(self): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(5) - sage: B(5).as_affine_point() + sage: B = Berkovich_Cp_Projective(5) # optional - sage.rings.padics + sage: B(5).as_affine_point() # optional - sage.rings.padics Type I point centered at 5 + O(5^21) :: - sage: Q = B(0, 1).as_affine_point(); Q + sage: Q = B(0, 1).as_affine_point(); Q # optional - sage.rings.padics Type II point centered at 0 of radius 5^0 - sage: Q.parent() + sage: Q.parent() # optional - sage.rings.padics Affine Berkovich line over Cp(5) of precision 20 :: - sage: L. = PolynomialRing(Qp(5)) - sage: T = FractionField(L) - sage: f = T(1/t) + sage: L. = PolynomialRing(Qp(5)) # optional - sage.rings.padics + sage: T = FractionField(L) # optional - sage.rings.padics + sage: f = T(1/t) # optional - sage.rings.padics sage: R. = RR[] sage: Y = FractionField(R) - sage: g = (40*pi)/x - sage: Q2 = B(f, g) - sage: Q2.as_affine_point() + sage: g = (40*pi)/x # optional - sage.rings.padics sage.symbolic + sage: Q2 = B(f, g) # optional - sage.rings.padics sage.symbolic + sage: Q2.as_affine_point() # optional - sage.rings.padics sage.symbolic Type IV point of precision 20 with centers given by (1 + O(5^20))/((1 + O(5^20))*t) and radii given by 40.0000000000000*pi/x """ @@ -1973,28 +1973,28 @@ def __eq__(self, other): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B([2, 2], RR(3**(1/2))) - sage: Q2 = B([1, 1], 3**(1/2)) - sage: Q1 == Q2 + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B([2, 2], RR(3**(1/2))) # optional - sage.rings.padics sage.symbolic + sage: Q2 = B([1, 1], 3**(1/2)) # optional - sage.rings.padics sage.symbolic + sage: Q1 == Q2 # optional - sage.rings.padics sage.symbolic True :: - sage: Q3 = B(1) - sage: Q4 = B(4) - sage: Q3 == Q4 + sage: Q3 = B(1) # optional - sage.rings.padics + sage: Q4 = B(4) # optional - sage.rings.padics + sage: Q3 == Q4 # optional - sage.rings.padics False :: - sage: Q5 = B(1, 4) - sage: Q1 == Q5 + sage: Q5 = B(1, 4) # optional - sage.rings.padics + sage: Q1 == Q5 # optional - sage.rings.padics sage.symbolic False :: - sage: Q1 == Q3 + sage: Q1 == Q3 # optional - sage.rings.padics sage.symbolic False """ if other is self: @@ -2025,22 +2025,22 @@ def __hash__(self): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: P = ProjectiveSpace(B.base_ring(), 1) - sage: Q1 = B(P.point([2, 2], False), RR(3**(1/2))) - sage: Q2 = B([1, 1], 3**(1/2)) - sage: hash(Q1) == hash(Q2) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: P = ProjectiveSpace(B.base_ring(), 1) # optional - sage.rings.padics + sage: Q1 = B(P.point([2, 2], False), RR(3**(1/2))) # optional - sage.rings.padics sage.symbolic + sage: Q2 = B([1, 1], 3**(1/2)) # optional - sage.rings.padics sage.symbolic + sage: hash(Q1) == hash(Q2) # optional - sage.rings.padics sage.symbolic True :: sage: R. = QQ[] - sage: A. = NumberField(x^3 + 20) - sage: ideal = A.ideal(-1/2*a^2 + a - 3) - sage: B = Berkovich_Cp_Projective(A, ideal) - sage: Q1 = B(a^2 + 1, 2) - sage: Q2 = B(0, 2) - sage: hash(Q1) == hash(Q2) + sage: A. = NumberField(x^3 + 20) # optional - sage.rings.number_field + sage: ideal = A.ideal(-1/2*a^2 + a - 3) # optional - sage.rings.number_field + sage: B = Berkovich_Cp_Projective(A, ideal) # optional - sage.rings.number_field + sage: Q1 = B(a^2 + 1, 2) # optional - sage.rings.number_field + sage: Q2 = B(0, 2) # optional - sage.rings.number_field + sage: hash(Q1) == hash(Q2) # optional - sage.rings.number_field True """ if self.type_of_point() == 1: @@ -2072,51 +2072,51 @@ def lt(self, other): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B(5, 0.5) - sage: Q2 = B(5, 1) - sage: Q1.lt(Q2) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B(5, 0.5) # optional - sage.rings.padics + sage: Q2 = B(5, 1) # optional - sage.rings.padics + sage: Q1.lt(Q2) # optional - sage.rings.padics True :: - sage: Q3 = B(1) - sage: Q1.lt(Q3) + sage: Q3 = B(1) # optional - sage.rings.padics + sage: Q1.lt(Q3) # optional - sage.rings.padics False TESTS:: - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B(5) - sage: Q1.lt(Q1) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B(5) # optional - sage.rings.padics + sage: Q1.lt(Q1) # optional - sage.rings.padics False :: - sage: Q2 = B([4, 1/3], [5, 1]) - sage: Q1.lt(Q2) + sage: Q2 = B([4, 1/3], [5, 1]) # optional - sage.rings.padics + sage: Q1.lt(Q2) # optional - sage.rings.padics False :: - sage: Q3 = B((1,0)) - sage: Q4 = B(0, 1) - sage: Q3.lt(Q4) + sage: Q3 = B((1,0)) # optional - sage.rings.padics + sage: Q4 = B(0, 1) # optional - sage.rings.padics + sage: Q3.lt(Q4) # optional - sage.rings.padics False :: - sage: Q4.lt(Q3) + sage: Q4.lt(Q3) # optional - sage.rings.padics True :: - sage: Q1.lt(Q4) + sage: Q1.lt(Q4) # optional - sage.rings.padics True :: - sage: Q2.lt(Q4) + sage: Q2.lt(Q4) # optional - sage.rings.padics False """ if not isinstance(other, Berkovich_Element_Cp_Projective): @@ -2251,58 +2251,58 @@ def join(self, other, basepoint=Infinity): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B(2, 1) - sage: Q2 = B(2, 2) - sage: Q1.join(Q2) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B(2, 1) # optional - sage.rings.padics + sage: Q2 = B(2, 2) # optional - sage.rings.padics + sage: Q1.join(Q2) # optional - sage.rings.padics Type III point centered at (2 + O(3^20) : 1 + O(3^20)) of radius 2.00000000000000 :: - sage: Q3 = B(5) - sage: Q3.join(Q1) + sage: Q3 = B(5) # optional - sage.rings.padics + sage: Q3.join(Q1) # optional - sage.rings.padics Type II point centered at (2 + 3 + O(3^20) : 1 + O(3^20)) of radius 3^0 :: - sage: Q3.join(Q1, basepoint=Q2) + sage: Q3.join(Q1, basepoint=Q2) # optional - sage.rings.padics Type II point centered at (2 + O(3^20) : 1 + O(3^20)) of radius 3^0 TESTS:: - sage: Q4 = B(1/3**8 + 2, 1) - sage: Q2.join(Q4, basepoint=Q1) + sage: Q4 = B(1/3**8 + 2, 1) # optional - sage.rings.padics + sage: Q2.join(Q4, basepoint=Q1) # optional - sage.rings.padics Type III point centered at (2 + O(3^20) : 1 + O(3^20)) of radius 2.00000000000000 - sage: Q5 = B(2, 1/9) - sage: Q6 = B(1, 1/27) - sage: Q4.join(Q5, basepoint=Q6) + sage: Q5 = B(2, 1/9) # optional - sage.rings.padics + sage: Q6 = B(1, 1/27) # optional - sage.rings.padics + sage: Q4.join(Q5, basepoint=Q6) # optional - sage.rings.padics Type II point centered at (1 + O(3^20) : 1 + O(3^20)) of radius 3^0 - sage: Q7 = B(1/27, 1/27) - sage: Q1.join(Q7, Q2) + sage: Q7 = B(1/27, 1/27) # optional - sage.rings.padics + sage: Q1.join(Q7, Q2) # optional - sage.rings.padics Type III point centered at (2 + O(3^20) : 1 + O(3^20)) of radius 2.00000000000000 - sage: Q1.join(Q2, Q7) + sage: Q1.join(Q2, Q7) # optional - sage.rings.padics Type III point centered at (2 + O(3^20) : 1 + O(3^20)) of radius 2.00000000000000 - sage: Q8 = B(0, power=1/3) - sage: Q9 = B(0, power=1/2) - sage: Q8.join(Q9) + sage: Q8 = B(0, power=1/3) # optional - sage.rings.padics + sage: Q9 = B(0, power=1/2) # optional - sage.rings.padics + sage: Q8.join(Q9) # optional - sage.rings.padics Type II point centered at (0 : 1 + O(3^20)) of radius 3^1/2 sage: R. = QQ[] - sage: A. = NumberField(x^3 + 20) - sage: ideal = A.prime_above(3) - sage: C = Berkovich_Cp_Projective(A, ideal) - sage: Q10 = C(a, 1/9) - sage: Q10.join(Q9) + sage: A. = NumberField(x^3 + 20) # optional - sage.rings.number_field + sage: ideal = A.prime_above(3) # optional - sage.rings.number_field + sage: C = Berkovich_Cp_Projective(A, ideal) # optional - sage.rings.number_field + sage: Q10 = C(a, 1/9) # optional - sage.rings.number_field + sage: Q10.join(Q9) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: other must be a point of the same projective Berkovich line - sage: Q11 = C(0, 1/3) - sage: Q11.join(Q10) + sage: Q11 = C(0, 1/3) # optional - sage.rings.number_field + sage: Q11.join(Q10) # optional - sage.rings.number_field Type II point centered at (0 : 1) of radius 3^0 """ if not isinstance(other, Berkovich_Element_Cp_Projective): @@ -2415,49 +2415,49 @@ def involution_map(self): The involution map is 1/z on type I points:: - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B(1/2) - sage: Q1.involution_map() + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B(1/2) # optional - sage.rings.padics + sage: Q1.involution_map() # optional - sage.rings.padics Type I point centered at (2 + O(3^20) : 1 + O(3^20)) :: - sage: Q2 = B(0, 1/3) - sage: Q2.involution_map() + sage: Q2 = B(0, 1/3) # optional - sage.rings.padics + sage: Q2.involution_map() # optional - sage.rings.padics Type II point centered at (0 : 1 + O(3^20)) of radius 3^1 :: - sage: Q3 = B(1/3, 1/3) - sage: Q3.involution_map() + sage: Q3 = B(1/3, 1/3) # optional - sage.rings.padics + sage: Q3.involution_map() # optional - sage.rings.padics Type II point centered at (3 + O(3^21) : 1 + O(3^20)) of radius 3^-3 TESTS:: - sage: B = Berkovich_Cp_Projective(3) - sage: B((1,0)).involution_map() + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: B((1,0)).involution_map() # optional - sage.rings.padics Type I point centered at (0 : 1 + O(3^20)) :: - sage: B(0).involution_map() + sage: B(0).involution_map() # optional - sage.rings.padics Type I point centered at (1 + O(3^20) : 0) :: - sage: B(1/81, 1.5).involution_map() + sage: B(1/81, 1.5).involution_map() # optional - sage.rings.padics Type III point centered at (3^4 + O(3^24) : 1 + O(3^20)) of radius 0.000228623685413809 :: - sage: B([1, 2], [3, 1]).involution_map() + sage: B([1, 2], [3, 1]).involution_map() # optional - sage.rings.padics Traceback (most recent call last): ... ValueError: precision of type IV is not high enough to define image :: - sage: B([1/81, 10/81], [10, 9]).involution_map() + sage: B([1/81, 10/81], [10, 9]).involution_map() # optional - sage.rings.padics Type IV point of precision 2, approximated by disks centered at [(3^4 + O(3^24) : 1 + O(3^20)), (3^4 + 2*3^6 + 2*3^7 + 2*3^10 + 2*3^11 + 2*3^14 + 2*3^15 + 2*3^18 + 2*3^19 + 2*3^22 + 2*3^23 + O(3^24) : 1 + O(3^20))] @@ -2514,48 +2514,48 @@ def contained_in_interval(self, start, end): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: Q1 = B(2, 1) - sage: Q2 = B(2, 4) - sage: Q3 = B(1/3) - sage: Q2.contained_in_interval(Q1, Q3.join(Q1)) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: Q1 = B(2, 1) # optional - sage.rings.padics + sage: Q2 = B(2, 4) # optional - sage.rings.padics + sage: Q3 = B(1/3) # optional - sage.rings.padics + sage: Q2.contained_in_interval(Q1, Q3.join(Q1)) # optional - sage.rings.padics False :: - sage: Q4 = B(1/81, 1) - sage: Q2.contained_in_interval(Q1, Q4.join(Q1)) + sage: Q4 = B(1/81, 1) # optional - sage.rings.padics + sage: Q2.contained_in_interval(Q1, Q4.join(Q1)) # optional - sage.rings.padics True TESTS:: - sage: B = Berkovich_Cp_Projective(3) - sage: infty = B((1, 0)) - sage: zero = B(0) - sage: gauss = B(0, 1) - sage: infty.contained_in_interval(zero, gauss) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: infty = B((1, 0)) # optional - sage.rings.padics + sage: zero = B(0) # optional - sage.rings.padics + sage: gauss = B(0, 1) # optional - sage.rings.padics + sage: infty.contained_in_interval(zero, gauss) # optional - sage.rings.padics False :: - sage: Q1 = B(1,3) - sage: infty.contained_in_interval(gauss, Q1) + sage: Q1 = B(1, 3) # optional - sage.rings.padics + sage: infty.contained_in_interval(gauss, Q1) # optional - sage.rings.padics False :: - sage: zero.contained_in_interval(infty, gauss) + sage: zero.contained_in_interval(infty, gauss) # optional - sage.rings.padics False :: - sage: gauss.contained_in_interval(zero, infty) + sage: gauss.contained_in_interval(zero, infty) # optional - sage.rings.padics True :: - sage: Q2 = B(81, 1/3) - sage: gauss.contained_in_interval(infty, Q2) + sage: Q2 = B(81, 1/3) # optional - sage.rings.padics + sage: gauss.contained_in_interval(infty, Q2) # optional - sage.rings.padics True """ if not isinstance(start, Berkovich_Element_Cp_Projective): diff --git a/src/sage/schemes/berkovich/berkovich_space.py b/src/sage/schemes/berkovich/berkovich_space.py index 17eee57dd0a..5a73c368c7d 100644 --- a/src/sage/schemes/berkovich/berkovich_space.py +++ b/src/sage/schemes/berkovich/berkovich_space.py @@ -19,7 +19,7 @@ AUTHORS: - - Alexander Galarraga (2020-06-22): initial implementation +- Alexander Galarraga (2020-06-22): initial implementation """ @@ -40,7 +40,6 @@ from sage.categories.number_fields import NumberFields import sage.rings.abc from sage.rings.integer_ring import ZZ -from sage.rings.padics.factory import Qp from sage.rings.rational_field import QQ from sage.rings.number_field.number_field_ideal import NumberFieldFractionalIdeal from sage.categories.topological_spaces import TopologicalSpaces @@ -56,9 +55,9 @@ def is_Berkovich(space): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics sage: from sage.schemes.berkovich.berkovich_space import is_Berkovich - sage: is_Berkovich(B) + sage: is_Berkovich(B) # optional - sage.rings.padics True """ return isinstance(space, Berkovich) @@ -74,9 +73,9 @@ def is_Berkovich_Cp(space): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics sage: from sage.schemes.berkovich.berkovich_space import is_Berkovich - sage: is_Berkovich(B) + sage: is_Berkovich(B) # optional - sage.rings.padics True """ return isinstance(space, Berkovich_Cp) @@ -98,17 +97,17 @@ def residue_characteristic(self): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: B.prime() + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: B.prime() # optional - sage.rings.padics 3 :: sage: R. = QQ[] - sage: A. = NumberField(x^3 + 20) - sage: ideal = A.ideal(-1/2*a^2 + a - 3) - sage: B = Berkovich_Cp_Affine(A, ideal) - sage: B.residue_characteristic() + sage: A. = NumberField(x^3 + 20) # optional - sage.rings.number_field + sage: ideal = A.ideal(-1/2*a^2 + a - 3) # optional - sage.rings.number_field + sage: B = Berkovich_Cp_Affine(A, ideal) # optional - sage.rings.number_field + sage: B.residue_characteristic() # optional - sage.rings.number_field 7 """ return self._p @@ -126,11 +125,11 @@ def is_padic_base(self): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(Qp(3)) - sage: B.is_padic_base() + sage: B = Berkovich_Cp_Affine(Qp(3)) # optional - sage.rings.padics + sage: B.is_padic_base() # optional - sage.rings.padics True - :: + :: sage: B = Berkovich_Cp_Affine(QQ, 3) sage: B.is_padic_base() @@ -140,7 +139,7 @@ def is_padic_base(self): def is_number_field_base(self): """ - Return ``True`` if this Berkovich space is backed by a p-adic field. + Return ``True`` if this Berkovich space is backed by a number field. OUTPUT: @@ -149,8 +148,8 @@ def is_number_field_base(self): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(Qp(3)) - sage: B.is_number_field_base() + sage: B = Berkovich_Cp_Affine(Qp(3)) # optional - sage.rings.padics + sage: B.is_number_field_base() # optional - sage.rings.padics False :: @@ -179,10 +178,10 @@ def ideal(self): EXAMPLES:: sage: R. = QQ[] - sage: A. = NumberField(z^2 + 1) - sage: ideal = A.prime_above(5) - sage: B = Berkovich_Cp_Projective(A, ideal) - sage: B.ideal() + sage: A. = NumberField(z^2 + 1) # optional - sage.rings.number_field + sage: ideal = A.prime_above(5) # optional - sage.rings.number_field + sage: B = Berkovich_Cp_Projective(A, ideal) # optional - sage.rings.number_field + sage: B.ideal() # optional - sage.rings.number_field Fractional ideal (-a - 2) :: @@ -193,8 +192,8 @@ def ideal(self): :: - sage: B = Berkovich_Cp_Projective(Qp(3)) - sage: B.ideal() is None + sage: B = Berkovich_Cp_Projective(Qp(3)) # optional - sage.rings.padics + sage: B.ideal() is None # optional - sage.rings.padics True """ return self._ideal @@ -205,35 +204,35 @@ def __eq__(self,right): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: A. = Qq(27) - sage: C = Berkovich_Cp_Affine(A) - sage: B == C + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: A. = Qq(27) # optional - sage.rings.padics + sage: C = Berkovich_Cp_Affine(A) # optional - sage.rings.padics + sage: B == C # optional - sage.rings.padics True :: sage: R. = QQ[] - sage: A. = NumberField(x^2 + 1) - sage: A_ideal = A.prime_above(2) - sage: B. = NumberField(x^4 + 1) - sage: B_ideal = B.prime_above(2) - sage: C = Berkovich_Cp_Projective(A, A_ideal) - sage: D = Berkovich_Cp_Projective(B, B_ideal) - sage: C == D + sage: A. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: A_ideal = A.prime_above(2) # optional - sage.rings.number_field + sage: B. = NumberField(x^4 + 1) # optional - sage.rings.number_field + sage: B_ideal = B.prime_above(2) # optional - sage.rings.number_field + sage: C = Berkovich_Cp_Projective(A, A_ideal) # optional - sage.rings.number_field + sage: D = Berkovich_Cp_Projective(B, B_ideal) # optional - sage.rings.number_field + sage: C == D # optional - sage.rings.number_field False :: - sage: C = Berkovich_Cp_Affine(A, A_ideal) - sage: D = Berkovich_Cp_Affine(B, B_ideal) - sage: C == D + sage: C = Berkovich_Cp_Affine(A, A_ideal) # optional - sage.rings.number_field + sage: D = Berkovich_Cp_Affine(B, B_ideal) # optional - sage.rings.number_field + sage: C == D # optional - sage.rings.number_field False :: - sage: A_ideal_2 = A.prime_above(5) - sage: E = Berkovich_Cp_Affine(A, A_ideal_2) + sage: A_ideal_2 = A.prime_above(5) # optional - sage.rings.number_field + sage: E = Berkovich_Cp_Affine(A, A_ideal_2) # optional - sage.rings.number_field sage: C == E False """ @@ -252,10 +251,10 @@ def __ne__(self,right): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(5) - sage: A. = Qq(25) - sage: C = Berkovich_Cp_Affine(A) - sage: B != C + sage: B = Berkovich_Cp_Affine(5) # optional - sage.rings.padics + sage: A. = Qq(25) # optional - sage.rings.padics + sage: C = Berkovich_Cp_Affine(A) # optional - sage.rings.padics + sage: B != C # optional - sage.rings.padics False """ return not (self == right) @@ -266,16 +265,16 @@ def __hash__(self): EXAMPLES:: - sage: hash(Berkovich_Cp_Projective(3)) + sage: hash(Berkovich_Cp_Projective(3)) # optional - sage.rings.padics 3 :: sage: R. = QQ[] - sage: A. = NumberField(z^2 + 1) - sage: B = Berkovich_Cp_Projective(A, A.primes_above(5)[0]) - sage: C = Berkovich_Cp_Projective(A, A.primes_above(5)[1]) - sage: hash(B) != hash(C) + sage: A. = NumberField(z^2 + 1) # optional - sage.rings.number_field + sage: B = Berkovich_Cp_Projective(A, A.primes_above(5)[0]) # optional - sage.rings.number_field + sage: C = Berkovich_Cp_Projective(A, A.primes_above(5)[1]) # optional - sage.rings.number_field + sage: hash(B) != hash(C) # optional - sage.rings.number_field True """ if self._base_type == 'padic field': @@ -315,59 +314,59 @@ class Berkovich_Cp_Affine(Berkovich_Cp): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3); B + sage: B = Berkovich_Cp_Affine(3); B # optional - sage.rings.padics Affine Berkovich line over Cp(3) of precision 20 We can create elements:: - sage: B(-2) + sage: B(-2) # optional - sage.rings.padics Type I point centered at 1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11 + 2*3^12 + 2*3^13 + 2*3^14 + 2*3^15 + 2*3^16 + 2*3^17 + 2*3^18 + 2*3^19 + O(3^20) :: - sage: B(1, 2) + sage: B(1, 2) # optional - sage.rings.padics Type III point centered at 1 + O(3^20) of radius 2.00000000000000 For details on element creation, see the documentation of :class:`Berkovich_Element_Cp_Affine`. Initializing by passing in `\QQ_p` looks the same:: - sage: B = Berkovich_Cp_Affine(Qp(3)); B + sage: B = Berkovich_Cp_Affine(Qp(3)); B # optional - sage.rings.padics Affine Berkovich line over Cp(3) of precision 20 However, this method allows for more control over behind-the-scenes conversion:: - sage: B = Berkovich_Cp_Affine(Qp(3, 1)); B + sage: B = Berkovich_Cp_Affine(Qp(3, 1)); B # optional - sage.rings.padics Affine Berkovich line over Cp(3) of precision 1 - sage: B(1/2) + sage: B(1/2) # optional - sage.rings.padics Type I point centered at 2 + O(3) Note that this point has very low precision, as ``B`` was initialized with a p-adic field of capped-relative precision one. For high precision, pass in a high precision p-adic field:: - sage: B = Berkovich_Cp_Affine(Qp(3, 1000)); B + sage: B = Berkovich_Cp_Affine(Qp(3, 1000)); B # optional - sage.rings.padics Affine Berkovich line over Cp(3) of precision 1000 Points of Berkovich space can be created from points of extensions of `\QQ_p`:: - sage: B = Berkovich_Cp_Affine(3) - sage: A. = Qp(3).extension(x^3 - 3) - sage: B(a) + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: A. = Qp(3).extension(x^3 - 3) # optional - sage.rings.padics + sage: B(a) # optional - sage.rings.padics Type I point centered at a + O(a^61) For exact computation, a number field can be used:: sage: R. = QQ[] - sage: A. = NumberField(x^3 + 20) - sage: ideal = A.prime_above(3) - sage: B = Berkovich_Cp_Affine(A, ideal); B - Affine Berkovich line over Cp(3), with base Number - Field in a with defining polynomial x^3 + 20 + sage: A. = NumberField(x^3 + 20) # optional - sage.rings.number_field + sage: ideal = A.prime_above(3) # optional - sage.rings.number_field + sage: B = Berkovich_Cp_Affine(A, ideal); B # optional - sage.rings.number_field + Affine Berkovich line over Cp(3), with base + Number Field in a with defining polynomial x^3 + 20 Number fields have a major advantage of exact computation. @@ -383,11 +382,11 @@ class Berkovich_Cp_Affine(Berkovich_Cp): must be centered at a point of that number field:: sage: R. = QQ[] - sage: A. = NumberField(x^3 + 20) - sage: ideal = A.prime_above(3) - sage: B = Berkovich_Cp_Affine(A, ideal) - sage: C. = NumberField(x^2 + 1) - sage: B(c) + sage: A. = NumberField(x^3 + 20) # optional - sage.rings.number_field + sage: ideal = A.prime_above(3) # optional - sage.rings.number_field + sage: B = Berkovich_Cp_Affine(A, ideal) # optional - sage.rings.number_field + sage: C. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: B(c) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: could not convert c to Number Field in a @@ -395,14 +394,14 @@ class Berkovich_Cp_Affine(Berkovich_Cp): TESTS:: - sage: A. = AffineSpace(Qp(3), 1) - sage: Berkovich_Cp_Affine(A) + sage: A. = AffineSpace(Qp(3), 1) # optional - sage.rings.padics + sage: Berkovich_Cp_Affine(A) # optional - sage.rings.padics Affine Berkovich line over Cp(3) of precision 20 :: - sage: B = Berkovich_Cp_Projective(3) - sage: TestSuite(B).run() + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: TestSuite(B).run() # optional - sage.rings.padics """ Element = Berkovich_Element_Cp_Affine @@ -413,11 +412,13 @@ def __init__(self, base, ideal=None): EXAMPLES:: - sage: Berkovich_Cp_Affine(3) + sage: Berkovich_Cp_Affine(3) # optional - sage.rings.padics Affine Berkovich line over Cp(3) of precision 20 """ if base in ZZ: if base.is_prime(): + from sage.rings.padics.factory import Qp + base = Qp(base) # change to Qpbar else: raise ValueError("non-prime passed into Berkovich space") @@ -457,18 +458,18 @@ def _repr_(self): EXAMPLES:: - sage: B = Berkovich_Cp_Affine(3) - sage: B + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: B # optional - sage.rings.padics Affine Berkovich line over Cp(3) of precision 20 :: sage: R. = QQ[] - sage: A. = NumberField(z^2 + 1) - sage: ideal = A.prime_above(3) - sage: Berkovich_Cp_Affine(A, ideal) - Affine Berkovich line over Cp(3), with base Number Field - in a with defining polynomial z^2 + 1 + sage: A. = NumberField(z^2 + 1) # optional - sage.rings.number_field + sage: ideal = A.prime_above(3) # optional - sage.rings.number_field + sage: Berkovich_Cp_Affine(A, ideal) # optional - sage.rings.number_field + Affine Berkovich line over Cp(3), with base + Number Field in a with defining polynomial z^2 + 1 """ if self._base_type == 'padic field': return "Affine Berkovich line over Cp(%s) of precision %s" %(self.prime(),\ @@ -483,8 +484,8 @@ def _latex_(self): EXAMPLES: - sage: B = Berkovich_Cp_Affine(3) - sage: latex(B) + sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics + sage: latex(B) # optional - sage.rings.padics \text{Affine Berkovich line over } \Bold{C}_{3} """ return r"\text{Affine Berkovich line over } \Bold{C}_{%s}" % (self.prime()) @@ -523,36 +524,36 @@ class Berkovich_Cp_Projective(Berkovich_Cp): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3); B + sage: B = Berkovich_Cp_Projective(3); B # optional - sage.rings.padics Projective Berkovich line over Cp(3) of precision 20 Elements can be constructed:: - sage: B(1/2) + sage: B(1/2) # optional - sage.rings.padics Type I point centered at (2 + 3 + 3^2 + 3^3 + 3^4 + 3^5 + 3^6 + 3^7 + 3^8 + 3^9 + 3^10 + 3^11 + 3^12 + 3^13 + 3^14 + 3^15 + 3^16 + 3^17 + 3^18 + 3^19 + O(3^20) : 1 + O(3^20)) :: - sage: B(2, 1) + sage: B(2, 1) # optional - sage.rings.padics Type II point centered at (2 + O(3^20) : 1 + O(3^20)) of radius 3^0 For details about element construction, see the documentation of :class:`Berkovich_Element_Cp_Projective`. Initializing a Berkovich projective line by passing in a p-adic space looks the same:: - sage: B = Berkovich_Cp_Projective(Qp(3)); B + sage: B = Berkovich_Cp_Projective(Qp(3)); B # optional - sage.rings.padics Projective Berkovich line over Cp(3) of precision 20 However, this method allows for more control over behind-the-scenes conversion:: - sage: S = Qp(3, 1) - sage: B = Berkovich_Cp_Projective(S); B + sage: S = Qp(3, 1) # optional - sage.rings.padics + sage: B = Berkovich_Cp_Projective(S); B # optional - sage.rings.padics Projective Berkovich line over Cp(3) of precision 1 - sage: Q1 = B(1/2); Q1 + sage: Q1 = B(1/2); Q1 # optional - sage.rings.padics Type I point centered at (2 + O(3) : 1 + O(3)) Note that this point has very low precision, as S has low @@ -560,11 +561,11 @@ class Berkovich_Cp_Projective(Berkovich_Cp): a number field, as long as an ideal is specified:: sage: R. = QQ[] - sage: A. = NumberField(x^2 + 1) - sage: ideal = A.prime_above(2) - sage: B = Berkovich_Cp_Projective(A, ideal); B + sage: A. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: ideal = A.prime_above(2) # optional - sage.rings.number_field + sage: B = Berkovich_Cp_Projective(A, ideal); B # optional - sage.rings.number_field Projective Berkovich line over Cp(2), with base - Number Field in a with defining polynomial x^2 + 1 + Number Field in a with defining polynomial x^2 + 1 Number fields have the benefit that computation is exact, but lack support for all of `\CC_p`. @@ -582,11 +583,11 @@ class Berkovich_Cp_Projective(Berkovich_Cp): must be centered at a point of that number field:: sage: R. = QQ[] - sage: A. = NumberField(x^3 + 20) - sage: ideal = A.prime_above(3) - sage: B = Berkovich_Cp_Projective(A, ideal) - sage: C. = NumberField(x^2 + 1) - sage: B(c) + sage: A. = NumberField(x^3 + 20) # optional - sage.rings.number_field + sage: ideal = A.prime_above(3) # optional - sage.rings.number_field + sage: B = Berkovich_Cp_Projective(A, ideal) # optional - sage.rings.number_field + sage: C. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: B(c) # optional - sage.rings.number_field Traceback (most recent call last): ... TypeError: could not convert c to Projective Space @@ -594,8 +595,8 @@ class Berkovich_Cp_Projective(Berkovich_Cp): TESTS:: - sage: B = Berkovich_Cp_Projective(3) - sage: TestSuite(B).run() + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: TestSuite(B).run() # optional - sage.rings.padics """ Element = Berkovich_Element_Cp_Projective @@ -606,11 +607,13 @@ def __init__(self, base, ideal=None): EXAMPLES:: - sage: Berkovich_Cp_Projective(3) + sage: Berkovich_Cp_Projective(3) # optional - sage.rings.padics Projective Berkovich line over Cp(3) of precision 20 """ if base in ZZ: if base.is_prime(): + from sage.rings.padics.factory import Qp + base = ProjectiveSpace(Qp(base), 1) else: raise ValueError("non-prime passed into Berkovich space") @@ -661,23 +664,23 @@ def base_ring(self): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: B.base_ring() + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: B.base_ring() # optional - sage.rings.padics 3-adic Field with capped relative precision 20 :: - sage: C = Berkovich_Cp_Projective(ProjectiveSpace(Qp(3, 1), 1)) - sage: C.base_ring() + sage: C = Berkovich_Cp_Projective(ProjectiveSpace(Qp(3, 1), 1)) # optional - sage.rings.padics + sage: C.base_ring() # optional - sage.rings.padics 3-adic Field with capped relative precision 1 :: sage: R. = QQ[] - sage: A. = NumberField(x^3 + 20) - sage: ideal = A.prime_above(3) - sage: D = Berkovich_Cp_Projective(A, ideal) - sage: D.base_ring() + sage: A. = NumberField(x^3 + 20) # optional - sage.rings.number_field + sage: ideal = A.prime_above(3) # optional - sage.rings.number_field + sage: D = Berkovich_Cp_Projective(A, ideal) # optional - sage.rings.number_field + sage: D.base_ring() # optional - sage.rings.number_field Number Field in a with defining polynomial x^3 + 20 """ return self.base().base_ring() @@ -688,17 +691,18 @@ def _repr_(self): EXAMPLES:: - sage: B = Berkovich_Cp_Projective(3) - sage: B + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: B # optional - sage.rings.padics Projective Berkovich line over Cp(3) of precision 20 :: sage: R. = QQ[] - sage: A. = NumberField(x^2 + 1) - sage: v = A.ideal(a + 1) - sage: Berkovich_Cp_Projective(A, v) - Projective Berkovich line over Cp(2), with base Number Field in a with defining polynomial x^2 + 1 + sage: A. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: v = A.ideal(a + 1) # optional - sage.rings.number_field + sage: Berkovich_Cp_Projective(A, v) # optional - sage.rings.number_field + Projective Berkovich line over Cp(2), + with base Number Field in a with defining polynomial x^2 + 1 """ if self._base_type == 'padic field': return "Projective Berkovich line over Cp(%s) of precision %s" %(self.prime(),\ @@ -713,8 +717,8 @@ def _latex_(self): EXAMPLES: - sage: B = Berkovich_Cp_Projective(3) - sage: latex(B) + sage: B = Berkovich_Cp_Projective(3) # optional - sage.rings.padics + sage: latex(B) # optional - sage.rings.padics \text{Projective Berkovich line over } \Bold{C}_{3} """ return r"\text{Projective Berkovich line over } \Bold{C}_{%s}" %(self.prime()) diff --git a/src/sage/schemes/curves/affine_curve.py b/src/sage/schemes/curves/affine_curve.py index a329e927d51..7ce3f291461 100644 --- a/src/sage/schemes/curves/affine_curve.py +++ b/src/sage/schemes/curves/affine_curve.py @@ -27,49 +27,49 @@ EXAMPLES:: - sage: k. = GF(2) - sage: A. = AffineSpace(k, 3) - sage: C = Curve([x^2 + x - y^3, y^4 - y - z^3], A) - sage: C.genus() + sage: k. = GF(2) # optional - sage.rings.finite_rings + sage: A. = AffineSpace(k, 3) # optional - sage.rings.finite_rings + sage: C = Curve([x^2 + x - y^3, y^4 - y - z^3], A) # optional - sage.rings.finite_rings + sage: C.genus() # optional - sage.rings.finite_rings 10 - sage: C.function_field() + sage: C.function_field() # optional - sage.rings.finite_rings Function field in z defined by z^9 + x^8 + x^6 + x^5 + x^4 + x^3 + x Closed points of arbitrary degree can be computed:: - sage: C.closed_points() + sage: C.closed_points() # optional - sage.rings.finite_rings [Point (x, y, z), Point (x + 1, y, z)] - sage: C.closed_points(2) + sage: C.closed_points(2) # optional - sage.rings.finite_rings [Point (x^2 + x + 1, y + 1, z), Point (y^2 + y + 1, x + y, z), Point (y^2 + y + 1, x + y + 1, z)] - sage: p = _[0] - sage: p.places() + sage: p = _[0] # optional - sage.rings.finite_rings + sage: p.places() # optional - sage.rings.finite_rings [Place (x^2 + x + 1, (1/(x^4 + x^2 + 1))*z^7 + (1/(x^4 + x^2 + 1))*z^6 + 1)] The places at infinity correspond to the extra closed points of the curve's projective closure:: - sage: C.places_at_infinity() + sage: C.places_at_infinity() # optional - sage.rings.finite_rings [Place (1/x, 1/x*z)] It is easy to transit to and from the function field of the curve:: - sage: fx = C(x) - sage: fy = C(y) - sage: fx^2 + fx - fy^3 + sage: fx = C(x) # optional - sage.rings.finite_rings + sage: fy = C(y) # optional - sage.rings.finite_rings + sage: fx^2 + fx - fy^3 # optional - sage.rings.finite_rings 0 - sage: fx.divisor() + sage: fx.divisor() # optional - sage.rings.finite_rings -9*Place (1/x, 1/x*z) + 9*Place (x, z) - sage: p, = fx.zeros() - sage: C.place_to_closed_point(p) + sage: p, = fx.zeros() # optional - sage.rings.finite_rings + sage: C.place_to_closed_point(p) # optional - sage.rings.finite_rings Point (x, y, z) - sage: _.rational_point() + sage: _.rational_point() # optional - sage.rings.finite_rings (0, 0, 0) - sage: _.closed_point() + sage: _.closed_point() # optional - sage.rings.finite_rings Point (x, y, z) - sage: _.place() + sage: _.place() # optional - sage.rings.finite_rings Place (x, z) Integral affine curves over `\QQ` @@ -95,10 +95,10 @@ s sage: sy = sy.polynomial(10); sy -7/256*s^10 - 5/128*s^8 - 1/16*s^6 - 1/8*s^4 - 1/2*s^2 + 1 - sage: s = var('s') - sage: P1 = parametric_plot([sx, sy], (s, -1, 1), color='red') - sage: P2 = C.plot((x, -1, 1), (y, 0, 2)) # half circle - sage: P1 + P2 + sage: s = var('s') # optional - sage.symbolic + sage: P1 = parametric_plot([sx, sy], (s, -1, 1), color='red') # optional - sage.plot sage.symbolic + sage: P2 = C.plot((x, -1, 1), (y, 0, 2)) # half circle # optional - sage.plot sage.symbolic + sage: P1 + P2 # optional - sage.plot sage.symbolic Graphics object consisting of 2 graphics primitives AUTHORS: @@ -168,16 +168,16 @@ class AffineCurve(Curve_generic, AlgebraicScheme_subscheme_affine): EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(v^2 + 3) - sage: A. = AffineSpace(K, 3) - sage: C = Curve([z - u*x^2, y^2], A); C + sage: K. = NumberField(v^2 + 3) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 3) # optional - sage.rings.number_field + sage: C = Curve([z - u*x^2, y^2], A); C # optional - sage.rings.number_field Affine Curve over Number Field in u with defining polynomial v^2 + 3 defined by (-u)*x^2 + z, y^2 :: - sage: A. = AffineSpace(GF(7), 3) - sage: C = Curve([x^2 - z, z - 8*x], A); C + sage: A. = AffineSpace(GF(7), 3) # optional - sage.rings.finite_rings + sage: C = Curve([x^2 - z, z - 8*x], A); C # optional - sage.rings.finite_rings Affine Curve over Finite Field of size 7 defined by x^2 - z, -x + z """ def __init__(self, A, X): @@ -187,16 +187,16 @@ def __init__(self, A, X): EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(v^2 + 3) - sage: A. = AffineSpace(K, 3) - sage: C = Curve([z - u*x^2, y^2], A); C + sage: K. = NumberField(v^2 + 3) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 3) # optional - sage.rings.number_field + sage: C = Curve([z - u*x^2, y^2], A); C # optional - sage.rings.number_field Affine Curve over Number Field in u with defining polynomial v^2 + 3 defined by (-u)*x^2 + z, y^2 :: - sage: A. = AffineSpace(GF(7), 3) - sage: C = Curve([x^2 - z, z - 8*x], A); C + sage: A. = AffineSpace(GF(7), 3) # optional - sage.rings.finite_rings + sage: C = Curve([x^2 - z, z - 8*x], A); C # optional - sage.rings.finite_rings Affine Curve over Finite Field of size 7 defined by x^2 - z, -x + z """ if not is_AffineSpace(A): @@ -229,9 +229,7 @@ def projective_closure(self, i=0, PP=None): - ``PP`` -- (default: None) ambient projective space to compute the projective closure in. This is constructed if it is not given. - OUTPUT: - - - a curve in projective space. + OUTPUT: A curve in projective space. EXAMPLES:: @@ -324,18 +322,18 @@ def divisor_of_function(self, r): EXAMPLES:: - sage: F = GF(5) - sage: P2 = AffineSpace(2, F, names = 'xy') - sage: R = P2.coordinate_ring() - sage: x, y = R.gens() - sage: f = y^2 - x^9 - x - sage: C = Curve(f) - sage: K = FractionField(R) - sage: r = 1/x - sage: C.divisor_of_function(r) # todo: not implemented (broken) + sage: F = GF(5) # optional - sage.rings.finite_rings + sage: P2 = AffineSpace(2, F, names='xy') # optional - sage.rings.finite_rings + sage: R = P2.coordinate_ring() # optional - sage.rings.finite_rings + sage: x, y = R.gens() # optional - sage.rings.finite_rings + sage: f = y^2 - x^9 - x # optional - sage.rings.finite_rings + sage: C = Curve(f) # optional - sage.rings.finite_rings + sage: K = FractionField(R) # optional - sage.rings.finite_rings + sage: r = 1/x # optional - sage.rings.finite_rings + sage: C.divisor_of_function(r) # todo: not implemented (broken) # optional - sage.rings.finite_rings [[-1, (0, 0, 1)]] - sage: r = 1/x^3 - sage: C.divisor_of_function(r) # todo: not implemented (broken) + sage: r = 1/x^3 # optional - sage.rings.finite_rings + sage: C.divisor_of_function(r) # todo: not implemented (broken) # optional - sage.rings.finite_rings [[-3, (0, 0, 1)]] """ F = self.base_ring() @@ -378,13 +376,13 @@ def local_coordinates(self, pt, n): EXAMPLES:: - sage: F = GF(5) - sage: pt = (2,3) - sage: R = PolynomialRing(F,2, names = ['x','y']) - sage: x,y = R.gens() - sage: f = y^2-x^9-x - sage: C = Curve(f) - sage: C.local_coordinates(pt, 9) + sage: F = GF(5) # optional - sage.rings.finite_rings + sage: pt = (2,3) # optional - sage.rings.finite_rings + sage: R = PolynomialRing(F, 2, names = ['x','y']) # optional - sage.rings.finite_rings + sage: x,y = R.gens() # optional - sage.rings.finite_rings + sage: f = y^2 - x^9 - x # optional - sage.rings.finite_rings + sage: C = Curve(f) # optional - sage.rings.finite_rings + sage: C.local_coordinates(pt, 9) # optional - sage.rings.finite_rings [t + 2, -2*t^12 - 2*t^11 + 2*t^9 + t^8 - 2*t^7 - 2*t^6 - 2*t^4 + t^3 - 2*t^2 - 2] """ f = self.defining_polynomial() @@ -483,7 +481,7 @@ def is_transverse(self, C, P): - ``P`` -- a point in the intersection of both curves. - OUTPUT: Boolean. + OUTPUT: A boolean. EXAMPLES:: @@ -497,12 +495,12 @@ def is_transverse(self, C, P): :: sage: R. = QQ[] - sage: K. = NumberField(a^3 + 2) - sage: A. = AffineSpace(K, 2) - sage: C = A.curve([x*y]) - sage: D = A.curve([y - b*x]) - sage: Q = A([0,0]) - sage: C.is_transverse(D, Q) + sage: K. = NumberField(a^3 + 2) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: C = A.curve([x*y]) # optional - sage.rings.number_field + sage: D = A.curve([y - b*x]) # optional - sage.rings.number_field + sage: Q = A([0,0]) # optional - sage.rings.number_field + sage: C.is_transverse(D, Q) # optional - sage.rings.number_field False :: @@ -538,9 +536,7 @@ def multiplicity(self, P): - ``P`` -- a point in the ambient space of this curve. - OUTPUT: - - An integer. + OUTPUT: An integer. EXAMPLES:: @@ -555,11 +551,12 @@ def multiplicity(self, P): :: - sage: A. = AffineSpace(QQbar,2) - sage: C = Curve([-x^7 + (-7)*x^6 + y^6 + (-21)*x^5 + 12*y^5 + (-35)*x^4 + 60*y^4 +\ - (-35)*x^3 + 160*y^3 + (-21)*x^2 + 240*y^2 + (-7)*x + 192*y + 63], A) - sage: Q = A([-1,-2]) - sage: C.multiplicity(Q) + sage: A. = AffineSpace(QQbar,2) # optional - sage.rings.number_field + sage: C = Curve([-x^7 + (-7)*x^6 + y^6 + (-21)*x^5 + 12*y^5 # optional - sage.rings.number_field + ....: + (-35)*x^4 + 60*y^4 + (-35)*x^3 + 160*y^3 + ....: + (-21)*x^2 + 240*y^2 + (-7)*x + 192*y + 63], A) + sage: Q = A([-1,-2]) # optional - sage.rings.number_field + sage: C.multiplicity(Q) # optional - sage.rings.number_field 6 :: @@ -605,31 +602,34 @@ def tangents(self, P, factor=True): curve, or to just return the polynomial corresponding to the union of the tangent lines (which requires fewer computations) - OUTPUT: a list of polynomials in the coordinate ring of the ambient space + OUTPUT: A list of polynomials in the coordinate ring of the ambient space. EXAMPLES:: sage: set_verbose(-1) - sage: A. = AffineSpace(QQbar, 2) - sage: C = Curve([x^5*y^3 + 2*x^4*y^4 + x^3*y^5 + 3*x^4*y^3 + 6*x^3*y^4 + 3*x^2*y^5\ - + 3*x^3*y^3 + 6*x^2*y^4 + 3*x*y^5 + x^5 + 10*x^4*y + 40*x^3*y^2 + 81*x^2*y^3 + 82*x*y^4\ - + 33*y^5], A) - sage: Q = A([0,0]) - sage: C.tangents(Q) - [x + 3.425299577684700?*y, x + (1.949159013086856? + 1.179307909383728?*I)*y, - x + (1.949159013086856? - 1.179307909383728?*I)*y, x + (1.338191198070795? + 0.2560234251008043?*I)*y, - x + (1.338191198070795? - 0.2560234251008043?*I)*y] - sage: C.tangents(Q, factor=False) + sage: A. = AffineSpace(QQbar, 2) # optional - sage.rings.number_field + sage: C = Curve([x^5*y^3 + 2*x^4*y^4 + x^3*y^5 + 3*x^4*y^3 # optional - sage.rings.number_field + ....: + 6*x^3*y^4 + 3*x^2*y^5 + 3*x^3*y^3 + ....: + 6*x^2*y^4 + 3*x*y^5 + x^5 + 10*x^4*y + ....: + 40*x^3*y^2 + 81*x^2*y^3 + 82*x*y^4 + 33*y^5], A) + sage: Q = A([0,0]) # optional - sage.rings.number_field + sage: C.tangents(Q) # optional - sage.rings.number_field + [x + 3.425299577684700?*y, + x + (1.949159013086856? + 1.179307909383728?*I)*y, + x + (1.949159013086856? - 1.179307909383728?*I)*y, + x + (1.338191198070795? + 0.2560234251008043?*I)*y, + x + (1.338191198070795? - 0.2560234251008043?*I)*y] + sage: C.tangents(Q, factor=False) # optional - sage.rings.number_field [120*x^5 + 1200*x^4*y + 4800*x^3*y^2 + 9720*x^2*y^3 + 9840*x*y^4 + 3960*y^5] :: sage: R. = QQ[] - sage: K. = NumberField(a^2 - 3) - sage: A. = AffineSpace(K, 2) - sage: C = Curve([(x^2 + y^2 - 2*x)^2 - x^2 - y^2], A) - sage: Q = A([0,0]) - sage: C.tangents(Q) + sage: K. = NumberField(a^2 - 3) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: C = Curve([(x^2 + y^2 - 2*x)^2 - x^2 - y^2], A) # optional - sage.rings.number_field + sage: Q = A([0,0]) # optional - sage.rings.number_field + sage: C.tangents(Q) # optional - sage.rings.number_field [x + (-1/3*b)*y, x + (1/3*b)*y] :: @@ -721,11 +721,11 @@ def is_ordinary_singularity(self, P): :: sage: R. = QQ[] - sage: K. = NumberField(a^2 - 3) - sage: A. = AffineSpace(K, 2) - sage: C = Curve([(x^2 + y^2 - 2*x)^2 - x^2 - y^2], A) - sage: Q = A([0,0]) - sage: C.is_ordinary_singularity(Q) + sage: K. = NumberField(a^2 - 3) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: C = Curve([(x^2 + y^2 - 2*x)^2 - x^2 - y^2], A) # optional - sage.rings.number_field + sage: Q = A([0,0]) # optional - sage.rings.number_field + sage: C.is_ordinary_singularity(Q) # optional - sage.rings.number_field True :: @@ -829,16 +829,16 @@ def __init__(self, A, X): EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(v^2 + 3) - sage: A. = AffineSpace(K, 3) - sage: C = Curve([z - u*x^2, y^2], A); C + sage: K. = NumberField(v^2 + 3) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 3) # optional - sage.rings.number_field + sage: C = Curve([z - u*x^2, y^2], A); C # optional - sage.rings.number_field Affine Curve over Number Field in u with defining polynomial v^2 + 3 defined by (-u)*x^2 + z, y^2 :: - sage: A. = AffineSpace(GF(7), 3) - sage: C = Curve([x^2 - z, z - 8*x], A); C + sage: A. = AffineSpace(GF(7), 3) # optional - sage.rings.number_field + sage: C = Curve([x^2 - z, z - 8*x], A); C # optional - sage.rings.number_field Affine Curve over Finite Field of size 7 defined by x^2 - z, -x + z """ super().__init__(A, X) @@ -870,7 +870,7 @@ def projection(self, indices, AS=None): this curve, and must have dimension equal to the length of ``indices``. This space is constructed if not specified. - OUTPUT: a tuple of + OUTPUT: A tuple of - a scheme morphism from this curve to affine space of dimension equal to the number of coordinates specified in ``indices`` @@ -884,8 +884,8 @@ def projection(self, indices, AS=None): sage: C = Curve([y^7 - x^2 + x^3 - 2*z, z^2 - x^7 - y^2], A) sage: C.projection([0,1]) (Scheme morphism: - From: Affine Curve over Rational Field defined by y^7 + x^3 - x^2 - - 2*z, -x^7 - y^2 + z^2 + From: Affine Curve over Rational Field + defined by y^7 + x^3 - x^2 - 2*z, -x^7 - y^2 + z^2 To: Affine Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x, y, z) to (x, y), @@ -912,14 +912,15 @@ def projection(self, indices, AS=None): :: - sage: A. = AffineSpace(GF(11), 5) - sage: C = Curve([x^3 - 5*y*z + u^2, x - y^2 + 3*z^2, w^2 + 2*u^3*y, y - u^2 + z*x], A) - sage: B. = AffineSpace(GF(11), 3) - sage: proj1 = C.projection([1,2,4], AS=B) - sage: proj1 + sage: A. = AffineSpace(GF(11), 5) # optional - sage.rings.finite_rings + sage: C = Curve([x^3 - 5*y*z + u^2, x - y^2 + 3*z^2, # optional - sage.rings.finite_rings + ....: w^2 + 2*u^3*y, y - u^2 + z*x], A) + sage: B. = AffineSpace(GF(11), 3) # optional - sage.rings.finite_rings + sage: proj1 = C.projection([1,2,4], AS=B) # optional - sage.rings.finite_rings + sage: proj1 # optional - sage.rings.finite_rings (Scheme morphism: From: Affine Curve over Finite Field of size 11 defined by x^3 - - 5*y*z + u^2, -y^2 + 3*z^2 + x, 2*y*u^3 + w^2, x*z - u^2 + y + 5*y*z + u^2, -y^2 + 3*z^2 + x, 2*y*u^3 + w^2, x*z - u^2 + y To: Affine Space of dimension 3 over Finite Field of size 11 Defn: Defined on coordinates by sending (x, y, z, w, u) to (y, z, u), @@ -929,12 +930,12 @@ def projection(self, indices, AS=None): 3*b*c^2 + 3*a*b, a^4*c^2 + 2*b^4*c^2 - a^5 - 2*a*b^4 + 5*b*c^4 + a*b*c^2 - 5*a*b^2 + 4*b^3 + b*c^2 + 5*c^2 - 5*a, a^6 - 5*b^6 - 5*b^3*c^2 + 5*a*b^3 + 2*c^4 - 4*a*c^2 + 2*a^2 - 5*a*b + c^2) - sage: proj1[1].ambient_space() is B + sage: proj1[1].ambient_space() is B # optional - sage.rings.finite_rings True - sage: proj2 = C.projection([1,2,4]) - sage: proj2[1].ambient_space() is B + sage: proj2 = C.projection([1,2,4]) # optional - sage.rings.finite_rings + sage: proj2[1].ambient_space() is B # optional - sage.rings.finite_rings False - sage: C.projection([1,2,3,5], AS=B) + sage: C.projection([1,2,3,5], AS=B) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: (=Affine Space of dimension 3 over Finite Field of size 11) @@ -946,22 +947,21 @@ def projection(self, indices, AS=None): sage: C = A.curve([x*y - z^3, x*z - w^3, w^2 - x^3]) sage: C.projection([y,z]) (Scheme morphism: - From: Affine Curve over Rational Field defined by -z^3 + x*y, -w^3 + - x*z, -x^3 + w^2 + From: Affine Curve over Rational Field defined by + -z^3 + x*y, -w^3 + x*z, -x^3 + w^2 To: Affine Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x, y, z, w) to - (y, z), + Defn: Defined on coordinates by sending (x, y, z, w) to (y, z), Affine Plane Curve over Rational Field defined by x1^23 - x0^7*x1^4) sage: B. = AffineSpace(QQ, 3) sage: C.projection([x,y,z], AS=B) (Scheme morphism: - From: Affine Curve over Rational Field defined by -z^3 + x*y, -w^3 + - x*z, -x^3 + w^2 + From: Affine Curve over Rational Field defined by + -z^3 + x*y, -w^3 + x*z, -x^3 + w^2 To: Affine Space of dimension 3 over Rational Field Defn: Defined on coordinates by sending (x, y, z, w) to (x, y, z), - Affine Curve over Rational Field defined by z^3 - x*y, x^8 - x*z^2, - x^7*z^2 - x*y*z) + Affine Curve over Rational Field defined by + z^3 - x*y, x^8 - x*z^2, x^7*z^2 - x*y*z) sage: C.projection([y,z,z]) Traceback (most recent call last): ... @@ -1031,7 +1031,7 @@ def plane_projection(self, AP=None): curve, and must have dimension two. This space will be constructed if not specified. - OUTPUT: a tuple of + OUTPUT: A tuple of - a scheme morphism from this curve into an affine plane @@ -1043,35 +1043,35 @@ def plane_projection(self, AP=None): sage: C = Curve([x^2 - y*z*w, z^3 - w, w + x*y - 3*z^3], A) sage: C.plane_projection() (Scheme morphism: - From: Affine Curve over Rational Field defined by -y*z*w + x^2, z^3 - - w, -3*z^3 + x*y + w + From: Affine Curve over Rational Field defined by + -y*z*w + x^2, z^3 - w, -3*z^3 + x*y + w To: Affine Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x, y, z, w) to - (x, y), Affine Plane Curve over Rational Field defined by - x0^2*x1^7 - 16*x0^4) + Defn: Defined on coordinates by sending (x, y, z, w) to (x, y), + Affine Plane Curve over Rational Field defined by + x0^2*x1^7 - 16*x0^4) :: sage: R. = QQ[] - sage: K. = NumberField(a^2 + 2) - sage: A. = AffineSpace(K, 3) - sage: C = A.curve([x - b, y - 2]) - sage: B. = AffineSpace(K, 2) - sage: proj1 = C.plane_projection(AP=B) - sage: proj1 + sage: K. = NumberField(a^2 + 2) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 3) # optional - sage.rings.number_field + sage: C = A.curve([x - b, y - 2]) # optional - sage.rings.number_field + sage: B. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: proj1 = C.plane_projection(AP=B) # optional - sage.rings.number_field + sage: proj1 # optional - sage.rings.number_field (Scheme morphism: - From: Affine Curve over Number Field in b with defining polynomial - a^2 + 2 defined by x + (-b), y - 2 - To: Affine Space of dimension 2 over Number Field in b with - defining polynomial a^2 + 2 + From: Affine Curve over Number Field in b + with defining polynomial a^2 + 2 defined by x + (-b), y - 2 + To: Affine Space of dimension 2 over Number Field in b + with defining polynomial a^2 + 2 Defn: Defined on coordinates by sending (x, y, z) to (x, z), - Affine Plane Curve over Number Field in b with defining polynomial a^2 - + 2 defined by a + (-b)) - sage: proj1[1].ambient_space() is B + Affine Plane Curve over Number Field in b + with defining polynomial a^2 + 2 defined by a + (-b)) + sage: proj1[1].ambient_space() is B # optional - sage.rings.number_field True - sage: proj2 = C.plane_projection() - sage: proj2[1].ambient_space() is B + sage: proj2 = C.plane_projection() # optional - sage.rings.number_field + sage: proj2[1].ambient_space() is B # optional - sage.rings.number_field False """ n = self.ambient_space().dimension_relative() @@ -1095,7 +1095,7 @@ def blowup(self, P=None): - ``P`` -- (default: None) a point on this curve at which to blow up; if ``None``, then ``P`` is taken to be the origin. - OUTPUT: a tuple of + OUTPUT: A tuple of - a tuple of curves in affine space of the same dimension as the ambient space of this curve, which define the blow up in each affine @@ -1114,65 +1114,89 @@ def blowup(self, P=None): sage: C = Curve([y^2 - x^3], A) sage: C.blowup() ((Affine Plane Curve over Rational Field defined by s1^2 - x, - Affine Plane Curve over Rational Field defined by y*s0^3 - 1), - ([Scheme endomorphism of Affine Plane Curve over Rational Field defined by s1^2 - x - Defn: Defined on coordinates by sending (x, s1) to - (x, s1), Scheme morphism: + Affine Plane Curve over Rational Field defined by y*s0^3 - 1), + ([Scheme endomorphism of Affine Plane Curve over Rational Field + defined by s1^2 - x + Defn: Defined on coordinates by sending (x, s1) to (x, s1), + Scheme morphism: From: Affine Plane Curve over Rational Field defined by s1^2 - x To: Affine Plane Curve over Rational Field defined by y*s0^3 - 1 - Defn: Defined on coordinates by sending (x, s1) to - (x*s1, 1/s1)], [Scheme morphism: + Defn: Defined on coordinates by sending (x, s1) to (x*s1, 1/s1)], + [Scheme morphism: From: Affine Plane Curve over Rational Field defined by y*s0^3 - 1 To: Affine Plane Curve over Rational Field defined by s1^2 - x - Defn: Defined on coordinates by sending (y, s0) to - (y*s0, 1/s0), - Scheme endomorphism of Affine Plane Curve over Rational Field defined by y*s0^3 - 1 - Defn: Defined on coordinates by sending (y, s0) to - (y, s0)]), + Defn: Defined on coordinates by sending (y, s0) to (y*s0, 1/s0), + Scheme endomorphism of Affine Plane Curve over Rational Field + defined by y*s0^3 - 1 + Defn: Defined on coordinates by sending (y, s0) to (y, s0)]), (Scheme morphism: From: Affine Plane Curve over Rational Field defined by s1^2 - x To: Affine Plane Curve over Rational Field defined by -x^3 + y^2 - Defn: Defined on coordinates by sending (x, s1) to - (x, x*s1), Scheme morphism: + Defn: Defined on coordinates by sending (x, s1) to (x, x*s1), + Scheme morphism: From: Affine Plane Curve over Rational Field defined by y*s0^3 - 1 To: Affine Plane Curve over Rational Field defined by -x^3 + y^2 - Defn: Defined on coordinates by sending (y, s0) to - (y*s0, y))) + Defn: Defined on coordinates by sending (y, s0) to (y*s0, y))) :: - sage: K. = QuadraticField(2) - sage: A. = AffineSpace(K, 3) - sage: C = Curve([y^2 - a*x^5, x - z], A) - sage: B = C.blowup() - sage: B[0] - (Affine Curve over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? defined by s2 - 1, 2*x^3 + (-a)*s1^2, - Affine Curve over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? defined by s0 - s2, 2*y^3*s2^5 + (-a), - Affine Curve over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? defined by s0 - 1, 2*z^3 + (-a)*s1^2) - sage: B[1][0][2] + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 3) # optional - sage.rings.number_field + sage: C = Curve([y^2 - a*x^5, x - z], A) # optional - sage.rings.number_field + sage: B = C.blowup() # optional - sage.rings.number_field + sage: B[0] # optional - sage.rings.number_field + (Affine Curve over Number Field in a with defining polynomial x^2 - 2 + with a = 1.414213562373095? defined by s2 - 1, 2*x^3 + (-a)*s1^2, + Affine Curve over Number Field in a with defining polynomial x^2 - 2 + with a = 1.414213562373095? defined by s0 - s2, 2*y^3*s2^5 + (-a), + Affine Curve over Number Field in a with defining polynomial x^2 - 2 + with a = 1.414213562373095? defined by s0 - 1, 2*z^3 + (-a)*s1^2) + sage: B[1][0][2] # optional - sage.rings.number_field Scheme morphism: - From: Affine Curve over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? defined by s2 - 1, 2*x^3 + (-a)*s1^2 - To: Affine Curve over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? defined by s0 - 1, 2*z^3 + (-a)*s1^2 + From: Affine Curve over Number Field in a + with defining polynomial x^2 - 2 with a = 1.414213562373095? + defined by s2 - 1, 2*x^3 + (-a)*s1^2 + To: Affine Curve over Number Field in a + with defining polynomial x^2 - 2 with a = 1.414213562373095? + defined by s0 - 1, 2*z^3 + (-a)*s1^2 Defn: Defined on coordinates by sending (x, s1, s2) to (x*s2, 1/s2, s1/s2) - sage: B[1][2][0] + sage: B[1][2][0] # optional - sage.rings.number_field Scheme morphism: - From: Affine Curve over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? defined by s0 - 1, 2*z^3 + (-a)*s1^2 - To: Affine Curve over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? defined by s2 - 1, 2*x^3 + (-a)*s1^2 + From: Affine Curve over Number Field in a + with defining polynomial x^2 - 2 with a = 1.414213562373095? + defined by s0 - 1, 2*z^3 + (-a)*s1^2 + To: Affine Curve over Number Field in a + with defining polynomial x^2 - 2 with a = 1.414213562373095? + defined by s2 - 1, 2*x^3 + (-a)*s1^2 Defn: Defined on coordinates by sending (z, s0, s1) to (z*s0, s1/s0, 1/s0) - sage: B[2] + sage: B[2] # optional - sage.rings.number_field (Scheme morphism: - From: Affine Curve over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? defined by s2 - 1, 2*x^3 + (-a)*s1^2 - To: Affine Curve over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? defined by (-a)*x^5 + y^2, x - z + From: Affine Curve over Number Field in a + with defining polynomial x^2 - 2 with a = 1.414213562373095? + defined by s2 - 1, 2*x^3 + (-a)*s1^2 + To: Affine Curve over Number Field in a + with defining polynomial x^2 - 2 with a = 1.414213562373095? + defined by (-a)*x^5 + y^2, x - z Defn: Defined on coordinates by sending (x, s1, s2) to - (x, x*s1, x*s2), Scheme morphism: - From: Affine Curve over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? defined by s0 - s2, 2*y^3*s2^5 + (-a) - To: Affine Curve over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? defined by (-a)*x^5 + y^2, x - z + (x, x*s1, x*s2), + Scheme morphism: + From: Affine Curve over Number Field in a + with defining polynomial x^2 - 2 with a = 1.414213562373095? + defined by s0 - s2, 2*y^3*s2^5 + (-a) + To: Affine Curve over Number Field in a + with defining polynomial x^2 - 2 with a = 1.414213562373095? + defined by (-a)*x^5 + y^2, x - z Defn: Defined on coordinates by sending (y, s0, s2) to - (y*s0, y, y*s2), Scheme morphism: - From: Affine Curve over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? defined by s0 - 1, 2*z^3 + (-a)*s1^2 - To: Affine Curve over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? defined by (-a)*x^5 + y^2, x - z + (y*s0, y, y*s2), + Scheme morphism: + From: Affine Curve over Number Field in a + with defining polynomial x^2 - 2 with a = 1.414213562373095? + defined by s0 - 1, 2*z^3 + (-a)*s1^2 + To: Affine Curve over Number Field in a + with defining polynomial x^2 - 2 with a = 1.414213562373095? + defined by (-a)*x^5 + y^2, x - z Defn: Defined on coordinates by sending (z, s0, s1) to (z*s0, z*s1, z)) @@ -1182,37 +1206,49 @@ def blowup(self, P=None): sage: C = A.curve((y - 3/2)^3 - (x + 2)^5 - (x + 2)^6) sage: Q = A([-2,3/2]) sage: C.blowup(Q) - ((Affine Plane Curve over Rational Field defined by x^3 - s1^3 + 7*x^2 + 16*x + 12, - Affine Plane Curve over Rational Field defined by 8*y^3*s0^6 - 36*y^2*s0^6 + 8*y^2*s0^5 + - 54*y*s0^6 - 24*y*s0^5 - 27*s0^6 + 18*s0^5 - 8), - ([Scheme endomorphism of Affine Plane Curve over Rational Field defined by x^3 - s1^3 + 7*x^2 + - 16*x + 12 + ((Affine Plane Curve over Rational Field + defined by x^3 - s1^3 + 7*x^2 + 16*x + 12, + Affine Plane Curve over Rational Field + defined by 8*y^3*s0^6 - 36*y^2*s0^6 + 8*y^2*s0^5 + + 54*y*s0^6 - 24*y*s0^5 - 27*s0^6 + 18*s0^5 - 8), + ([Scheme endomorphism of Affine Plane Curve over Rational Field + defined by x^3 - s1^3 + 7*x^2 + 16*x + 12 + Defn: Defined on coordinates by sending (x, s1) to (x, s1), + Scheme morphism: + From: Affine Plane Curve over Rational Field + defined by x^3 - s1^3 + 7*x^2 + 16*x + 12 + To: Affine Plane Curve over Rational Field + defined by 8*y^3*s0^6 - 36*y^2*s0^6 + 8*y^2*s0^5 + + 54*y*s0^6 - 24*y*s0^5 - 27*s0^6 + 18*s0^5 - 8 Defn: Defined on coordinates by sending (x, s1) to - (x, s1), Scheme morphism: - From: Affine Plane Curve over Rational Field defined by x^3 - s1^3 + 7*x^2 + 16*x + 12 - To: Affine Plane Curve over Rational Field defined by 8*y^3*s0^6 - 36*y^2*s0^6 + 8*y^2*s0^5 + - 54*y*s0^6 - 24*y*s0^5 - 27*s0^6 + 18*s0^5 - 8 - Defn: Defined on coordinates by sending (x, s1) to - (x*s1 + 2*s1 + 3/2, 1/s1)], [Scheme morphism: - From: Affine Plane Curve over Rational Field defined by 8*y^3*s0^6 - 36*y^2*s0^6 + 8*y^2*s0^5 + - 54*y*s0^6 - 24*y*s0^5 - 27*s0^6 + 18*s0^5 - 8 - To: Affine Plane Curve over Rational Field defined by x^3 - s1^3 + 7*x^2 + 16*x + 12 + (x*s1 + 2*s1 + 3/2, 1/s1)], + [Scheme morphism: + From: Affine Plane Curve over Rational Field + defined by 8*y^3*s0^6 - 36*y^2*s0^6 + 8*y^2*s0^5 + + 54*y*s0^6 - 24*y*s0^5 - 27*s0^6 + 18*s0^5 - 8 + To: Affine Plane Curve over Rational Field + defined by x^3 - s1^3 + 7*x^2 + 16*x + 12 Defn: Defined on coordinates by sending (y, s0) to (y*s0 - 3/2*s0 - 2, 1/s0), - Scheme endomorphism of Affine Plane Curve over Rational Field defined by 8*y^3*s0^6 - 36*y^2*s0^6 + - 8*y^2*s0^5 + 54*y*s0^6 - 24*y*s0^5 - 27*s0^6 + 18*s0^5 - 8 - Defn: Defined on coordinates by sending (y, s0) to - (y, s0)]), + Scheme endomorphism of Affine Plane Curve over Rational Field + defined by 8*y^3*s0^6 - 36*y^2*s0^6 + 8*y^2*s0^5 + 54*y*s0^6 + - 24*y*s0^5 - 27*s0^6 + 18*s0^5 - 8 + Defn: Defined on coordinates by sending (y, s0) to (y, s0)]), (Scheme morphism: - From: Affine Plane Curve over Rational Field defined by x^3 - s1^3 + 7*x^2 + 16*x + 12 - To: Affine Plane Curve over Rational Field defined by -x^6 - 13*x^5 - 70*x^4 - 200*x^3 + y^3 - - 320*x^2 - 9/2*y^2 - 272*x + 27/4*y - 795/8 + From: Affine Plane Curve over Rational Field + defined by x^3 - s1^3 + 7*x^2 + 16*x + 12 + To: Affine Plane Curve over Rational Field + defined by -x^6 - 13*x^5 - 70*x^4 - 200*x^3 + y^3 + - 320*x^2 - 9/2*y^2 - 272*x + 27/4*y - 795/8 Defn: Defined on coordinates by sending (x, s1) to - (x, x*s1 + 2*s1 + 3/2), Scheme morphism: - From: Affine Plane Curve over Rational Field defined by 8*y^3*s0^6 - 36*y^2*s0^6 + 8*y^2*s0^5 + - 54*y*s0^6 - 24*y*s0^5 - 27*s0^6 + 18*s0^5 - 8 - To: Affine Plane Curve over Rational Field defined by -x^6 - 13*x^5 - 70*x^4 - 200*x^3 + y^3 - - 320*x^2 - 9/2*y^2 - 272*x + 27/4*y - 795/8 + (x, x*s1 + 2*s1 + 3/2), + Scheme morphism: + From: Affine Plane Curve over Rational Field + defined by 8*y^3*s0^6 - 36*y^2*s0^6 + 8*y^2*s0^5 + + 54*y*s0^6 - 24*y*s0^5 - 27*s0^6 + 18*s0^5 - 8 + To: Affine Plane Curve over Rational Field + defined by -x^6 - 13*x^5 - 70*x^4 - 200*x^3 + y^3 + - 320*x^2 - 9/2*y^2 - 272*x + 27/4*y - 795/8 Defn: Defined on coordinates by sending (y, s0) to (y*s0 - 3/2*s0 - 2, y))) @@ -1223,16 +1259,15 @@ def blowup(self, P=None): sage: Q = C([-1,0,0,4]) sage: B = C.blowup(Q) sage: B[0] - (Affine Curve over Rational Field defined by s3, s1 - s2, x^2*s2^6 + - 2*x*s2^6 + 3*x^2*s2^4 + s2^6 + 6*x*s2^4 + 3*x^2*s2^2 + 3*s2^4 + 6*x*s2^2 - + x^2 - s2^2 + 2*x + 1, - Affine Curve over Rational Field defined by s3, s2 - 1, y^2*s0^6 + - 3*y^2*s0^4 + 3*y^2*s0^2 + y^2 - 4*s0^2, - Affine Curve over Rational Field defined by s3, s1 - 1, z^2*s0^6 + - 3*z^2*s0^4 + 3*z^2*s0^2 + z^2 - 4*s0^2, + (Affine Curve over Rational Field defined by s3, s1 - s2, + x^2*s2^6 + 2*x*s2^6 + 3*x^2*s2^4 + s2^6 + 6*x*s2^4 + + 3*x^2*s2^2 + 3*s2^4 + 6*x*s2^2 + x^2 - s2^2 + 2*x + 1, + Affine Curve over Rational Field defined by s3, s2 - 1, + y^2*s0^6 + 3*y^2*s0^4 + 3*y^2*s0^2 + y^2 - 4*s0^2, + Affine Curve over Rational Field defined by s3, s1 - 1, + z^2*s0^6 + 3*z^2*s0^4 + 3*z^2*s0^2 + z^2 - 4*s0^2, Closed subscheme of Affine Space of dimension 4 over Rational Field - defined by: - 1) + defined by: 1) sage: Q = A([6,2,3,1]) sage: B = C.blowup(Q) Traceback (most recent call last): @@ -1241,9 +1276,9 @@ def blowup(self, P=None): :: - sage: A. = AffineSpace(QuadraticField(-1), 2) - sage: C = A.curve([y^2 + x^2]) - sage: C.blowup() + sage: A. = AffineSpace(QuadraticField(-1), 2) # optional - sage.rings.number_field + sage: C = A.curve([y^2 + x^2]) # optional - sage.rings.number_field + sage: C.blowup() # optional - sage.rings.number_field Traceback (most recent call last): ... TypeError: this curve must be irreducible @@ -1369,7 +1404,7 @@ def resolution_of_singularities(self, extend=False): resolved. However, setting ``extend`` to ``True`` will slow down computations. - OUTPUT: a tuple of + OUTPUT: A tuple of - a tuple of curves in affine space of the same dimension as the ambient space of this curve, which represent affine patches of the @@ -1390,71 +1425,78 @@ def resolution_of_singularities(self, extend=False): sage: C.resolution_of_singularities() ((Affine Plane Curve over Rational Field defined by s1^2 - x, Affine Plane Curve over Rational Field defined by y*s0^3 - 1), - ((Scheme endomorphism of Affine Plane Curve over Rational Field defined by s1^2 - x - Defn: Defined on coordinates by sending (x, s1) to - (x, s1), Scheme morphism: + ((Scheme endomorphism of Affine Plane Curve over Rational Field + defined by s1^2 - x + Defn: Defined on coordinates by sending (x, s1) to (x, s1), + Scheme morphism: From: Affine Plane Curve over Rational Field defined by s1^2 - x To: Affine Plane Curve over Rational Field defined by y*s0^3 - 1 - Defn: Defined on coordinates by sending (x, s1) to - (x*s1, 1/s1)), (Scheme morphism: + Defn: Defined on coordinates by sending (x, s1) to (x*s1, 1/s1)), + (Scheme morphism: From: Affine Plane Curve over Rational Field defined by y*s0^3 - 1 To: Affine Plane Curve over Rational Field defined by s1^2 - x - Defn: Defined on coordinates by sending (y, s0) to - (y*s0, 1/s0), - Scheme endomorphism of Affine Plane Curve over Rational Field defined by y*s0^3 - 1 - Defn: Defined on coordinates by sending (y, s0) to - (y, s0))), + Defn: Defined on coordinates by sending (y, s0) to (y*s0, 1/s0), + Scheme endomorphism of Affine Plane Curve over Rational Field + defined by y*s0^3 - 1 + Defn: Defined on coordinates by sending (y, s0) to (y, s0))), (Scheme morphism: From: Affine Plane Curve over Rational Field defined by s1^2 - x To: Affine Plane Curve over Rational Field defined by -x^3 + y^2 - Defn: Defined on coordinates by sending (x, s1) to - (x, x*s1), Scheme morphism: + Defn: Defined on coordinates by sending (x, s1) to (x, x*s1), + Scheme morphism: From: Affine Plane Curve over Rational Field defined by y*s0^3 - 1 To: Affine Plane Curve over Rational Field defined by -x^3 + y^2 - Defn: Defined on coordinates by sending (y, s0) to - (y*s0, y))) + Defn: Defined on coordinates by sending (y, s0) to (y*s0, y))) :: sage: set_verbose(-1) - sage: K. = QuadraticField(3) - sage: A. = AffineSpace(K, 2) - sage: C = A.curve(x^4 + 2*x^2 + a*y^3 + 1) - sage: C.resolution_of_singularities(extend=True)[0] # long time (2 seconds) - (Affine Plane Curve over Number Field in a0 with defining polynomial y^4 - 4*y^2 + 16 defined by - 24*x^2*ss1^3 + 24*ss1^3 + (a0^3 - 8*a0), - Affine Plane Curve over Number Field in a0 with defining polynomial y^4 - 4*y^2 + 16 defined by - 24*s1^2*ss0 + (a0^3 - 8*a0)*ss0^2 + (-6*a0^3)*s1, - Affine Plane Curve over Number Field in a0 with defining polynomial y^4 - 4*y^2 + 16 defined by - 8*y^2*s0^4 + (4*a0^3)*y*s0^3 - 32*s0^2 + (a0^3 - 8*a0)*y) + sage: K. = QuadraticField(3) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: C = A.curve(x^4 + 2*x^2 + a*y^3 + 1) # optional - sage.rings.number_field + sage: C.resolution_of_singularities(extend=True)[0] # long time (2 s) # optional - sage.rings.number_field + (Affine Plane Curve over Number Field in a0 + with defining polynomial y^4 - 4*y^2 + 16 + defined by 24*x^2*ss1^3 + 24*ss1^3 + (a0^3 - 8*a0), + Affine Plane Curve over Number Field in a0 + with defining polynomial y^4 - 4*y^2 + 16 + defined by 24*s1^2*ss0 + (a0^3 - 8*a0)*ss0^2 + (-6*a0^3)*s1, + Affine Plane Curve over Number Field in a0 + with defining polynomial y^4 - 4*y^2 + 16 + defined by 8*y^2*s0^4 + (4*a0^3)*y*s0^3 - 32*s0^2 + (a0^3 - 8*a0)*y) :: - sage: A. = AffineSpace(GF(5), 3) - sage: C = Curve([y - x^3, (z - 2)^2 - y^3 - x^3], A) - sage: R = C.resolution_of_singularities() - sage: R[0] - (Affine Curve over Finite Field of size 5 defined by x^2 - s1, s1^4 - x*s2^2 + s1, x*s1^3 - s2^2 + x, - Affine Curve over Finite Field of size 5 defined by y*s2^2 - y^2 - 1, s2^4 - s0^3 - y^2 - 2, y*s0^3 - - s2^2 + y, Affine Curve over Finite Field of size 5 defined by s0^3*s1 + z*s1^3 + s1^4 - 2*s1^3 - 1, - z*s0^3 + z*s1^3 - 2*s0^3 - 2*s1^3 - 1, z^2*s1^3 + z*s1^3 - s1^3 - z + s1 + 2) + sage: A. = AffineSpace(GF(5), 3) # optional - sage.rings.finite_rings + sage: C = Curve([y - x^3, (z - 2)^2 - y^3 - x^3], A) # optional - sage.rings.finite_rings + sage: R = C.resolution_of_singularities() # optional - sage.rings.finite_rings + sage: R[0] # optional - sage.rings.finite_rings + (Affine Curve over Finite Field of size 5 + defined by x^2 - s1, s1^4 - x*s2^2 + s1, x*s1^3 - s2^2 + x, + Affine Curve over Finite Field of size 5 + defined by y*s2^2 - y^2 - 1, s2^4 - s0^3 - y^2 - 2, y*s0^3 - s2^2 + y, + Affine Curve over Finite Field of size 5 + defined by s0^3*s1 + z*s1^3 + s1^4 - 2*s1^3 - 1, + z*s0^3 + z*s1^3 - 2*s0^3 - 2*s1^3 - 1, + z^2*s1^3 + z*s1^3 - s1^3 - z + s1 + 2) :: sage: A. = AffineSpace(QQ, 4) - sage: C = A.curve([((x - 2)^2 + y^2)^2 - (x - 2)^2 - y^2 + (x - 2)^3, z - y - 7, w - 4]) + sage: C = A.curve([((x - 2)^2 + y^2)^2 - (x - 2)^2 - y^2 + (x - 2)^3, + ....: z - y - 7, w - 4]) sage: B = C.resolution_of_singularities() sage: B[0] - (Affine Curve over Rational Field defined by s3, s1 - s2, x^2*s2^4 - - 4*x*s2^4 + 2*x^2*s2^2 + 4*s2^4 - 8*x*s2^2 + x^2 + 7*s2^2 - 3*x + 1, - Affine Curve over Rational Field defined by s3, s2 - 1, y^2*s0^4 + - 2*y^2*s0^2 + y*s0^3 + y^2 - s0^2 - 1, - Affine Curve over Rational Field defined by s3, s1 - 1, z^2*s0^4 - - 14*z*s0^4 + 2*z^2*s0^2 + z*s0^3 + 49*s0^4 - 28*z*s0^2 - 7*s0^3 + z^2 + - 97*s0^2 - 14*z + 48, + (Affine Curve over Rational Field defined by s3, s1 - s2, + x^2*s2^4 - 4*x*s2^4 + 2*x^2*s2^2 + 4*s2^4 - 8*x*s2^2 + + x^2 + 7*s2^2 - 3*x + 1, + Affine Curve over Rational Field defined by s3, s2 - 1, + y^2*s0^4 + 2*y^2*s0^2 + y*s0^3 + y^2 - s0^2 - 1, + Affine Curve over Rational Field defined by s3, s1 - 1, + z^2*s0^4 - 14*z*s0^4 + 2*z^2*s0^2 + z*s0^3 + 49*s0^4 + - 28*z*s0^2 - 7*s0^3 + z^2 + 97*s0^2 - 14*z + 48, Closed subscheme of Affine Space of dimension 4 over Rational Field - defined by: - 1) + defined by: 1) :: @@ -1653,15 +1695,13 @@ def tangent_line(self, p): sage: Tp = C.tangent_space(p) sage: Tp - Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: - x + y + z, - 2*x + 3*z + Closed subscheme of Affine Space of dimension 3 over Rational Field + defined by: x + y + z, 2*x + 3*z sage: phi = A3.translation(A3.origin(), p) sage: T = phi * Tp.embedding_morphism() sage: T.image() - Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: - -2*y + z + 1, - x + y + z + Closed subscheme of Affine Space of dimension 3 over Rational Field + defined by: -2*y + z + 1, x + y + z sage: _ == C.tangent_line(p) True @@ -1705,19 +1745,19 @@ def fundamental_group(self): sage: A. = AffineSpace(QQ, 2) sage: C = A.curve(y^2 - x^3 - x^2) - sage: C.fundamental_group() # optional - sirocco + sage: C.fundamental_group() # optional - sirocco Finitely presented group < x0 | > In the case of number fields, they need to have an embedding to the algebraic field:: - sage: a = QQ[x](x^2+5).roots(QQbar)[0][0] - sage: F = NumberField(a.minpoly(), 'a', embedding=a) - sage: F.inject_variables() + sage: a = QQ[x](x^2 + 5).roots(QQbar)[0][0] # optional - sage.rings.number_field + sage: F = NumberField(a.minpoly(), 'a', embedding=a) # optional - sage.rings.number_field + sage: F.inject_variables() # optional - sage.rings.number_field Defining a - sage: A. = AffineSpace(F, 2) - sage: C = A.curve(y^2 - a*x^3 - x^2) - sage: C.fundamental_group() # optional - sirocco + sage: A. = AffineSpace(F, 2) # optional - sage.rings.number_field + sage: C = A.curve(y^2 - a*x^3 - x^2) # optional - sage.rings.number_field + sage: C.fundamental_group() # optional - sirocco # optional - sage.rings.number_field Finitely presented group < x0 | > .. WARNING:: @@ -1752,7 +1792,7 @@ def braid_monodromy(self): sage: A. = AffineSpace(QQ, 2) sage: C = A.curve((x^2-y^3)*(x+3*y-5)) - sage: C.braid_monodromy() # optional - sirocco + sage: C.braid_monodromy() # optional - sirocco [s1*s0*(s1*s2)^2*s0*s2^2*s0^-1*(s2^-1*s1^-1)^2*s0^-1*s1^-1, s1*s0*(s1*s2)^2*(s0*s2^-1*s1*s2*s1*s2^-1)^2*(s2^-1*s1^-1)^2*s0^-1*s1^-1, s1*s0*(s1*s2)^2*s2*s1^-1*s2^-1*s1^-1*s0^-1*s1^-1, @@ -1773,16 +1813,15 @@ def riemann_surface(self, **kwargs): r""" Return the complex Riemann surface determined by this curve - OUTPUT: - - - RiemannSurface object + OUTPUT: A :class:`~sage.schemes.riemann_surfaces.riemann_surface.RiemannSurface` object. EXAMPLES:: - sage: R.=QQ[] - sage: C = Curve(x^3+3*y^3+5) + sage: R. = QQ[] + sage: C = Curve(x^3 + 3*y^3 + 5) sage: C.riemann_surface() - Riemann surface defined by polynomial f = x^3 + 3*y^3 + 5 = 0, with 53 bits of precision + Riemann surface defined by polynomial f = x^3 + 3*y^3 + 5 = 0, + with 53 bits of precision """ from sage.schemes.riemann_surfaces.riemann_surface import RiemannSurface S = RiemannSurface(self.defining_polynomial(),**kwargs) @@ -1815,16 +1854,16 @@ def riemann_roch_basis(self, D): divisor `Div = d_1P_1 + \dots + d_nP_n`, where `X(F) = \{P_1, \dots, P_n\}`. The ordering is that dictated by ``places_on_curve``. - OUTPUT: a basis of `L(Div)` + OUTPUT: A basis of `L(Div)`. EXAMPLES:: - sage: R = PolynomialRing(GF(5),2,names = ["x","y"]) - sage: x, y = R.gens() - sage: f = y^2 - x^9 - x - sage: C = Curve(f) - sage: D = [6,0,0,0,0,0] - sage: C.riemann_roch_basis(D) + sage: R = PolynomialRing(GF(5), 2, names=["x","y"]) # optional - sage.rings.finite_rings + sage: x, y = R.gens() # optional - sage.rings.finite_rings + sage: f = y^2 - x^9 - x # optional - sage.rings.finite_rings + sage: C = Curve(f) # optional - sage.rings.finite_rings + sage: D = [6,0,0,0,0,0] # optional - sage.rings.finite_rings + sage: C.riemann_roch_basis(D) # optional - sage.rings.finite_rings [1, (-x*z^5 + y^2*z^4)/x^6, (-x*z^6 + y^2*z^5)/x^7, (-x*z^7 + y^2*z^6)/x^8] """ F = self.base_ring() @@ -1870,33 +1909,35 @@ def rational_points(self, algorithm="enum"): EXAMPLES:: - sage: x, y = (GF(5)['x,y']).gens() - sage: f = y^2 - x^9 - x - sage: C = Curve(f); C + sage: x, y = (GF(5)['x,y']).gens() # optional - sage.rings.finite_rings + sage: f = y^2 - x^9 - x # optional - sage.rings.finite_rings + sage: C = Curve(f); C # optional - sage.rings.finite_rings Affine Plane Curve over Finite Field of size 5 defined by -x^9 + y^2 - x - sage: C.rational_points(algorithm='bn') + sage: C.rational_points(algorithm='bn') # optional - sage.rings.finite_rings [(0, 0), (2, 2), (2, 3), (3, 1), (3, 4)] - sage: C = Curve(x - y + 1) - sage: C.rational_points() + sage: C = Curve(x - y + 1) # optional - sage.rings.finite_rings + sage: C.rational_points() # optional - sage.rings.finite_rings [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)] We compare Brill-Noether and enumeration:: - sage: x, y = (GF(17)['x,y']).gens() - sage: C = Curve(x^2 + y^5 + x*y - 19) - sage: v = C.rational_points(algorithm='bn') - sage: w = C.rational_points(algorithm='enum') - sage: len(v) + sage: x, y = (GF(17)['x,y']).gens() # optional - sage.rings.finite_rings + sage: C = Curve(x^2 + y^5 + x*y - 19) # optional - sage.rings.finite_rings + sage: v = C.rational_points(algorithm='bn') # optional - sage.rings.finite_rings + sage: w = C.rational_points(algorithm='enum') # optional - sage.rings.finite_rings + sage: len(v) # optional - sage.rings.finite_rings 20 - sage: v == w + sage: v == w # optional - sage.rings.finite_rings True - sage: A. = AffineSpace(2,GF(9,'a')) - sage: C = Curve(x^2 + y^2 - 1) - sage: C - Affine Plane Curve over Finite Field in a of size 3^2 defined by x^2 + y^2 - 1 - sage: C.rational_points() - [(0, 1), (0, 2), (1, 0), (2, 0), (a + 1, a + 1), (a + 1, 2*a + 2), (2*a + 2, a + 1), (2*a + 2, 2*a + 2)] + sage: A. = AffineSpace(2, GF(9,'a')) # optional - sage.rings.finite_rings + sage: C = Curve(x^2 + y^2 - 1) # optional - sage.rings.finite_rings + sage: C # optional - sage.rings.finite_rings + Affine Plane Curve over Finite Field in a of size 3^2 + defined by x^2 + y^2 - 1 + sage: C.rational_points() # optional - sage.rings.finite_rings + [(0, 1), (0, 2), (1, 0), (2, 0), (a + 1, a + 1), + (a + 1, 2*a + 2), (2*a + 2, a + 1), (2*a + 2, 2*a + 2)] """ if algorithm == "enum": f = self.defining_polynomial() @@ -1961,9 +2002,9 @@ def function_field(self): :: - sage: A. = AffineSpace(GF(8), 2) - sage: C = Curve(x^5 + y^5 + x*y + 1) - sage: C.function_field() + sage: A. = AffineSpace(GF(8), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y + 1) # optional - sage.rings.finite_rings + sage: C.function_field() # optional - sage.rings.finite_rings Function field in y defined by y^5 + x*y + x^5 + 1 """ return self._function_field @@ -1975,9 +2016,9 @@ def _genus(self): EXAMPLES:: - sage: A. = AffineSpace(GF(2), 2) - sage: C = Curve(x^5 + y^5 + x*y + 1) - sage: C.genus() # indirect doctest + sage: A. = AffineSpace(GF(2), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y + 1) # optional - sage.rings.finite_rings + sage: C.genus() # indirect doctest # optional - sage.rings.finite_rings 1 """ k = self.base_ring() @@ -1997,25 +2038,25 @@ def __call__(self, *args): EXAMPLES:: - sage: A. = AffineSpace(GF(8), 2) - sage: C = Curve(x^5 + y^5 + x*y + 1) - sage: C(1,1) + sage: A. = AffineSpace(GF(8), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y + 1) # optional - sage.rings.finite_rings + sage: C(1,1) # optional - sage.rings.finite_rings (1, 1) - sage: C(x/y) + sage: C(x/y) # optional - sage.rings.finite_rings (x/(x^5 + 1))*y^4 + x^2/(x^5 + 1) - sage: C(GF(8^2)) + sage: C(GF(8^2)) # optional - sage.rings.finite_rings Set of rational points of Closed subscheme of Affine Space of dimension 2 over Finite Field in z6 of size 2^6 defined by: x^5 + y^5 + x*y + 1 :: - sage: A. = AffineSpace(GF(11), 3) - sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) - sage: C([0,0,0]) + sage: A. = AffineSpace(GF(11), 3) # optional - sage.rings.finite_rings + sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) # optional - sage.rings.finite_rings + sage: C([0,0,0]) # optional - sage.rings.finite_rings (0, 0, 0) - sage: C(y) + sage: C(y) # optional - sage.rings.finite_rings z^2 - sage: C(A.coordinate_ring()(y)) + sage: C(A.coordinate_ring()(y)) # optional - sage.rings.finite_rings z^2 """ try: @@ -2037,14 +2078,14 @@ def function(self, f): EXAMPLES:: - sage: A. = AffineSpace(GF(8), 2) - sage: C = Curve(x^5 + y^5 + x*y + 1) - sage: f = C.function(x/y) - sage: f + sage: A. = AffineSpace(GF(8), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y + 1) # optional - sage.rings.finite_rings + sage: f = C.function(x/y) # optional - sage.rings.finite_rings + sage: f # optional - sage.rings.finite_rings (x/(x^5 + 1))*y^4 + x^2/(x^5 + 1) - sage: df = f.differential(); df + sage: df = f.differential(); df # optional - sage.rings.finite_rings ((1/(x^10 + 1))*y^4 + x^6/(x^10 + 1)) d(x) - sage: df.divisor() + sage: df.divisor() # optional - sage.rings.finite_rings 2*Place (1/x, 1/x^4*y^4 + 1/x^3*y^3 + 1/x^2*y^2 + 1/x*y + 1) + 2*Place (1/x, 1/x*y + 1) - 2*Place (x + 1, y) @@ -2065,10 +2106,10 @@ def coordinate_functions(self): EXAMPLES:: - sage: A. = AffineSpace(GF(8), 2) - sage: C = Curve(x^5 + y^5 + x*y + 1) - sage: x, y = C.coordinate_functions() - sage: x^5 + y^5 + x*y + 1 + sage: A. = AffineSpace(GF(8), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y + 1) # optional - sage.rings.finite_rings + sage: x, y = C.coordinate_functions() # optional - sage.rings.finite_rings + sage: x^5 + y^5 + x*y + 1 # optional - sage.rings.finite_rings 0 """ return self._coordinate_functions @@ -2085,11 +2126,13 @@ def _nonsingular_model(self): TESTS:: - sage: A. = AffineSpace(GF(11), 3) - sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) - sage: C._nonsingular_model - (Function field in z defined by z^3 + 10*x, Ring morphism: - From: Multivariate Polynomial Ring in x, y, z over Finite Field of size 11 + sage: A. = AffineSpace(GF(11), 3) # optional - sage.rings.finite_rings + sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) # optional - sage.rings.finite_rings + sage: C._nonsingular_model # optional - sage.rings.finite_rings + (Function field in z defined by z^3 + 10*x, + Ring morphism: + From: Multivariate Polynomial Ring in x, y, z + over Finite Field of size 11 To: Function field in z defined by z^3 + 10*x Defn: x |--> x y |--> z^2 @@ -2190,9 +2233,9 @@ def _function_field(self): TESTS:: - sage: A. = AffineSpace(GF(11), 3) - sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) - sage: C._function_field + sage: A. = AffineSpace(GF(11), 3) # optional - sage.rings.finite_rings + sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) # optional - sage.rings.finite_rings + sage: C._function_field # optional - sage.rings.finite_rings Function field in z defined by z^3 + 10*x """ return self._nonsingular_model[0] @@ -2204,11 +2247,12 @@ def _lift_to_function_field(self): TESTS:: - sage: A. = AffineSpace(GF(11), 3) - sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) - sage: C._lift_to_function_field + sage: A. = AffineSpace(GF(11), 3) # optional - sage.rings.finite_rings + sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) # optional - sage.rings.finite_rings + sage: C._lift_to_function_field # optional - sage.rings.finite_rings Ring morphism: - From: Multivariate Polynomial Ring in x, y, z over Finite Field of size 11 + From: Multivariate Polynomial Ring in x, y, z + over Finite Field of size 11 To: Function field in z defined by z^3 + 10*x Defn: x |--> x y |--> z^2 @@ -2223,9 +2267,9 @@ def _coordinate_functions(self): TESTS:: - sage: A. = AffineSpace(GF(11), 3) - sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) - sage: C._coordinate_functions + sage: A. = AffineSpace(GF(11), 3) # optional - sage.rings.finite_rings + sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) # optional - sage.rings.finite_rings + sage: C._coordinate_functions # optional - sage.rings.finite_rings [x, z^2, z] """ return self._nonsingular_model[1].im_gens() @@ -2237,9 +2281,9 @@ def _singularities(self): TESTS:: - sage: A. = AffineSpace(GF(7^2),2) - sage: C = Curve(x^2 - x^4 - y^4) - sage: C._singularities + sage: A. = AffineSpace(GF(7^2), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^2 - x^4 - y^4) # optional - sage.rings.finite_rings + sage: C._singularities # optional - sage.rings.finite_rings [(Point (x, y), [Place (x, 1/x*y^3 + 1/x*y^2 + 1), Place (x, 1/x*y^3 + 1/x*y^2 + 6)])] """ @@ -2279,16 +2323,16 @@ def singular_closed_points(self): EXAMPLES:: - sage: A. = AffineSpace(GF(7^2),2) - sage: C = Curve(x^2 - x^4 - y^4) - sage: C.singular_closed_points() + sage: A. = AffineSpace(GF(7^2), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^2 - x^4 - y^4) # optional - sage.rings.finite_rings + sage: C.singular_closed_points() # optional - sage.rings.finite_rings [Point (x, y)] :: - sage: A. = AffineSpace(GF(11), 3) - sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) - sage: C.singular_closed_points() + sage: A. = AffineSpace(GF(11), 3) # optional - sage.rings.finite_rings + sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) # optional - sage.rings.finite_rings + sage: C.singular_closed_points() # optional - sage.rings.finite_rings [] """ return [p for p, _ in self._singularities] @@ -2304,13 +2348,13 @@ def place_to_closed_point(self, place): EXAMPLES:: - sage: A. = AffineSpace(GF(4), 2) - sage: C = Curve(x^5 + y^5 + x*y + 1) - sage: F = C.function_field() - sage: pls = F.places(1) - sage: C.place_to_closed_point(pls[-1]) + sage: A. = AffineSpace(GF(4), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y + 1) # optional - sage.rings.finite_rings + sage: F = C.function_field() # optional - sage.rings.finite_rings + sage: pls = F.places(1) # optional - sage.rings.finite_rings + sage: C.place_to_closed_point(pls[-1]) # optional - sage.rings.finite_rings Point (x + 1, y + 1) - sage: C.place_to_closed_point(pls[-2]) + sage: C.place_to_closed_point(pls[-2]) # optional - sage.rings.finite_rings Point (x + 1, y + 1) """ F = self.function_field() @@ -2388,17 +2432,17 @@ def places_at_infinity(self): :: - sage: F = GF(9) - sage: A2. = AffineSpace(F, 2) - sage: C = A2.curve(y^3 + y - x^4) - sage: C.places_at_infinity() + sage: F = GF(9) # optional - sage.rings.finite_rings + sage: A2. = AffineSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = A2.curve(y^3 + y - x^4) # optional - sage.rings.finite_rings + sage: C.places_at_infinity() # optional - sage.rings.finite_rings [Place (1/x, 1/x^3*y^2)] :: - sage: A. = AffineSpace(GF(11), 3) - sage: C = Curve([x*z-y^2,y-z^2,x-y*z], A) - sage: C.places_at_infinity() + sage: A. = AffineSpace(GF(11), 3) # optional - sage.rings.finite_rings + sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) # optional - sage.rings.finite_rings + sage: C.places_at_infinity() # optional - sage.rings.finite_rings [Place (1/x, 1/x*z^2)] """ return list(set(p for f in self._coordinate_functions if f for p in f.poles())) @@ -2411,7 +2455,7 @@ def places_on(self, point): - ``point`` -- a closed point of the curve - OUTPUT: a list of the places of the function field of the curve + OUTPUT: A list of the places of the function field of the curve. EXAMPLES:: @@ -2425,11 +2469,11 @@ def places_on(self, point): :: - sage: k. = GF(9) - sage: A. = AffineSpace(k,2) - sage: C = Curve(y^2 - x^5 - x^4 - 2*x^3 - 2*x - 2) - sage: pts = C.closed_points() - sage: pts + sage: k. = GF(9) # optional - sage.rings.finite_rings + sage: A. = AffineSpace(k, 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 - x^5 - x^4 - 2*x^3 - 2*x - 2) # optional - sage.rings.finite_rings + sage: pts = C.closed_points() # optional - sage.rings.finite_rings + sage: pts # optional - sage.rings.finite_rings [Point (x, y + (a + 1)), Point (x, y + (-a - 1)), Point (x + (a + 1), y + (a - 1)), @@ -2440,20 +2484,20 @@ def places_on(self, point): Point (x + (-a - 1), y + (-a)), Point (x + 1, y + 1), Point (x + 1, y - 1)] - sage: p1, p2, p3 = pts[:3] - sage: C.places_on(p1) + sage: p1, p2, p3 = pts[:3] # optional - sage.rings.finite_rings + sage: C.places_on(p1) # optional - sage.rings.finite_rings [Place (x, y + a + 1)] - sage: C.places_on(p2) + sage: C.places_on(p2) # optional - sage.rings.finite_rings [Place (x, y + 2*a + 2)] - sage: C.places_on(p3) + sage: C.places_on(p3) # optional - sage.rings.finite_rings [Place (x + a + 1, y + a + 2)] :: - sage: F. = GF(8) - sage: P. = ProjectiveSpace(F, 2) - sage: Cp = Curve(x^3*y + y^3*z + x*z^3) - sage: C = Cp.affine_patch(0) + sage: F. = GF(8) # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(F, 2) # optional - sage.rings.finite_rings + sage: Cp = Curve(x^3*y + y^3*z + x*z^3) # optional - sage.rings.finite_rings + sage: C = Cp.affine_patch(0) # optional - sage.rings.finite_rings """ phi = self._lift_to_function_field gs = [phi(g) for g in point.prime_ideal().gens()] @@ -2487,17 +2531,17 @@ def parametric_representation(self, place, name=None): :: - sage: A. = AffineSpace(GF(7^2), 2) - sage: C = Curve(x^2 - x^4 - y^4) - sage: p, = C.singular_closed_points() - sage: b1, b2 = p.places() - sage: xs, ys = C.parametric_representation(b1) - sage: f = xs^2 - xs^4 - ys^4 - sage: [f.coefficient(i) for i in range(5)] + sage: A. = AffineSpace(GF(7^2), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^2 - x^4 - y^4) # optional - sage.rings.finite_rings + sage: p, = C.singular_closed_points() # optional - sage.rings.finite_rings + sage: b1, b2 = p.places() # optional - sage.rings.finite_rings + sage: xs, ys = C.parametric_representation(b1) # optional - sage.rings.finite_rings + sage: f = xs^2 - xs^4 - ys^4 # optional - sage.rings.finite_rings + sage: [f.coefficient(i) for i in range(5)] # optional - sage.rings.finite_rings [0, 0, 0, 0, 0] - sage: xs, ys = C.parametric_representation(b2) - sage: f = xs^2 - xs^4 - ys^4 - sage: [f.coefficient(i) for i in range(5)] + sage: xs, ys = C.parametric_representation(b2) # optional - sage.rings.finite_rings + sage: f = xs^2 - xs^4 - ys^4 # optional - sage.rings.finite_rings + sage: [f.coefficient(i) for i in range(5)] # optional - sage.rings.finite_rings [0, 0, 0, 0, 0] """ F = place.function_field() @@ -2518,10 +2562,11 @@ class IntegralAffineCurve_finite_field(IntegralAffineCurve): EXAMPLES:: - sage: A. = AffineSpace(GF(11), 3) - sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A); C - Affine Curve over Finite Field of size 11 defined by -y^2 + x*z, -z^2 + y, -y*z + x - sage: C.function_field() + sage: A. = AffineSpace(GF(11), 3) # optional - sage.rings.finite_rings + sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A); C # optional - sage.rings.finite_rings + Affine Curve over Finite Field of size 11 + defined by -y^2 + x*z, -z^2 + y, -y*z + x + sage: C.function_field() # optional - sage.rings.finite_rings Function field in z defined by z^3 + 10*x """ _point = IntegralAffineCurvePoint_finite_field @@ -2536,10 +2581,10 @@ def places(self, degree=1): EXAMPLES:: - sage: F = GF(9) - sage: A2. = AffineSpace(F, 2) - sage: C = A2.curve(y^3 + y - x^4) - sage: C.places() + sage: F = GF(9) # optional - sage.rings.finite_rings + sage: A2. = AffineSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = A2.curve(y^3 + y - x^4) # optional - sage.rings.finite_rings + sage: C.places() # optional - sage.rings.finite_rings [Place (1/x, 1/x^3*y^2), Place (x, y), Place (x, y + z2 + 1), @@ -2583,9 +2628,9 @@ def closed_points(self, degree=1): EXAMPLES:: - sage: A. = AffineSpace(GF(7),2) - sage: C = Curve(x^2 - x^4 - y^4) - sage: C.closed_points() + sage: A. = AffineSpace(GF(7), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^2 - x^4 - y^4) # optional - sage.rings.finite_rings + sage: C.closed_points() # optional - sage.rings.finite_rings [Point (x, y), Point (x + 1, y), Point (x + 2, y + 2), @@ -2628,10 +2673,11 @@ class IntegralAffinePlaneCurve_finite_field(AffinePlaneCurve_finite_field, Integ EXAMPLES:: - sage: A. = AffineSpace(GF(8), 2) - sage: C = Curve(x^5 + y^5 + x*y + 1); C - Affine Plane Curve over Finite Field in z3 of size 2^3 defined by x^5 + y^5 + x*y + 1 - sage: C.function_field() + sage: A. = AffineSpace(GF(8), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y + 1); C # optional - sage.rings.finite_rings + Affine Plane Curve over Finite Field in z3 of size 2^3 + defined by x^5 + y^5 + x*y + 1 + sage: C.function_field() # optional - sage.rings.finite_rings Function field in y defined by y^5 + x*y + x^5 + 1 """ _point = IntegralAffinePlaneCurvePoint_finite_field diff --git a/src/sage/schemes/curves/closed_point.py b/src/sage/schemes/curves/closed_point.py index 9d881016bb7..3f11fb19b19 100644 --- a/src/sage/schemes/curves/closed_point.py +++ b/src/sage/schemes/curves/closed_point.py @@ -9,30 +9,30 @@ EXAMPLES:: - sage: F. = GF(2) - sage: P. = AffineSpace(F, 2); - sage: C = Curve(y^2 + y - x^3) - sage: C.closed_points() + sage: F. = GF(2) # optional - sage.rings.finite_rings + sage: P. = AffineSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 + y - x^3) # optional - sage.rings.finite_rings + sage: C.closed_points() # optional - sage.rings.finite_rings [Point (x, y), Point (x, y + 1)] - sage: C.closed_points(2) + sage: C.closed_points(2) # optional - sage.rings.finite_rings [Point (y^2 + y + 1, x + 1), Point (y^2 + y + 1, x + y), Point (y^2 + y + 1, x + y + 1)] - sage: C.closed_points(3) + sage: C.closed_points(3) # optional - sage.rings.finite_rings [Point (x^2 + x + y, x*y + 1, y^2 + x + 1), Point (x^2 + x + y + 1, x*y + x + 1, y^2 + x)] Closed points of projective curves are represented by homogeneous maximal ideals:: - sage: F. = GF(2) - sage: P. = ProjectiveSpace(F, 2) - sage: C = Curve(x^3*y + y^3*z + x*z^3) - sage: C.closed_points() + sage: F. = GF(2) # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^3*y + y^3*z + x*z^3) # optional - sage.rings.finite_rings + sage: C.closed_points() # optional - sage.rings.finite_rings [Point (x, z), Point (x, y), Point (y, z)] - sage: C.closed_points(2) + sage: C.closed_points(2) # optional - sage.rings.finite_rings [Point (y^2 + y*z + z^2, x + y + z)] - sage: C.closed_points(3) + sage: C.closed_points(3) # optional - sage.rings.finite_rings [Point (y^3 + y^2*z + z^3, x + y), Point (y^3 + y*z^2 + z^3, x + z), Point (x^2 + x*z + y*z + z^2, x*y + x*z + z^2, y^2 + x*z), @@ -44,19 +44,19 @@ Rational points are easily converted to closed points and vice versa if the closed point is of degree one:: - sage: F. = GF(2) - sage: P. = ProjectiveSpace(F, 2) - sage: C = Curve(x^3*y + y^3*z + x*z^3) - sage: p1, p2, p3 = C.closed_points() - sage: p1.rational_point() + sage: F. = GF(2) # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^3*y + y^3*z + x*z^3) # optional - sage.rings.finite_rings + sage: p1, p2, p3 = C.closed_points() # optional - sage.rings.finite_rings + sage: p1.rational_point() # optional - sage.rings.finite_rings (0 : 1 : 0) - sage: p2.rational_point() + sage: p2.rational_point() # optional - sage.rings.finite_rings (0 : 0 : 1) - sage: p3.rational_point() + sage: p3.rational_point() # optional - sage.rings.finite_rings (1 : 0 : 0) - sage: _.closed_point() + sage: _.closed_point() # optional - sage.rings.finite_rings Point (y, z) - sage: _ == p3 + sage: _ == p3 # optional - sage.rings.finite_rings True AUTHORS: @@ -99,10 +99,10 @@ class IntegralCurveClosedPoint(CurveClosedPoint): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); - sage: C = Curve(y^2 + y - x^3) - sage: C.closed_points() + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: P. = AffineSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 + y - x^3) # optional - sage.rings.finite_rings + sage: C.closed_points() # optional - sage.rings.finite_rings [Point (x, y), Point (x, y + 1), Point (x + a, y + a), @@ -118,12 +118,12 @@ def __init__(self, curve, prime_ideal, degree): TESTS:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); - sage: C = Curve(y^2 + y - x^3) - sage: p = C([0,0]); p + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: P. = AffineSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 + y - x^3) # optional - sage.rings.finite_rings + sage: p = C([0,0]); p # optional - sage.rings.finite_rings (0, 0) - sage: loads(dumps(p)) == p + sage: loads(dumps(p)) == p # optional - sage.rings.finite_rings True """ super().__init__(curve.ambient_space(), prime_ideal) @@ -137,12 +137,12 @@ def __hash__(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); - sage: C = Curve(y^2 + y - x^3) - sage: pts = C.closed_points() - sage: p = pts[0] - sage: {p: 1} + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: P. = AffineSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 + y - x^3) # optional - sage.rings.finite_rings + sage: pts = C.closed_points() # optional - sage.rings.finite_rings + sage: p = pts[0] # optional - sage.rings.finite_rings + sage: {p: 1} # optional - sage.rings.finite_rings {Point (x, y): 1} """ return hash((self.parent(),self.prime_ideal())) @@ -159,11 +159,11 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); - sage: C = Curve(y^2 + y - x^3) - sage: pts = C.closed_points() - sage: pts[0] == pts[1] + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: P. = AffineSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 + y - x^3) # optional - sage.rings.finite_rings + sage: pts = C.closed_points() # optional - sage.rings.finite_rings + sage: pts[0] == pts[1] # optional - sage.rings.finite_rings False """ return richcmp((self._curve, self.prime_ideal()), (other._curve, other.prime_ideal()), op) @@ -174,11 +174,11 @@ def _repr_(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); - sage: C = Curve(y^2 + y - x^3) - sage: pts = C.closed_points() - sage: pts[0] + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: P. = AffineSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 + y - x^3) # optional - sage.rings.finite_rings + sage: pts = C.closed_points() # optional - sage.rings.finite_rings + sage: pts[0] # optional - sage.rings.finite_rings Point (x, y) """ return "Point ({})".format(', '.join(repr(g) for g in self.prime_ideal().gens())) @@ -189,12 +189,12 @@ def curve(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); - sage: C = Curve(y^2 + y - x^3) - sage: pts = C.closed_points() - sage: p = pts[0] - sage: p.curve() + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: P. = AffineSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 + y - x^3) # optional - sage.rings.finite_rings + sage: pts = C.closed_points() # optional - sage.rings.finite_rings + sage: p = pts[0] # optional - sage.rings.finite_rings + sage: p.curve() # optional - sage.rings.finite_rings Affine Plane Curve over Finite Field in a of size 2^2 defined by x^3 + y^2 + y """ return self._curve @@ -205,12 +205,12 @@ def degree(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); - sage: C = Curve(y^2 + y - x^3) - sage: pts = C.closed_points() - sage: p = pts[0] - sage: p.degree() + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: P. = AffineSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 + y - x^3) # optional - sage.rings.finite_rings + sage: pts = C.closed_points() # optional - sage.rings.finite_rings + sage: p = pts[0] # optional - sage.rings.finite_rings + sage: p.degree() # optional - sage.rings.finite_rings 1 """ return self._degree @@ -221,12 +221,12 @@ def places(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); - sage: C = Curve(y^2 + y - x^3) - sage: pts = C.closed_points() - sage: p = pts[0] - sage: p.places() + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: P. = AffineSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 + y - x^3) # optional - sage.rings.finite_rings + sage: pts = C.closed_points() # optional - sage.rings.finite_rings + sage: p = pts[0] # optional - sage.rings.finite_rings + sage: p.places() # optional - sage.rings.finite_rings [Place (x, y)] """ return self._curve.places_on(self) @@ -239,12 +239,12 @@ def place(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); - sage: C = Curve(y^2 + y - x^3) - sage: pts = C.closed_points() - sage: p = pts[0] - sage: p.place() + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: P. = AffineSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 + y - x^3) # optional - sage.rings.finite_rings + sage: pts = C.closed_points() # optional - sage.rings.finite_rings + sage: p = pts[0] # optional - sage.rings.finite_rings + sage: p.place() # optional - sage.rings.finite_rings Place (x, y) """ return self._curve.places_on(self)[0] @@ -260,9 +260,9 @@ def rational_point(self): EXAMPLES:: - sage: A. = AffineSpace(GF(3^2),2) - sage: C = Curve(y^2 - x^5 - x^4 - 2*x^3 - 2*x-2) - sage: C.closed_points() + sage: A. = AffineSpace(GF(3^2), 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 - x^5 - x^4 - 2*x^3 - 2*x - 2) # optional - sage.rings.finite_rings + sage: C.closed_points() # optional - sage.rings.finite_rings [Point (x, y + (z2 + 1)), Point (x, y + (-z2 - 1)), Point (x + (z2 + 1), y + (z2 - 1)), @@ -273,7 +273,7 @@ def rational_point(self): Point (x + (-z2 - 1), y + (-z2)), Point (x + 1, y + 1), Point (x + 1, y - 1)] - sage: [p.rational_point() for p in _] + sage: [p.rational_point() for p in _] # optional - sage.rings.finite_rings [(0, 2*z2 + 2), (0, z2 + 1), (2*z2 + 2, 2*z2 + 1), @@ -284,7 +284,7 @@ def rational_point(self): (z2 + 1, z2), (2, 2), (2, 1)] - sage: set(_) == set(C.rational_points()) + sage: set(_) == set(C.rational_points()) # optional - sage.rings.finite_rings True """ if self.degree() != 1: @@ -305,21 +305,21 @@ def projective(self, i=0): EXAMPLES:: - sage: F. = GF(2) - sage: A. = AffineSpace(F, 2) - sage: C = Curve(y^2 + y - x^3, A) - sage: p1, p2 = C.closed_points() - sage: p1 + sage: F. = GF(2) # optional - sage.rings.finite_rings + sage: A. = AffineSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 + y - x^3, A) # optional - sage.rings.finite_rings + sage: p1, p2 = C.closed_points() # optional - sage.rings.finite_rings + sage: p1 # optional - sage.rings.finite_rings Point (x, y) - sage: p2 + sage: p2 # optional - sage.rings.finite_rings Point (x, y + 1) - sage: p1.projective() + sage: p1.projective() # optional - sage.rings.finite_rings Point (x1, x2) - sage: p2.projective(0) + sage: p2.projective(0) # optional - sage.rings.finite_rings Point (x1, x0 + x2) - sage: p2.projective(1) + sage: p2.projective(1) # optional - sage.rings.finite_rings Point (x0, x1 + x2) - sage: p2.projective(2) + sage: p2.projective(2) # optional - sage.rings.finite_rings Point (x0, x1 + x2) """ C = self.curve() @@ -349,18 +349,18 @@ def rational_point(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = ProjectiveSpace(F, 2) - sage: C = Curve(x^3*y + y^3*z + x*z^3) - sage: C.closed_points() + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^3*y + y^3*z + x*z^3) # optional - sage.rings.finite_rings + sage: C.closed_points() # optional - sage.rings.finite_rings [Point (x, z), Point (x, y), Point (y, z), Point (x + a*z, y + (a + 1)*z), Point (x + (a + 1)*z, y + a*z)] - sage: [p.rational_point() for p in _] + sage: [p.rational_point() for p in _] # optional - sage.rings.finite_rings [(0 : 1 : 0), (0 : 0 : 1), (1 : 0 : 0), (a : a + 1 : 1), (a + 1 : a : 1)] - sage: set(_) == set(C.rational_points()) + sage: set(_) == set(C.rational_points()) # optional - sage.rings.finite_rings True """ if self.degree() != 1: @@ -385,19 +385,19 @@ def affine(self, i=None): EXAMPLES:: - sage: F. = GF(2) - sage: P. = ProjectiveSpace(F, 2) - sage: C = Curve(x^3*y + y^3*z + x*z^3) - sage: p1, p2, p3 = C.closed_points() - sage: p1.affine() + sage: F. = GF(2) # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^3*y + y^3*z + x*z^3) # optional - sage.rings.finite_rings + sage: p1, p2, p3 = C.closed_points() # optional - sage.rings.finite_rings + sage: p1.affine() # optional - sage.rings.finite_rings Point (x, z) - sage: p2.affine() + sage: p2.affine() # optional - sage.rings.finite_rings Point (x, y) - sage: p3.affine() + sage: p3.affine() # optional - sage.rings.finite_rings Point (y, z) - sage: p3.affine(0) + sage: p3.affine(0) # optional - sage.rings.finite_rings Point (y, z) - sage: p3.affine(1) + sage: p3.affine(1) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not in the affine patch diff --git a/src/sage/schemes/curves/constructor.py b/src/sage/schemes/curves/constructor.py index 88f9b95701f..690a3962896 100644 --- a/src/sage/schemes/curves/constructor.py +++ b/src/sage/schemes/curves/constructor.py @@ -12,9 +12,10 @@ :: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: Curve(y^2*z^7 - x^9 - x*z^8) - Projective Plane Curve over Finite Field of size 5 defined by -x^9 + y^2*z^7 - x*z^8 + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: Curve(y^2*z^7 - x^9 - x*z^8) # optional - sage.rings.finite_rings + Projective Plane Curve over Finite Field of size 5 + defined by -x^9 + y^2*z^7 - x*z^8 AUTHORS: @@ -123,10 +124,10 @@ def Curve(F, A=None): Affine plane curves. :: - sage: x,y = GF(7)['x,y'].gens() - sage: C = Curve(y^2 + x^3 + x^10); C + sage: x,y = GF(7)['x,y'].gens() # optional - sage.rings.finite_rings + sage: C = Curve(y^2 + x^3 + x^10); C # optional - sage.rings.finite_rings Affine Plane Curve over Finite Field of size 7 defined by x^10 + x^3 + y^2 - sage: C.genus() + sage: C.genus() # optional - sage.rings.finite_rings 0 sage: x, y = QQ['x,y'].gens() sage: Curve(x^3 + y^3 + 1) @@ -168,24 +169,25 @@ def Curve(F, A=None): The intersection is not a curve, though it is a scheme. :: sage: X = C.intersection(D); X - Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x^3 + y^3 + z^3, - x^4 + y^4 + z^4 + Closed subscheme of Projective Space of dimension 2 over Rational Field + defined by: x^3 + y^3 + z^3, + x^4 + y^4 + z^4 Note that the intersection has dimension 0. :: sage: X.dimension() 0 sage: I = X.defining_ideal(); I - Ideal (x^3 + y^3 + z^3, x^4 + y^4 + z^4) of Multivariate Polynomial Ring in x, y, z over Rational Field + Ideal (x^3 + y^3 + z^3, x^4 + y^4 + z^4) of + Multivariate Polynomial Ring in x, y, z over Rational Field If only a polynomial in three variables is given, then it must be homogeneous such that a projective curve is constructed. :: sage: x,y,z = QQ['x,y,z'].gens() - sage: Curve(x^2+y^2) + sage: Curve(x^2 + y^2) Projective Conic Curve over Rational Field defined by x^2 + y^2 - sage: Curve(x^2+y^2+z) + sage: Curve(x^2 + y^2 + z) Traceback (most recent call last): ... TypeError: x^2 + y^2 + z is not a homogeneous polynomial @@ -203,11 +205,11 @@ def Curve(F, A=None): The defining polynomial must be nonzero unless the ambient space itself is of dimension 1. :: - sage: P1. = ProjectiveSpace(1,GF(5)) - sage: S = P1.coordinate_ring() - sage: Curve(S(0), P1) + sage: P1. = ProjectiveSpace(1, GF(5)) # optional - sage.rings.finite_rings + sage: S = P1.coordinate_ring() # optional - sage.rings.finite_rings + sage: Curve(S(0), P1) # optional - sage.rings.finite_rings Projective Line over Finite Field of size 5 - sage: Curve(P1) + sage: Curve(P1) # optional - sage.rings.finite_rings Projective Line over Finite Field of size 5 :: diff --git a/src/sage/schemes/curves/curve.py b/src/sage/schemes/curves/curve.py index e5576459629..49f8fbeb611 100644 --- a/src/sage/schemes/curves/curve.py +++ b/src/sage/schemes/curves/curve.py @@ -46,8 +46,8 @@ class Curve_generic(AlgebraicScheme_subscheme): EXAMPLES:: - sage: A. = AffineSpace(QQ,3) - sage: C = Curve([x-y,z-2]) + sage: A. = AffineSpace(QQ, 3) + sage: C = Curve([x - y, z - 2]) sage: loads(C.dumps()) == C True """ @@ -57,13 +57,13 @@ def _repr_(self): EXAMPLES:: - sage: A. = AffineSpace(QQ,3) - sage: C = Curve([x-y,z-2]) + sage: A. = AffineSpace(QQ, 3) + sage: C = Curve([x - y, z - 2]) sage: C Affine Curve over Rational Field defined by x - y, z - 2 - sage: P. = ProjectiveSpace(QQ,2) - sage: C = Curve(x-y) + sage: P. = ProjectiveSpace(QQ, 2) + sage: C = Curve(x - y) sage: C Projective Plane Curve over Rational Field defined by x - y """ @@ -215,29 +215,29 @@ def geometric_genus(self): Examples of projective curves. :: - sage: P2 = ProjectiveSpace(2, GF(5), names=['x','y','z']) - sage: x, y, z = P2.coordinate_ring().gens() - sage: C = Curve(y^2*z - x^3 - 17*x*z^2 + y*z^2) - sage: C.geometric_genus() - 1 - sage: C = Curve(y^2*z - x^3) - sage: C.geometric_genus() - 0 - sage: C = Curve(x^10 + y^7*z^3 + z^10) - sage: C.geometric_genus() - 3 + sage: P2 = ProjectiveSpace(2, GF(5), names=['x','y','z']) # optional - sage.rings.finite_rings + sage: x, y, z = P2.coordinate_ring().gens() # optional - sage.rings.finite_rings + sage: C = Curve(y^2*z - x^3 - 17*x*z^2 + y*z^2) # optional - sage.rings.finite_rings + sage: C.geometric_genus() # optional - sage.rings.finite_rings + 1 + sage: C = Curve(y^2*z - x^3) # optional - sage.rings.finite_rings + sage: C.geometric_genus() # optional - sage.rings.finite_rings + 0 + sage: C = Curve(x^10 + y^7*z^3 + z^10) # optional - sage.rings.finite_rings + sage: C.geometric_genus() # optional - sage.rings.finite_rings + 3 Examples of affine curves. :: - sage: x, y = PolynomialRing(GF(5), 2, 'xy').gens() - sage: C = Curve(y^2 - x^3 - 17*x + y) - sage: C.geometric_genus() + sage: x, y = PolynomialRing(GF(5), 2, 'xy').gens() # optional - sage.rings.finite_rings + sage: C = Curve(y^2 - x^3 - 17*x + y) # optional - sage.rings.finite_rings + sage: C.geometric_genus() # optional - sage.rings.finite_rings 1 - sage: C = Curve(y^2 - x^3) - sage: C.geometric_genus() + sage: C = Curve(y^2 - x^3) # optional - sage.rings.finite_rings + sage: C.geometric_genus() # optional - sage.rings.finite_rings 0 - sage: C = Curve(x^10 + y^7 + 1) - sage: C.geometric_genus() + sage: C = Curve(x^10 + y^7 + 1) # optional - sage.rings.finite_rings + sage: C.geometric_genus() # optional - sage.rings.finite_rings 3 """ @@ -278,7 +278,7 @@ def singular_subscheme(self): sage: C = Curve([y^4 - 2*x^5 - x^2*y], A) sage: C.singular_subscheme() Closed subscheme of Affine Space of dimension 2 over Complex Field - with 53 bits of precision defined by: + with 53 bits of precision defined by: (-2.00000000000000)*x^5 + y^4 - x^2*y, (-10.0000000000000)*x^4 + (-2.00000000000000)*x*y, 4.00000000000000*y^3 - x^2 @@ -288,16 +288,16 @@ def singular_subscheme(self): sage: P. = ProjectiveSpace(QQ, 3) sage: C = Curve([y^8 - x^2*z*w^5, w^2 - 2*y^2 - x*z], P) sage: C.singular_subscheme() - Closed subscheme of Projective Space of dimension 3 over Rational - Field defined by: + Closed subscheme of Projective Space of dimension 3 + over Rational Field defined by: y^8 - x^2*z*w^5, -2*y^2 - x*z + w^2, -x^3*y*z^4 + 3*x^2*y*z^3*w^2 - 3*x*y*z^2*w^4 + 8*x*y*z*w^5 + y*z*w^6, x^2*z*w^5, -5*x^2*z^2*w^4 - 4*x*z*w^6, x^4*y*z^3 - 3*x^3*y*z^2*w^2 + 3*x^2*y*z*w^4 - 4*x^2*y*w^5 - x*y*w^6, - -2*x^3*y*z^3*w + 6*x^2*y*z^2*w^3 - 20*x^2*y*z*w^4 - 6*x*y*z*w^5 + - 2*y*w^7, + -2*x^3*y*z^3*w + 6*x^2*y*z^2*w^3 - 20*x^2*y*z*w^4 + - 6*x*y*z*w^5 + 2*y*w^7, -5*x^3*z*w^4 - 2*x^2*w^6 """ return self.ambient_space().subscheme(self.Jacobian()) @@ -323,12 +323,12 @@ def singular_points(self, F=None): :: sage: R. = QQ[] - sage: K. = NumberField(a^8 - a^4 + 1) - sage: P. = ProjectiveSpace(QQ, 2) - sage: C = Curve([359/12*x*y^2*z^2 + 2*y*z^4 + 187/12*y^3*z^2 + x*z^4\ - + 67/3*x^2*y*z^2 + 117/4*y^5 + 9*x^5 + 6*x^3*z^2 + 393/4*x*y^4\ - + 145*x^2*y^3 + 115*x^3*y^2 + 49*x^4*y], P) - sage: sorted(C.singular_points(K), key=str) + sage: K. = NumberField(a^8 - a^4 + 1) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(QQ, 2) # optional - sage.rings.number_field + sage: C = Curve([359/12*x*y^2*z^2 + 2*y*z^4 + 187/12*y^3*z^2 + x*z^4 # optional - sage.rings.number_field + ....: + 67/3*x^2*y*z^2 + 117/4*y^5 + 9*x^5 + 6*x^3*z^2 + ....: + 393/4*x*y^4 + 145*x^2*y^3 + 115*x^3*y^2 + 49*x^4*y], P) + sage: sorted(C.singular_points(K), key=str) # optional - sage.rings.number_field [(-1/2*b^5 - 1/2*b^3 + 1/2*b - 1 : 1 : 0), (-2/3*b^4 + 1/3 : 0 : 1), (-b^6 : b^6 : 1), @@ -372,10 +372,10 @@ def is_singular(self, P=None): :: - sage: A. = AffineSpace(GF(11), 3) - sage: C = A.curve([y^3 - z^5, x^5 - y + 1]) - sage: Q = A([7,0,0]) - sage: C.is_singular(Q) + sage: A. = AffineSpace(GF(11), 3) # optional - sage.rings.finite_rings + sage: C = A.curve([y^3 - z^5, x^5 - y + 1]) # optional - sage.rings.finite_rings + sage: Q = A([7,0,0]) # optional - sage.rings.finite_rings + sage: C.is_singular(Q) # optional - sage.rings.finite_rings True """ return not self.is_smooth(P) @@ -405,14 +405,14 @@ def intersects_at(self, C, P): :: - sage: A. = AffineSpace(GF(13), 2) - sage: C = Curve([y + 12*x^5 + 3*x^3 + 7], A) - sage: D = Curve([y^2 + 7*x^2 + 8], A) - sage: Q1 = A([9,6]) - sage: C.intersects_at(D, Q1) + sage: A. = AffineSpace(GF(13), 2) # optional - sage.rings.finite_rings + sage: C = Curve([y + 12*x^5 + 3*x^3 + 7], A) # optional - sage.rings.finite_rings + sage: D = Curve([y^2 + 7*x^2 + 8], A) # optional - sage.rings.finite_rings + sage: Q1 = A([9,6]) # optional - sage.rings.finite_rings + sage: C.intersects_at(D, Q1) # optional - sage.rings.finite_rings True - sage: Q2 = A([3,7]) - sage: C.intersects_at(D, Q2) + sage: Q2 = A([3,7]) # optional - sage.rings.finite_rings + sage: C.intersects_at(D, Q2) # optional - sage.rings.finite_rings False """ if C.ambient_space() != self.ambient_space(): @@ -451,22 +451,21 @@ def intersection_points(self, C, F=None): EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(a^2 + a + 1) - sage: P. = ProjectiveSpace(QQ, 3) - sage: C = Curve([y^2 - w*z, w^3 - y^3], P) - sage: D = Curve([x*y - w*z, z^3 - y^3], P) - sage: C.intersection_points(D, F=K) - [(-b - 1 : -b - 1 : b : 1), (b : b : -b - 1 : 1), (1 : 0 : 0 : 0), - (1 : 1 : 1 : 1)] + sage: K. = NumberField(a^2 + a + 1) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(QQ, 3) # optional - sage.rings.number_field + sage: C = Curve([y^2 - w*z, w^3 - y^3], P) # optional - sage.rings.number_field + sage: D = Curve([x*y - w*z, z^3 - y^3], P) # optional - sage.rings.number_field + sage: C.intersection_points(D, F=K) # optional - sage.rings.number_field + [(-b - 1 : -b - 1 : b : 1), (b : b : -b - 1 : 1), + (1 : 0 : 0 : 0), (1 : 1 : 1 : 1)] :: - sage: A. = AffineSpace(GF(7), 2) - sage: C = Curve([y^3 - x^3], A) - sage: D = Curve([-x*y^3 + y^4 - 2*x^3 + 2*x^2*y], A) - sage: C.intersection_points(D) - [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 3), (5, 5), (5, 6), - (6, 6)] + sage: A. = AffineSpace(GF(7), 2) # optional - sage.rings.finite_rings + sage: C = Curve([y^3 - x^3], A) # optional - sage.rings.finite_rings + sage: D = Curve([-x*y^3 + y^4 - 2*x^3 + 2*x^2*y], A) # optional - sage.rings.finite_rings + sage: C.intersection_points(D) # optional - sage.rings.finite_rings + [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 3), (5, 5), (5, 6), (6, 6)] :: @@ -506,26 +505,27 @@ def change_ring(self, R): sage: P. = ProjectiveSpace(QQ, 3) sage: C = Curve([x^2 - y^2, z*y - 4/5*w^2], P) - sage: C.change_ring(QuadraticField(-1)) - Projective Curve over Number Field in a with defining polynomial x^2 + 1 with a = 1*I defined by x^2 - y^2, y*z - 4/5*w^2 + sage: C.change_ring(QuadraticField(-1)) # optional - sage.rings.number_field + Projective Curve over Number Field in a with defining polynomial x^2 + 1 + with a = 1*I defined by x^2 - y^2, y*z - 4/5*w^2 :: sage: R. = QQ[] - sage: K. = NumberField(a^3 + a^2 - 1) - sage: A. = AffineSpace(K, 2) - sage: C = Curve([K.0*x^2 - x + y^3 - 11], A) - sage: L = K.embeddings(QQbar) + sage: K. = NumberField(a^3 + a^2 - 1) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: C = Curve([K.0*x^2 - x + y^3 - 11], A) # optional - sage.rings.number_field + sage: L = K.embeddings(QQbar) # optional - sage.rings.number_field sage: set_verbose(-1) # suppress warnings for slow computation - sage: C.change_ring(L[0]) - Affine Plane Curve over Algebraic Field defined by y^3 + - (-0.8774388331233464? - 0.744861766619745?*I)*x^2 - x - 11 + sage: C.change_ring(L[0]) # optional - sage.rings.number_field + Affine Plane Curve over Algebraic Field defined + by y^3 + (-0.8774388331233464? - 0.744861766619745?*I)*x^2 - x - 11 :: sage: P. = ProjectiveSpace(QQ, 2) sage: C = P.curve([y*x - 18*x^2 + 17*z^2]) - sage: C.change_ring(GF(17)) + sage: C.change_ring(GF(17)) # optional - sage.rings.finite_rings Projective Plane Curve over Finite Field of size 17 defined by -x^2 + x*y """ new_AS = self.ambient_space().change_ring(R) diff --git a/src/sage/schemes/curves/point.py b/src/sage/schemes/curves/point.py index 0ae3ab7e820..aa41d55627a 100644 --- a/src/sage/schemes/curves/point.py +++ b/src/sage/schemes/curves/point.py @@ -7,17 +7,17 @@ sage: C = Curve([x^3 - 2*x*z^2 - y^3, z^3 - w^3 - x*y*z], P) sage: Q = C([1,1,0,0]) sage: Q.parent() - Set of rational points of Projective Curve over Rational Field defined - by x^3 - y^3 - 2*x*z^2, -x*y*z + z^3 - w^3 + Set of rational points of Projective Curve over Rational Field + defined by x^3 - y^3 - 2*x*z^2, -x*y*z + z^3 - w^3 or on affine curves:: - sage: A. = AffineSpace(GF(23), 2) - sage: C = Curve([y - y^4 + 17*x^2 - 2*x + 22], A) - sage: Q = C([22,21]) - sage: Q.parent() - Set of rational points of Affine Plane Curve over Finite Field of size - 23 defined by -y^4 - 6*x^2 - 2*x + y - 1 + sage: A. = AffineSpace(GF(23), 2) # optional - sage.rings.finite_rings + sage: C = Curve([y - y^4 + 17*x^2 - 2*x + 22], A) # optional - sage.rings.finite_rings + sage: Q = C([22,21]) # optional - sage.rings.finite_rings + sage: Q.parent() # optional - sage.rings.finite_rings + Set of rational points of Affine Plane Curve over Finite Field of size 23 + defined by -y^4 - 6*x^2 - 2*x + y - 1 AUTHORS: @@ -70,10 +70,10 @@ def multiplicity(self): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(17), 2) - sage: C = Curve([y^3*z - 16*x^4], P) - sage: Q = C([0,0,1]) - sage: Q.multiplicity() + sage: P. = ProjectiveSpace(GF(17), 2) # optional - sage.rings.finite_rings + sage: C = Curve([y^3*z - 16*x^4], P) # optional - sage.rings.finite_rings + sage: Q = C([0,0,1]) # optional - sage.rings.finite_rings + sage: Q.multiplicity() # optional - sage.rings.finite_rings 3 """ return self.codomain().multiplicity(self) @@ -113,14 +113,14 @@ def is_ordinary_singularity(self): :: sage: R. = QQ[] - sage: K. = NumberField(a^2 - 3) - sage: P. = ProjectiveSpace(K, 2) - sage: C = P.curve([x^2*y^3*z^4 - y^6*z^3 - 4*x^2*y^4*z^3 - + sage: K. = NumberField(a^2 - 3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: C = P.curve([x^2*y^3*z^4 - y^6*z^3 - 4*x^2*y^4*z^3 - # optional - sage.rings.number_field ....: 4*x^4*y^2*z^3 + 3*y^7*z^2 + 10*x^2*y^5*z^2 + 9*x^4*y^3*z^2 + ....: 5*x^6*y*z^2 - 3*y^8*z - 9*x^2*y^6*z - 11*x^4*y^4*z - 7*x^6*y^2*z - ....: 2*x^8*z + y^9 + 2*x^2*y^7 + 3*x^4*y^5 + 4*x^6*y^3 + 2*x^8*y]) - sage: Q = C([-1/2, 1/2, 1]) - sage: Q.is_ordinary_singularity() + sage: Q = C([-1/2, 1/2, 1]) # optional - sage.rings.number_field + sage: Q.is_ordinary_singularity() # optional - sage.rings.number_field True """ return self.codomain().is_ordinary_singularity(self) @@ -145,11 +145,11 @@ def is_transverse(self, D): :: - sage: P. = ProjectiveSpace(GF(17), 2) - sage: C = Curve([x^4 - 16*y^3*z], P) - sage: D = Curve([y^2 - z*x], P) - sage: Q = C([0,0,1]) - sage: Q.is_transverse(D) + sage: P. = ProjectiveSpace(GF(17), 2) # optional - sage.rings.finite_rings + sage: C = Curve([x^4 - 16*y^3*z], P) # optional - sage.rings.finite_rings + sage: D = Curve([y^2 - z*x], P) # optional - sage.rings.finite_rings + sage: Q = C([0,0,1]) # optional - sage.rings.finite_rings + sage: Q.is_transverse(D) # optional - sage.rings.finite_rings False """ return self.codomain().is_transverse(D, self) @@ -170,12 +170,12 @@ def closed_point(self): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(17), 2) - sage: C = Curve([x^4 - 16*y^3*z], P) - sage: C.singular_points() + sage: P. = ProjectiveSpace(GF(17), 2) # optional - sage.rings.finite_rings + sage: C = Curve([x^4 - 16*y^3*z], P) # optional - sage.rings.finite_rings + sage: C.singular_points() # optional - sage.rings.finite_rings [(0 : 0 : 1)] - sage: p = _[0] - sage: p.closed_point() + sage: p = _[0] # optional - sage.rings.finite_rings + sage: p.closed_point() # optional - sage.rings.finite_rings Point (x, y) """ curve = self.codomain() @@ -197,12 +197,12 @@ def places(self): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(17), 2) - sage: C = Curve([x^4 - 16*y^3*z], P) - sage: C.singular_points() + sage: P. = ProjectiveSpace(GF(17), 2) # optional - sage.rings.finite_rings + sage: C = Curve([x^4 - 16*y^3*z], P) # optional - sage.rings.finite_rings + sage: C.singular_points() # optional - sage.rings.finite_rings [(0 : 0 : 1)] - sage: p = _[0] - sage: p.places() + sage: p = _[0] # optional - sage.rings.finite_rings + sage: p.places() # optional - sage.rings.finite_rings [Place (y)] """ return self.closed_point().places() @@ -213,12 +213,12 @@ def place(self): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(17), 2) - sage: C = Curve([x^4 - 16*y^3*z], P) - sage: C.singular_points() + sage: P. = ProjectiveSpace(GF(17), 2) # optional - sage.rings.finite_rings + sage: C = Curve([x^4 - 16*y^3*z], P) # optional - sage.rings.finite_rings + sage: C.singular_points() # optional - sage.rings.finite_rings [(0 : 0 : 1)] - sage: p = _[0] - sage: p.place() + sage: p = _[0] # optional - sage.rings.finite_rings + sage: p.place() # optional - sage.rings.finite_rings Place (y) """ return self.closed_point().place() @@ -253,14 +253,14 @@ def is_singular(self): EXAMPLES:: - sage: K = QuadraticField(-1) - sage: A. = AffineSpace(K, 3) - sage: C = Curve([(x^4 + 2*z + 2)*y, z - y + 1]) - sage: Q1 = C([0,0,-1]) - sage: Q1.is_singular() + sage: K = QuadraticField(-1) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 3) # optional - sage.rings.number_field + sage: C = Curve([(x^4 + 2*z + 2)*y, z - y + 1]) # optional - sage.rings.number_field + sage: Q1 = C([0,0,-1]) # optional - sage.rings.number_field + sage: Q1.is_singular() # optional - sage.rings.number_field True - sage: Q2 = C([-K.gen(),0,-1]) - sage: Q2.is_singular() + sage: Q2 = C([-K.gen(),0,-1]) # optional - sage.rings.number_field + sage: Q2.is_singular() # optional - sage.rings.number_field False """ return self.codomain().is_singular(self) @@ -324,10 +324,10 @@ def is_ordinary_singularity(self): :: - sage: A. = AffineSpace(GF(7), 2) - sage: C = A.curve([y^2 - x^7 - 6*x^3]) - sage: Q = C([0,0]) - sage: Q.is_ordinary_singularity() + sage: A. = AffineSpace(GF(7), 2) # optional - sage.rings.finite_rings + sage: C = A.curve([y^2 - x^7 - 6*x^3]) # optional - sage.rings.finite_rings + sage: Q = C([0,0]) # optional - sage.rings.finite_rings + sage: Q.is_ordinary_singularity() # optional - sage.rings.finite_rings False """ return self.codomain().is_ordinary_singularity(self) @@ -353,12 +353,12 @@ def is_transverse(self, D): :: sage: R. = QQ[] - sage: K. = NumberField(a^2 - 2) - sage: A. = AffineSpace(K, 2) - sage: C = Curve([y^2 + x^2 - 1], A) - sage: D = Curve([y - x], A) - sage: Q = C([-1/2*b,-1/2*b]) - sage: Q.is_transverse(D) + sage: K. = NumberField(a^2 - 2) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: C = Curve([y^2 + x^2 - 1], A) # optional - sage.rings.number_field + sage: D = Curve([y - x], A) # optional - sage.rings.number_field + sage: Q = C([-1/2*b, -1/2*b]) # optional - sage.rings.number_field + sage: Q.is_transverse(D) # optional - sage.rings.number_field True """ return self.codomain().is_transverse(D, self) @@ -381,10 +381,10 @@ def closed_point(self): EXAMPLES:: - sage: A. = AffineSpace(GF(8), 2) - sage: C = Curve(x^5 + y^5 + x*y + 1) - sage: p = C([1,1]) - sage: p.closed_point() + sage: A. = AffineSpace(GF(8), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y + 1) # optional - sage.rings.finite_rings + sage: p = C([1,1]) # optional - sage.rings.finite_rings + sage: p.closed_point() # optional - sage.rings.finite_rings Point (x + 1, y + 1) """ curve = self.codomain() @@ -400,18 +400,18 @@ def places(self): EXAMPLES:: - sage: A. = AffineSpace(GF(2), 2) - sage: C = Curve(x^5 + y^5 + x*y + 1) - sage: p = C(-1,-1) - sage: p + sage: A. = AffineSpace(GF(2), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y + 1) # optional - sage.rings.finite_rings + sage: p = C(-1,-1) # optional - sage.rings.finite_rings + sage: p # optional - sage.rings.finite_rings (1, 1) - sage: p.closed_point() + sage: p.closed_point() # optional - sage.rings.finite_rings Point (x + 1, y + 1) - sage: _.places() + sage: _.places() # optional - sage.rings.finite_rings [Place (x + 1, (1/(x^5 + 1))*y^4 + ((x^5 + x^4 + 1)/(x^5 + 1))*y^3 - + ((x^5 + x^3 + 1)/(x^5 + 1))*y^2 + (x^2/(x^5 + 1))*y), Place (x + - 1, (1/(x^5 + 1))*y^4 + ((x^5 + x^4 + 1)/(x^5 + 1))*y^3 + (x^3/(x^5 - + 1))*y^2 + (x^2/(x^5 + 1))*y + x + 1)] + + ((x^5 + x^3 + 1)/(x^5 + 1))*y^2 + (x^2/(x^5 + 1))*y), + Place (x + 1, (1/(x^5 + 1))*y^4 + ((x^5 + x^4 + 1)/(x^5 + 1))*y^3 + + (x^3/(x^5 + 1))*y^2 + (x^2/(x^5 + 1))*y + x + 1)] """ return self.closed_point().places() @@ -421,16 +421,16 @@ def place(self): EXAMPLES:: - sage: A. = AffineSpace(GF(2), 2) - sage: C = Curve(x^5 + y^5 + x*y + 1) - sage: p = C(-1,-1) - sage: p + sage: A. = AffineSpace(GF(2), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y + 1) # optional - sage.rings.finite_rings + sage: p = C(-1,-1) # optional - sage.rings.finite_rings + sage: p # optional - sage.rings.finite_rings (1, 1) - sage: p.closed_point() + sage: p.closed_point() # optional - sage.rings.finite_rings Point (x + 1, y + 1) - sage: _.place() - Place (x + 1, (1/(x^5 + 1))*y^4 + ((x^5 + x^4 + 1)/(x^5 + 1))*y^3 + - ((x^5 + x^3 + 1)/(x^5 + 1))*y^2 + (x^2/(x^5 + 1))*y) + sage: _.place() # optional - sage.rings.finite_rings + Place (x + 1, (1/(x^5 + 1))*y^4 + ((x^5 + x^4 + 1)/(x^5 + 1))*y^3 + + ((x^5 + x^3 + 1)/(x^5 + 1))*y^2 + (x^2/(x^5 + 1))*y) """ return self.closed_point().place() diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index e5a6ba01be1..4fe4463f764 100644 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -27,54 +27,54 @@ EXAMPLES:: - sage: k = GF(2) - sage: P. = ProjectiveSpace(k, 2) - sage: C = Curve(x^2*z - y^3, P) - sage: C.genus() + sage: k = GF(2) # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(k, 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^2*z - y^3, P) # optional - sage.rings.finite_rings + sage: C.genus() # optional - sage.rings.finite_rings 0 - sage: C.function_field() + sage: C.function_field() # optional - sage.rings.finite_rings Function field in z defined by z + y^3 Closed points of arbitrary degree can be computed:: - sage: C.closed_points() + sage: C.closed_points() # optional - sage.rings.finite_rings [Point (x, y), Point (y, z), Point (x + z, y + z)] - sage: C.closed_points(2) + sage: C.closed_points(2) # optional - sage.rings.finite_rings [Point (y^2 + y*z + z^2, x + z)] - sage: C.closed_points(3) + sage: C.closed_points(3) # optional - sage.rings.finite_rings [Point (y^3 + y^2*z + z^3, x + y + z), Point (x^2 + y*z + z^2, x*y + x*z + y*z, y^2 + x*z + y*z + z^2)] All singular closed points can be found:: - sage: C.singular_closed_points() + sage: C.singular_closed_points() # optional - sage.rings.finite_rings [Point (x, y)] - sage: p = _[0] - sage: p.places() # a unibranch singularity, that is, a cusp + sage: p = _[0] # optional - sage.rings.finite_rings + sage: p.places() # a unibranch singularity, that is, a cusp # optional - sage.rings.finite_rings [Place (1/y)] - sage: pls = _[0] - sage: C.place_to_closed_point(pls) + sage: pls = _[0] # optional - sage.rings.finite_rings + sage: C.place_to_closed_point(pls) # optional - sage.rings.finite_rings Point (x, y) It is easy to transit to and from the function field of the curve:: - sage: fx = C(x/z) - sage: fy = C(y/z) - sage: fx^2 - fy^3 + sage: fx = C(x/z) # optional - sage.rings.finite_rings + sage: fy = C(y/z) # optional - sage.rings.finite_rings + sage: fx^2 - fy^3 # optional - sage.rings.finite_rings 0 - sage: fx.divisor() + sage: fx.divisor() # optional - sage.rings.finite_rings 3*Place (1/y) - 3*Place (y) - sage: p, = fx.poles() - sage: p + sage: p, = fx.poles() # optional - sage.rings.finite_rings + sage: p # optional - sage.rings.finite_rings Place (y) - sage: C.place_to_closed_point(p) + sage: C.place_to_closed_point(p) # optional - sage.rings.finite_rings Point (y, z) - sage: _.rational_point() + sage: _.rational_point() # optional - sage.rings.finite_rings (1 : 0 : 0) - sage: _.closed_point() + sage: _.closed_point() # optional - sage.rings.finite_rings Point (y, z) - sage: _.place() + sage: _.place() # optional - sage.rings.finite_rings Place (y) Integral projective curves over `\QQ` @@ -187,18 +187,18 @@ class ProjectiveCurve(Curve_generic, AlgebraicScheme_subscheme_projective): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(7), 4) - sage: C = Curve([y*u^2 - x^3, z*u^2 - x^3, w*u^2 - x^3, y^3 - x^3], P); C - Projective Curve over Finite Field of size 7 defined by -x^3 + y*u^2, - -x^3 + z*u^2, -x^3 + w*u^2, -x^3 + y^3 + sage: P. = ProjectiveSpace(GF(7), 4) # optional - sage.rings.finite_rings + sage: C = Curve([y*u^2 - x^3, z*u^2 - x^3, w*u^2 - x^3, y^3 - x^3], P); C # optional - sage.rings.finite_rings + Projective Curve over Finite Field of size 7 defined + by -x^3 + y*u^2, -x^3 + z*u^2, -x^3 + w*u^2, -x^3 + y^3 :: - sage: K. = CyclotomicField(11) - sage: P. = ProjectiveSpace(K, 3) - sage: C = Curve([y*w - u*z^2 - x^2, x*w - 3*u^2*z*w], P); C + sage: K. = CyclotomicField(11) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 3) # optional - sage.rings.number_field + sage: C = Curve([y*w - u*z^2 - x^2, x*w - 3*u^2*z*w], P); C # optional - sage.rings.number_field Projective Curve over Cyclotomic Field of order 11 and degree 10 defined - by -x^2 + (-u)*z^2 + y*w, x*w + (-3*u^2)*z*w + by -x^2 + (-u)*z^2 + y*w, x*w + (-3*u^2)*z*w """ def __init__(self, A, X): """ @@ -241,15 +241,15 @@ def affine_patch(self, i, AA=None): - ``AA`` -- (default: None) ambient affine space, this is constructed if it is not given - OUTPUT: a curve in affine space + OUTPUT: A curve in affine space. EXAMPLES:: sage: P. = ProjectiveSpace(CC, 3) sage: C = Curve([y*z - x^2, w^2 - x*y], P) sage: C.affine_patch(0) - Affine Curve over Complex Field with 53 bits of precision defined by - y*z - 1.00000000000000, w^2 - y + Affine Curve over Complex Field with 53 bits of precision defined + by y*z - 1.00000000000000, w^2 - y :: @@ -289,7 +289,7 @@ def projection(self, P=None, PS=None): ambient space of this curve. This space will be constructed if not specified. - OUTPUT: a tuple of + OUTPUT: A tuple of - a scheme morphism from this curve into a projective space of dimension one less than that of the ambient space of this curve @@ -298,21 +298,21 @@ def projection(self, P=None, PS=None): EXAMPLES:: - sage: K. = CyclotomicField(3) - sage: P. = ProjectiveSpace(K, 3) - sage: C = Curve([y*w - x^2, z*w^2 - a*x^3], P) - sage: L. = ProjectiveSpace(K, 2) - sage: proj1 = C.projection(PS=L) - sage: proj1 + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 3) # optional - sage.rings.number_field + sage: C = Curve([y*w - x^2, z*w^2 - a*x^3], P) # optional - sage.rings.number_field + sage: L. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: proj1 = C.projection(PS=L) # optional - sage.rings.number_field + sage: proj1 # optional - sage.rings.number_field (Scheme morphism: From: Projective Curve over Cyclotomic Field of order 3 and degree 2 - defined by -x^2 + y*w, (-a)*x^3 + z*w^2 - To: Projective Space of dimension 2 over Cyclotomic Field of order - 3 and degree 2 + defined by -x^2 + y*w, (-a)*x^3 + z*w^2 + To: Projective Space of dimension 2 + over Cyclotomic Field of order 3 and degree 2 Defn: Defined on coordinates by sending (x : y : z : w) to (x : y : -z + w), Projective Plane Curve over Cyclotomic Field of order 3 and degree 2 - defined by a^6 + (-a)*a^3*b^3 - a^4*b*c) + defined by a^6 + (-a)*a^3*b^3 - a^4*b*c) sage: proj1[1].ambient_space() is L True sage: proj2 = C.projection() @@ -325,46 +325,46 @@ def projection(self, P=None, PS=None): sage: C = Curve([y - x, z - a - b, w^2 - c^2, z - x - a, x^2 - w*z], P) sage: C.projection() (Scheme morphism: - From: Projective Curve over Rational Field defined by -x + y, z - a - - b, w^2 - c^2, -x + z - a, x^2 - z*w + From: Projective Curve over Rational Field + defined by -x + y, z - a - b, w^2 - c^2, -x + z - a, x^2 - z*w To: Projective Space of dimension 5 over Rational Field Defn: Defined on coordinates by sending (x : y : z : w : a : b : c) - to - (x : y : -z + w : a : b : c), + to (x : y : -z + w : a : b : c), Projective Curve over Rational Field defined by x1 - x4, x0 - x4, x2*x3 - + x3^2 + x2*x4 + 2*x3*x4, x2^2 - x3^2 - 2*x3*x4 + x4^2 - x5^2, x2*x4^2 + - x3*x4^2 + x4^3 - x3*x5^2 - x4*x5^2, x4^4 - x3^2*x5^2 - 2*x3*x4*x5^2 - - x4^2*x5^2) + + x3^2 + x2*x4 + 2*x3*x4, x2^2 - x3^2 - 2*x3*x4 + x4^2 - x5^2, x2*x4^2 + + x3*x4^2 + x4^3 - x3*x5^2 - x4*x5^2, x4^4 - x3^2*x5^2 - 2*x3*x4*x5^2 - + x4^2*x5^2) :: - sage: P. = ProjectiveSpace(GF(2), 3) - sage: C = P.curve([(x - y)*(x - z)*(x - w)*(y - z)*(y - w), x*y*z*w*(x+y+z+w)]) - sage: C.projection() + sage: P. = ProjectiveSpace(GF(2), 3) # optional - sage.rings.finite_rings + sage: C = P.curve([(x - y)*(x - z)*(x - w)*(y - z)*(y - w), # optional - sage.rings.finite_rings + ....: x*y*z*w*(x + y + z + w)]) + sage: C.projection() # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: this curve contains all points of its ambient space :: - sage: P. = ProjectiveSpace(GF(7), 4) - sage: C = P.curve([x^3 - y*z*u, w^2 - u^2 + 2*x*z, 3*x*w - y^2]) - sage: L. = ProjectiveSpace(GF(7), 3) - sage: C.projection(PS=L) + sage: P. = ProjectiveSpace(GF(7), 4) # optional - sage.rings.finite_rings + sage: C = P.curve([x^3 - y*z*u, w^2 - u^2 + 2*x*z, 3*x*w - y^2]) # optional - sage.rings.finite_rings + sage: L. = ProjectiveSpace(GF(7), 3) # optional - sage.rings.finite_rings + sage: C.projection(PS=L) # optional - sage.rings.finite_rings (Scheme morphism: - From: Projective Curve over Finite Field of size 7 defined by x^3 - - y*z*u, 2*x*z + w^2 - u^2, -y^2 + 3*x*w + From: Projective Curve over Finite Field of size 7 + defined by x^3 - y*z*u, 2*x*z + w^2 - u^2, -y^2 + 3*x*w To: Projective Space of dimension 3 over Finite Field of size 7 Defn: Defined on coordinates by sending (x : y : z : w : u) to (x : y : z : w), Projective Curve over Finite Field of size 7 defined by b^2 - 3*a*d, - a^5*b + a*b*c^3*d - 3*b*c^2*d^3, a^6 + a^2*c^3*d - 3*a*c^2*d^3) - sage: Q. = ProjectiveSpace(GF(7), 2) - sage: C.projection(PS=Q) + a^5*b + a*b*c^3*d - 3*b*c^2*d^3, a^6 + a^2*c^3*d - 3*a*c^2*d^3) + sage: Q. = ProjectiveSpace(GF(7), 2) # optional - sage.rings.finite_rings + sage: C.projection(PS=Q) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: (=Projective Space of dimension 2 over Finite Field of size - 7) must have dimension (=3) + TypeError: (=Projective Space of dimension 2 over Finite Field of + size 7) must have dimension (=3) :: @@ -374,19 +374,20 @@ def projection(self, P=None, PS=None): sage: Q = PP([1,0,1,1]) sage: C.projection(P=Q) (Scheme morphism: - From: Projective Curve over Rational Field defined by x^3 - y*z^2, -x*z + w^2 + From: Projective Curve over Rational Field + defined by x^3 - y*z^2, -x*z + w^2 To: Projective Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x : y : z : w) to (y : -x + z : -x + w), Projective Plane Curve over Rational Field defined by x0*x1^5 - - 6*x0*x1^4*x2 + 14*x0*x1^3*x2^2 - 16*x0*x1^2*x2^3 + 9*x0*x1*x2^4 - - 2*x0*x2^5 - x2^6) + 6*x0*x1^4*x2 + 14*x0*x1^3*x2^2 - 16*x0*x1^2*x2^3 + 9*x0*x1*x2^4 - + 2*x0*x2^5 - x2^6) sage: LL. = ProjectiveSpace(QQ, 2) sage: Q = PP([0,0,0,1]) sage: C.projection(PS=LL, P=Q) (Scheme morphism: - From: Projective Curve over Rational Field defined by x^3 - y*z^2, - -x*z + w^2 + From: Projective Curve over Rational Field + defined by x^3 - y*z^2, -x*z + w^2 To: Projective Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x : y : z : w) to (x : y : z), @@ -502,7 +503,7 @@ def plane_projection(self, PP=None): as this curve, and must have dimension two. This space is constructed if not specified. - OUTPUT: a tuple of + OUTPUT: A tuple of - a scheme morphism from this curve into a projective plane @@ -516,13 +517,13 @@ def plane_projection(self, PP=None): sage: proj1 = C.plane_projection(PP=L) sage: proj1 (Scheme morphism: - From: Projective Curve over Rational Field defined by x*u - z*v, -y + - w, -x^2 + y*w, -w^5 + 2*y^3*z*u + From: Projective Curve over Rational Field + defined by x*u - z*v, -y + w, -x^2 + y*w, -w^5 + 2*y^3*z*u To: Projective Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x : y : z : w : u : v) to (x : -z + u : -z + v), Projective Plane Curve over Rational Field defined by a^8 + 6*a^7*b + - 4*a^5*b^3 - 4*a^7*c - 2*a^6*b*c - 4*a^5*b^2*c + 2*a^6*c^2) + 4*a^5*b^3 - 4*a^7*c - 2*a^6*b*c - 4*a^5*b^2*c + 2*a^6*c^2) sage: proj1[1].ambient_space() is L True sage: proj2 = C.projection() @@ -531,21 +532,24 @@ def plane_projection(self, PP=None): :: - sage: P. = ProjectiveSpace(GF(7), 4) - sage: C = P.curve([x^2 - 6*y^2, w*z*u - y^3 + 4*y^2*z, u^2 - x^2]) - sage: C.plane_projection() + sage: P. = ProjectiveSpace(GF(7), 4) # optional - sage.rings.finite_rings + sage: C = P.curve([x^2 - 6*y^2, w*z*u - y^3 + 4*y^2*z, u^2 - x^2]) # optional - sage.rings.finite_rings + sage: C.plane_projection() # optional - sage.rings.finite_rings (Scheme morphism: - From: Projective Curve over Finite Field of size 7 defined by x^2 + y^2, -y^3 - 3*y^2*z + z*w*u, -x^2 + u^2 + From: Projective Curve over Finite Field of size 7 + defined by x^2 + y^2, -y^3 - 3*y^2*z + z*w*u, -x^2 + u^2 To: Projective Space of dimension 2 over Finite Field of size 7 Defn: Defined on coordinates by sending (x : y : z : w : u) to (x : z : -y + w), - Projective Plane Curve over Finite Field of size 7 defined by x0^10 + 2*x0^8*x1^2 + 2*x0^6*x1^4 - 3*x0^6*x1^3*x2 + 2*x0^6*x1^2*x2^2 - 2*x0^4*x1^4*x2^2 + x0^2*x1^4*x2^4) + Projective Plane Curve over Finite Field of size 7 + defined by x0^10 + 2*x0^8*x1^2 + 2*x0^6*x1^4 - 3*x0^6*x1^3*x2 + + 2*x0^6*x1^2*x2^2 - 2*x0^4*x1^4*x2^2 + x0^2*x1^4*x2^4) :: - sage: P. = ProjectiveSpace(GF(17), 2) - sage: C = P.curve(x^2 - y*z - z^2) - sage: C.plane_projection() + sage: P. = ProjectiveSpace(GF(17), 2) # optional - sage.rings.finite_rings + sage: C = P.curve(x^2 - y*z - z^2) # optional - sage.rings.finite_rings + sage: C.plane_projection() # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: this curve is already a plane curve @@ -585,17 +589,18 @@ class ProjectivePlaneCurve(ProjectiveCurve): A projective plane curve defined over an algebraic closure of `\QQ`:: - sage: P. = ProjectiveSpace(QQbar, 2) - sage: set_verbose(-1) # suppress warnings for slow computation - sage: C = Curve([y*z - x^2 - QQbar.gen()*z^2], P); C - Projective Plane Curve over Algebraic Field defined by - -x^2 + y*z + (-I)*z^2 + sage: P. = ProjectiveSpace(QQbar, 2) # optional - sage.rings.number_field + sage: set_verbose(-1) # suppress warnings for slow computation # optional - sage.rings.number_field + sage: C = Curve([y*z - x^2 - QQbar.gen()*z^2], P); C # optional - sage.rings.number_field + Projective Plane Curve over Algebraic Field + defined by -x^2 + y*z + (-I)*z^2 A projective plane curve defined over a finite field:: - sage: P. = ProjectiveSpace(GF(5^2, 'v'), 2) - sage: C = Curve([y^2*z - x*z^2 - z^3], P); C - Projective Plane Curve over Finite Field in v of size 5^2 defined by y^2*z - x*z^2 - z^3 + sage: P. = ProjectiveSpace(GF(5^2, 'v'), 2) # optional - sage.rings.finite_rings + sage: C = Curve([y^2*z - x*z^2 - z^3], P); C # optional - sage.rings.finite_rings + Projective Plane Curve over Finite Field in v of size 5^2 + defined by y^2*z - x*z^2 - z^3 """ def __init__(self, A, f): """ @@ -630,28 +635,26 @@ def divisor_of_function(self, r): """ Return the divisor of a function on a curve. - INPUT: r is a rational function on X - - OUTPUT: + INPUT: ``r`` is a rational function on X - - ``list`` -- The divisor of r represented as a list of coefficients and - points. (TODO: This will change to a more structural output in the - future.) + OUTPUT: A list. The divisor of r represented as a list of coefficients and + points. (TODO: This will change to a more structural output in the + future.) EXAMPLES:: - sage: FF = FiniteField(5) - sage: P2 = ProjectiveSpace(2, FF, names = ['x','y','z']) - sage: R = P2.coordinate_ring() - sage: x, y, z = R.gens() - sage: f = y^2*z^7 - x^9 - x*z^8 - sage: C = Curve(f) - sage: K = FractionField(R) - sage: r = 1/x - sage: C.divisor_of_function(r) # todo: not implemented !!!! + sage: FF = FiniteField(5) # optional - sage.rings.finite_rings + sage: P2 = ProjectiveSpace(2, FF, names=['x','y','z']) # optional - sage.rings.finite_rings + sage: R = P2.coordinate_ring() # optional - sage.rings.finite_rings + sage: x, y, z = R.gens() # optional - sage.rings.finite_rings + sage: f = y^2*z^7 - x^9 - x*z^8 # optional - sage.rings.finite_rings + sage: C = Curve(f) # optional - sage.rings.finite_rings + sage: K = FractionField(R) # optional - sage.rings.finite_rings + sage: r = 1/x # optional - sage.rings.finite_rings + sage: C.divisor_of_function(r) # todo: not implemented !!!! # optional - sage.rings.finite_rings [[-1, (0, 0, 1)]] - sage: r = 1/x^3 - sage: C.divisor_of_function(r) # todo: not implemented !!!! + sage: r = 1/x^3 # optional - sage.rings.finite_rings + sage: C.divisor_of_function(r) # todo: not implemented !!!! # optional - sage.rings.finite_rings [[-3, (0, 0, 1)]] """ F = self.base_ring() @@ -686,13 +689,14 @@ def local_coordinates(self, pt, n): EXAMPLES:: - sage: FF = FiniteField(5) - sage: P2 = ProjectiveSpace(2, FF, names = ['x','y','z']) - sage: x, y, z = P2.coordinate_ring().gens() - sage: C = Curve(y^2*z^7-x^9-x*z^8) - sage: pt = C([2,3,1]) - sage: C.local_coordinates(pt,9) # todo: not implemented !!!! - [2 + t, 3 + 3*t^2 + t^3 + 3*t^4 + 3*t^6 + 3*t^7 + t^8 + 2*t^9 + 3*t^11 + 3*t^12] + sage: FF = FiniteField(5) # optional - sage.rings.finite_rings + sage: P2 = ProjectiveSpace(2, FF, names=['x','y','z']) # optional - sage.rings.finite_rings + sage: x, y, z = P2.coordinate_ring().gens() # optional - sage.rings.finite_rings + sage: C = Curve(y^2*z^7 - x^9 - x*z^8) # optional - sage.rings.finite_rings + sage: pt = C([2,3,1]) # optional - sage.rings.finite_rings + sage: C.local_coordinates(pt,9) # todo: not implemented !!!! # optional - sage.rings.finite_rings + [2 + t, + 3 + 3*t^2 + t^3 + 3*t^4 + 3*t^6 + 3*t^7 + t^8 + 2*t^9 + 3*t^11 + 3*t^12] """ f = self.defining_polynomial() @@ -764,25 +768,25 @@ def plot(self, *args, **kwds): sage: R. = QQ[] sage: C = Curve(x^3 - y^2*z) - sage: C.plot() + sage: C.plot() # optional - sage.plot Graphics object consisting of 1 graphics primitive The other affine patches of the same curve:: - sage: C.plot(patch=0) + sage: C.plot(patch=0) # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: C.plot(patch=1) + sage: C.plot(patch=1) # optional - sage.plot Graphics object consisting of 1 graphics primitive An elliptic curve:: sage: E = EllipticCurve('101a') sage: C = Curve(E) - sage: C.plot() + sage: C.plot() # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: C.plot(patch=0) + sage: C.plot(patch=0) # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: C.plot(patch=1) + sage: C.plot(patch=1) # optional - sage.plot Graphics object consisting of 1 graphics primitive A hyperelliptic curve:: @@ -790,11 +794,11 @@ def plot(self, *args, **kwds): sage: P. = QQ[] sage: f = 4*x^5 - 30*x^3 + 45*x - 22 sage: C = HyperellipticCurve(f) - sage: C.plot() + sage: C.plot() # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: C.plot(patch=0) + sage: C.plot(patch=0) # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: C.plot(patch=1) + sage: C.plot(patch=1) # optional - sage.plot Graphics object consisting of 1 graphics primitive """ # if user has not specified a favorite affine patch, take the @@ -826,47 +830,47 @@ def is_singular(self, P=None): Over `\QQ`:: sage: F = QQ - sage: P2. = ProjectiveSpace(F,2) - sage: C = Curve(X^3-Y^2*Z) + sage: P2. = ProjectiveSpace(F, 2) + sage: C = Curve(X^3 - Y^2*Z) sage: C.is_singular() True Over a finite field:: - sage: F = GF(19) - sage: P2. = ProjectiveSpace(F,2) - sage: C = Curve(X^3+Y^3+Z^3) - sage: C.is_singular() + sage: F = GF(19) # optional - sage.rings.finite_rings + sage: P2. = ProjectiveSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(X^3 + Y^3 + Z^3) # optional - sage.rings.finite_rings + sage: C.is_singular() # optional - sage.rings.finite_rings False - sage: D = Curve(X^4-X*Z^3) - sage: D.is_singular() + sage: D = Curve(X^4 - X*Z^3) # optional - sage.rings.finite_rings + sage: D.is_singular() # optional - sage.rings.finite_rings True - sage: E = Curve(X^5+19*Y^5+Z^5) - sage: E.is_singular() + sage: E = Curve(X^5 + 19*Y^5 + Z^5) # optional - sage.rings.finite_rings + sage: E.is_singular() # optional - sage.rings.finite_rings True - sage: E = Curve(X^5+9*Y^5+Z^5) - sage: E.is_singular() + sage: E = Curve(X^5 + 9*Y^5 + Z^5) # optional - sage.rings.finite_rings + sage: E.is_singular() # optional - sage.rings.finite_rings False Over `\CC`:: sage: F = CC - sage: P2. = ProjectiveSpace(F,2) + sage: P2. = ProjectiveSpace(F, 2) sage: C = Curve(X) sage: C.is_singular() False - sage: D = Curve(Y^2*Z-X^3) + sage: D = Curve(Y^2*Z - X^3) sage: D.is_singular() True - sage: E = Curve(Y^2*Z-X^3+Z^3) + sage: E = Curve(Y^2*Z - X^3 + Z^3) sage: E.is_singular() False Showing that :trac:`12187` is fixed:: - sage: F. = GF(2)[] - sage: G = Curve(X^2+Y*Z) - sage: G.is_singular() + sage: F. = GF(2)[] # optional - sage.rings.finite_rings + sage: G = Curve(X^2 + Y*Z) # optional - sage.rings.finite_rings + sage: G.is_singular() # optional - sage.rings.finite_rings False :: @@ -889,7 +893,7 @@ def degree(self): For a plane curve, this is just the degree of its defining polynomial. - OUTPUT: integer. + OUTPUT: An integer. EXAMPLES:: @@ -918,27 +922,30 @@ def tangents(self, P, factor=True): OUTPUT: - a list of polynomials in the coordinate ring of the ambient space of + A list of polynomials in the coordinate ring of the ambient space of this curve. EXAMPLES:: sage: set_verbose(-1) - sage: P. = ProjectiveSpace(QQbar, 2) - sage: C = Curve([x^3*y + 2*x^2*y^2 + x*y^3 + x^3*z + 7*x^2*y*z + 14*x*y^2*z + 9*y^3*z], P) - sage: Q = P([0,0,1]) - sage: C.tangents(Q) - [x + 4.147899035704788?*y, x + (1.426050482147607? + 0.3689894074818041?*I)*y, - x + (1.426050482147607? - 0.3689894074818041?*I)*y] - sage: C.tangents(Q, factor=False) + sage: P. = ProjectiveSpace(QQbar, 2) # optional - sage.rings.number_field + sage: C = Curve([x^3*y + 2*x^2*y^2 + x*y^3 + x^3*z # optional - sage.rings.number_field + ....: + 7*x^2*y*z + 14*x*y^2*z + 9*y^3*z], P) + sage: Q = P([0,0,1]) # optional - sage.rings.number_field + sage: C.tangents(Q) # optional - sage.rings.number_field + [x + 4.147899035704788?*y, + x + (1.426050482147607? + 0.3689894074818041?*I)*y, + x + (1.426050482147607? - 0.3689894074818041?*I)*y] + sage: C.tangents(Q, factor=False) # optional - sage.rings.number_field [6*x^3 + 42*x^2*y + 84*x*y^2 + 54*y^3] :: - sage: P. = ProjectiveSpace(QQ,2) - sage: C = P.curve([x^2*y^3*z^4 - y^6*z^3 - 4*x^2*y^4*z^3 - 4*x^4*y^2*z^3 + 3*y^7*z^2 +\ - 10*x^2*y^5*z^2 + 9*x^4*y^3*z^2 + 5*x^6*y*z^2 - 3*y^8*z - 9*x^2*y^6*z - 11*x^4*y^4*z -\ - 7*x^6*y^2*z - 2*x^8*z + y^9 + 2*x^2*y^7 + 3*x^4*y^5 + 4*x^6*y^3 + 2*x^8*y]) + sage: P. = ProjectiveSpace(QQ, 2) + sage: C = P.curve([x^2*y^3*z^4 - y^6*z^3 - 4*x^2*y^4*z^3 - 4*x^4*y^2*z^3 + ....: + 3*y^7*z^2 + 10*x^2*y^5*z^2 + 9*x^4*y^3*z^2 + 5*x^6*y*z^2 + ....: - 3*y^8*z - 9*x^2*y^6*z - 11*x^4*y^4*z - 7*x^6*y^2*z + ....: - 2*x^8*z + y^9 + 2*x^2*y^7 + 3*x^4*y^5 + 4*x^6*y^3 + 2*x^8*y]) sage: Q = P([0,1,1]) sage: C.tangents(Q) [-y + z, 3*x^2 - y^2 + 2*y*z - z^2] @@ -1001,13 +1008,15 @@ def is_ordinary_singularity(self, P): :: sage: R. = QQ[] - sage: K. = NumberField(a^2 - 3) - sage: P. = ProjectiveSpace(K, 2) - sage: C = P.curve([x^2*y^3*z^4 - y^6*z^3 - 4*x^2*y^4*z^3 - 4*x^4*y^2*z^3 + 3*y^7*z^2 + 10*x^2*y^5*z^2\ - + 9*x^4*y^3*z^2 + 5*x^6*y*z^2 - 3*y^8*z - 9*x^2*y^6*z - 11*x^4*y^4*z - 7*x^6*y^2*z - 2*x^8*z + y^9 +\ - 2*x^2*y^7 + 3*x^4*y^5 + 4*x^6*y^3 + 2*x^8*y]) - sage: Q = P([0,1,1]) - sage: C.is_ordinary_singularity(Q) + sage: K. = NumberField(a^2 - 3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: C = P.curve([x^2*y^3*z^4 - y^6*z^3 - 4*x^2*y^4*z^3 - 4*x^4*y^2*z^3 # optional - sage.rings.number_field + ....: + 3*y^7*z^2 + 10*x^2*y^5*z^2 + 9*x^4*y^3*z^2 + ....: + 5*x^6*y*z^2 - 3*y^8*z - 9*x^2*y^6*z - 11*x^4*y^4*z + ....: - 7*x^6*y^2*z - 2*x^8*z + y^9 + 2*x^2*y^7 + 3*x^4*y^5 + ....: + 4*x^6*y^3 + 2*x^8*y]) + sage: Q = P([0,1,1]) # optional - sage.rings.number_field + sage: C.is_ordinary_singularity(Q) # optional - sage.rings.number_field True :: @@ -1051,23 +1060,23 @@ def quadratic_transform(self): sage: C = Curve(x^3*y - z^4 - z^2*x^2, P) sage: C.quadratic_transform() Scheme morphism: - From: Projective Plane Curve over Rational Field defined by x^3*y - - x^2*z^2 - z^4 - To: Projective Plane Curve over Rational Field defined by -x^3*y - - x*y*z^2 + z^4 + From: Projective Plane Curve over Rational Field + defined by x^3*y - x^2*z^2 - z^4 + To: Projective Plane Curve over Rational Field + defined by -x^3*y - x*y*z^2 + z^4 Defn: Defined on coordinates by sending (x : y : z) to (y*z : x*z : x*y) :: - sage: P. = ProjectiveSpace(GF(17), 2) - sage: C = P.curve([y^7*z^2 - 16*x^9 + x*y*z^7 + 2*z^9]) - sage: C.quadratic_transform() + sage: P. = ProjectiveSpace(GF(17), 2) # optional - sage.rings.finite_rings + sage: C = P.curve([y^7*z^2 - 16*x^9 + x*y*z^7 + 2*z^9]) # optional - sage.rings.finite_rings + sage: C.quadratic_transform() # optional - sage.rings.finite_rings Scheme morphism: - From: Projective Plane Curve over Finite Field of size 17 defined by - x^9 + y^7*z^2 + x*y*z^7 + 2*z^9 - To: Projective Plane Curve over Finite Field of size 17 defined by - 2*x^9*y^7 + x^8*y^6*z^2 + x^9*z^7 + y^7*z^9 + From: Projective Plane Curve over Finite Field of size 17 + defined by x^9 + y^7*z^2 + x*y*z^7 + 2*z^9 + To: Projective Plane Curve over Finite Field of size 17 + defined by 2*x^9*y^7 + x^8*y^6*z^2 + x^9*z^7 + y^7*z^9 Defn: Defined on coordinates by sending (x : y : z) to (y*z : x*z : x*y) """ @@ -1119,55 +1128,66 @@ def excellent_position(self, Q): sage: C.excellent_position(Q) Scheme morphism: From: Projective Plane Curve over Rational Field defined by x*y - z^2 - To: Projective Plane Curve over Rational Field defined by -x^2 - - 3*x*y - 4*y^2 - x*z - 3*y*z + To: Projective Plane Curve over Rational Field + defined by -x^2 - 3*x*y - 4*y^2 - x*z - 3*y*z Defn: Defined on coordinates by sending (x : y : z) to (-x + 1/2*y + 1/2*z : -1/2*y + 1/2*z : x + 1/2*y - 1/2*z) :: sage: R. = QQ[] - sage: K. = NumberField(a^2 - 3) - sage: P. = ProjectiveSpace(K, 2) - sage: C = P.curve([z^2*y^3*x^4 - y^6*x^3 - 4*z^2*y^4*x^3 - 4*z^4*y^2*x^3 + 3*y^7*x^2 + 10*z^2*y^5*x^2\ - + 9*z^4*y^3*x^2 + 5*z^6*y*x^2 - 3*y^8*x - 9*z^2*y^6*x - 11*z^4*y^4*x - 7*z^6*y^2*x - 2*z^8*x + y^9 +\ - 2*z^2*y^7 + 3*z^4*y^5 + 4*z^6*y^3 + 2*z^8*y]) - sage: Q = P([1,0,0]) - sage: C.excellent_position(Q) + sage: K. = NumberField(a^2 - 3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: C = P.curve([z^2*y^3*x^4 - y^6*x^3 - 4*z^2*y^4*x^3 - 4*z^4*y^2*x^3 # optional - sage.rings.number_field + ....: + 3*y^7*x^2 + 10*z^2*y^5*x^2 + 9*z^4*y^3*x^2 + ....: + 5*z^6*y*x^2 - 3*y^8*x - 9*z^2*y^6*x - 11*z^4*y^4*x + ....: - 7*z^6*y^2*x - 2*z^8*x + y^9 + 2*z^2*y^7 + 3*z^4*y^5 + ....: + 4*z^6*y^3 + 2*z^8*y]) + sage: Q = P([1,0,0]) # optional - sage.rings.number_field + sage: C.excellent_position(Q) # optional - sage.rings.number_field Scheme morphism: - From: Projective Plane Curve over Number Field in b with defining - polynomial a^2 - 3 defined by -x^3*y^6 + 3*x^2*y^7 - 3*x*y^8 + y^9 + - x^4*y^3*z^2 - 4*x^3*y^4*z^2 + 10*x^2*y^5*z^2 - 9*x*y^6*z^2 + 2*y^7*z^2 - - 4*x^3*y^2*z^4 + 9*x^2*y^3*z^4 - 11*x*y^4*z^4 + 3*y^5*z^4 + 5*x^2*y*z^6 - - 7*x*y^2*z^6 + 4*y^3*z^6 - 2*x*z^8 + 2*y*z^8 - To: Projective Plane Curve over Number Field in b with defining - polynomial a^2 - 3 defined by 900*x^9 - 7410*x^8*y + 29282*x^7*y^2 - - 69710*x^6*y^3 + 110818*x^5*y^4 - 123178*x^4*y^5 + 96550*x^3*y^6 - - 52570*x^2*y^7 + 18194*x*y^8 - 3388*y^9 - 1550*x^8*z + 9892*x^7*y*z - - 30756*x^6*y^2*z + 58692*x^5*y^3*z - 75600*x^4*y^4*z + 67916*x^3*y^5*z - - 42364*x^2*y^6*z + 16844*x*y^7*z - 3586*y^8*z + 786*x^7*z^2 - - 3958*x^6*y*z^2 + 9746*x^5*y^2*z^2 - 14694*x^4*y^3*z^2 + - 15174*x^3*y^4*z^2 - 10802*x^2*y^5*z^2 + 5014*x*y^6*z^2 - 1266*y^7*z^2 - - 144*x^6*z^3 + 512*x^5*y*z^3 - 912*x^4*y^2*z^3 + 1024*x^3*y^3*z^3 - - 816*x^2*y^4*z^3 + 512*x*y^5*z^3 - 176*y^6*z^3 + 8*x^5*z^4 - 8*x^4*y*z^4 - - 16*x^3*y^2*z^4 + 16*x^2*y^3*z^4 + 8*x*y^4*z^4 - 8*y^5*z^4 + From: Projective Plane Curve over Number Field in b + with defining polynomial a^2 - 3 + defined by -x^3*y^6 + 3*x^2*y^7 - 3*x*y^8 + y^9 + x^4*y^3*z^2 + - 4*x^3*y^4*z^2 + 10*x^2*y^5*z^2 - 9*x*y^6*z^2 + + 2*y^7*z^2 - 4*x^3*y^2*z^4 + 9*x^2*y^3*z^4 + - 11*x*y^4*z^4 + 3*y^5*z^4 + 5*x^2*y*z^6 + - 7*x*y^2*z^6 + 4*y^3*z^6 - 2*x*z^8 + 2*y*z^8 + To: Projective Plane Curve over Number Field in b + with defining polynomial a^2 - 3 + defined by 900*x^9 - 7410*x^8*y + 29282*x^7*y^2 - 69710*x^6*y^3 + + 110818*x^5*y^4 - 123178*x^4*y^5 + 96550*x^3*y^6 + - 52570*x^2*y^7 + 18194*x*y^8 - 3388*y^9 - 1550*x^8*z + + 9892*x^7*y*z - 30756*x^6*y^2*z + 58692*x^5*y^3*z + - 75600*x^4*y^4*z + 67916*x^3*y^5*z - 42364*x^2*y^6*z + + 16844*x*y^7*z - 3586*y^8*z + 786*x^7*z^2 + - 3958*x^6*y*z^2 + 9746*x^5*y^2*z^2 - 14694*x^4*y^3*z^2 + + 15174*x^3*y^4*z^2 - 10802*x^2*y^5*z^2 + + 5014*x*y^6*z^2 - 1266*y^7*z^2 - 144*x^6*z^3 + + 512*x^5*y*z^3 - 912*x^4*y^2*z^3 + 1024*x^3*y^3*z^3 + - 816*x^2*y^4*z^3 + 512*x*y^5*z^3 - 176*y^6*z^3 + + 8*x^5*z^4 - 8*x^4*y*z^4 - 16*x^3*y^2*z^4 + + 16*x^2*y^3*z^4 + 8*x*y^4*z^4 - 8*y^5*z^4 Defn: Defined on coordinates by sending (x : y : z) to (1/4*y + 1/2*z : -1/4*y + 1/2*z : x + 1/4*y - 1/2*z) :: sage: set_verbose(-1) - sage: a = QQbar(sqrt(2)) - sage: P. = ProjectiveSpace(QQbar, 2) - sage: C = Curve([(-1/4*a)*x^3 + (-3/4*a)*x^2*y + (-3/4*a)*x*y^2 + (-1/4*a)*y^3 - 2*x*y*z], P) - sage: Q = P([0,0,1]) - sage: C.excellent_position(Q) + sage: a = QQbar(sqrt(2)) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(QQbar, 2) # optional - sage.rings.number_field + sage: C = Curve([(-1/4*a)*x^3 + (-3/4*a)*x^2*y # optional - sage.rings.number_field + ....: + (-3/4*a)*x*y^2 + (-1/4*a)*y^3 - 2*x*y*z], P) + sage: Q = P([0,0,1]) # optional - sage.rings.number_field + sage: C.excellent_position(Q) # optional - sage.rings.number_field Scheme morphism: - From: Projective Plane Curve over Algebraic Field defined by - (-0.3535533905932738?)*x^3 + (-1.060660171779822?)*x^2*y + - (-1.060660171779822?)*x*y^2 + (-0.3535533905932738?)*y^3 + (-2)*x*y*z - To: Projective Plane Curve over Algebraic Field defined by - (-2.828427124746190?)*x^3 + (-2)*x^2*y + 2*y^3 + (-2)*x^2*z + 2*y^2*z + From: Projective Plane Curve over Algebraic Field defined + by (-0.3535533905932738?)*x^3 + (-1.060660171779822?)*x^2*y + + (-1.060660171779822?)*x*y^2 + (-0.3535533905932738?)*y^3 + + (-2)*x*y*z + To: Projective Plane Curve over Algebraic Field defined + by (-2.828427124746190?)*x^3 + (-2)*x^2*y + 2*y^3 + + (-2)*x^2*z + 2*y^2*z Defn: Defined on coordinates by sending (x : y : z) to (1/2*x + 1/2*y : (-1/2)*x + 1/2*y : 1/2*x + (-1/2)*y + z) """ @@ -1311,39 +1331,52 @@ def ordinary_model(self): EXAMPLES:: sage: set_verbose(-1) - sage: K = QuadraticField(3) - sage: P. = ProjectiveSpace(K, 2) - sage: C = Curve([x^5 - K.0*y*z^4], P) - sage: C.ordinary_model() + sage: K = QuadraticField(3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: C = Curve([x^5 - K.0*y*z^4], P) # optional - sage.rings.number_field + sage: C.ordinary_model() # optional - sage.rings.number_field Scheme morphism: - From: Projective Plane Curve over Number Field in a with defining polynomial x^2 - 3 with a = 1.732050807568878? defined by x^5 + (-a)*y*z^4 - To: Projective Plane Curve over Number Field in a with defining polynomial x^2 - 3 with a = 1.732050807568878? defined by (-a)*x^5*y + (-4*a)*x^4*y^2 + (-6*a)*x^3*y^3 + (-4*a)*x^2*y^4 + (-a)*x*y^5 + (-a - 1)*x^5*z + (-4*a + 5)*x^4*y*z + (-6*a - 10)*x^3*y^2*z + (-4*a + 10)*x^2*y^3*z + (-a - 5)*x*y^4*z + y^5*z + From: Projective Plane Curve over Number Field in a + with defining polynomial x^2 - 3 with a = 1.732050807568878? + defined by x^5 + (-a)*y*z^4 + To: Projective Plane Curve over Number Field in a + with defining polynomial x^2 - 3 with a = 1.732050807568878? + defined by (-a)*x^5*y + (-4*a)*x^4*y^2 + (-6*a)*x^3*y^3 + + (-4*a)*x^2*y^4 + (-a)*x*y^5 + (-a - 1)*x^5*z + + (-4*a + 5)*x^4*y*z + (-6*a - 10)*x^3*y^2*z + + (-4*a + 10)*x^2*y^3*z + (-a - 5)*x*y^4*z + y^5*z Defn: Defined on coordinates by sending (x : y : z) to - (-1/4*x^2 - 1/2*x*y + 1/2*x*z + 1/2*y*z - 1/4*z^2 : 1/4*x^2 + 1/2*x*y + 1/2*y*z - 1/4*z^2 : -1/4*x^2 + 1/4*z^2) + (-1/4*x^2 - 1/2*x*y + 1/2*x*z + 1/2*y*z - 1/4*z^2 : + 1/4*x^2 + 1/2*x*y + 1/2*y*z - 1/4*z^2 : + -1/4*x^2 + 1/4*z^2) :: sage: set_verbose(-1) sage: P. = ProjectiveSpace(QQ, 2) sage: C = Curve([y^2*z^2 - x^4 - x^3*z], P) - sage: D = C.ordinary_model(); D # long time (2 seconds) + sage: D = C.ordinary_model(); D # long time (2 seconds) Scheme morphism: - From: Projective Plane Curve over Rational Field defined by -x^4 - - x^3*z + y^2*z^2 - To: Projective Plane Curve over Rational Field defined by 4*x^6*y^3 - - 24*x^5*y^4 + 36*x^4*y^5 + 8*x^6*y^2*z - 40*x^5*y^3*z + 24*x^4*y^4*z + - 72*x^3*y^5*z - 4*x^6*y*z^2 + 8*x^5*y^2*z^2 - 56*x^4*y^3*z^2 + - 104*x^3*y^4*z^2 + 44*x^2*y^5*z^2 + 8*x^6*z^3 - 16*x^5*y*z^3 - - 24*x^4*y^2*z^3 + 40*x^3*y^3*z^3 + 48*x^2*y^4*z^3 + 8*x*y^5*z^3 - - 8*x^5*z^4 + 36*x^4*y*z^4 - 56*x^3*y^2*z^4 + 20*x^2*y^3*z^4 + - 40*x*y^4*z^4 - 16*y^5*z^4 + From: Projective Plane Curve over Rational Field defined + by -x^4 - x^3*z + y^2*z^2 + To: Projective Plane Curve over Rational Field defined + by 4*x^6*y^3 - 24*x^5*y^4 + 36*x^4*y^5 + 8*x^6*y^2*z + - 40*x^5*y^3*z + 24*x^4*y^4*z + 72*x^3*y^5*z - 4*x^6*y*z^2 + + 8*x^5*y^2*z^2 - 56*x^4*y^3*z^2 + 104*x^3*y^4*z^2 + + 44*x^2*y^5*z^2 + 8*x^6*z^3 - 16*x^5*y*z^3 + - 24*x^4*y^2*z^3 + 40*x^3*y^3*z^3 + 48*x^2*y^4*z^3 + + 8*x*y^5*z^3 - 8*x^5*z^4 + 36*x^4*y*z^4 - 56*x^3*y^2*z^4 + + 20*x^2*y^3*z^4 + 40*x*y^4*z^4 - 16*y^5*z^4 Defn: Defined on coordinates by sending (x : y : z) to - (-3/64*x^4 + 9/64*x^2*y^2 - 3/32*x*y^3 - 1/16*x^3*z - - 1/8*x^2*y*z + 1/4*x*y^2*z - 1/16*y^3*z - 1/8*x*y*z^2 + 1/16*y^2*z^2 : - -1/64*x^4 + 3/64*x^2*y^2 - 1/32*x*y^3 + 1/16*x*y^2*z - 1/16*y^3*z + - 1/16*y^2*z^2 : 3/64*x^4 - 3/32*x^3*y + 3/64*x^2*y^2 + 1/16*x^3*z - - 3/16*x^2*y*z + 1/8*x*y^2*z - 1/8*x*y*z^2 + 1/16*y^2*z^2) - sage: all(D.codomain().is_ordinary_singularity(Q) for Q in D.codomain().singular_points()) # long time + (-3/64*x^4 + 9/64*x^2*y^2 - 3/32*x*y^3 - 1/16*x^3*z + - 1/8*x^2*y*z + 1/4*x*y^2*z - 1/16*y^3*z - 1/8*x*y*z^2 + + 1/16*y^2*z^2 : + -1/64*x^4 + 3/64*x^2*y^2 - 1/32*x*y^3 + 1/16*x*y^2*z + - 1/16*y^3*z + 1/16*y^2*z^2 : + 3/64*x^4 - 3/32*x^3*y + 3/64*x^2*y^2 + 1/16*x^3*z + - 3/16*x^2*y*z + 1/8*x*y^2*z - 1/8*x*y*z^2 + 1/16*y^2*z^2) + sage: all(D.codomain().is_ordinary_singularity(Q) # long time + ....: for Q in D.codomain().singular_points()) True :: @@ -1353,44 +1386,53 @@ def ordinary_model(self): sage: C = Curve([(x^2 + y^2 - y*z - 2*z^2)*(y*z - x^2 + 2*z^2)*z + y^5], P) sage: C.ordinary_model() # long time (5 seconds) Scheme morphism: - From: Projective Plane Curve over Number Field in a with defining - polynomial y^2 - 2 defined by y^5 - x^4*z - x^2*y^2*z + 2*x^2*y*z^2 + - y^3*z^2 + 4*x^2*z^3 + y^2*z^3 - 4*y*z^4 - 4*z^5 - To: Projective Plane Curve over Number Field in a with defining - polynomial y^2 - 2 defined by (-29*a + 1)*x^8*y^6 + (10*a + 158)*x^7*y^7 - + (-109*a - 31)*x^6*y^8 + (-80*a - 198)*x^8*y^5*z + (531*a + - 272)*x^7*y^6*z + (170*a - 718)*x^6*y^7*z + (19*a - 636)*x^5*y^8*z + - (-200*a - 628)*x^8*y^4*z^2 + (1557*a - 114)*x^7*y^5*z^2 + (2197*a - - 2449)*x^6*y^6*z^2 + (1223*a - 3800)*x^5*y^7*z^2 + (343*a - - 1329)*x^4*y^8*z^2 + (-323*a - 809)*x^8*y^3*z^3 + (1630*a - - 631)*x^7*y^4*z^3 + (4190*a - 3126)*x^6*y^5*z^3 + (3904*a - - 7110)*x^5*y^6*z^3 + (1789*a - 5161)*x^4*y^7*z^3 + (330*a - - 1083)*x^3*y^8*z^3 + (-259*a - 524)*x^8*y^2*z^4 + (720*a - - 605)*x^7*y^3*z^4 + (3082*a - 2011)*x^6*y^4*z^4 + (4548*a - - 5462)*x^5*y^5*z^4 + (2958*a - 6611)*x^4*y^6*z^4 + (994*a - - 2931)*x^3*y^7*z^4 + (117*a - 416)*x^2*y^8*z^4 + (-108*a - 184)*x^8*y*z^5 - + (169*a - 168)*x^7*y^2*z^5 + (831*a - 835)*x^6*y^3*z^5 + (2225*a - - 1725)*x^5*y^4*z^5 + (1970*a - 3316)*x^4*y^5*z^5 + (952*a - - 2442)*x^3*y^6*z^5 + (217*a - 725)*x^2*y^7*z^5 + (16*a - 77)*x*y^8*z^5 + - (-23*a - 35)*x^8*z^6 + (43*a + 24)*x^7*y*z^6 + (21*a - 198)*x^6*y^2*z^6 - + (377*a - 179)*x^5*y^3*z^6 + (458*a - 537)*x^4*y^4*z^6 + (288*a - - 624)*x^3*y^5*z^6 + (100*a - 299)*x^2*y^6*z^6 + (16*a - 67)*x*y^7*z^6 - - 5*y^8*z^6 + From: Projective Plane Curve over Number Field in a + with defining polynomial y^2 - 2 defined + by y^5 - x^4*z - x^2*y^2*z + 2*x^2*y*z^2 + y^3*z^2 + + 4*x^2*z^3 + y^2*z^3 - 4*y*z^4 - 4*z^5 + To: Projective Plane Curve over Number Field in a + with defining polynomial y^2 - 2 defined + by (-29*a + 1)*x^8*y^6 + (10*a + 158)*x^7*y^7 + + (-109*a - 31)*x^6*y^8 + (-80*a - 198)*x^8*y^5*z + + (531*a + 272)*x^7*y^6*z + (170*a - 718)*x^6*y^7*z + + (19*a - 636)*x^5*y^8*z + (-200*a - 628)*x^8*y^4*z^2 + + (1557*a - 114)*x^7*y^5*z^2 + (2197*a - 2449)*x^6*y^6*z^2 + + (1223*a - 3800)*x^5*y^7*z^2 + (343*a - 1329)*x^4*y^8*z^2 + + (-323*a - 809)*x^8*y^3*z^3 + (1630*a - 631)*x^7*y^4*z^3 + + (4190*a - 3126)*x^6*y^5*z^3 + (3904*a - 7110)*x^5*y^6*z^3 + + (1789*a - 5161)*x^4*y^7*z^3 + (330*a - 1083)*x^3*y^8*z^3 + + (-259*a - 524)*x^8*y^2*z^4 + (720*a - 605)*x^7*y^3*z^4 + + (3082*a - 2011)*x^6*y^4*z^4 + (4548*a - 5462)*x^5*y^5*z^4 + + (2958*a - 6611)*x^4*y^6*z^4 + (994*a - 2931)*x^3*y^7*z^4 + + (117*a - 416)*x^2*y^8*z^4 + (-108*a - 184)*x^8*y*z^5 + + (169*a - 168)*x^7*y^2*z^5 + (831*a - 835)*x^6*y^3*z^5 + + (2225*a - 1725)*x^5*y^4*z^5 + (1970*a - 3316)*x^4*y^5*z^5 + + (952*a - 2442)*x^3*y^6*z^5 + (217*a - 725)*x^2*y^7*z^5 + + (16*a - 77)*x*y^8*z^5 + (-23*a - 35)*x^8*z^6 + + (43*a + 24)*x^7*y*z^6 + (21*a - 198)*x^6*y^2*z^6 + + (377*a - 179)*x^5*y^3*z^6 + (458*a - 537)*x^4*y^4*z^6 + + (288*a - 624)*x^3*y^5*z^6 + (100*a - 299)*x^2*y^6*z^6 + + (16*a - 67)*x*y^7*z^6 - 5*y^8*z^6 Defn: Defined on coordinates by sending (x : y : z) to - ((-5/128*a - 5/128)*x^4 + (-5/32*a + 5/32)*x^3*y + (-1/16*a + - 3/32)*x^2*y^2 + (1/16*a - 1/16)*x*y^3 + (1/32*a - 1/32)*y^4 - 1/32*x^3*z - + (3/16*a - 5/8)*x^2*y*z + (1/8*a - 5/16)*x*y^2*z + (1/8*a + - 5/32)*x^2*z^2 + (-3/16*a + 5/16)*x*y*z^2 + (-3/16*a - 1/16)*y^2*z^2 + - 1/16*x*z^3 + (1/4*a + 1/4)*y*z^3 + (-3/32*a - 5/32)*z^4 : (-5/128*a - - 5/128)*x^4 + (5/32*a)*x^3*y + (3/32*a + 3/32)*x^2*y^2 + (-1/16*a)*x*y^3 - + (-1/32*a - 1/32)*y^4 - 1/32*x^3*z + (-11/32*a)*x^2*y*z + (1/8*a + - 5/16)*x*y^2*z + (3/16*a + 1/4)*y^3*z + (1/8*a + 5/32)*x^2*z^2 + (-1/16*a - - 3/8)*x*y*z^2 + (-3/8*a - 9/16)*y^2*z^2 + 1/16*x*z^3 + (5/16*a + - 1/2)*y*z^3 + (-3/32*a - 5/32)*z^4 : (1/64*a + 3/128)*x^4 + (-1/32*a - - 1/32)*x^3*y + (3/32*a - 9/32)*x^2*y^2 + (1/16*a - 3/16)*x*y^3 - 1/32*y^4 - + (3/32*a + 1/8)*x^2*y*z + (-1/8*a + 1/8)*x*y^2*z + (-1/16*a)*y^3*z + - (-1/16*a - 3/32)*x^2*z^2 + (1/16*a + 1/16)*x*y*z^2 + (3/16*a + - 3/16)*y^2*z^2 + (-3/16*a - 1/4)*y*z^3 + (1/16*a + 3/32)*z^4) + ((-5/128*a - 5/128)*x^4 + (-5/32*a + 5/32)*x^3*y + + (-1/16*a + 3/32)*x^2*y^2 + (1/16*a - 1/16)*x*y^3 + + (1/32*a - 1/32)*y^4 - 1/32*x^3*z + (3/16*a - 5/8)*x^2*y*z + + (1/8*a - 5/16)*x*y^2*z + (1/8*a + 5/32)*x^2*z^2 + + (-3/16*a + 5/16)*x*y*z^2 + (-3/16*a - 1/16)*y^2*z^2 + + 1/16*x*z^3 + (1/4*a + 1/4)*y*z^3 + (-3/32*a - 5/32)*z^4 : + (-5/128*a - 5/128)*x^4 + (5/32*a)*x^3*y + + (3/32*a + 3/32)*x^2*y^2 + (-1/16*a)*x*y^3 + + (-1/32*a - 1/32)*y^4 - 1/32*x^3*z + (-11/32*a)*x^2*y*z + + (1/8*a + 5/16)*x*y^2*z + (3/16*a + 1/4)*y^3*z + + (1/8*a + 5/32)*x^2*z^2 + (-1/16*a - 3/8)*x*y*z^2 + + (-3/8*a - 9/16)*y^2*z^2 + 1/16*x*z^3 + (5/16*a + 1/2)*y*z^3 + + (-3/32*a - 5/32)*z^4 : + (1/64*a + 3/128)*x^4 + (-1/32*a - 1/32)*x^3*y + + (3/32*a - 9/32)*x^2*y^2 + (1/16*a - 3/16)*x*y^3 - 1/32*y^4 + + (3/32*a + 1/8)*x^2*y*z + (-1/8*a + 1/8)*x*y^2*z + + (-1/16*a)*y^3*z + (-1/16*a - 3/32)*x^2*z^2 + + (1/16*a + 1/16)*x*y*z^2 + (3/16*a + 3/16)*y^2*z^2 + + (-3/16*a - 1/4)*y*z^3 + (1/16*a + 3/32)*z^4) """ # helper function for extending the base field def extension(self): @@ -1477,7 +1519,7 @@ def is_transverse(self, C, P): - ``P`` -- a point in the intersection of both curves. - OUTPUT: Boolean. + OUTPUT: A boolean. EXAMPLES:: @@ -1490,12 +1532,12 @@ def is_transverse(self, C, P): :: - sage: K = QuadraticField(-1) - sage: P. = ProjectiveSpace(K, 2) - sage: C = Curve([y^2*z - K.0*x^3], P) - sage: D = Curve([z*x + y^2], P) - sage: Q = P([0,0,1]) - sage: C.is_transverse(D, Q) + sage: K = QuadraticField(-1) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: C = Curve([y^2*z - K.0*x^3], P) # optional - sage.rings.number_field + sage: D = Curve([z*x + y^2], P) # optional - sage.rings.number_field + sage: Q = P([0,0,1]) # optional - sage.rings.number_field + sage: C.is_transverse(D, Q) # optional - sage.rings.number_field False :: @@ -1555,9 +1597,9 @@ def arithmetic_genus(self): :: - sage: P. = ProjectiveSpace(GF(7), 4) - sage: C = P.curve([t^3 - x*y*w, x^3 + y^3 + z^3, z - w]) - sage: C.arithmetic_genus() + sage: P. = ProjectiveSpace(GF(7), 4) # optional - sage.rings.finite_rings + sage: C = P.curve([t^3 - x*y*w, x^3 + y^3 + z^3, z - w]) # optional - sage.rings.finite_rings + sage: C.arithmetic_genus() # optional - sage.rings.finite_rings 10 """ if not self.is_irreducible(): @@ -1606,7 +1648,8 @@ def tangent_line(self, p): sage: C = Curve([x*y - z*w, x^2 - y*w, y^2*w - x*z*w], P) sage: p = C(1,1,1,1) sage: C.tangent_line(p) - Projective Curve over Rational Field defined by -2*x + y + w, -3*x + z + 2*w + Projective Curve over Rational Field + defined by -2*x + y + w, -3*x + z + 2*w """ for i in range(len(p)): @@ -1636,12 +1679,13 @@ def arithmetic_genus(self): EXAMPLES:: - sage: x,y,z = PolynomialRing(GF(5), 3, 'xyz').gens() - sage: C = Curve(y^2*z^7 - x^9 - x*z^8); C - Projective Plane Curve over Finite Field of size 5 defined by -x^9 + y^2*z^7 - x*z^8 - sage: C.arithmetic_genus() + sage: x,y,z = PolynomialRing(GF(5), 3, 'xyz').gens() # optional - sage.rings.finite_rings + sage: C = Curve(y^2*z^7 - x^9 - x*z^8); C # optional - sage.rings.finite_rings + Projective Plane Curve over Finite Field of size 5 + defined by -x^9 + y^2*z^7 - x*z^8 + sage: C.arithmetic_genus() # optional - sage.rings.finite_rings 28 - sage: C.genus() + sage: C.genus() # optional - sage.rings.finite_rings 4 :: @@ -1668,23 +1712,23 @@ def fundamental_group(self): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,2) - sage: C = P.curve(x^2*z-y^3) - sage: C.fundamental_group() # optional - sirocco + sage: P. = ProjectiveSpace(QQ, 2) + sage: C = P.curve(x^2*z - y^3) + sage: C.fundamental_group() # optional - sirocco Finitely presented group < x0 | x0^3 > In the case of number fields, they need to have an embedding into the algebraic field:: - sage: a = QQ[x](x^2+5).roots(QQbar)[0][0] - sage: a + sage: a = QQ[x](x^2 + 5).roots(QQbar)[0][0] # optional - sage.rings.number_field + sage: a # optional - sage.rings.number_field -2.236067977499790?*I - sage: F = NumberField(a.minpoly(), 'a', embedding=a) - sage: P. = ProjectiveSpace(F, 2) - sage: F.inject_variables() + sage: F = NumberField(a.minpoly(), 'a', embedding=a) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(F, 2) # optional - sage.rings.number_field + sage: F.inject_variables() # optional - sage.rings.number_field Defining a - sage: C = P.curve(x^2 + a * y^2) - sage: C.fundamental_group() # optional - sirocco + sage: C = P.curve(x^2 + a * y^2) # optional - sage.rings.number_field + sage: C.fundamental_group() # optional - sirocco # optional - sage.rings.number_field Finitely presented group < x0 | > .. WARNING:: @@ -1693,11 +1737,13 @@ def fundamental_group(self): TESTS:: - sage: P.=ProjectiveSpace(QQ,2) - sage: f=z^2*y^3-z*(33*x*z+2*x^2+8*z^2)*y^2+(21*z^2+21*x*z-x^2)*(z^2+11*x*z-x^2)*y+(x-18*z)*(z^2+11*x*z-x^2)^2 - sage: C = P.curve(f) - sage: C.fundamental_group() # optional - sirocco - Finitely presented group < x1, x3 | (x3^-1*x1^-1*x3*x1^-1)^2*x3^-1, x3*(x1^-1*x3^-1)^2*x1^-1*(x3*x1)^2 > + sage: P. = ProjectiveSpace(QQ, 2) + sage: C = P.curve(z^2*y^3 - z*(33*x*z+2*x^2+8*z^2)*y^2 + ....: + (21*z^2+21*x*z-x^2)*(z^2+11*x*z-x^2)*y + ....: + (x-18*z)*(z^2+11*x*z-x^2)^2) + sage: C.fundamental_group() # optional - sirocco + Finitely presented group < x1, x3 | (x3^-1*x1^-1*x3*x1^-1)^2*x3^-1, + x3*(x1^-1*x3^-1)^2*x1^-1*(x3*x1)^2 > """ from sage.schemes.curves.zariski_vankampen import fundamental_group @@ -1734,7 +1780,8 @@ def rational_parameterization(self): sage: C.rational_parameterization() Scheme morphism: From: Projective Space of dimension 1 over Rational Field - To: Projective Plane Curve over Rational Field defined by -x^3 + y^2*z + To: Projective Plane Curve over Rational Field + defined by -x^3 + y^2*z Defn: Defined on coordinates by sending (s : t) to (s^2*t : s^3 : t^3) @@ -1745,7 +1792,8 @@ def rational_parameterization(self): sage: C.rational_parameterization() Scheme morphism: From: Projective Space of dimension 1 over Rational Field - To: Projective Plane Curve over Rational Field defined by x^3 - x*y*z + x*z^2 - 4*y*z^2 + To: Projective Plane Curve over Rational Field + defined by x^3 - x*y*z + x*z^2 - 4*y*z^2 Defn: Defined on coordinates by sending (s : t) to (4*s^2*t + s*t^2 : s^2*t + t^3 : 4*s^3 + s^2*t) @@ -1753,11 +1801,12 @@ def rational_parameterization(self): sage: P. = ProjectiveSpace(QQ, 2) sage: C = Curve([x^2 + y^2 + z^2], P) - sage: C.rational_parameterization() + sage: C.rational_parameterization() # optional - sage.rings.number_field Scheme morphism: - From: Projective Space of dimension 1 over Number Field in a with defining polynomial a^2 + 1 - To: Projective Plane Curve over Number Field in a with defining - polynomial a^2 + 1 defined by x^2 + y^2 + z^2 + From: Projective Space of dimension 1 over Number Field in a + with defining polynomial a^2 + 1 + To: Projective Plane Curve over Number Field in a + with defining polynomial a^2 + 1 defined by x^2 + y^2 + z^2 Defn: Defined on coordinates by sending (s : t) to ((-a)*s^2 + (-a)*t^2 : s^2 - t^2 : 2*s*t) """ @@ -1778,16 +1827,15 @@ def riemann_surface(self,**kwargs): r""" Return the complex Riemann surface determined by this curve - OUTPUT: - - - RiemannSurface object + OUTPUT: A :class:`~sage.schemes.riemann_surfaces.riemann_surface.RiemannSurface` object. EXAMPLES:: - sage: R.=QQ[] - sage: C=Curve(x^3+3*y^3+5*z^3) + sage: R. = QQ[] + sage: C = Curve(x^3 + 3*y^3 + 5*z^3) sage: C.riemann_surface() - Riemann surface defined by polynomial f = x^3 + 3*y^3 + 5 = 0, with 53 bits of precision + Riemann surface defined by polynomial f = x^3 + 3*y^3 + 5 = 0, + with 53 bits of precision """ return self.affine_patch(2).riemann_surface(**kwargs) @@ -1813,62 +1861,62 @@ def rational_points_iterator(self): EXAMPLES:: - sage: F = GF(37) - sage: P2. = ProjectiveSpace(F,2) - sage: C = Curve(X^7+Y*X*Z^5*55+Y^7*12) - sage: len(list(C.rational_points_iterator())) + sage: F = GF(37) # optional - sage.rings.finite_rings + sage: P2. = ProjectiveSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(X^7 + Y*X*Z^5*55 + Y^7*12) # optional - sage.rings.finite_rings + sage: len(list(C.rational_points_iterator())) # optional - sage.rings.finite_rings 37 :: - sage: F = GF(2) - sage: P2. = ProjectiveSpace(F,2) - sage: C = Curve(X*Y*Z) - sage: a = C.rational_points_iterator() - sage: next(a) + sage: F = GF(2) # optional - sage.rings.finite_rings + sage: P2. = ProjectiveSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(X*Y*Z) # optional - sage.rings.finite_rings + sage: a = C.rational_points_iterator() # optional - sage.rings.finite_rings + sage: next(a) # optional - sage.rings.finite_rings (1 : 0 : 0) - sage: next(a) + sage: next(a) # optional - sage.rings.finite_rings (0 : 1 : 0) - sage: next(a) + sage: next(a) # optional - sage.rings.finite_rings (1 : 1 : 0) - sage: next(a) + sage: next(a) # optional - sage.rings.finite_rings (0 : 0 : 1) - sage: next(a) + sage: next(a) # optional - sage.rings.finite_rings (1 : 0 : 1) - sage: next(a) + sage: next(a) # optional - sage.rings.finite_rings (0 : 1 : 1) - sage: next(a) + sage: next(a) # optional - sage.rings.finite_rings Traceback (most recent call last): ... StopIteration :: - sage: F = GF(3^2,'a') - sage: P2. = ProjectiveSpace(F,2) - sage: C = Curve(X^3+5*Y^2*Z-33*X*Y*X) - sage: b = C.rational_points_iterator() - sage: next(b) + sage: F = GF(3^2,'a') # optional - sage.rings.finite_rings + sage: P2. = ProjectiveSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(X^3 + 5*Y^2*Z - 33*X*Y*X) # optional - sage.rings.finite_rings + sage: b = C.rational_points_iterator() # optional - sage.rings.finite_rings + sage: next(b) # optional - sage.rings.finite_rings (0 : 1 : 0) - sage: next(b) + sage: next(b) # optional - sage.rings.finite_rings (0 : 0 : 1) - sage: next(b) + sage: next(b) # optional - sage.rings.finite_rings (2*a + 2 : a : 1) - sage: next(b) + sage: next(b) # optional - sage.rings.finite_rings (2 : a + 1 : 1) - sage: next(b) + sage: next(b) # optional - sage.rings.finite_rings (a + 1 : 2*a + 1 : 1) - sage: next(b) + sage: next(b) # optional - sage.rings.finite_rings (1 : 2 : 1) - sage: next(b) + sage: next(b) # optional - sage.rings.finite_rings (2*a + 2 : 2*a : 1) - sage: next(b) + sage: next(b) # optional - sage.rings.finite_rings (2 : 2*a + 2 : 1) - sage: next(b) + sage: next(b) # optional - sage.rings.finite_rings (a + 1 : a + 2 : 1) - sage: next(b) + sage: next(b) # optional - sage.rings.finite_rings (1 : 1 : 1) - sage: next(b) + sage: next(b) # optional - sage.rings.finite_rings Traceback (most recent call last): ... StopIteration @@ -1923,15 +1971,15 @@ def _points_via_singular(self, sort=True): EXAMPLES:: - sage: x, y, z = PolynomialRing(GF(5), 3, 'xyz').gens() - sage: f = y^2*z^7 - x^9 - x*z^8 - sage: C = Curve(f); C + sage: x, y, z = PolynomialRing(GF(5), 3, 'xyz').gens() # optional - sage.rings.finite_rings + sage: f = y^2*z^7 - x^9 - x*z^8 # optional - sage.rings.finite_rings + sage: C = Curve(f); C # optional - sage.rings.finite_rings Projective Plane Curve over Finite Field of size 5 defined by -x^9 + y^2*z^7 - x*z^8 - sage: C._points_via_singular() + sage: C._points_via_singular() # optional - sage.rings.finite_rings [(0 : 0 : 1), (0 : 1 : 0), (2 : 2 : 1), (2 : 3 : 1), (3 : 1 : 1), (3 : 4 : 1)] - sage: C._points_via_singular(sort=False) #random + sage: C._points_via_singular(sort=False) # random # optional - sage.rings.finite_rings [(0 : 1 : 0), (3 : 1 : 1), (3 : 4 : 1), (2 : 2 : 1), (0 : 0 : 1), (2 : 3 : 1)] @@ -1988,25 +2036,25 @@ def riemann_roch_basis(self, D): - ``D`` - a divisor - OUTPUT: a list of function field elements that form a basis of the - Riemann-Roch space + OUTPUT: A list of function field elements that form a basis of the + Riemann-Roch space. EXAMPLES:: - sage: R. = GF(2)[] - sage: f = x^3*y + y^3*z + x*z^3 - sage: C = Curve(f); pts = C.rational_points() - sage: D = C.divisor([ (4, pts[0]), (4, pts[2]) ]) - sage: C.riemann_roch_basis(D) + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: f = x^3*y + y^3*z + x*z^3 # optional - sage.rings.finite_rings + sage: C = Curve(f); pts = C.rational_points() # optional - sage.rings.finite_rings + sage: D = C.divisor([ (4, pts[0]), (4, pts[2]) ]) # optional - sage.rings.finite_rings + sage: C.riemann_roch_basis(D) # optional - sage.rings.finite_rings [x/y, 1, z/y, z^2/y^2, z/x, z^2/(x*y)] :: - sage: R. = GF(5)[] - sage: f = x^7 + y^7 + z^7 - sage: C = Curve(f); pts = C.rational_points() - sage: D = C.divisor([ (3, pts[0]), (-1,pts[1]), (10, pts[5]) ]) - sage: C.riemann_roch_basis(D) + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: f = x^7 + y^7 + z^7 # optional - sage.rings.finite_rings + sage: C = Curve(f); pts = C.rational_points() # optional - sage.rings.finite_rings + sage: D = C.divisor([ (3, pts[0]), (-1,pts[1]), (10, pts[5]) ]) # optional - sage.rings.finite_rings + sage: C.riemann_roch_basis(D) # optional - sage.rings.finite_rings [(-2*x + y)/(x + y), (-x + z)/(x + y)] .. NOTE:: @@ -2073,7 +2121,7 @@ def rational_points(self, algorithm="enum", sort=True): points should be sorted. If False, the order of the output is non-deterministic. - OUTPUT: a list of all the rational points on the curve, possibly sorted. + OUTPUT: A list of all the rational points on the curve, possibly sorted. .. NOTE:: @@ -2082,55 +2130,55 @@ def rational_points(self, algorithm="enum", sort=True): EXAMPLES:: - sage: x, y, z = PolynomialRing(GF(5), 3, 'xyz').gens() - sage: f = y^2*z^7 - x^9 - x*z^8 - sage: C = Curve(f); C - Projective Plane Curve over Finite Field of size 5 defined by - -x^9 + y^2*z^7 - x*z^8 - sage: C.rational_points() + sage: x, y, z = PolynomialRing(GF(5), 3, 'xyz').gens() # optional - sage.rings.finite_rings + sage: f = y^2*z^7 - x^9 - x*z^8 # optional - sage.rings.finite_rings + sage: C = Curve(f); C # optional - sage.rings.finite_rings + Projective Plane Curve over Finite Field of size 5 + defined by -x^9 + y^2*z^7 - x*z^8 + sage: C.rational_points() # optional - sage.rings.finite_rings [(0 : 0 : 1), (0 : 1 : 0), (2 : 2 : 1), (2 : 3 : 1), (3 : 1 : 1), (3 : 4 : 1)] - sage: C = Curve(x - y + z) - sage: C.rational_points() + sage: C = Curve(x - y + z) # optional - sage.rings.finite_rings + sage: C.rational_points() # optional - sage.rings.finite_rings [(0 : 1 : 1), (1 : 1 : 0), (1 : 2 : 1), (2 : 3 : 1), (3 : 4 : 1), (4 : 0 : 1)] - sage: C = Curve(x*z+z^2) - sage: C.rational_points('all') + sage: C = Curve(x*z + z^2) # optional - sage.rings.finite_rings + sage: C.rational_points('all') # optional - sage.rings.finite_rings [(0 : 1 : 0), (1 : 0 : 0), (1 : 1 : 0), (2 : 1 : 0), (3 : 1 : 0), (4 : 0 : 1), (4 : 1 : 0), (4 : 1 : 1), (4 : 2 : 1), (4 : 3 : 1), (4 : 4 : 1)] :: - sage: F = GF(7) - sage: P2. = ProjectiveSpace(F,2) - sage: C = Curve(X^3+Y^3-Z^3) - sage: C.rational_points() + sage: F = GF(7) # optional - sage.rings.finite_rings + sage: P2. = ProjectiveSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(X^3 + Y^3 - Z^3) # optional - sage.rings.finite_rings + sage: C.rational_points() # optional - sage.rings.finite_rings [(0 : 1 : 1), (0 : 2 : 1), (0 : 4 : 1), (1 : 0 : 1), (2 : 0 : 1), (3 : 1 : 0), (4 : 0 : 1), (5 : 1 : 0), (6 : 1 : 0)] :: - sage: F = GF(1237) - sage: P2. = ProjectiveSpace(F,2) - sage: C = Curve(X^7+7*Y^6*Z+Z^4*X^2*Y*89) - sage: len(C.rational_points()) + sage: F = GF(1237) # optional - sage.rings.finite_rings + sage: P2. = ProjectiveSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(X^7 + 7*Y^6*Z + Z^4*X^2*Y*89) # optional - sage.rings.finite_rings + sage: len(C.rational_points()) # optional - sage.rings.finite_rings 1237 :: - sage: F = GF(2^6,'a') - sage: P2. = ProjectiveSpace(F,2) - sage: C = Curve(X^5+11*X*Y*Z^3 + X^2*Y^3 - 13*Y^2*Z^3) - sage: len(C.rational_points()) + sage: F = GF(2^6,'a') # optional - sage.rings.finite_rings + sage: P2. = ProjectiveSpace(F, 2) # optional - sage.rings.finite_rings + sage: C = Curve(X^5 + 11*X*Y*Z^3 + X^2*Y^3 - 13*Y^2*Z^3) # optional - sage.rings.finite_rings + sage: len(C.rational_points()) # optional - sage.rings.finite_rings 104 :: - sage: R. = GF(2)[] - sage: f = x^3*y + y^3*z + x*z^3 - sage: C = Curve(f); pts = C.rational_points() - sage: pts + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: f = x^3*y + y^3*z + x*z^3 # optional - sage.rings.finite_rings + sage: C = Curve(f); pts = C.rational_points() # optional - sage.rings.finite_rings + sage: pts # optional - sage.rings.finite_rings [(0 : 0 : 1), (0 : 1 : 0), (1 : 0 : 0)] """ @@ -2171,9 +2219,9 @@ def __init__(self, A, f): TESTS:: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: C = Curve(y^2*z^7 - x^9 - x*z^8) - sage: loads(dumps(C)) == C + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2*z^7 - x^9 - x*z^8) # optional - sage.rings.finite_rings + sage: loads(dumps(C)) == C # optional - sage.rings.finite_rings True """ super().__init__(A, f) @@ -2201,9 +2249,9 @@ def function_field(self): :: - sage: P. = ProjectiveSpace(GF(4), 2) - sage: C = Curve(x^5 + y^5 + x*y*z^3 + z^5) - sage: C.function_field() + sage: P. = ProjectiveSpace(GF(4), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y*z^3 + z^5) # optional - sage.rings.finite_rings + sage: C.function_field() # optional - sage.rings.finite_rings Function field in z defined by z^5 + y*z^3 + y^5 + 1 """ return self._function_field @@ -2215,9 +2263,9 @@ def _genus(self): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(4), 2) - sage: C = Curve(x^5 + y^5 + x*y*z^3 + z^5) - sage: C.genus() # indirect doctest + sage: P. = ProjectiveSpace(GF(4), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y*z^3 + z^5) # optional - sage.rings.finite_rings + sage: C.genus() # indirect doctest # optional - sage.rings.finite_rings 1 """ return self._open_affine.genus() @@ -2228,16 +2276,16 @@ def __call__(self, *args): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(4), 2) - sage: C = Curve(x^5 + y^5 + x*y*z^3 + z^5) - sage: C(1,1,1) + sage: P. = ProjectiveSpace(GF(4), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y*z^3 + z^5) # optional - sage.rings.finite_rings + sage: C(1,1,1) # optional - sage.rings.finite_rings (1 : 1 : 1) - sage: C(y/z) + sage: C(y/z) # optional - sage.rings.finite_rings (y/(y^5 + 1))*z^4 + (y^2/(y^5 + 1))*z^2 - sage: C(GF(4^2)) + sage: C(GF(4^2)) # optional - sage.rings.finite_rings Set of rational points of Closed subscheme of Projective Space of - dimension 2 over Finite Field in z4 of size 2^4 defined by: x^5 + - y^5 + x*y*z^3 + z^5 + dimension 2 over Finite Field in z4 of size 2^4 defined by: + x^5 + y^5 + x*y*z^3 + z^5 """ try: return super().__call__(*args) @@ -2253,11 +2301,11 @@ def function(self, f): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(4), 2) - sage: C = Curve(x^5 + y^5 + x*y*z^3 + z^5) - sage: f = C.function(x/y); f + sage: P. = ProjectiveSpace(GF(4), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y*z^3 + z^5) # optional - sage.rings.finite_rings + sage: f = C.function(x/y); f # optional - sage.rings.finite_rings 1/y - sage: f.divisor() + sage: f.divisor() # optional - sage.rings.finite_rings Place (1/y, 1/y^2*z^2 + z2/y*z + 1) + Place (1/y, 1/y^2*z^2 + ((z2 + 1)/y)*z + 1) + Place (1/y, 1/y*z + 1) @@ -2282,11 +2330,11 @@ def coordinate_functions(self, i=None): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(4), 2) - sage: C = Curve(x^5 + y^5 + x*y*z^3 + z^5) - sage: C.coordinate_functions(0) + sage: P. = ProjectiveSpace(GF(4), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^5 + y^5 + x*y*z^3 + z^5) # optional - sage.rings.finite_rings + sage: C.coordinate_functions(0) # optional - sage.rings.finite_rings (y, z) - sage: C.coordinate_functions(1) + sage: C.coordinate_functions(1) # optional - sage.rings.finite_rings (1/y, 1/y*z) """ coords = self._coordinate_functions @@ -2302,9 +2350,9 @@ def _function_field(self): TESTS:: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: C = Curve(y^2*z^7 - x^9 - x*z^8) - sage: C._function_field + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2*z^7 - x^9 - x*z^8) # optional - sage.rings.finite_rings + sage: C._function_field # optional - sage.rings.finite_rings Function field in z defined by z^8 + 4*y^2*z^7 + 1 """ return self._open_affine._function_field @@ -2316,9 +2364,9 @@ def _lift_to_function_field(self): TESTS:: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: C = Curve(y^2*z^7 - x^9 - x*z^8) - sage: C._lift_to_function_field + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2*z^7 - x^9 - x*z^8) # optional - sage.rings.finite_rings + sage: C._lift_to_function_field # optional - sage.rings.finite_rings Ring morphism: From: Multivariate Polynomial Ring in x, y, z over Finite Field of size 5 To: Function field in z defined by z^8 + 4*y^2*z^7 + 1 @@ -2337,9 +2385,9 @@ def _coordinate_functions(self): TESTS:: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: C = Curve(y^2*z^7 - x^9 - x*z^8) - sage: C._coordinate_functions + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2*z^7 - x^9 - x*z^8) # optional - sage.rings.finite_rings + sage: C._coordinate_functions # optional - sage.rings.finite_rings (1, y, z) """ # homogeneous coordinate functions @@ -2354,12 +2402,12 @@ def _singularities(self): TESTS:: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: C = Curve(y^2*z^7 - x^9 - x*z^8) - sage: C._singularities + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2*z^7 - x^9 - x*z^8) # optional - sage.rings.finite_rings + sage: C._singularities # optional - sage.rings.finite_rings [(Point (x, z), [Place (1/y, 1/y*z^5 + 4*y*z^4 + 1/y^2*z)])] - sage: D = Curve(x) - sage: D._singularities + sage: D = Curve(x) # optional - sage.rings.finite_rings + sage: D._singularities # optional - sage.rings.finite_rings [] """ @@ -2414,9 +2462,9 @@ def singular_closed_points(self): :: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: C = Curve(y^2*z^7 - x^9 - x*z^8) - sage: C.singular_closed_points() + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2*z^7 - x^9 - x*z^8) # optional - sage.rings.finite_rings + sage: C.singular_closed_points() # optional - sage.rings.finite_rings [Point (x, z)] """ return [p[0] for p in self._singularities] @@ -2432,13 +2480,13 @@ def place_to_closed_point(self, place): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: C = Curve(y^2*z^7 - x^9 - x*z^8) - sage: pls = C.places() - sage: C.place_to_closed_point(pls[-1]) + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2*z^7 - x^9 - x*z^8) # optional - sage.rings.finite_rings + sage: pls = C.places() # optional - sage.rings.finite_rings + sage: C.place_to_closed_point(pls[-1]) # optional - sage.rings.finite_rings Point (x - 2*z, y - 2*z) - sage: pls2 = C.places(2) - sage: C.place_to_closed_point(pls2[0]) + sage: pls2 = C.places(2) # optional - sage.rings.finite_rings + sage: C.place_to_closed_point(pls2[0]) # optional - sage.rings.finite_rings Point (y^2 + y*z + z^2, x + y) """ F = self.function_field() @@ -2522,7 +2570,8 @@ def places_on(self, point): [Point (x, y)] sage: p, = _ sage: C.places_on(p) - [Place (1/y, 1/y^2*z, 1/y^3*z^2, 1/y^4*z^3), Place (y, y*z, y*z^2, y*z^3)] + [Place (1/y, 1/y^2*z, 1/y^3*z^2, 1/y^4*z^3), + Place (y, y*z, y*z^2, y*z^3)] sage: pl1, pl2 =_ sage: C.place_to_closed_point(pl1) Point (x, y) @@ -2531,9 +2580,9 @@ def places_on(self, point): :: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: C = Curve(x^2*z - y^3) - sage: [C.places_on(p) for p in C.closed_points()] + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^2*z - y^3) # optional - sage.rings.finite_rings + sage: [C.places_on(p) for p in C.closed_points()] # optional - sage.rings.finite_rings [[Place (1/y)], [Place (y)], [Place (y + 1)], @@ -2573,11 +2622,11 @@ class IntegralProjectiveCurve_finite_field(IntegralProjectiveCurve): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: C = Curve(y^2*z^7 - x^9 - x*z^8) - sage: C.function_field() + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2*z^7 - x^9 - x*z^8) # optional - sage.rings.finite_rings + sage: C.function_field() # optional - sage.rings.finite_rings Function field in z defined by z^8 + 4*y^2*z^7 + 1 - sage: C.closed_points() + sage: C.closed_points() # optional - sage.rings.finite_rings [Point (x, z), Point (x, y), Point (x - 2*z, y + 2*z), @@ -2597,16 +2646,16 @@ def places(self, degree=1): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: C = Curve(x^2*z - y^3) - sage: C.places() + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: C = Curve(x^2*z - y^3) # optional - sage.rings.finite_rings + sage: C.places() # optional - sage.rings.finite_rings [Place (1/y), Place (y), Place (y + 1), Place (y + 2), Place (y + 3), Place (y + 4)] - sage: C.places(2) + sage: C.places(2) # optional - sage.rings.finite_rings [Place (y^2 + 2), Place (y^2 + 3), Place (y^2 + y + 1), @@ -2631,10 +2680,10 @@ def closed_points(self, degree=1): EXAMPLES:: - sage: A. = AffineSpace(GF(9),2) - sage: C = Curve(y^2 - x^5 - x^4 - 2*x^3 - 2*x-2) - sage: Cp = C.projective_closure() - sage: Cp.closed_points() + sage: A. = AffineSpace(GF(9),2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 - x^5 - x^4 - 2*x^3 - 2*x-2) # optional - sage.rings.finite_rings + sage: Cp = C.projective_closure() # optional - sage.rings.finite_rings + sage: Cp.closed_points() # optional - sage.rings.finite_rings [Point (x0, x1), Point (x0 + (-z2 - 1)*x2, x1), Point (x0 + (z2 + 1)*x2, x1), @@ -2678,10 +2727,10 @@ def L_polynomial(self, name='t'): EXAMPLES:: - sage: A. = AffineSpace(GF(3), 2) - sage: C = Curve(y^2 - x^5 - x^4 - 2*x^3 - 2*x - 2) - sage: Cbar = C.projective_closure() - sage: Cbar.L_polynomial() + sage: A. = AffineSpace(GF(3), 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 - x^5 - x^4 - 2*x^3 - 2*x - 2) # optional - sage.rings.finite_rings + sage: Cbar = C.projective_closure() # optional - sage.rings.finite_rings + sage: Cbar.L_polynomial() # optional - sage.rings.finite_rings 9*t^4 - 3*t^3 + t^2 - t + 1 """ @@ -2710,15 +2759,15 @@ def number_of_rational_points(self, r=1): EXAMPLES:: - sage: A. = AffineSpace(GF(3), 2) - sage: C = Curve(y^2 - x^5 - x^4 - 2*x^3 - 2*x - 2) - sage: Cbar = C.projective_closure() - sage: Cbar.number_of_rational_points(3) + sage: A. = AffineSpace(GF(3), 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 - x^5 - x^4 - 2*x^3 - 2*x - 2) # optional - sage.rings.finite_rings + sage: Cbar = C.projective_closure() # optional - sage.rings.finite_rings + sage: Cbar.number_of_rational_points(3) # optional - sage.rings.finite_rings 21 - sage: D = Cbar.change_ring(Cbar.base_ring().extension(3)) - sage: D.base_ring() + sage: D = Cbar.change_ring(Cbar.base_ring().extension(3)) # optional - sage.rings.finite_rings + sage: D.base_ring() # optional - sage.rings.finite_rings Finite Field in z3 of size 3^3 - sage: len(D.closed_points()) + sage: len(D.closed_points()) # optional - sage.rings.finite_rings 21 """ @@ -2753,12 +2802,12 @@ class IntegralProjectivePlaneCurve_finite_field(IntegralProjectiveCurve_finite_f EXAMPLES:: - sage: A. = AffineSpace(GF(9),2) - sage: C = Curve(y^2-x^5-x^4-2*x^3-2*x-2) - sage: Cb = C.projective_closure() - sage: Cb.singular_closed_points() + sage: A. = AffineSpace(GF(9), 2) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 - x^5 - x^4 - 2*x^3 - 2*x - 2) # optional - sage.rings.finite_rings + sage: Cb = C.projective_closure() # optional - sage.rings.finite_rings + sage: Cb.singular_closed_points() # optional - sage.rings.finite_rings [Point (x0, x1)] - sage: Cb.function_field() + sage: Cb.function_field() # optional - sage.rings.finite_rings Function field in y defined by y^2 + 2*x^5 + 2*x^4 + x^3 + x + 1 """ _point = IntegralProjectivePlaneCurvePoint_finite_field @@ -2774,9 +2823,7 @@ def Hasse_bounds(q, genus=1): - ``genus`` (int, default 1) -- a non-negative integer, - OUTPUT: - - (tuple) The Hasse bounds (lb,ub) for the cardinality of a curve of + OUTPUT: A tuple. The Hasse bounds (lb,ub) for the cardinality of a curve of genus ``genus`` defined over `\GF{q}`. EXAMPLES:: diff --git a/src/sage/schemes/curves/zariski_vankampen.py b/src/sage/schemes/curves/zariski_vankampen.py index 01e50f43ea0..751ed6502e0 100644 --- a/src/sage/schemes/curves/zariski_vankampen.py +++ b/src/sage/schemes/curves/zariski_vankampen.py @@ -24,7 +24,7 @@ sage: from sage.schemes.curves.zariski_vankampen import fundamental_group # optional - sirocco sage: R. = QQ[] - sage: f = y^3 + x^3 -1 + sage: f = y^3 + x^3 - 1 sage: fundamental_group(f) # optional - sirocco Finitely presented group < x0 | > """ diff --git a/src/sage/schemes/cyclic_covers/charpoly_frobenius.py b/src/sage/schemes/cyclic_covers/charpoly_frobenius.py index 4c63fe44783..fc5cc3b1c3e 100644 --- a/src/sage/schemes/cyclic_covers/charpoly_frobenius.py +++ b/src/sage/schemes/cyclic_covers/charpoly_frobenius.py @@ -32,7 +32,7 @@ def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a=1, known_factor= OUTPUT: - A list of integers corresponding to the characteristic polynomial of the Frobenius action + A list of integers corresponding to the characteristic polynomial of the Frobenius action. EXAMPLES:: @@ -41,29 +41,33 @@ def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a=1, known_factor= sage: charpoly_frobenius(M, [2, 1, 1], 17, 1, 1) [17, 2, 1] - sage: R = Zq(17**2 , names=('a',)) - sage: M = Matrix(R, [[8*17 + 16*17**2 + O(17**3), 8 + 11*17 + O(17**2)], [7*17**2 + O(17**3), 15 + 8*17 + O(17**2)]]) + sage: R = Zq(17**2, names=('a',)) + sage: M = Matrix(R, [[8*17 + 16*17**2 + O(17**3), 8 + 11*17 + O(17**2)], + ....: [7*17**2 + O(17**3), 15 + 8*17 + O(17**2)]]) sage: charpoly_frobenius(M*M, [3, 2, 2], 17, 1, 2) [289, 30, 1] - sage: M = Matrix([[8*31 + 8*31**2 + O(31**3), O(31**3), O(31**3), O(31**3)], [O(31**3), 23*31 + 22*31**2 + O(31**3), O(31**3), O(31**3)], [O(31**3), O(31**3), 27 + 7*31 + O(31**3), O(31**3)], [O(31**3), O(31**3), O(31**3), 4 + 23*31 + O(31**3)]]) + sage: M = Matrix([[8*31 + 8*31**2 + O(31**3), O(31**3), O(31**3), O(31**3)], + ....: [O(31**3), 23*31 + 22*31**2 + O(31**3), O(31**3), O(31**3)], + ....: [O(31**3), O(31**3), 27 + 7*31 + O(31**3), O(31**3)], + ....: [O(31**3), O(31**3), O(31**3), 4 + 23*31 + O(31**3)]]) sage: charpoly_frobenius(M, [4, 3, 2, 2, 2], 31, 1, 1) [961, 0, 46, 0, 1] sage: M = Matrix([(4*43^2 + O(43^3), 17*43 + 11*43^2 + O(43^3), O(43^3), O(43^3), 17 + 37*43 + O(43^3), O(43^3)), - ....: (30*43 + 23*43^2 + O(43^3), 5*43 + O(43^3), O(43^3), O(43^3), 3 + 38*43 + O(43^3), O(43^3)), - ....: (O(43^3), O(43^3), 9*43 + 32*43^2 + O(43^3), 13 + 25*43 + O(43^3), O(43^3), 17 + 18*43 + O(43^3)), - ....: (O(43^3), O(43^3), 22*43 + 25*43^2 + O(43^3), 11 + 24*43 + O(43^3), O(43^3), 36 + 5*43 + O(43^3)), - ....: (42*43 + 15*43^2 + O(43^3), 22*43 + 8*43^2 + O(43^3), O(43^3), O(43^3), 29 + 4*43 + O(43^3), O(43^3)), - ....: (O(43^3), O(43^3), 6*43 + 19*43^2 + O(43^3), 8 + 24*43 + O(43^3), O(43^3), 31 + 42*43 + O(43^3))]) + ....: (30*43 + 23*43^2 + O(43^3), 5*43 + O(43^3), O(43^3), O(43^3), 3 + 38*43 + O(43^3), O(43^3)), + ....: (O(43^3), O(43^3), 9*43 + 32*43^2 + O(43^3), 13 + 25*43 + O(43^3), O(43^3), 17 + 18*43 + O(43^3)), + ....: (O(43^3), O(43^3), 22*43 + 25*43^2 + O(43^3), 11 + 24*43 + O(43^3), O(43^3), 36 + 5*43 + O(43^3)), + ....: (42*43 + 15*43^2 + O(43^3), 22*43 + 8*43^2 + O(43^3), O(43^3), O(43^3), 29 + 4*43 + O(43^3), O(43^3)), + ....: (O(43^3), O(43^3), 6*43 + 19*43^2 + O(43^3), 8 + 24*43 + O(43^3), O(43^3), 31 + 42*43 + O(43^3))]) sage: charpoly_frobenius(M, [5, 4, 3, 2, 2, 2, 2], 43, 1, 1) [79507, 27735, 6579, 1258, 153, 15, 1] sage: M = Matrix([(1 + O(4999), O(4999), 0, 0), - ....: (O(4999), 4860 + O(4999), 0, 0), - ....: (0, 0, O(4999), O(4999)), - ....: (0, 0, O(4999), 1 + O(4999))]) - sage: charpoly_frobenius(M, [2, 1, 1], 4999, 1, 1, [1, -2 ,1 ]) + ....: (O(4999), 4860 + O(4999), 0, 0), + ....: (0, 0, O(4999), O(4999)), + ....: (0, 0, O(4999), 1 + O(4999))]) + sage: charpoly_frobenius(M, [2, 1, 1], 4999, 1, 1, [1, -2, 1]) [4999, 139, 1] TESTS:: diff --git a/src/sage/schemes/cyclic_covers/constructor.py b/src/sage/schemes/cyclic_covers/constructor.py index 0a8926d7db6..d2975336301 100644 --- a/src/sage/schemes/cyclic_covers/constructor.py +++ b/src/sage/schemes/cyclic_covers/constructor.py @@ -28,7 +28,7 @@ def CyclicCover(r, f, names=None, check_smooth=True): - ``f`` - univariate polynomial if not given, then it defaults to 0. - ``names`` (default: ``["x","y"]``) - names for the - coordinate functions + coordinate functions - ``check_squarefree`` (default: ``True``) - test if the input defines a unramified cover of the projective line. @@ -64,39 +64,44 @@ def CyclicCover(r, f, names=None, check_smooth=True): sage: CyclicCover(15, x^9 + x + 1) Cyclic Cover of P^1 over Rational Field defined by y^15 = x^9 + x + 1 - sage: k. = GF(9); R. = k[] - sage: CyclicCover(5, x^9 + x + 1) - Cyclic Cover of P^1 over Finite Field in a of size 3^2 defined by y^5 = x^9 + x + 1 - sage: CyclicCover(15, x^9 + x + 1) + sage: k. = GF(9); R. = k[] # optional - sage.rings.finite_rings + sage: CyclicCover(5, x^9 + x + 1) # optional - sage.rings.finite_rings + Cyclic Cover of P^1 over Finite Field in a of size 3^2 + defined by y^5 = x^9 + x + 1 + sage: CyclicCover(15, x^9 + x + 1) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: As the characteristic divides the order of the cover, this model is not smooth. + ValueError: As the characteristic divides the order of the cover, + this model is not smooth. We can change the names of the variables in the output:: - sage: k. = GF(9); R. = k[] - sage: CyclicCover(5, x^9 + x + 1, names = ["A","B"]) - Cyclic Cover of P^1 over Finite Field in a of size 3^2 defined by B^5 = A^9 + A + 1 + sage: k. = GF(9); R. = k[] # optional - sage.rings.finite_rings + sage: CyclicCover(5, x^9 + x + 1, names=["A","B"]) # optional - sage.rings.finite_rings + Cyclic Cover of P^1 over Finite Field in a of size 3^2 + defined by B^5 = A^9 + A + 1 Double roots:: - sage: P. = GF(7)[] - sage: CyclicCover(2,(x^3-x+2)^2*(x^6-1)) + sage: P. = GF(7)[] # optional - sage.rings.finite_rings + sage: CyclicCover(2, (x^3-x+2)^2*(x^6-1)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Not a smooth Cyclic Cover of P^1: singularity in the provided affine patch. - sage: CyclicCover(2, (x^3-x+2)^2*(x^6-1), check_smooth=False) - Cyclic Cover of P^1 over Finite Field of size 7 defined by y^2 = x^12 - 2*x^10 - 3*x^9 + x^8 + 3*x^7 + 3*x^6 + 2*x^4 + 3*x^3 - x^2 - 3*x + 3 + sage: CyclicCover(2, (x^3-x+2)^2*(x^6-1), check_smooth=False) # optional - sage.rings.finite_rings + Cyclic Cover of P^1 over Finite Field of size 7 + defined by y^2 = x^12 - 2*x^10 - 3*x^9 + x^8 + 3*x^7 + 3*x^6 + + 2*x^4 + 3*x^3 - x^2 - 3*x + 3 Input with integer coefficients creates objects with the integers as base ring, but only checks smoothness over `\QQ`, not over Spec(`\ZZ`). In other words, it is checked that the discriminant is non-zero, but it is - not checked whether the discriminant is a unit in `\ZZ^*`.:: + not checked whether the discriminant is a unit in `\ZZ^*`:: sage: R. = ZZ[] - sage: CyclicCover(5,(x^3-x+2)*(x^6-1)) + sage: CyclicCover(5, (x^3-x+2)*(x^6-1)) Cyclic Cover of P^1 over Integer Ring defined by y^5 = x^9 - x^7 + 2*x^6 - x^3 + x - 2 diff --git a/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py b/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py index ef39c87dabb..d2bdefa5e3a 100644 --- a/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py +++ b/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" Cyclic covers over a finite field @@ -22,13 +23,14 @@ sage: C.frobenius_polynomial().reverse()(t)/((1-t)*(1-p*t)) + O(t^5) 1 + 8*t + 102*t^2 + 1384*t^3 + 18089*t^4 + O(t^5) - sage: p = 49999 sage: x = PolynomialRing(GF(p),"x").gen() - sage: CyclicCover(5, x^5 + x).frobenius_polynomial() # long time - x^12 + 299994*x^10 + 37498500015*x^8 + 2499850002999980*x^6 + 93742500224997000015*x^4 + 1874812507499850001499994*x^2 + 15623125093747500037499700001 - sage: CyclicCover(5, 2*x^5 + x).frobenius_polynomial() # long time - x^12 + 299994*x^10 + 37498500015*x^8 + 2499850002999980*x^6 + 93742500224997000015*x^4 + 1874812507499850001499994*x^2 + 15623125093747500037499700001 + sage: CyclicCover(5, x^5 + x).frobenius_polynomial() # long time + x^12 + 299994*x^10 + 37498500015*x^8 + 2499850002999980*x^6 + 93742500224997000015*x^4 + + 1874812507499850001499994*x^2 + 15623125093747500037499700001 + sage: CyclicCover(5, 2*x^5 + x).frobenius_polynomial() # long time + x^12 + 299994*x^10 + 37498500015*x^8 + 2499850002999980*x^6 + 93742500224997000015*x^4 + + 1874812507499850001499994*x^2 + 15623125093747500037499700001 sage: p = 107 sage: x = PolynomialRing(GF(p),"x").gen() @@ -114,7 +116,7 @@ def __init__(self, AA, r, f, names=None, verbose=0): EXAMPLES:: sage: p = 13 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: C = CyclicCover(4, x^4 + 1) sage: C.frobenius_polynomial() x^6 - 6*x^5 + 3*x^4 + 60*x^3 + 39*x^2 - 1014*x + 2197 @@ -306,7 +308,7 @@ def _divide_vector(self, D, vect, R): TESTS:: sage: p = 4999 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: C = CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1) sage: C._init_frob() sage: C._divide_vector(p, vector(C._Qq, [p, p^2, p^3]), C._Qq) @@ -388,7 +390,7 @@ def _frob_sparse(self, i, j, N0): TESTS:: sage: p = 499 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: C = CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1) sage: C._init_frob() sage: C._frob_sparse(2, 0, 1) @@ -490,7 +492,7 @@ def _horizontal_matrix_reduction(self, s): TESTS:: sage: p = 4999 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: C = CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1) sage: C._init_frob() sage: C._horizontal_matrix_reduction(24995) @@ -559,7 +561,7 @@ def _vertical_matrix_reduction(self, s0): TESTS:: sage: p = 4999 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: C = CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1) sage: C._init_frob() sage: C._vertical_matrix_reduction(1) @@ -627,7 +629,7 @@ def _reduce_vector_horizontal(self, G, e, s, k=1): TESTS:: sage: p = 4999 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: C = CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1) sage: C._init_frob() sage: C._initialize_fat_horizontal(p, 3) @@ -656,7 +658,7 @@ def _reduce_vector_horizontal_BSGS(self, G, e, s): TESTS:: sage: p = 4999 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: C = CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1) sage: C._init_frob() sage: C._initialize_fat_horizontal(p, 3) @@ -715,7 +717,7 @@ def _initialize_fat_horizontal(self, s, L): TESTS:: sage: p = 4999 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: C = CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1) sage: C._init_frob() sage: C._initialize_fat_horizontal(p, 3) @@ -779,7 +781,7 @@ def _reduce_vector_horizontal_plain(self, G, e, s, k=1): TESTS:: sage: p = 4999 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: C = CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1) sage: C._init_frob() sage: C._initialize_fat_horizontal(p, 3) @@ -910,7 +912,7 @@ def _initialize_fat_vertical(self, s0, max_upper_target): TESTS:: sage: p = 4999 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: C = CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1) sage: C._init_frob() sage: C._initialize_fat_vertical(1, p + p // 3) @@ -959,7 +961,7 @@ def _frob(self, i, j, N0): TESTS:: sage: p = 4999 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: C = CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1) sage: C._init_frob() sage: C._frob(2, 0, 1) @@ -1027,7 +1029,7 @@ def frobenius_matrix(self, N=None): EXAMPLES:: sage: p = 107 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: CyclicCover(2, x^5 + x).frobenius_matrix() [ O(107^2) 89*107 + O(107^2) O(107^2) O(107^2)] [ 89*107 + O(107^2) O(107^2) O(107^2) O(107^2)] @@ -1094,7 +1096,7 @@ def frobenius_polynomial(self): Hyperelliptic curves:: sage: p = 11 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: f = x^7 + 4*x^2 + 10*x + 4 sage: CyclicCover(2, f).frobenius_polynomial() == \ ....: HyperellipticCurve(f).frobenius_polynomial() @@ -1108,7 +1110,7 @@ def frobenius_polynomial(self): ....: HyperellipticCurve(f).frobenius_polynomial() True sage: p = 1117 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: f = x^9 + 4*x^2 + 10*x + 4 sage: P1 = CyclicCover(2, f).frobenius_polynomial() sage: P2 = HyperellipticCurve(f).frobenius_polynomial() @@ -1122,7 +1124,7 @@ def frobenius_polynomial(self): Superelliptic curves:: sage: p = 11 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1).frobenius_polynomial() x^6 + 21*x^4 + 231*x^2 + 1331 sage: CyclicCover(4, x^3 + x + 1).frobenius_polynomial() @@ -1134,71 +1136,88 @@ def frobenius_polynomial(self): True sage: CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1).frobenius_polynomial() x^6 + 180*x^5 + 20988*x^4 + 1854349*x^3 + 104919012*x^2 + 4498200180*x + 124925014999 - sage: CyclicCover(4,x^5 + x + 1).frobenius_polynomial() - x^12 - 64*x^11 + 5018*x^10 - 488640*x^9 + 28119583*x^8 - 641791616*x^7 + 124245485932*x^6 - 3208316288384*x^5 + 702708407289583*x^4 - 61043359329111360*x^3 + 3133741752599645018*x^2 - 199800079984001599936*x + 15606259372500374970001 + sage: CyclicCover(4, x^5 + x + 1).frobenius_polynomial() + x^12 - 64*x^11 + 5018*x^10 - 488640*x^9 + 28119583*x^8 - 641791616*x^7 + + 124245485932*x^6 - 3208316288384*x^5 + 702708407289583*x^4 - 61043359329111360*x^3 + + 3133741752599645018*x^2 - 199800079984001599936*x + 15606259372500374970001 - sage: CyclicCover(11, PolynomialRing(GF(1129), 'x')([-1] + [0]*(5-1) + [1])).frobenius_polynomial() # long time - x^40 + 7337188909826596*x^30 + 20187877911930897108199045855206*x^20 + 24687045654725446027864774006541463602997309796*x^10 + 11320844849639649951608809973589776933203136765026963553258401 + sage: h = PolynomialRing(GF(1129), 'x')([-1] + [0]*(5-1) + [1]) + sage: CyclicCover(11, h).frobenius_polynomial() # long time + x^40 + 7337188909826596*x^30 + 20187877911930897108199045855206*x^20 + + 24687045654725446027864774006541463602997309796*x^10 + + 11320844849639649951608809973589776933203136765026963553258401 - sage: CyclicCover(3, PolynomialRing(GF(1009^2), 'x')([-1] + [0]*(5-1) + [1])).frobenius_polynomial() # long time - x^8 + 532*x^7 - 2877542*x^6 - 242628176*x^5 + 4390163797795*x^4 - 247015136050256*x^3 - 2982540407204025062*x^2 + 561382189105547134612*x + 1074309286591662654798721 + sage; h = PolynomialRing(GF(1009^2), 'x')([-1] + [0]*(5-1) + [1]) + sage: CyclicCover(3, h).frobenius_polynomial() # long time + x^8 + 532*x^7 - 2877542*x^6 - 242628176*x^5 + 4390163797795*x^4 - 247015136050256*x^3 + - 2982540407204025062*x^2 + 561382189105547134612*x + 1074309286591662654798721 A non-monic example checking that :trac:`29015` is fixed:: sage: a = 3 - sage: K.=GF(83^3); - sage: R.= PolynomialRing(K) - sage: h = s*x^4 +x*3+ 8; - sage: C = CyclicCover(a,h) + sage: K. = GF(83^3); + sage: R. = PolynomialRing(K) + sage: h = s*x^4 + x*3 + 8 + sage: C = CyclicCover(a, h) sage: C.frobenius_polynomial() x^6 + 1563486*x^4 + 893980969482*x^2 + 186940255267540403 Non-superelliptic curves:: sage: p = 13 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: C = CyclicCover(4, x^4 + 1) sage: C.frobenius_polynomial() x^6 - 6*x^5 + 3*x^4 + 60*x^3 + 39*x^2 - 1014*x + 2197 sage: R. = PowerSeriesRing(Integers()) - sage: C.projective_closure().zeta_series(2,t) + sage: C.projective_closure().zeta_series(2, t) 1 + 8*t + 102*t^2 + O(t^3) sage: C.frobenius_polynomial().reverse()(t)/((1-t)*(1-p*t)) + O(t^5) 1 + 8*t + 102*t^2 + 1384*t^3 + 18089*t^4 + O(t^5) - sage: x = PolynomialRing(GF(11),"x").gen() - sage: CyclicCover(4, x^6 - 11*x^3 + 70*x^2 - x + 961).frobenius_polynomial() # long time + sage: x = PolynomialRing(GF(11), "x").gen() + sage: CyclicCover(4, x^6 - 11*x^3 + 70*x^2 - x + 961).frobenius_polynomial() # long time x^14 + 14*x^12 + 287*x^10 + 3025*x^8 + 33275*x^6 + 381997*x^4 + 2254714*x^2 + 19487171 - sage: x = PolynomialRing(GF(4999),"x").gen() - sage: CyclicCover(4, x^6 - 11*x^3 + 70*x^2 - x + 961).frobenius_polynomial() # long time - x^14 - 4*x^13 - 2822*x^12 - 30032*x^11 + 37164411*x^10 - 152369520*x^9 + 54217349361*x^8 - 1021791160888*x^7 + 271032529455639*x^6 - 3807714457169520*x^5 + 4642764601604000589*x^4 - 18754988504199390032*x^3 - 8809934776794570547178*x^2 - 62425037490001499880004*x + 78015690603129374475034999 + sage: x = PolynomialRing(GF(4999), "x").gen() + sage: CyclicCover(4, x^6 - 11*x^3 + 70*x^2 - x + 961).frobenius_polynomial() # long time + x^14 - 4*x^13 - 2822*x^12 - 30032*x^11 + 37164411*x^10 - 152369520*x^9 + + 54217349361*x^8 - 1021791160888*x^7 + 271032529455639*x^6 - 3807714457169520*x^5 + + 4642764601604000589*x^4 - 18754988504199390032*x^3 - 8809934776794570547178*x^2 + - 62425037490001499880004*x + 78015690603129374475034999 sage: p = 11 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: CyclicCover(3, 5*x^3 - 5*x + 13).frobenius_polynomial() x^2 + 11 sage: CyclicCover(3, x^6 + x^4 - x^3 + 2*x^2 - x - 1).frobenius_polynomial() x^8 + 32*x^6 + 462*x^4 + 3872*x^2 + 14641 sage: p = 4999 - sage: x = PolynomialRing(GF(p),"x").gen() + sage: x = PolynomialRing(GF(p), "x").gen() sage: CyclicCover(3, 5*x^3 - 5*x + 13).frobenius_polynomial() x^2 - 47*x + 4999 sage: CyclicCover(3, x^6 + x^4 - x^3 + 2*x^2 - x - 1).frobenius_polynomial() - x^8 + 122*x^7 + 4594*x^6 - 639110*x^5 - 82959649*x^4 - 3194910890*x^3 + 114804064594*x^2 + 15240851829878*x + 624500149980001 + x^8 + 122*x^7 + 4594*x^6 - 639110*x^5 - 82959649*x^4 - 3194910890*x^3 + + 114804064594*x^2 + 15240851829878*x + 624500149980001 sage: p = 11 - sage: x = PolynomialRing(GF(p),"x").gen() - sage: CyclicCover(5, x^5 + x).frobenius_polynomial() # long time - x^12 + 4*x^11 + 22*x^10 + 108*x^9 + 503*x^8 + 1848*x^7 + 5588*x^6 + 20328*x^5 + 60863*x^4 + 143748*x^3 + 322102*x^2 + 644204*x + 1771561 - sage: CyclicCover(5, 2*x^5 + x).frobenius_polynomial() # long time - x^12 - 9*x^11 + 42*x^10 - 108*x^9 - 47*x^8 + 1782*x^7 - 8327*x^6 + 19602*x^5 - 5687*x^4 - 143748*x^3 + 614922*x^2 - 1449459*x + 1771561 + sage: x = PolynomialRing(GF(p), "x").gen() + sage: CyclicCover(5, x^5 + x).frobenius_polynomial() # long time + x^12 + 4*x^11 + 22*x^10 + 108*x^9 + 503*x^8 + 1848*x^7 + 5588*x^6 + 20328*x^5 + + 60863*x^4 + 143748*x^3 + 322102*x^2 + 644204*x + 1771561 + sage: CyclicCover(5, 2*x^5 + x).frobenius_polynomial() # long time + x^12 - 9*x^11 + 42*x^10 - 108*x^9 - 47*x^8 + 1782*x^7 - 8327*x^6 + 19602*x^5 + - 5687*x^4 - 143748*x^3 + 614922*x^2 - 1449459*x + 1771561 sage: p = 49999 - sage: x = PolynomialRing(GF(p),"x").gen() - sage: CyclicCover(5, x^5 + x ).frobenius_polynomial() # long time - x^12 + 299994*x^10 + 37498500015*x^8 + 2499850002999980*x^6 + 93742500224997000015*x^4 + 1874812507499850001499994*x^2 + 15623125093747500037499700001 + sage: x = PolynomialRing(GF(p), "x").gen() + sage: CyclicCover(5, x^5 + x).frobenius_polynomial() # long time + x^12 + 299994*x^10 + 37498500015*x^8 + 2499850002999980*x^6 + + 93742500224997000015*x^4 + 1874812507499850001499994*x^2 + + 15623125093747500037499700001 sage: CyclicCover(5, 2*x^5 + x).frobenius_polynomial() # long time - x^12 + 299994*x^10 + 37498500015*x^8 + 2499850002999980*x^6 + 93742500224997000015*x^4 + 1874812507499850001499994*x^2 + 15623125093747500037499700001 + x^12 + 299994*x^10 + 37498500015*x^8 + 2499850002999980*x^6 + + 93742500224997000015*x^4 + 1874812507499850001499994*x^2 + + 15623125093747500037499700001 TESTS:: diff --git a/src/sage/schemes/cyclic_covers/cycliccover_generic.py b/src/sage/schemes/cyclic_covers/cycliccover_generic.py index 7531d933c0b..d9cb5f4c406 100644 --- a/src/sage/schemes/cyclic_covers/cycliccover_generic.py +++ b/src/sage/schemes/cyclic_covers/cycliccover_generic.py @@ -12,19 +12,18 @@ Projective Plane Curve over Integer Ring defined by x0^5 + x0^4*x1 + x1^5 - x2^5 sage: D.change_ring(QQ).genus() 6 - sage: C.change_ring(GF(5)) + sage: C.change_ring(GF(5)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: As the characteristic divides the order of the cover, this model is not smooth. - - sage: GF7x. = GF(7)[] - sage: C = CyclicCover(3, x^9 + x + 1) - sage: C + sage: GF7x. = GF(7)[] # optional - sage.rings.finite_rings + sage: C = CyclicCover(3, x^9 + x + 1) # optional - sage.rings.finite_rings + sage: C # optional - sage.rings.finite_rings Cyclic Cover of P^1 over Finite Field of size 7 defined by y^3 = x^9 + x + 1 - sage: C.genus() + sage: C.genus() # optional - sage.rings.finite_rings 7 - sage: C.projective_closure() + sage: C.projective_closure() # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: Weighted Projective Space is not implemented @@ -73,19 +72,20 @@ def __init__(self, AA, r, f, names=None): Projective Plane Curve over Integer Ring defined by x0^5 + x0^4*x1 + x1^5 - x2^5 sage: D.change_ring(QQ).genus() 6 - sage: C.change_ring(GF(5)) + sage: C.change_ring(GF(5)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: As the characteristic divides the order of the cover, this model is not smooth. + ValueError: As the characteristic divides the order of the cover, + this model is not smooth. - sage: GF7x. = GF(7)[] - sage: C = CyclicCover(3, x^9 + x + 1) - sage: C + sage: GF7x. = GF(7)[] # optional - sage.rings.finite_rings + sage: C = CyclicCover(3, x^9 + x + 1) # optional - sage.rings.finite_rings + sage: C # optional - sage.rings.finite_rings Cyclic Cover of P^1 over Finite Field of size 7 defined by y^3 = x^9 + x + 1 - sage: C.genus() + sage: C.genus() # optional - sage.rings.finite_rings 7 - sage: C.projective_closure() + sage: C.projective_closure() # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: Weighted Projective Space is not implemented @@ -116,15 +116,17 @@ def change_ring(self, R): sage: ZZx. = ZZ[] sage: C = CyclicCover(5, x^5 + x + 1) - sage: C.change_ring(GF(5)) + sage: C.change_ring(GF(5)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: As the characteristic divides the order of the cover, this model is not smooth. - sage: C.change_ring(GF(3)) + ValueError: As the characteristic divides the order of the cover, + this model is not smooth. + sage: C.change_ring(GF(3)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: Not a smooth Cyclic Cover of P^1: singularity in the provided affine patch. - sage: C.change_ring(GF(17)) + ValueError: Not a smooth Cyclic Cover of P^1: singularity in the + provided affine patch. + sage: C.change_ring(GF(17)) # optional - sage.rings.finite_rings Cyclic Cover of P^1 over Finite Field of size 17 defined by y^5 = x^5 + x + 1 """ from .constructor import CyclicCover @@ -240,8 +242,8 @@ def projective_closure(self, **kwds): EXAMPLES:: - sage: GF7x. = GF(7)[] - sage: CyclicCover(3, x^9 + x + 1).projective_closure() + sage: GF7x. = GF(7)[] # optional - sage.rings.finite_rings + sage: CyclicCover(3, x^9 + x + 1).projective_closure() # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: Weighted Projective Space is not implemented diff --git a/src/sage/schemes/elliptic_curves/BSD.py b/src/sage/schemes/elliptic_curves/BSD.py index b44ef5d9c16..f5522de2e00 100644 --- a/src/sage/schemes/elliptic_curves/BSD.py +++ b/src/sage/schemes/elliptic_curves/BSD.py @@ -21,7 +21,8 @@ class BSD_data: sage: D.curve=EllipticCurve('11a') sage: D.update() sage: D.Sha - Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Tate-Shafarevich group for the Elliptic Curve + defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field """ def __init__(self): self.curve = None @@ -52,7 +53,8 @@ def update(self): sage: D.curve = EllipticCurve('11a') sage: D.update() sage: D.Sha - Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Tate-Shafarevich group for the Elliptic Curve + defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field """ self.two_tor_rk = self.curve.two_torsion_rank() self.Sha = self.curve.sha() @@ -247,9 +249,9 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, - ``verbosity`` -- int, how much information about the proof to print. - - 0: print nothing - - 1: print sketch of proof - - 2: print information about remaining primes + - 0: print nothing + - 1: print sketch of proof + - 2: print information about remaining primes - ``two_desc`` -- string (default ``'mwrank'``), what to use for the two-descent. Options are ``'mwrank', 'simon', 'sage'`` @@ -351,13 +353,16 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, sage: E.prove_BSD() Traceback (most recent call last): ... - RuntimeError: It seems that the rank conjecture does not hold for this curve (Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field)! This may be a counterexample to BSD, but is more likely a bug. + RuntimeError: It seems that the rank conjecture does not hold for this curve + (Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field)! + This may be a counterexample to BSD, but is more likely a bug. We test the consistency check for the 2-part of Sha:: sage: E = EllipticCurve('37a') sage: S = E.sha(); S - Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 - x + over Rational Field sage: def foo(use_database): ....: return 4 sage: S.an = foo diff --git a/src/sage/schemes/elliptic_curves/Qcurves.py b/src/sage/schemes/elliptic_curves/Qcurves.py index d526915ac3f..df577822cc2 100644 --- a/src/sage/schemes/elliptic_curves/Qcurves.py +++ b/src/sage/schemes/elliptic_curves/Qcurves.py @@ -53,19 +53,19 @@ def is_Q_curve(E, maxp=100, certificate=False, verbose=False): - when the flag is ``True``, so `E` is a `\QQ`-curve: - - either {'CM':`D`} where `D` is a negative discriminant, when - `E` has potential CM with discriminant `D`; - - - otherwise {'CM': `0`, 'core_poly': `f`, 'rho': `\rho`, 'r': - `r`, 'N': `N`}, when `E` is a non-CM `\QQ`-curve, where the - core polynomial `f` is an irreducible monic polynomial over - `QQ` of degree `2^\rho`, all of whose roots are - `j`-invariants of curves isogenous to `E`, the core level - `N` is a square-free integer with `r` prime factors which is - the LCM of the degrees of the isogenies between these - conjugates. For example, if there exists a curve `E'` - isogenous to `E` with `j(E')=j\in\QQ`, then the certificate - is {'CM':0, 'r':0, 'rho':0, 'core_poly': x-j, 'N':1}. + - either {'CM':`D`} where `D` is a negative discriminant, when + `E` has potential CM with discriminant `D`; + + - otherwise {'CM': `0`, 'core_poly': `f`, 'rho': `\rho`, 'r': + `r`, 'N': `N`}, when `E` is a non-CM `\QQ`-curve, where the + core polynomial `f` is an irreducible monic polynomial over + `QQ` of degree `2^\rho`, all of whose roots are + `j`-invariants of curves isogenous to `E`, the core level + `N` is a square-free integer with `r` prime factors which is + the LCM of the degrees of the isogenies between these + conjugates. For example, if there exists a curve `E'` + isogenous to `E` with `j(E')=j\in\QQ`, then the certificate + is {'CM':0, 'r':0, 'rho':0, 'core_poly': x-j, 'N':1}. - when the flag is ``False``, so `E` is not a `\QQ`-curve, the certificate is a prime `p` such that the reductions of `E` at @@ -130,9 +130,10 @@ def is_Q_curve(E, maxp=100, certificate=False, verbose=False): sage: from sage.schemes.elliptic_curves.Qcurves import is_Q_curve sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(R([3, 0, -5, 0, 1])) - sage: E = EllipticCurve([K([-3,-4,1,1]),K([4,-1,-1,0]),K([-2,0,1,0]),K([-621,778,138,-178]),K([9509,2046,-24728,10380])]) - sage: is_Q_curve(E, certificate=True, verbose=True) + sage: K. = NumberField(R([3, 0, -5, 0, 1])) # optional - sage.rings.number_field + sage: E = EllipticCurve([K([-3,-4,1,1]), K([4,-1,-1,0]), K([-2,0,1,0]), # optional - sage.rings.number_field + ....: K([-621,778,138,-178]), K([9509,2046,-24728,10380])]) + sage: is_Q_curve(E, certificate=True, verbose=True) # optional - sage.rings.number_field Checking whether Elliptic Curve defined by y^2 + (a^3+a^2-4*a-3)*x*y + (a^2-2)*y = x^3 + (-a^2-a+4)*x^2 + (-178*a^3+138*a^2+778*a-621)*x + (10380*a^3-24728*a^2+2046*a+9509) over Number Field in a with defining polynomial x^4 - 5*x^2 + 3 is a Q-curve No: inconsistency at the 2 primes dividing 3 - potentially multiplicative: [True, False] @@ -142,9 +143,10 @@ def is_Q_curve(E, maxp=100, certificate=False, verbose=False): primes is consistent, but the local test at good primes above `13` is not:: - sage: K. = NumberField(R([-10, 0, 1])) - sage: E = EllipticCurve([K([0,1]),K([-1,-1]),K([0,0]),K([-236,40]),K([-1840,464])]) - sage: is_Q_curve(E, certificate=True, verbose=True) + sage: K. = NumberField(R([-10, 0, 1])) # optional - sage.rings.number_field + sage: E = EllipticCurve([K([0,1]), K([-1,-1]), K([0,0]), # optional - sage.rings.number_field + ....: K([-236,40]), K([-1840,464])]) + sage: is_Q_curve(E, certificate=True, verbose=True) # optional - sage.rings.number_field Checking whether Elliptic Curve defined by y^2 + a*x*y = x^3 + (-a-1)*x^2 + (40*a-236)*x + (464*a-1840) over Number Field in a with defining polynomial x^2 - 10 is a Q-curve Applying local tests at good primes above p<=100 No: inconsistency at the 2 ordinary primes dividing 13 @@ -156,9 +158,9 @@ def is_Q_curve(E, maxp=100, certificate=False, verbose=False): sage: from sage.schemes.elliptic_curves.Qcurves import is_Q_curve sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(R([-1, -1, 1])) - sage: E = EllipticCurve([K([1,0]),K([-1,0]),K([0,1]),K([0,-2]),K([0,1])]) - sage: is_Q_curve(E, certificate=True, verbose=True) + sage: K. = NumberField(R([-1, -1, 1])) # optional - sage.rings.number_field + sage: E = EllipticCurve([K([1,0]), K([-1,0]), K([0,1]), K([0,-2]), K([0,1])]) + sage: is_Q_curve(E, certificate=True, verbose=True) # optional - sage.rings.number_field Checking whether Elliptic Curve defined by y^2 + x*y + a*y = x^3 + (-1)*x^2 + (-2*a)*x + a over Number Field in a with defining polynomial x^2 - x - 1 is a Q-curve Yes: E is CM (discriminant -15) (True, {'CM': -15}) @@ -168,12 +170,14 @@ def is_Q_curve(E, maxp=100, certificate=False, verbose=False): in fact there is an isogenous curve with rational `j`, so we have a so-called rational `\QQ`-curve:: - sage: K. = NumberField(R([1, 0, -4, 0, 1])) - sage: E = EllipticCurve([K([-2,-4,1,1]),K([0,1,0,0]),K([0,1,0,0]),K([-4780,9170,1265,-2463]),K([163923,-316598,-43876,84852])]) - sage: flag, cert = is_Q_curve(E, certificate=True) - sage: flag + sage: K. = NumberField(R([1, 0, -4, 0, 1])) # optional - sage.rings.number_field + sage: E = EllipticCurve([K([-2,-4,1,1]), K([0,1,0,0]), K([0,1,0,0]), # optional - sage.rings.number_field + ....: K([-4780,9170,1265,-2463]), + ....: K([163923,-316598,-43876,84852])]) + sage: flag, cert = is_Q_curve(E, certificate=True) # optional - sage.rings.number_field + sage: flag # optional - sage.rings.number_field True - sage: cert + sage: cert # optional - sage.rings.number_field {'CM': 0, 'N': 1, 'core_degs': [1], 'core_poly': x - 85184/3, 'r': 0, 'rho': 0} Over the same field, a so-called strict `\QQ`-curve which is not @@ -183,11 +187,12 @@ def is_Q_curve(E, maxp=100, certificate=False, verbose=False): quadratic conjugate `j`-invariants in `\QQ(\sqrt{3})` (but which are not base-changes from the quadratic subfield):: - sage: E = EllipticCurve([K([0,-3,0,1]),K([1,4,0,-1]),K([0,0,0,0]),K([-2,-16,0,4]),K([-19,-32,4,8])]) - sage: flag, cert = is_Q_curve(E, certificate=True) - sage: flag + sage: E = EllipticCurve([K([0,-3,0,1]), K([1,4,0,-1]), K([0,0,0,0]), # optional - sage.rings.number_field + ....: K([-2,-16,0,4]), K([-19,-32,4,8])]) + sage: flag, cert = is_Q_curve(E, certificate=True) # optional - sage.rings.number_field + sage: flag # optional - sage.rings.number_field True - sage: cert + sage: cert # optional - sage.rings.number_field {'CM': 0, 'N': 2, 'core_degs': [1, 2], @@ -197,8 +202,8 @@ def is_Q_curve(E, maxp=100, certificate=False, verbose=False): TESTS:: - sage: E = EllipticCurve([GF(5)(t) for t in [2,3,5,7,11]]) - sage: is_Q_curve(E) + sage: E = EllipticCurve([GF(5)(t) for t in [2,3,5,7,11]]) # optional - sage.rings.finite_rings + sage: is_Q_curve(E) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: Elliptic Curve defined by ... must be an elliptic curve @@ -400,9 +405,9 @@ def Step4Test(E, B, oldB=0, verbose=False): - `B` (integer): upper bound on primes to test - - `oldB` (integer, default 0): lower bound on primes to test + - ``oldB`` (integer, default 0): lower bound on primes to test - - `verbose` (boolean, default ``False``): verbosity flag + - ``verbose`` (boolean, default ``False``): verbosity flag OUTPUT: @@ -426,9 +431,10 @@ def Step4Test(E, B, oldB=0, verbose=False): sage: from sage.schemes.elliptic_curves.Qcurves import Step4Test sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(R([3, 0, -5, 0, 1])) - sage: E = EllipticCurve([K([-3,-4,1,1]),K([4,-1,-1,0]),K([-2,0,1,0]),K([-621,778,138,-178]),K([9509,2046,-24728,10380])]) - sage: Step4Test(E, 100, verbose=True) + sage: K. = NumberField(R([3, 0, -5, 0, 1])) # optional - sage.rings.number_field + sage: E = EllipticCurve([K([-3,-4,1,1]), K([4,-1,-1,0]), K([-2,0,1,0]), # optional - sage.rings.number_field + ....: K([-621,778,138,-178]), K([9509,2046,-24728,10380])]) + sage: Step4Test(E, 100, verbose=True) # optional - sage.rings.number_field No: inconsistency at the 2 ordinary primes dividing 13 - Frobenius discriminants mod squares: [-3, -1] (False, 13) @@ -438,8 +444,10 @@ def Step4Test(E, B, oldB=0, verbose=False): sage: from sage.schemes.elliptic_curves.Qcurves import Step4Test sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(R([-3, 0, 9, 0, -6, 0, 1])) - sage: E = EllipticCurve([K([1,-3,0,1,0,0]),K([5,-3,-6,1,1,0]),K([1,-3,0,1,0,0]),K([-139,-129,331,277,-76,-63]),K([2466,1898,-5916,-4582,1361,1055])]) + sage: K. = NumberField(R([-3, 0, 9, 0, -6, 0, 1])) # optional - sage.rings.number_field + sage: E = EllipticCurve([K([1,-3,0,1,0,0]), K([5,-3,-6,1,1,0]), + ....: K([1,-3,0,1,0,0]), K([-139,-129,331,277,-76,-63]), + ....: K([2466,1898,-5916,-4582,1361,1055])]) sage: Step4Test(E, 100, verbose=True) (True, 0) """ @@ -487,9 +495,9 @@ def conjugacy_test(jlist, verbose=False): INPUT: - - `jlist` (list): a list of algebraic numbers in the same field + - ``jlist`` (list): a list of algebraic numbers in the same field - - `verbose` (boolean, default ``False``): verbosity flag + - ``verbose`` (boolean, default ``False``): verbosity flag OUTPUT: @@ -501,29 +509,29 @@ def conjugacy_test(jlist, verbose=False): sage: from sage.schemes.elliptic_curves.Qcurves import conjugacy_test sage: conjugacy_test([3]) [x - 3] - sage: K. = QuadraticField(2) - sage: conjugacy_test([K(3), a]) + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: conjugacy_test([K(3), a]) # optional - sage.rings.number_field [x - 3] - sage: conjugacy_test([K(3), 3+a]) + sage: conjugacy_test([K(3), 3 + a]) # optional - sage.rings.number_field [x - 3] - sage: conjugacy_test([3+a]) + sage: conjugacy_test([3 + a]) # optional - sage.rings.number_field [] - sage: conjugacy_test([3+a, 3-a]) + sage: conjugacy_test([3 + a, 3 - a]) # optional - sage.rings.number_field [x^2 - 6*x + 7] - sage: x = polygen(QQ) - sage: f = x^3-3 - sage: K. = f.splitting_field() - sage: js = f.roots(K, multiplicities=False) - sage: conjugacy_test(js) + sage: x = polygen(QQ) # optional - sage.rings.number_field + sage: f = x^3 - 3 + sage: K. = f.splitting_field() # optional - sage.rings.number_field + sage: js = f.roots(K, multiplicities=False) # optional - sage.rings.number_field + sage: conjugacy_test(js) # optional - sage.rings.number_field [] - sage: f = x^4-3 - sage: K. = NumberField(f) - sage: js = f.roots(K, multiplicities=False) - sage: conjugacy_test(js) + sage: f = x^4 - 3 # optional - sage.rings.number_field + sage: K. = NumberField(f) # optional - sage.rings.number_field + sage: js = f.roots(K, multiplicities=False) # optional - sage.rings.number_field + sage: conjugacy_test(js) # optional - sage.rings.number_field [] - sage: K. = f.splitting_field() - sage: js = f.roots(K, multiplicities=False) - sage: conjugacy_test(js) + sage: K. = f.splitting_field() # optional - sage.rings.number_field + sage: js = f.roots(K, multiplicities=False) # optional - sage.rings.number_field + sage: conjugacy_test(js) # optional - sage.rings.number_field [x^4 - 3] """ from sage.sets.set import Set diff --git a/src/sage/schemes/elliptic_curves/cardinality.py b/src/sage/schemes/elliptic_curves/cardinality.py index 345b0e761d4..2a73de71a50 100644 --- a/src/sage/schemes/elliptic_curves/cardinality.py +++ b/src/sage/schemes/elliptic_curves/cardinality.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings """ Specific algorithms to compute cardinality of elliptic curves over a finite field @@ -39,19 +40,22 @@ def _cardinality_with_j_invariant_1728(self): An example with q=p=1 (mod 4):: sage: F = GF(10009) - sage: [_cardinality_with_j_invariant_1728(EllipticCurve(F,[0,0,0,11^i,0])) for i in range(4)] + sage: [_cardinality_with_j_invariant_1728(EllipticCurve(F, [0,0,0,11^i,0])) + ....: for i in range(4)] [10016, 10210, 10004, 9810] An example with q=p=3 (mod 4):: sage: F = GF(10007) - sage: [_cardinality_with_j_invariant_1728(EllipticCurve(F,[0,0,0,5^i,0])) for i in range(4)] + sage: [_cardinality_with_j_invariant_1728(EllipticCurve(F, [0,0,0,5^i,0])) + ....: for i in range(4)] [10008, 10008, 10008, 10008] An example with `q=p^2`, p=3 (mod 4):: sage: F. = GF(10007^2,'a') - sage: [_cardinality_with_j_invariant_1728(EllipticCurve(F,[0,0,0,a^i,0])) for i in range(4)] + sage: [_cardinality_with_j_invariant_1728(EllipticCurve(F,[0,0,0,a^i,0])) + ....: for i in range(4)] [100160064, 100140050, 100120036, 100140050] Examples with `q=2^d`, d odd (3 isomorphism classes):: @@ -68,8 +72,9 @@ def _cardinality_with_j_invariant_1728(self): sage: F. = GF(2**16,'a') sage: b = a^11 # trace 1 - sage: ais = [[0,0,1,0,0],[0,0,1,0,b],[0,0,1,b,0],[0,0,a,0,0],[0,0,a,0,a^2*b],[0,0,a^2,0,0],[0,0,a^2,0,a^4*b]] - sage: curves = [EllipticCurve(F,ai) for ai in ais] + sage: ais = [[0,0,1,0,0], [0,0,1,0,b], [0,0,1,b,0], [0,0,a,0,0], + ....: [0,0,a,0,a^2*b], [0,0,a^2,0,0], [0,0,a^2,0,a^4*b]] + sage: curves = [EllipticCurve(F, ai) for ai in ais] sage: all((e1 == e2 or not e1.is_isomorphic(e2)) for e1 in curves for e2 in curves) True sage: [_cardinality_with_j_invariant_1728(e) for e in curves] @@ -79,8 +84,8 @@ def _cardinality_with_j_invariant_1728(self): sage: F. = GF(3**15,'a') sage: b = a^7 # has trace 1 - sage: ais = [[0,0,0,1,0],[0,0,0,-1,0],[0,0,0,-1,b],[0,0,0,-1,-b]] - sage: curves = [EllipticCurve(F,ai) for ai in ais] + sage: ais = [[0,0,0,1,0], [0,0,0,-1,0], [0,0,0,-1,b], [0,0,0,-1,-b]] + sage: curves = [EllipticCurve(F, ai) for ai in ais] sage: all((e1 == e2 or not e1.is_isomorphic(e2)) for e1 in curves for e2 in curves) True sage: [_cardinality_with_j_invariant_1728(e) for e in curves] @@ -91,8 +96,9 @@ def _cardinality_with_j_invariant_1728(self): sage: F. = GF(3^18,'g') sage: i = F(-1).sqrt() sage: a = g^8 # has trace 1 - sage: ais = [[0,0,0,1,0],[0,0,0,1,i*a],[0,0,0,g,0],[0,0,0,g^3,0],[0,0,0,g^2,0], [0,0,0,g^2,i*a*g^3]] - sage: curves = [EllipticCurve(F,ai) for ai in ais] + sage: ais = [[0,0,0,1,0], [0,0,0,1,i*a], [0,0,0,g,0], + ....: [0,0,0,g^3,0], [0,0,0,g^2,0], [0,0,0,g^2,i*a*g^3]] + sage: curves = [EllipticCurve(F, ai) for ai in ais] sage: all((e1 == e2 or not e1.is_isomorphic(e2)) for e1 in curves for e2 in curves) True sage: [_cardinality_with_j_invariant_1728(e) for e in curves] @@ -374,10 +380,10 @@ def cardinality_exhaustive(self): EXAMPLES:: sage: p = next_prime(10^3) - sage: E = EllipticCurve(GF(p),[3,4]) + sage: E = EllipticCurve(GF(p), [3,4]) sage: E.cardinality_exhaustive() 1020 - sage: E = EllipticCurve(GF(3^4,'a'),[1,1]) + sage: E = EllipticCurve(GF(3^4,'a'), [1,1]) sage: E.cardinality_exhaustive() 64 """ @@ -405,10 +411,10 @@ def cardinality_bsgs(self, verbose=False): EXAMPLES:: sage: p = next_prime(10^3) - sage: E = EllipticCurve(GF(p),[3,4]) + sage: E = EllipticCurve(GF(p), [3,4]) sage: E.cardinality_bsgs() 1020 - sage: E = EllipticCurve(GF(3^4,'a'),[1,1]) + sage: E = EllipticCurve(GF(3^4,'a'), [1,1]) sage: E.cardinality_bsgs() 64 sage: F. = GF(101^3,'a') @@ -543,7 +549,8 @@ def _cardinality_subfield(self, jpol): sage: from sage.schemes.elliptic_curves.cardinality import _cardinality_subfield sage: k. = GF(7^5) sage: E = EllipticCurve(k, [1,2,3,4,5]); E - Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Finite Field in a of size 7^5 + Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 + over Finite Field in a of size 7^5 sage: _cardinality_subfield(E, E.j_invariant().minimal_polynomial()) 17019 diff --git a/src/sage/schemes/elliptic_curves/cm.py b/src/sage/schemes/elliptic_curves/cm.py index 94b922a0365..ad65c21fe48 100644 --- a/src/sage/schemes/elliptic_curves/cm.py +++ b/src/sage/schemes/elliptic_curves/cm.py @@ -342,28 +342,29 @@ def cm_j_invariants(K, proof=None): EXAMPLES:: sage: cm_j_invariants(QQ) - [-262537412640768000, -147197952000, -884736000, -12288000, -884736, -32768, -3375, 0, 1728, 8000, 54000, 287496, 16581375] + [-262537412640768000, -147197952000, -884736000, -12288000, -884736, + -32768, -3375, 0, 1728, 8000, 54000, 287496, 16581375] Over imaginary quadratic fields there are no more than over `QQ`:: - sage: cm_j_invariants(QuadraticField(-1, 'i')) - [-262537412640768000, -147197952000, -884736000, -12288000, -884736, -32768, -3375, 0, 1728, 8000, 54000, 287496, 16581375] + sage: cm_j_invariants(QuadraticField(-1, 'i')) # optional - sage.rings.number_field + [-262537412640768000, -147197952000, -884736000, -12288000, -884736, + -32768, -3375, 0, 1728, 8000, 54000, 287496, 16581375] Over real quadratic fields there may be more, for example:: - sage: len(cm_j_invariants(QuadraticField(5, 'a'))) + sage: len(cm_j_invariants(QuadraticField(5, 'a'))) # optional - sage.rings.number_field 31 Over number fields K of many higher degrees this also works:: - sage: K. = NumberField(x^3 - 2) - sage: cm_j_invariants(K) - [-262537412640768000, -147197952000, -884736000, - -884736, -32768, 8000, -3375, 16581375, 1728, 287496, 0, - 54000, -12288000, + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: cm_j_invariants(K) # optional - sage.rings.number_field + [-262537412640768000, -147197952000, -884736000, -884736, -32768, + 8000, -3375, 16581375, 1728, 287496, 0, 54000, -12288000, 31710790944000*a^2 + 39953093016000*a + 50337742902000] - sage: K. = NumberField(x^4 - 2) - sage: len(cm_j_invariants(K)) + sage: K. = NumberField(x^4 - 2) # optional - sage.rings.number_field + sage: len(cm_j_invariants(K)) # optional - sage.rings.number_field 23 """ return sorted(j for D, f, j in cm_j_invariants_and_orders(K, proof=proof)) @@ -388,11 +389,14 @@ def cm_j_invariants_and_orders(K, proof=None): EXAMPLES:: sage: cm_j_invariants_and_orders(QQ) - [(-3, 3, -12288000), (-3, 2, 54000), (-3, 1, 0), (-4, 2, 287496), (-4, 1, 1728), (-7, 2, 16581375), (-7, 1, -3375), (-8, 1, 8000), (-11, 1, -32768), (-19, 1, -884736), (-43, 1, -884736000), (-67, 1, -147197952000), (-163, 1, -262537412640768000)] + [(-3, 3, -12288000), (-3, 2, 54000), (-3, 1, 0), (-4, 2, 287496), (-4, 1, 1728), + (-7, 2, 16581375), (-7, 1, -3375), (-8, 1, 8000), (-11, 1, -32768), + (-19, 1, -884736), (-43, 1, -884736000), (-67, 1, -147197952000), + (-163, 1, -262537412640768000)] Over an imaginary quadratic field there are no more than over `QQ`:: - sage: cm_j_invariants_and_orders(QuadraticField(-1, 'i')) + sage: cm_j_invariants_and_orders(QuadraticField(-1, 'i')) # optional - sage.rings.number_field [(-163, 1, -262537412640768000), (-67, 1, -147197952000), (-43, 1, -884736000), (-19, 1, -884736), (-11, 1, -32768), (-8, 1, 8000), (-7, 1, -3375), (-7, 2, 16581375), (-4, 1, 1728), @@ -400,17 +404,17 @@ def cm_j_invariants_and_orders(K, proof=None): Over real quadratic fields there may be more:: - sage: v = cm_j_invariants_and_orders(QuadraticField(5,'a')); len(v) + sage: v = cm_j_invariants_and_orders(QuadraticField(5,'a')); len(v) # optional - sage.rings.number_field 31 - sage: [(D, f) for D, f, j in v if j not in QQ] + sage: [(D, f) for D, f, j in v if j not in QQ] # optional - sage.rings.number_field [(-235, 1), (-235, 1), (-115, 1), (-115, 1), (-40, 1), (-40, 1), (-35, 1), (-35, 1), (-20, 1), (-20, 1), (-15, 1), (-15, 1), (-15, 2), (-15, 2), (-4, 5), (-4, 5), (-3, 5), (-3, 5)] Over number fields K of many higher degrees this also works:: - sage: K. = NumberField(x^3 - 2) - sage: cm_j_invariants_and_orders(K) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: cm_j_invariants_and_orders(K) # optional - sage.rings.number_field [(-163, 1, -262537412640768000), (-67, 1, -147197952000), (-43, 1, -884736000), (-19, 1, -884736), (-11, 1, -32768), (-8, 1, 8000), (-7, 1, -3375), (-7, 2, 16581375), (-4, 1, 1728), @@ -466,11 +470,15 @@ def cm_orders(h, proof=None): sage: cm_orders(0) [] sage: v = cm_orders(1); v - [(-3, 1), (-3, 2), (-3, 3), (-4, 1), (-4, 2), (-7, 1), (-7, 2), (-8, 1), (-11, 1), (-19, 1), (-43, 1), (-67, 1), (-163, 1)] + [(-3, 1), (-3, 2), (-3, 3), (-4, 1), (-4, 2), (-7, 1), (-7, 2), (-8, 1), + (-11, 1), (-19, 1), (-43, 1), (-67, 1), (-163, 1)] sage: type(v[0][0]), type(v[0][1]) (<... 'sage.rings.integer.Integer'>, <... 'sage.rings.integer.Integer'>) sage: v = cm_orders(2); v - [(-3, 4), (-3, 5), (-3, 7), (-4, 3), (-4, 4), (-4, 5), (-7, 4), (-8, 2), (-8, 3), (-11, 3), (-15, 1), (-15, 2), (-20, 1), (-24, 1), (-35, 1), (-40, 1), (-51, 1), (-52, 1), (-88, 1), (-91, 1), (-115, 1), (-123, 1), (-148, 1), (-187, 1), (-232, 1), (-235, 1), (-267, 1), (-403, 1), (-427, 1)] + [(-3, 4), (-3, 5), (-3, 7), (-4, 3), (-4, 4), (-4, 5), (-7, 4), (-8, 2), + (-8, 3), (-11, 3), (-15, 1), (-15, 2), (-20, 1), (-24, 1), (-35, 1), + (-40, 1), (-51, 1), (-52, 1), (-88, 1), (-91, 1), (-115, 1), (-123, 1), + (-148, 1), (-187, 1), (-232, 1), (-235, 1), (-267, 1), (-403, 1), (-427, 1)] sage: len(v) 29 sage: set([hilbert_class_polynomial(D*f^2).degree() for D,f in v]) @@ -479,7 +487,10 @@ def cm_orders(h, proof=None): Any degree up to 100 is implemented, but may be slow:: sage: cm_orders(3) - [(-3, 6), (-3, 9), (-11, 2), (-19, 2), (-23, 1), (-23, 2), (-31, 1), (-31, 2), (-43, 2), (-59, 1), (-67, 2), (-83, 1), (-107, 1), (-139, 1), (-163, 2), (-211, 1), (-283, 1), (-307, 1), (-331, 1), (-379, 1), (-499, 1), (-547, 1), (-643, 1), (-883, 1), (-907, 1)] + [(-3, 6), (-3, 9), (-11, 2), (-19, 2), (-23, 1), (-23, 2), (-31, 1), (-31, 2), + (-43, 2), (-59, 1), (-67, 2), (-83, 1), (-107, 1), (-139, 1), (-163, 2), + (-211, 1), (-283, 1), (-307, 1), (-331, 1), (-379, 1), (-499, 1), (-547, 1), + (-643, 1), (-883, 1), (-907, 1)] sage: len(cm_orders(4)) 84 """ @@ -722,16 +733,24 @@ def discriminants_with_bounded_class_number(hmax, B=None, proof=None): EXAMPLES:: - sage: v = sage.schemes.elliptic_curves.cm.discriminants_with_bounded_class_number(3) + sage: from sage.schemes.elliptic_curves.cm import discriminants_with_bounded_class_number + sage: v = discriminants_with_bounded_class_number(3) sage: sorted(v) [1, 2, 3] sage: v[1] - [(-3, 1), (-3, 2), (-3, 3), (-4, 1), (-4, 2), (-7, 1), (-7, 2), (-8, 1), (-11, 1), (-19, 1), (-43, 1), (-67, 1), (-163, 1)] + [(-3, 1), (-3, 2), (-3, 3), (-4, 1), (-4, 2), (-7, 1), (-7, 2), (-8, 1), + (-11, 1), (-19, 1), (-43, 1), (-67, 1), (-163, 1)] sage: v[2] - [(-3, 4), (-3, 5), (-3, 7), (-4, 3), (-4, 4), (-4, 5), (-7, 4), (-8, 2), (-8, 3), (-11, 3), (-15, 1), (-15, 2), (-20, 1), (-24, 1), (-35, 1), (-40, 1), (-51, 1), (-52, 1), (-88, 1), (-91, 1), (-115, 1), (-123, 1), (-148, 1), (-187, 1), (-232, 1), (-235, 1), (-267, 1), (-403, 1), (-427, 1)] + [(-3, 4), (-3, 5), (-3, 7), (-4, 3), (-4, 4), (-4, 5), (-7, 4), (-8, 2), + (-8, 3), (-11, 3), (-15, 1), (-15, 2), (-20, 1), (-24, 1), (-35, 1), (-40, 1), + (-51, 1), (-52, 1), (-88, 1), (-91, 1), (-115, 1), (-123, 1), (-148, 1), + (-187, 1), (-232, 1), (-235, 1), (-267, 1), (-403, 1), (-427, 1)] sage: v[3] - [(-3, 6), (-3, 9), (-11, 2), (-19, 2), (-23, 1), (-23, 2), (-31, 1), (-31, 2), (-43, 2), (-59, 1), (-67, 2), (-83, 1), (-107, 1), (-139, 1), (-163, 2), (-211, 1), (-283, 1), (-307, 1), (-331, 1), (-379, 1), (-499, 1), (-547, 1), (-643, 1), (-883, 1), (-907, 1)] - sage: v = sage.schemes.elliptic_curves.cm.discriminants_with_bounded_class_number(8, proof=False) + [(-3, 6), (-3, 9), (-11, 2), (-19, 2), (-23, 1), (-23, 2), (-31, 1), (-31, 2), + (-43, 2), (-59, 1), (-67, 2), (-83, 1), (-107, 1), (-139, 1), (-163, 2), + (-211, 1), (-283, 1), (-307, 1), (-331, 1), (-379, 1), (-499, 1), (-547, 1), + (-643, 1), (-883, 1), (-907, 1)] + sage: v = discriminants_with_bounded_class_number(8, proof=False) sage: sorted(len(v[h]) for h in v) [13, 25, 29, 29, 38, 84, 101, 208] @@ -896,11 +915,11 @@ def is_cm_j_invariant(j, algorithm='CremonaSutherland', method=None): sage: is_cm_j_invariant(8000) (True, (-8, 1)) - sage: K. = QuadraticField(5) - sage: is_cm_j_invariant(282880*a + 632000) + sage: K. = QuadraticField(5) # optional - sage.rings.number_field + sage: is_cm_j_invariant(282880*a + 632000) # optional - sage.rings.number_field (True, (-20, 1)) - sage: K. = NumberField(x^3 - 2) - sage: is_cm_j_invariant(31710790944000*a^2 + 39953093016000*a + 50337742902000) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: is_cm_j_invariant(31710790944000*a^2 + 39953093016000*a + 50337742902000) # optional - sage.rings.number_field (True, (-3, 6)) An example of large degree. This is only possible using the default algorithm:: diff --git a/src/sage/schemes/elliptic_curves/constructor.py b/src/sage/schemes/elliptic_curves/constructor.py index fc8bd096142..ac934a14d89 100644 --- a/src/sage/schemes/elliptic_curves/constructor.py +++ b/src/sage/schemes/elliptic_curves/constructor.py @@ -113,9 +113,9 @@ class EllipticCurveFactory(UniqueFactory): We create curves over a finite field as follows:: - sage: EllipticCurve([GF(5)(0),0,1,-1,0]) + sage: EllipticCurve([GF(5)(0),0,1,-1,0]) # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5 - sage: EllipticCurve(GF(5), [0, 0,1,-1,0]) + sage: EllipticCurve(GF(5), [0, 0,1,-1,0]) # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5 Elliptic curves over `\ZZ/N\ZZ` with `N` prime are of type @@ -146,7 +146,8 @@ class EllipticCurveFactory(UniqueFactory): sage: E = EllipticCurve(CC, [0,0,1,-1,0]) sage: E - Elliptic Curve defined by y^2 + 1.00000000000000*y = x^3 + (-1.00000000000000)*x over Complex Field with 53 bits of precision + Elliptic Curve defined by y^2 + 1.00000000000000*y = x^3 + (-1.00000000000000)*x + over Complex Field with 53 bits of precision sage: E.j_invariant() 2988.97297297297 @@ -156,14 +157,14 @@ class EllipticCurveFactory(UniqueFactory): sage: EllipticCurve(y^2 + y - ( x^3 + x - 9 )) Elliptic Curve defined by y^2 + y = x^3 + x - 9 over Rational Field - sage: R. = GF(5)[] - sage: EllipticCurve(x^3 + x^2 + 2 - y^2 - y*x) + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: EllipticCurve(x^3 + x^2 + 2 - y^2 - y*x) # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 2 over Finite Field of size 5 We can also create elliptic curves by giving a smooth plane cubic with a rational point:: sage: R3. = PolynomialRing(QQ,3) - sage: F = x^3+y^3+30*z^3 + sage: F = x^3 + y^3 + 30*z^3 sage: P = [1,-1,0] sage: EllipticCurve(F,P) Elliptic Curve defined by y^2 - 270*y = x^3 - 24300 over Rational Field @@ -175,13 +176,13 @@ class EllipticCurveFactory(UniqueFactory): 1728 '32a2' - sage: E = EllipticCurve(j=GF(5)(2)); E; E.j_invariant() + sage: E = EllipticCurve(j=GF(5)(2)); E; E.j_invariant() # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5 2 See :trac:`6657` :: - sage: EllipticCurve(GF(144169),j=1728) + sage: EllipticCurve(GF(144169), j=1728) # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 144169 Elliptic curves over the same ring with the same Weierstrass @@ -215,7 +216,7 @@ class EllipticCurveFactory(UniqueFactory): since both `j` and `j-1728` have to be factored to compute the minimal twist (see :trac:`13100`):: - sage: E = EllipticCurve_from_j(2^256+1,minimal_twist=False) + sage: E = EllipticCurve_from_j(2^256+1, minimal_twist=False) sage: E.j_invariant() == 2^256+1 True @@ -228,66 +229,70 @@ class EllipticCurveFactory(UniqueFactory): We create a curve and a point over ``QQbar`` (see :trac:`6879`):: - sage: E = EllipticCurve(QQbar,[0,1]) - sage: E(0) + sage: E = EllipticCurve(QQbar, [0,1]) # optional - sage.rings.number_field + sage: E(0) # optional - sage.rings.number_field (0 : 1 : 0) - sage: E.base_field() + sage: E.base_field() # optional - sage.rings.number_field Algebraic Field - sage: E = EllipticCurve(RR,[1,2]); E; E.base_field() - Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000 over Real Field with 53 bits of precision + sage: E = EllipticCurve(RR, [1,2]); E; E.base_field() + Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000 + over Real Field with 53 bits of precision Real Field with 53 bits of precision - sage: EllipticCurve(CC,[3,4]); E; E.base_field() - Elliptic Curve defined by y^2 = x^3 + 3.00000000000000*x + 4.00000000000000 over Complex Field with 53 bits of precision - Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000 over Real Field with 53 bits of precision - Real Field with 53 bits of precision - sage: E = EllipticCurve(QQbar,[5,6]); E; E.base_field() + sage: E = EllipticCurve(CC,[3,4]); E; E.base_field() + Elliptic Curve defined by y^2 = x^3 + 3.00000000000000*x + 4.00000000000000 + over Complex Field with 53 bits of precision + Complex Field with 53 bits of precision + sage: E = EllipticCurve(QQbar, [5,6]); E; E.base_field() # optional - sage.rings.number_field Elliptic Curve defined by y^2 = x^3 + 5*x + 6 over Algebraic Field Algebraic Field See :trac:`6657` :: - sage: EllipticCurve(3,j=1728) + sage: EllipticCurve(3, j=1728) Traceback (most recent call last): ... ValueError: First parameter (if present) must be a ring when j is specified - sage: EllipticCurve(GF(5),j=3/5) + sage: EllipticCurve(GF(5), j=3/5) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: First parameter must be a ring containing 3/5 If the universe of the coefficients is a general field, the object - constructed has type EllipticCurve_field. Otherwise it is - EllipticCurve_generic. See :trac:`9816` :: + constructed has type :class:`EllipticCurve_field`. Otherwise it is + :class:`EllipticCurve_generic`. See :trac:`9816` :: - sage: E = EllipticCurve([QQbar(1),3]); E + sage: E = EllipticCurve([QQbar(1), 3]); E # optional - sage.rings.number_field Elliptic Curve defined by y^2 = x^3 + x + 3 over Algebraic Field - sage: type(E) + sage: type(E) # optional - sage.rings.number_field - sage: E = EllipticCurve([RR(1),3]); E - Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 3.00000000000000 over Real Field with 53 bits of precision + sage: E = EllipticCurve([RR(1), 3]); E + Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 3.00000000000000 + over Real Field with 53 bits of precision sage: type(E) - sage: E = EllipticCurve([SR(i),i]); E + sage: E = EllipticCurve([SR(i),i]); E # optional - sage.symbolic Elliptic Curve defined by y^2 = x^3 + I*x + I over Symbolic Ring - sage: type(E) + sage: type(E) # optional - sage.symbolic - sage: E.category() + sage: E.category() # optional - sage.symbolic Category of schemes over Symbolic Ring - sage: SR in Fields() + sage: SR in Fields() # optional - sage.symbolic True sage: F = FractionField(PolynomialRing(QQ,'t')) sage: t = F.gen() sage: E = EllipticCurve([t,0]); E - Elliptic Curve defined by y^2 = x^3 + t*x over Fraction Field of Univariate Polynomial Ring in t over Rational Field + Elliptic Curve defined by y^2 = x^3 + t*x + over Fraction Field of Univariate Polynomial Ring in t over Rational Field sage: type(E) sage: E.category() - Category of schemes over Fraction Field of Univariate Polynomial Ring in t over Rational Field + Category of schemes over + Fraction Field of Univariate Polynomial Ring in t over Rational Field See :trac:`12517`:: @@ -306,9 +311,7 @@ def create_key_and_extra_args(self, x=None, y=None, j=None, minimal_twist=True, """ Return a ``UniqueFactory`` key and possibly extra parameters. - INPUT: - - See the documentation for :class:`EllipticCurveFactory`. + INPUT: See the documentation for :class:`EllipticCurveFactory`. OUTPUT: @@ -456,8 +459,8 @@ def create_object(self, version, key, **kwds): EXAMPLES:: - sage: E = EllipticCurve.create_object(0, (GF(3), (1, 2, 0, 1, 2))) - sage: type(E) + sage: E = EllipticCurve.create_object(0, (GF(3), (1, 2, 0, 1, 2))) # optional - sage.rings.finite_rings + sage: type(E) # optional - sage.rings.finite_rings .. NOTE:: @@ -500,9 +503,7 @@ def EllipticCurve_from_Weierstrass_polynomial(f): - ``f`` -- a inhomogeneous cubic polynomial in long Weierstrass form. - OUTPUT: - - The elliptic curve defined by it. + OUTPUT: The elliptic curve defined by it. EXAMPLES:: @@ -655,7 +656,7 @@ def EllipticCurve_from_j(j, minimal_twist=True): `j-1728` the following example would take a long time without setting ``minimal_twist`` to False:: - sage: E = EllipticCurve_from_j(2^256+1,minimal_twist=False) + sage: E = EllipticCurve_from_j(2^256+1, minimal_twist=False) sage: E.j_invariant() == 2^256+1 True """ @@ -667,9 +668,7 @@ def coefficients_from_j(j, minimal_twist=True): Return Weierstrass coefficients `(a_1, a_2, a_3, a_4, a_6)` for an elliptic curve with given `j`-invariant. - INPUT: - - See :func:`EllipticCurve_from_j`. + INPUT: See :func:`EllipticCurve_from_j`. EXAMPLES:: @@ -819,7 +818,7 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): with Cremona label 27a1:: sage: R. = QQ[] - sage: cubic = x^3+y^3+z^3 + sage: cubic = x^3 + y^3 + z^3 sage: P = [1,-1,0] sage: E = EllipticCurve_from_cubic(cubic, P, morphism=False); E Elliptic Curve defined by y^2 - 9*y = x^3 - 27 over Rational Field @@ -834,7 +833,7 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): Selmer curve:: sage: R. = QQ[] - sage: cubic = a^3+b^3+60*c^3 + sage: cubic = a^3 + b^3 + 60*c^3 sage: P = [1,-1,0] sage: E = EllipticCurve_from_cubic(cubic, P, morphism=False); E Elliptic Curve defined by y^2 - 540*y = x^3 - 97200 over Rational Field @@ -865,8 +864,8 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): Scheme morphism: From: Elliptic Curve defined by y^2 + 2*x*y + 20*y = x^3 - x^2 - 20*x - 400/3 over Rational Field - To: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - a^3 + b^3 + 60*c^3 + To: Closed subscheme of Projective Space of dimension 2 over Rational Field + defined by: a^3 + b^3 + 60*c^3 Defn: Defined on coordinates by sending (x : y : z) to (x + y + 20*z : -x - y : -x) @@ -897,10 +896,19 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): sage: cubic = x^2*y + 4*x*y^2 + x^2*z + 8*x*y*z + 4*y^2*z + 9*x*z^2 + 9*y*z^2 sage: f = EllipticCurve_from_cubic(cubic, [1,-1,1], morphism=True); f Scheme morphism: - From: Projective Plane Curve over Rational Field defined by x^2*y + 4*x*y^2 + x^2*z + 8*x*y*z + 4*y^2*z + 9*x*z^2 + 9*y*z^2 - To: Elliptic Curve defined by y^2 + 7560/19*x*y + 552960000000/2352637*y = x^3 - 3445200/133*x^2 over Rational Field + From: Projective Plane Curve over Rational Field defined + by x^2*y + 4*x*y^2 + x^2*z + 8*x*y*z + 4*y^2*z + 9*x*z^2 + 9*y*z^2 + To: Elliptic Curve defined + by y^2 + 7560/19*x*y + 552960000000/2352637*y = x^3 - 3445200/133*x^2 + over Rational Field Defn: Defined on coordinates by sending (x : y : z) to - (2527/17280*x^2 + 133/2160*x*y + 133/108000*y^2 + 133/2880*x*z + 931/18000*y*z - 3857/48000*z^2 : -6859/288*x^2 + 323/36*x*y + 359/1800*y^2 + 551/48*x*z + 2813/300*y*z + 24389/800*z^2 : -2352637/99532800000*x^2 - 2352637/124416000000*x*y - 2352637/622080000000*y^2 + 2352637/82944000000*x*z + 2352637/207360000000*y*z - 2352637/276480000000*z^2) + (2527/17280*x^2 + 133/2160*x*y + 133/108000*y^2 + 133/2880*x*z + + 931/18000*y*z - 3857/48000*z^2 + : -6859/288*x^2 + 323/36*x*y + 359/1800*y^2 + 551/48*x*z + + 2813/300*y*z + 24389/800*z^2 + : -2352637/99532800000*x^2 - 2352637/124416000000*x*y + - 2352637/622080000000*y^2 + 2352637/82944000000*x*z + + 2352637/207360000000*y*z - 2352637/276480000000*z^2) Note that the morphism returned cannot be evaluated directly at the given point ``P=(1:-1:1)`` since the polynomials defining it @@ -951,7 +959,7 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): Weierstrass model:: sage: R. = QQ[] - sage: cubic = a^3+7*b^3+64*c^3 + sage: cubic = a^3 + 7*b^3 + 64*c^3 sage: P = [2,2,-1] sage: f = EllipticCurve_from_cubic(cubic, P, morphism=True) sage: E = f.codomain(); E @@ -989,7 +997,7 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): and one will be used as a base point:: sage: R. = QQ[] - sage: cubic = x^3+y^3+z^3 + sage: cubic = x^3 + y^3 + z^3 sage: f = EllipticCurve_from_cubic(cubic, morphism=True) sage: f Scheme morphism: @@ -1001,7 +1009,7 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): An error will be raised if no point is given and there are no rational flexes:: sage: R. = QQ[] - sage: cubic = 3*x^3+4*y^3+5*z^3 + sage: cubic = 3*x^3 + 4*y^3 + 5*z^3 sage: EllipticCurve_from_cubic(cubic) Traceback (most recent call last): ... @@ -1009,47 +1017,58 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): An example over a finite field, using a flex:: - sage: K = GF(17) - sage: R. = K[] - sage: cubic = 2*x^3+3*y^3+4*z^3 - sage: EllipticCurve_from_cubic(cubic,[0,3,1]) + sage: K = GF(17) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: cubic = 2*x^3 + 3*y^3 + 4*z^3 # optional - sage.rings.finite_rings + sage: EllipticCurve_from_cubic(cubic, [0,3,1]) # optional - sage.rings.finite_rings Scheme morphism: - From: Projective Plane Curve over Finite Field of size 17 defined by 2*x^3 + 3*y^3 + 4*z^3 + From: Projective Plane Curve over Finite Field of size 17 + defined by 2*x^3 + 3*y^3 + 4*z^3 To: Elliptic Curve defined by y^2 + 16*y = x^3 + 11 over Finite Field of size 17 Defn: Defined on coordinates by sending (x : y : z) to (-x : 4*y : 4*y + 5*z) An example in characteristic 3:: - sage: K = GF(3) - sage: R. = K[] - sage: cubic = x^3+y^3+z^3+x*y*z - sage: EllipticCurve_from_cubic(cubic,[0,1,-1]) + sage: K = GF(3) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: cubic = x^3 + y^3 + z^3 + x*y*z # optional - sage.rings.finite_rings + sage: EllipticCurve_from_cubic(cubic, [0,1,-1]) # optional - sage.rings.finite_rings Scheme morphism: - From: Projective Plane Curve over Finite Field of size 3 defined by x^3 + y^3 + x*y*z + z^3 + From: Projective Plane Curve over Finite Field of size 3 + defined by x^3 + y^3 + x*y*z + z^3 To: Elliptic Curve defined by y^2 + x*y = x^3 + 1 over Finite Field of size 3 Defn: Defined on coordinates by sending (x : y : z) to (y + z : -y : x) An example over a number field, using a non-flex and where there are no rational flexes:: - sage: K. = QuadraticField(-3) - sage: R. = K[] - sage: cubic = 2*x^3+3*y^3+5*z^3 - sage: EllipticCurve_from_cubic(cubic,[1,1,-1]) + sage: K. = QuadraticField(-3) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: cubic = 2*x^3 + 3*y^3 + 5*z^3 # optional - sage.rings.number_field + sage: EllipticCurve_from_cubic(cubic, [1,1,-1]) # optional - sage.rings.number_field Scheme morphism: - From: Projective Plane Curve over Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I defined by 2*x^3 + 3*y^3 + 5*z^3 - To: Elliptic Curve defined by y^2 + 1754460/2053*x*y + 5226454388736000/8653002877*y = x^3 + (-652253285700/4214809)*x^2 over Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I + From: Projective Plane Curve over Number Field in a + with defining polynomial x^2 + 3 with a = 1.732050807568878?*I + defined by 2*x^3 + 3*y^3 + 5*z^3 + To: Elliptic Curve defined by + y^2 + 1754460/2053*x*y + 5226454388736000/8653002877*y + = x^3 + (-652253285700/4214809)*x^2 + over Number Field in a with defining polynomial x^2 + 3 + with a = 1.732050807568878?*I Defn: Defined on coordinates by sending (x : y : z) to - (-16424/127575*x^2 - 231989/680400*x*y - 14371/64800*y^2 - 26689/81648*x*z - 10265/27216*y*z - 2053/163296*z^2 : 24496/315*x^2 + 119243/840*x*y + 4837/80*y^2 + 67259/504*x*z + 25507/168*y*z + 5135/1008*z^2 : 8653002877/2099914709760000*x^2 + 8653002877/699971569920000*x*y + 8653002877/933295426560000*y^2 + 8653002877/419982941952000*x*z + 8653002877/279988627968000*y*z + 8653002877/335986353561600*z^2) + (-16424/127575*x^2 - 231989/680400*x*y - 14371/64800*y^2 - 26689/81648*x*z - 10265/27216*y*z - 2053/163296*z^2 + : 24496/315*x^2 + 119243/840*x*y + 4837/80*y^2 + 67259/504*x*z + 25507/168*y*z + 5135/1008*z^2 + : 8653002877/2099914709760000*x^2 + 8653002877/699971569920000*x*y + 8653002877/933295426560000*y^2 + 8653002877/419982941952000*x*z + 8653002877/279988627968000*y*z + 8653002877/335986353561600*z^2) An example over a function field, using a non-flex:: sage: K. = FunctionField(QQ) sage: R. = K[] - sage: cubic = x^3+t*y^3+(1+t)*z^3 - sage: EllipticCurve_from_cubic(cubic,[1,1,-1], morphism=False) - Elliptic Curve defined by y^2 + ((162*t^6+486*t^5+810*t^4+810*t^3+486*t^2+162*t)/(t^6+12*t^5-3*t^4-20*t^3-3*t^2+12*t+1))*x*y + ((314928*t^14+4094064*t^13+23462136*t^12+78102144*t^11+167561379*t^10+243026001*t^9+243026001*t^8+167561379*t^7+78102144*t^6+23462136*t^5+4094064*t^4+314928*t^3)/(t^14+40*t^13+577*t^12+3524*t^11+8075*t^10+5288*t^9-8661*t^8-17688*t^7-8661*t^6+5288*t^5+8075*t^4+3524*t^3+577*t^2+40*t+1))*y = x^3 + ((2187*t^12+13122*t^11-17496*t^10-207765*t^9-516132*t^8-673596*t^7-516132*t^6-207765*t^5-17496*t^4+13122*t^3+2187*t^2)/(t^12+24*t^11+138*t^10-112*t^9-477*t^8+72*t^7+708*t^6+72*t^5-477*t^4-112*t^3+138*t^2+24*t+1))*x^2 over Rational function field in t over Rational Field + sage: cubic = x^3 + t*y^3 + (1+t)*z^3 + sage: EllipticCurve_from_cubic(cubic, [1,1,-1], morphism=False) + Elliptic Curve defined by y^2 + ((162*t^6+486*t^5+810*t^4+810*t^3+486*t^2+162*t)/(t^6+12*t^5-3*t^4-20*t^3-3*t^2+12*t+1))*x*y + ((314928*t^14+4094064*t^13+23462136*t^12+78102144*t^11+167561379*t^10+243026001*t^9+243026001*t^8+167561379*t^7+78102144*t^6+23462136*t^5+4094064*t^4+314928*t^3)/(t^14+40*t^13+577*t^12+3524*t^11+8075*t^10+5288*t^9-8661*t^8-17688*t^7-8661*t^6+5288*t^5+8075*t^4+3524*t^3+577*t^2+40*t+1))*y = x^3 + ((2187*t^12+13122*t^11-17496*t^10-207765*t^9-516132*t^8-673596*t^7-516132*t^6-207765*t^5-17496*t^4+13122*t^3+2187*t^2)/(t^12+24*t^11+138*t^10-112*t^9-477*t^8+72*t^7+708*t^6+72*t^5-477*t^4-112*t^3+138*t^2+24*t+1))*x^2 + over Rational function field in t over Rational Field TESTS: @@ -1059,8 +1078,10 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): sage: cubic = -3*x^2*y + 3*x*y^2 + 4*x^2*z + 4*y^2*z - 3*x*z^2 + 3*y*z^2 - 8*z^3 sage: EllipticCurve_from_cubic(cubic, (-4/5, 4/5, 3/5) ) Scheme morphism: - From: Projective Plane Curve over Rational Field defined by -3*x^2*y + 3*x*y^2 + 4*x^2*z + 4*y^2*z - 3*x*z^2 + 3*y*z^2 - 8*z^3 - To: Elliptic Curve defined by y^2 + 24*x*y + 3024*y = x^3 + 495*x^2 + 36288*x over Rational Field + From: Projective Plane Curve over Rational Field defined + by -3*x^2*y + 3*x*y^2 + 4*x^2*z + 4*y^2*z - 3*x*z^2 + 3*y*z^2 - 8*z^3 + To: Elliptic Curve defined by y^2 + 24*x*y + 3024*y = x^3 + 495*x^2 + 36288*x + over Rational Field Defn: Defined on coordinates by sending (x : y : z) to (-1/3*z : 3*x : -1/1008*x + 1/1008*y + 1/378*z) """ @@ -1233,13 +1254,13 @@ def tangent_at_smooth_point(C,P): sage: R. = QQ[] sage: from sage.schemes.elliptic_curves.constructor import tangent_at_smooth_point - sage: C = Curve(x^3+y^3+60*z^3) + sage: C = Curve(x^3 + y^3 + 60*z^3) sage: tangent_at_smooth_point(C, [1,-1,0]) x + y sage: K. = FunctionField(QQ) sage: R. = K[] - sage: C = Curve(x^3+2*y^3+3*z^3) + sage: C = Curve(x^3 + 2*y^3 + 3*z^3) sage: from sage.schemes.elliptic_curves.constructor import tangent_at_smooth_point sage: tangent_at_smooth_point(C,[1,1,-1]) 3*x + 6*y + 9*z @@ -1278,11 +1299,11 @@ def chord_and_tangent(F, P): sage: R. = QQ[] sage: from sage.schemes.elliptic_curves.constructor import chord_and_tangent - sage: F = x^3+y^3+60*z^3 + sage: F = x^3 + y^3 + 60*z^3 sage: chord_and_tangent(F, [1,-1,0]) (-1 : 1 : 0) - sage: F = x^3+7*y^3+64*z^3 + sage: F = x^3 + 7*y^3 + 64*z^3 sage: p0 = [2,2,-1] sage: p1 = chord_and_tangent(F, p0); p1 (5 : -3 : 1) @@ -1347,8 +1368,8 @@ def projective_point(p): sage: from sage.schemes.elliptic_curves.constructor import projective_point sage: projective_point([4/5, 6/5, 8/5]) [2, 3, 4] - sage: F = GF(11) - sage: projective_point([F(4), F(8), F(2)]) + sage: F = GF(11) # optional - sage.rings.finite_rings + sage: projective_point([F(4), F(8), F(2)]) # optional - sage.rings.finite_rings [4, 8, 2] """ from sage.rings.integer import GCD_list @@ -1372,9 +1393,7 @@ def are_projectively_equivalent(P, Q, base_ring): - ``base_ring`` -- the base ring. - OUTPUT: - - Boolean. + OUTPUT: A boolean. EXAMPLES:: @@ -1424,9 +1443,9 @@ def EllipticCurves_with_good_reduction_outside_S(S=[], proof=None, verbose=False sage: elist = EllipticCurves_with_good_reduction_outside_S([2]) sage: elist [Elliptic Curve defined by y^2 = x^3 + 4*x over Rational Field, - Elliptic Curve defined by y^2 = x^3 - x over Rational Field, - ... - Elliptic Curve defined by y^2 = x^3 - x^2 - 13*x + 21 over Rational Field] + Elliptic Curve defined by y^2 = x^3 - x over Rational Field, + ... + Elliptic Curve defined by y^2 = x^3 - x^2 - 13*x + 21 over Rational Field] sage: len(elist) 24 sage: ', '.join(e.label() for e in elist) @@ -1434,19 +1453,19 @@ def EllipticCurves_with_good_reduction_outside_S(S=[], proof=None, verbose=False Without ``Proof=False``, this example gives two warnings:: - sage: elist = EllipticCurves_with_good_reduction_outside_S([11],proof=False) # long time (14s on sage.math, 2011) - sage: len(elist) # long time + sage: elist = EllipticCurves_with_good_reduction_outside_S([11], proof=False) # long time (14s on sage.math, 2011) + sage: len(elist) # long time 12 - sage: ', '.join(e.label() for e in elist) # long time + sage: ', '.join(e.label() for e in elist) # long time '11a1, 11a2, 11a3, 121a1, 121a2, 121b1, 121b2, 121c1, 121c2, 121d1, 121d2, 121d3' - sage: elist = EllipticCurves_with_good_reduction_outside_S([2,3]) # long time (26s on sage.math, 2011) - sage: len(elist) # long time + sage: elist = EllipticCurves_with_good_reduction_outside_S([2,3]) # long time (26s on sage.math, 2011) + sage: len(elist) # long time 752 - sage: conds = sorted(set([e.conductor() for e in elist])) # long time - sage: max(conds) # long time + sage: conds = sorted(set([e.conductor() for e in elist])) # long time + sage: max(conds) # long time 62208 - sage: [N.factor() for N in conds] # long time + sage: [N.factor() for N in conds] # long time [2^3 * 3, 3^3, 2^5, diff --git a/src/sage/schemes/elliptic_curves/ec_database.py b/src/sage/schemes/elliptic_curves/ec_database.py index 4c221715432..375e01fa93a 100644 --- a/src/sage/schemes/elliptic_curves/ec_database.py +++ b/src/sage/schemes/elliptic_curves/ec_database.py @@ -58,10 +58,12 @@ which are not included in the tables. AUTHORS: + - William Stein (2007-10-07): initial version + - Simon Spicer (2014-10-24): Added examples of more high-rank curves -See also the functions cremona_curves() and cremona_optimal_curves() +See also the functions :func:`cremona_curves` and :func:`cremona_optimal_curves` which enable easy looping through the Cremona elliptic curve database. """ @@ -125,7 +127,8 @@ def rank(self, rank, tors=0, n=10, labels=False): sage: L[0].cremona_label() Traceback (most recent call last): ... - LookupError: Cremona database does not contain entry for Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 2582*x + 48720 over Rational Field + LookupError: Cremona database does not contain entry for Elliptic Curve + defined by y^2 + x*y = x^3 + x^2 - 2582*x + 48720 over Rational Field sage: elliptic_curves.rank(6, n=3, labels=True) [] """ diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index 213ac83d73b..4db005fe3cc 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -13,23 +13,25 @@ The usual way to create and work with isogenies is illustrated with the following example:: - sage: k = GF(11) - sage: E = EllipticCurve(k,[1,1]) - sage: Q = E(6,5) - sage: phi = E.isogeny(Q) - sage: phi - Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + x + 1 over - Finite Field of size 11 to Elliptic Curve defined by y^2 = x^3 + 7*x + 8 + sage: k = GF(11) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(k, [1,1]) # optional - sage.rings.finite_rings + sage: Q = E(6,5) # optional - sage.rings.finite_rings + sage: phi = E.isogeny(Q) # optional - sage.rings.finite_rings + sage: phi # optional - sage.rings.finite_rings + Isogeny of degree 7 + from Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 + to Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 11 - sage: P = E(4,5) - sage: phi(P) + sage: P = E(4,5) # optional - sage.rings.finite_rings + sage: phi(P) # optional - sage.rings.finite_rings (10 : 0 : 1) - sage: phi.codomain() + sage: phi.codomain() # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 11 - sage: phi.rational_maps() - ((x^7 + 4*x^6 - 3*x^5 - 2*x^4 - 3*x^3 + 3*x^2 + x - 2)/(x^6 + 4*x^5 - 4*x^4 - - 5*x^3 + 5*x^2), (x^9*y - 5*x^8*y - x^7*y + x^5*y - x^4*y - 5*x^3*y - - 5*x^2*y - 2*x*y - 5*y)/(x^9 - 5*x^8 + 4*x^6 - 3*x^4 + 2*x^3)) + sage: phi.rational_maps() # optional - sage.rings.finite_rings + ((x^7 + 4*x^6 - 3*x^5 - 2*x^4 + - 3*x^3 + 3*x^2 + x - 2)/(x^6 + 4*x^5 - 4*x^4 - 5*x^3 + 5*x^2), + (x^9*y - 5*x^8*y - x^7*y + x^5*y - x^4*y + - 5*x^3*y - 5*x^2*y - 2*x*y - 5*y)/(x^9 - 5*x^8 + 4*x^6 - 3*x^4 + 2*x^3)) The methods directly accessible from an elliptic curve ``E`` over a field are @@ -125,32 +127,32 @@ def _isogeny_determine_algorithm(E, kernel): This helper function will be implicitly called by the following examples:: - sage: R. = GF(5)[] - sage: E = EllipticCurve(GF(5), [0,0,0,1,0]) # indirect doctest + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(GF(5), [0,0,0,1,0]) # indirect doctest # optional - sage.rings.finite_rings We can construct the same isogeny from a kernel polynomial:: - sage: phi = EllipticCurveIsogeny(E, x+3) # indirect doctest + sage: phi = EllipticCurveIsogeny(E, x + 3) # indirect doctest # optional - sage.rings.finite_rings or from a list of coefficients of a kernel polynomial:: - sage: phi == EllipticCurveIsogeny(E, [3,1]) # indirect doctest + sage: phi == EllipticCurveIsogeny(E, [3,1]) # indirect doctest # optional - sage.rings.finite_rings True or from a rational point which generates the kernel:: - sage: phi == EllipticCurveIsogeny(E, E((2,0))) # indirect doctest + sage: phi == EllipticCurveIsogeny(E, E((2,0))) # indirect doctest # optional - sage.rings.finite_rings True In the first two cases, Kohel's algorithm will be used, while in the third case it is Vélu:: sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import _isogeny_determine_algorithm - sage: _isogeny_determine_algorithm(E, x+3) + sage: _isogeny_determine_algorithm(E, x + 3) # optional - sage.rings.finite_rings 'kohel' - sage: _isogeny_determine_algorithm(E, [3, 1]) + sage: _isogeny_determine_algorithm(E, [3, 1]) # optional - sage.rings.finite_rings 'kohel' - sage: _isogeny_determine_algorithm(E, E((2,0))) + sage: _isogeny_determine_algorithm(E, E((2,0))) # optional - sage.rings.finite_rings 'velu' """ kernel_is_list = isinstance(kernel, list) @@ -192,32 +194,38 @@ def isogeny_codomain_from_kernel(E, kernel, degree=None): EXAMPLES:: sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import isogeny_codomain_from_kernel - sage: E = EllipticCurve(GF(7), [1,0,1,0,1]) - sage: R. = GF(7)[] - sage: isogeny_codomain_from_kernel(E, [4,1]) - Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + 6 over Finite Field of size 7 - sage: EllipticCurveIsogeny(E, [4,1]).codomain() == isogeny_codomain_from_kernel(E, [4,1]) + sage: E = EllipticCurve(GF(7), [1,0,1,0,1]) # optional - sage.rings.finite_rings + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: isogeny_codomain_from_kernel(E, [4,1]) # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + 6 + over Finite Field of size 7 + sage: (EllipticCurveIsogeny(E, [4,1]).codomain() # optional - sage.rings.finite_rings + ....: == isogeny_codomain_from_kernel(E, [4,1])) True - sage: isogeny_codomain_from_kernel(E, x^3 + x^2 + 4*x + 3) - Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + 6 over Finite Field of size 7 - sage: isogeny_codomain_from_kernel(E, x^3 + 2*x^2 + 4*x + 3) - Elliptic Curve defined by y^2 + x*y + y = x^3 + 5*x + 2 over Finite Field of size 7 - - sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) - sage: kernel_list = [E((15,10)), E((10,3)), E((6,5))] - sage: isogeny_codomain_from_kernel(E, kernel_list) - Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 3*x + 15 over Finite Field of size 19 + sage: isogeny_codomain_from_kernel(E, x^3 + x^2 + 4*x + 3) # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + 6 + over Finite Field of size 7 + sage: isogeny_codomain_from_kernel(E, x^3 + 2*x^2 + 4*x + 3) # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 + x*y + y = x^3 + 5*x + 2 + over Finite Field of size 7 + + sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: kernel_list = [E((15,10)), E((10,3)), E((6,5))] # optional - sage.rings.finite_rings + sage: isogeny_codomain_from_kernel(E, kernel_list) # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 3*x + 15 + over Finite Field of size 19 TESTS: Test deprecation warning for obsolete argument:: - sage: isogeny_codomain_from_kernel(E, kernel_list, degree=4) + sage: isogeny_codomain_from_kernel(E, kernel_list, degree=4) # optional - sage.rings.finite_rings doctest:warning ... DeprecationWarning: The "degree" argument to isogeny_codomain_from_kernel() does nothing and will be removed. ... - Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 3*x + 15 over Finite Field of size 19 + Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 3*x + 15 + over Finite Field of size 19 """ if degree is not None: from sage.misc.superseded import deprecation @@ -257,14 +265,15 @@ def compute_codomain_formula(E, v, w): This formula is used by every invocation of the :class:`EllipticCurveIsogeny` constructor:: - sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) - sage: phi = EllipticCurveIsogeny(E, E((1,2)) ) - sage: phi.codomain() - Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 9*x + 13 over Finite Field of size 19 + sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((1,2)) ) # optional - sage.rings.finite_rings + sage: phi.codomain() # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 9*x + 13 + over Finite Field of size 19 sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import compute_codomain_formula - sage: v = phi._EllipticCurveIsogeny__v - sage: w = phi._EllipticCurveIsogeny__w - sage: compute_codomain_formula(E, v, w) == phi.codomain() + sage: v = phi._EllipticCurveIsogeny__v # optional - sage.rings.finite_rings + sage: w = phi._EllipticCurveIsogeny__w # optional - sage.rings.finite_rings + sage: compute_codomain_formula(E, v, w) == phi.codomain() # optional - sage.rings.finite_rings True """ a1, a2, a3, a4, a6 = E.a_invariants() @@ -293,14 +302,18 @@ def compute_vw_kohel_even_deg1(x0, y0, a1, a2, a4): This function will be implicitly called by the following example:: - sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) - sage: phi = EllipticCurveIsogeny(E, [9,1]); phi - Isogeny of degree 2 from Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Finite Field of size 19 to Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 9*x + 8 over Finite Field of size 19 + sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, [9,1]); phi # optional - sage.rings.finite_rings + Isogeny of degree 2 + from Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 + over Finite Field of size 19 + to Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 9*x + 8 + over Finite Field of size 19 sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import compute_vw_kohel_even_deg1 - sage: a1,a2,a3,a4,a6 = E.a_invariants() - sage: x0 = -9 - sage: y0 = -(a1*x0 + a3)/2 - sage: compute_vw_kohel_even_deg1(x0, y0, a1, a2, a4) + sage: a1,a2,a3,a4,a6 = E.a_invariants() # optional - sage.rings.finite_rings + sage: x0 = -9 # optional - sage.rings.finite_rings + sage: y0 = -(a1*x0 + a3)/2 # optional - sage.rings.finite_rings + sage: compute_vw_kohel_even_deg1(x0, y0, a1, a2, a4) # optional - sage.rings.finite_rings (18, 9) """ v = 3*x0**2 + 2*a2*x0 + a4 - a1*y0 @@ -327,14 +340,18 @@ def compute_vw_kohel_even_deg3(b2, b4, s1, s2, s3): This function will be implicitly called by the following example:: - sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) - sage: R. = GF(19)[] - sage: phi = EllipticCurveIsogeny(E, x^3 + 7*x^2 + 15*x + 12); phi - Isogeny of degree 4 from Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Finite Field of size 19 to Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 3*x + 15 over Finite Field of size 19 + sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: R. = GF(19)[] # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x^3 + 7*x^2 + 15*x + 12); phi # optional - sage.rings.finite_rings + Isogeny of degree 4 + from Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 + over Finite Field of size 19 + to Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 3*x + 15 + over Finite Field of size 19 sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import compute_vw_kohel_even_deg3 - sage: b2,b4 = E.b2(), E.b4() - sage: s1, s2, s3 = -7, 15, -12 - sage: compute_vw_kohel_even_deg3(b2, b4, s1, s2, s3) + sage: b2,b4 = E.b2(), E.b4() # optional - sage.rings.finite_rings + sage: s1, s2, s3 = -7, 15, -12 # optional - sage.rings.finite_rings + sage: compute_vw_kohel_even_deg3(b2, b4, s1, s2, s3) # optional - sage.rings.finite_rings (4, 7) """ temp1 = s1**2 - 2*s2 @@ -364,14 +381,18 @@ def compute_vw_kohel_odd(b2, b4, b6, s1, s2, s3, n): This function will be implicitly called by the following example:: - sage: E = EllipticCurve(GF(19), [18,17,16,15,14]) - sage: R. = GF(19)[] - sage: phi = EllipticCurveIsogeny(E, x^3 + 14*x^2 + 3*x + 11); phi - Isogeny of degree 7 from Elliptic Curve defined by y^2 + 18*x*y + 16*y = x^3 + 17*x^2 + 15*x + 14 over Finite Field of size 19 to Elliptic Curve defined by y^2 + 18*x*y + 16*y = x^3 + 17*x^2 + 18*x + 18 over Finite Field of size 19 + sage: E = EllipticCurve(GF(19), [18,17,16,15,14]) # optional - sage.rings.finite_rings + sage: R. = GF(19)[] # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x^3 + 14*x^2 + 3*x + 11); phi # optional - sage.rings.finite_rings + Isogeny of degree 7 + from Elliptic Curve defined by y^2 + 18*x*y + 16*y = x^3 + 17*x^2 + 15*x + 14 + over Finite Field of size 19 + to Elliptic Curve defined by y^2 + 18*x*y + 16*y = x^3 + 17*x^2 + 18*x + 18 + over Finite Field of size 19 sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import compute_vw_kohel_odd - sage: b2,b4,b6 = E.b2(), E.b4(), E.b6() - sage: s1,s2,s3 = -14,3,-11 - sage: compute_vw_kohel_odd(b2,b4,b6,s1,s2,s3,3) + sage: b2,b4,b6 = E.b2(), E.b4(), E.b6() # optional - sage.rings.finite_rings + sage: s1,s2,s3 = -14,3,-11 # optional - sage.rings.finite_rings + sage: compute_vw_kohel_odd(b2,b4,b6,s1,s2,s3,3) # optional - sage.rings.finite_rings (7, 1) """ v = 6*(s1**2 - 2*s2) + b2*s1 + n*b4 @@ -398,25 +419,28 @@ def compute_codomain_kohel(E, kernel): EXAMPLES:: sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import compute_codomain_kohel - sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) - sage: phi = EllipticCurveIsogeny(E, [9,1]) - sage: phi.codomain() == isogeny_codomain_from_kernel(E, [9,1]) + sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, [9,1]) # optional - sage.rings.finite_rings + sage: phi.codomain() == isogeny_codomain_from_kernel(E, [9,1]) # optional - sage.rings.finite_rings True - sage: compute_codomain_kohel(E, [9,1]) - Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 9*x + 8 over Finite Field of size 19 - sage: R. = GF(19)[] - sage: E = EllipticCurve(GF(19), [18,17,16,15,14]) - sage: phi = EllipticCurveIsogeny(E, x^3 + 14*x^2 + 3*x + 11) - sage: phi.codomain() == isogeny_codomain_from_kernel(E, x^3 + 14*x^2 + 3*x + 11) + sage: compute_codomain_kohel(E, [9,1]) # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 9*x + 8 + over Finite Field of size 19 + sage: R. = GF(19)[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(GF(19), [18,17,16,15,14]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x^3 + 14*x^2 + 3*x + 11) # optional - sage.rings.finite_rings + sage: phi.codomain() == isogeny_codomain_from_kernel(E, x^3 + 14*x^2 + 3*x + 11) # optional - sage.rings.finite_rings True - sage: compute_codomain_kohel(E, x^3 + 14*x^2 + 3*x + 11) - Elliptic Curve defined by y^2 + 18*x*y + 16*y = x^3 + 17*x^2 + 18*x + 18 over Finite Field of size 19 - sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) - sage: phi = EllipticCurveIsogeny(E, x^3 + 7*x^2 + 15*x + 12) - sage: isogeny_codomain_from_kernel(E, x^3 + 7*x^2 + 15*x + 12) == phi.codomain() + sage: compute_codomain_kohel(E, x^3 + 14*x^2 + 3*x + 11) # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 + 18*x*y + 16*y = x^3 + 17*x^2 + 18*x + 18 + over Finite Field of size 19 + sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x^3 + 7*x^2 + 15*x + 12) # optional - sage.rings.finite_rings + sage: isogeny_codomain_from_kernel(E, x^3 + 7*x^2 + 15*x + 12) == phi.codomain() # optional - sage.rings.finite_rings True - sage: compute_codomain_kohel(E, x^3 + 7*x^2 + 15*x + 12) - Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 3*x + 15 over Finite Field of size 19 + sage: compute_codomain_kohel(E, x^3 + 7*x^2 + 15*x + 12) # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 3*x + 15 + over Finite Field of size 19 ALGORITHM: @@ -505,13 +529,13 @@ def two_torsion_part(E, psi): Every function that computes the kernel polynomial via Kohel's formulas will call this function:: - sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) - sage: R. = GF(19)[] - sage: phi = EllipticCurveIsogeny(E, x + 13) - sage: isogeny_codomain_from_kernel(E, x + 13) == phi.codomain() + sage: E = EllipticCurve(GF(19), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: R. = GF(19)[] # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x + 13) # optional - sage.rings.finite_rings + sage: isogeny_codomain_from_kernel(E, x + 13) == phi.codomain() # optional - sage.rings.finite_rings True sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import two_torsion_part - sage: two_torsion_part(E, x+13) + sage: two_torsion_part(E, x + 13) # optional - sage.rings.finite_rings x + 13 """ x = psi.parent().gen() # NB psi is univariate but could be constant @@ -588,91 +612,105 @@ class EllipticCurveIsogeny(EllipticCurveHom): A simple example of creating an isogeny of a field of small characteristic:: - sage: E = EllipticCurve(GF(7), [0,0,0,1,0]) - sage: phi = EllipticCurveIsogeny(E, E((0,0)) ); phi - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 3*x over Finite Field of size 7 - sage: phi.degree() == 2 + sage: E = EllipticCurve(GF(7), [0,0,0,1,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0)) ); phi # optional - sage.rings.finite_rings + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7 + to Elliptic Curve defined by y^2 = x^3 + 3*x over Finite Field of size 7 + sage: phi.degree() == 2 # optional - sage.rings.finite_rings True - sage: phi.kernel_polynomial() + sage: phi.kernel_polynomial() # optional - sage.rings.finite_rings x - sage: phi.rational_maps() + sage: phi.rational_maps() # optional - sage.rings.finite_rings ((x^2 + 1)/x, (x^2*y - y)/x^2) - sage: phi == loads(dumps(phi)) # known bug + sage: phi == loads(dumps(phi)) # known bug # optional - sage.rings.finite_rings True A more complicated example of a characteristic-2 field:: - sage: E = EllipticCurve(GF(2^4,'alpha'), [0,0,1,0,1]) - sage: P = E((1,1)) - sage: phi_v = EllipticCurveIsogeny(E, P); phi_v - Isogeny of degree 3 from Elliptic Curve defined by y^2 + y = x^3 + 1 over Finite Field in alpha of size 2^4 to Elliptic Curve defined by y^2 + y = x^3 over Finite Field in alpha of size 2^4 - sage: phi_ker_poly = phi_v.kernel_polynomial() - sage: phi_ker_poly + sage: E = EllipticCurve(GF(2^4,'alpha'), [0,0,1,0,1]) # optional - sage.rings.finite_rings + sage: P = E((1,1)) # optional - sage.rings.finite_rings + sage: phi_v = EllipticCurveIsogeny(E, P); phi_v # optional - sage.rings.finite_rings + Isogeny of degree 3 + from Elliptic Curve defined by y^2 + y = x^3 + 1 + over Finite Field in alpha of size 2^4 + to Elliptic Curve defined by y^2 + y = x^3 + over Finite Field in alpha of size 2^4 + sage: phi_ker_poly = phi_v.kernel_polynomial() # optional - sage.rings.finite_rings + sage: phi_ker_poly # optional - sage.rings.finite_rings x + 1 - sage: phi_k = EllipticCurveIsogeny(E, phi_ker_poly) - sage: phi_k == phi_v + sage: phi_k = EllipticCurveIsogeny(E, phi_ker_poly) # optional - sage.rings.finite_rings + sage: phi_k == phi_v # optional - sage.rings.finite_rings True - sage: phi_k.rational_maps() + sage: phi_k.rational_maps() # optional - sage.rings.finite_rings ((x^3 + x + 1)/(x^2 + 1), (x^3*y + x^2*y + x*y + x + y)/(x^3 + x^2 + x + 1)) - sage: phi_v.rational_maps() + sage: phi_v.rational_maps() # optional - sage.rings.finite_rings ((x^3 + x + 1)/(x^2 + 1), (x^3*y + x^2*y + x*y + x + y)/(x^3 + x^2 + x + 1)) - sage: phi_k.degree() == phi_v.degree() == 3 + sage: phi_k.degree() == phi_v.degree() == 3 # optional - sage.rings.finite_rings True - sage: phi_k.is_separable() + sage: phi_k.is_separable() # optional - sage.rings.finite_rings True - sage: phi_v(E(0)) + sage: phi_v(E(0)) # optional - sage.rings.finite_rings (0 : 1 : 0) - sage: alpha = E.base_field().gen() - sage: Q = E((0, alpha*(alpha + 1))) - sage: phi_v(Q) + sage: alpha = E.base_field().gen() # optional - sage.rings.finite_rings + sage: Q = E((0, alpha*(alpha + 1))) # optional - sage.rings.finite_rings + sage: phi_v(Q) # optional - sage.rings.finite_rings (1 : alpha^2 + alpha : 1) - sage: phi_v(P) == phi_k(P) + sage: phi_v(P) == phi_k(P) # optional - sage.rings.finite_rings True - sage: phi_k(P) == phi_v.codomain()(0) + sage: phi_k(P) == phi_v.codomain()(0) # optional - sage.rings.finite_rings True We can create an isogeny whose kernel equals the full 2-torsion:: - sage: E = EllipticCurve(GF((3,2)), [0,0,0,1,1]) - sage: ker_poly = E.division_polynomial(2) - sage: phi = EllipticCurveIsogeny(E, ker_poly); phi - Isogeny of degree 4 from Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in z2 of size 3^2 to Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in z2 of size 3^2 - sage: P1,P2,P3 = filter(bool, E(0).division_points(2)) - sage: phi(P1) + sage: E = EllipticCurve(GF((3,2)), [0,0,0,1,1]) # optional - sage.rings.finite_rings + sage: ker_poly = E.division_polynomial(2) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, ker_poly); phi # optional - sage.rings.finite_rings + Isogeny of degree 4 + from Elliptic Curve defined by y^2 = x^3 + x + 1 + over Finite Field in z2 of size 3^2 + to Elliptic Curve defined by y^2 = x^3 + x + 1 + over Finite Field in z2 of size 3^2 + sage: P1,P2,P3 = filter(bool, E(0).division_points(2)) # optional - sage.rings.finite_rings + sage: phi(P1) # optional - sage.rings.finite_rings (0 : 1 : 0) - sage: phi(P2) + sage: phi(P2) # optional - sage.rings.finite_rings (0 : 1 : 0) - sage: phi(P3) + sage: phi(P3) # optional - sage.rings.finite_rings (0 : 1 : 0) - sage: phi.degree() + sage: phi.degree() # optional - sage.rings.finite_rings 4 We can also create trivial isogenies with the trivial kernel:: - sage: E = EllipticCurve(GF(17), [11, 11, 4, 12, 10]) - sage: phi_v = EllipticCurveIsogeny(E, E(0)) - sage: phi_v.degree() + sage: E = EllipticCurve(GF(17), [11, 11, 4, 12, 10]) # optional - sage.rings.finite_rings + sage: phi_v = EllipticCurveIsogeny(E, E(0)) # optional - sage.rings.finite_rings + sage: phi_v.degree() # optional - sage.rings.finite_rings 1 - sage: phi_v.rational_maps() + sage: phi_v.rational_maps() # optional - sage.rings.finite_rings (x, y) - sage: E == phi_v.codomain() + sage: E == phi_v.codomain() # optional - sage.rings.finite_rings True - sage: P = E.random_point() - sage: phi_v(P) == P + sage: P = E.random_point() # optional - sage.rings.finite_rings + sage: phi_v(P) == P # optional - sage.rings.finite_rings True - sage: E = EllipticCurve(GF(31), [23, 1, 22, 7, 18]) - sage: phi_k = EllipticCurveIsogeny(E, [1]); phi_k - Isogeny of degree 1 from Elliptic Curve defined by y^2 + 23*x*y + 22*y = x^3 + x^2 + 7*x + 18 over Finite Field of size 31 to Elliptic Curve defined by y^2 + 23*x*y + 22*y = x^3 + x^2 + 7*x + 18 over Finite Field of size 31 - sage: phi_k.degree() + sage: E = EllipticCurve(GF(31), [23, 1, 22, 7, 18]) # optional - sage.rings.finite_rings + sage: phi_k = EllipticCurveIsogeny(E, [1]); phi_k # optional - sage.rings.finite_rings + Isogeny of degree 1 + from Elliptic Curve defined by y^2 + 23*x*y + 22*y = x^3 + x^2 + 7*x + 18 + over Finite Field of size 31 + to Elliptic Curve defined by y^2 + 23*x*y + 22*y = x^3 + x^2 + 7*x + 18 + over Finite Field of size 31 + sage: phi_k.degree() # optional - sage.rings.finite_rings 1 - sage: phi_k.rational_maps() + sage: phi_k.rational_maps() # optional - sage.rings.finite_rings (x, y) - sage: phi_k.codomain() == E + sage: phi_k.codomain() == E # optional - sage.rings.finite_rings True - sage: phi_k.kernel_polynomial() + sage: phi_k.kernel_polynomial() # optional - sage.rings.finite_rings 1 - sage: P = E.random_point(); P == phi_k(P) + sage: P = E.random_point(); P == phi_k(P) # optional - sage.rings.finite_rings True Vélu and Kohel also work in characteristic `0`:: @@ -680,7 +718,9 @@ class EllipticCurveIsogeny(EllipticCurveHom): sage: E = EllipticCurve(QQ, [0,0,0,3,4]) sage: P_list = E.torsion_points() sage: phi = EllipticCurveIsogeny(E, P_list); phi - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 3*x + 4 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 27*x + 46 over Rational Field + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 3*x + 4 over Rational Field + to Elliptic Curve defined by y^2 = x^3 - 27*x + 46 over Rational Field sage: P = E((0,2)) sage: phi(P) (6 : -10 : 1) @@ -688,7 +728,9 @@ class EllipticCurveIsogeny(EllipticCurveHom): sage: phi_ker_poly x + 1 sage: phi_k = EllipticCurveIsogeny(E, phi_ker_poly); phi_k - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 3*x + 4 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 27*x + 46 over Rational Field + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 3*x + 4 over Rational Field + to Elliptic Curve defined by y^2 = x^3 - 27*x + 46 over Rational Field sage: phi_k(P) == phi(P) True sage: phi_k == phi @@ -703,14 +745,18 @@ class EllipticCurveIsogeny(EllipticCurveHom): sage: E = EllipticCurve('11a1') sage: P_list = E.torsion_points() sage: phi_v = EllipticCurveIsogeny(E, P_list); phi_v - Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field + Isogeny of degree 5 + from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field sage: P = E((16,-61)) sage: phi_v(P) (0 : 1 : 0) sage: ker_poly = phi_v.kernel_polynomial(); ker_poly x^2 - 21*x + 80 sage: phi_k = EllipticCurveIsogeny(E, ker_poly); phi_k - Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field + Isogeny of degree 5 + from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field sage: phi_k == phi_v True sage: phi_v(P) == phi_k(P) @@ -723,29 +769,36 @@ class EllipticCurveIsogeny(EllipticCurveHom): sage: E = EllipticCurve('11a1') sage: P_list = E.torsion_points() - sage: K. = NumberField(x^3 - 2* x^2 - 40*x - 158) - sage: EK = E.change_ring(K) - sage: P_list = [EK(P) for P in P_list] - sage: phi_v = EllipticCurveIsogeny(EK, P_list); phi_v - Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in alpha with defining polynomial x^3 - 2*x^2 - 40*x - 158 to Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-7820)*x + (-263580) over Number Field in alpha with defining polynomial x^3 - 2*x^2 - 40*x - 158 - sage: P = EK((alpha/2,-1/2)) - sage: phi_v(P) + sage: K. = NumberField(x^3 - 2* x^2 - 40*x - 158) # optional - sage.rings.number_field + sage: EK = E.change_ring(K) # optional - sage.rings.number_field + sage: P_list = [EK(P) for P in P_list] # optional - sage.rings.number_field + sage: phi_v = EllipticCurveIsogeny(EK, P_list); phi_v # optional - sage.rings.number_field + Isogeny of degree 5 + from Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) + over Number Field in alpha with defining polynomial x^3 - 2*x^2 - 40*x - 158 + to Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-7820)*x + (-263580) + over Number Field in alpha with defining polynomial x^3 - 2*x^2 - 40*x - 158 + sage: P = EK((alpha/2,-1/2)) # optional - sage.rings.number_field + sage: phi_v(P) # optional - sage.rings.number_field (122/121*alpha^2 + 1633/242*alpha - 3920/121 : -1/2 : 1) - sage: ker_poly = phi_v.kernel_polynomial() - sage: ker_poly + sage: ker_poly = phi_v.kernel_polynomial() # optional - sage.rings.number_field + sage: ker_poly # optional - sage.rings.number_field x^2 - 21*x + 80 - sage: phi_k = EllipticCurveIsogeny(EK, ker_poly) - sage: phi_k - Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in alpha with defining polynomial x^3 - 2*x^2 - 40*x - 158 to Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-7820)*x + (-263580) over Number Field in alpha with defining polynomial x^3 - 2*x^2 - 40*x - 158 - sage: phi_v == phi_k + sage: phi_k = EllipticCurveIsogeny(EK, ker_poly); phi_k # optional - sage.rings.number_field + Isogeny of degree 5 + from Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) + over Number Field in alpha with defining polynomial x^3 - 2*x^2 - 40*x - 158 + to Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-7820)*x + (-263580) + over Number Field in alpha with defining polynomial x^3 - 2*x^2 - 40*x - 158 + sage: phi_v == phi_k # optional - sage.rings.number_field True - sage: phi_k(P) == phi_v(P) + sage: phi_k(P) == phi_v(P) # optional - sage.rings.number_field True - sage: phi_k == phi_v + sage: phi_k == phi_v # optional - sage.rings.number_field True - sage: phi_k.degree() + sage: phi_k.degree() # optional - sage.rings.number_field 5 - sage: phi_v.is_separable() + sage: phi_v.is_separable() # optional - sage.rings.number_field True The following example shows how to specify an isogeny from domain @@ -756,9 +809,10 @@ class EllipticCurveIsogeny(EllipticCurveHom): sage: f = x^2 - 21*x + 80 sage: phi = E.isogeny(f) sage: E2 = phi.codomain() - sage: phi_s = EllipticCurveIsogeny(E, None, E2, 5) - sage: phi_s - Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field + sage: phi_s = EllipticCurveIsogeny(E, None, E2, 5); phi_s + Isogeny of degree 5 + from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field sage: phi_s == phi True sage: phi_s.rational_maps() == phi.rational_maps() @@ -779,24 +833,28 @@ class EllipticCurveIsogeny(EllipticCurveHom): ... ValueError: the two curves are not linked by a cyclic normalized isogeny of degree 5 sage: phihat = phi.dual(); phihat - Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Isogeny of degree 5 + from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 + over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: phihat.is_normalized() False Here an example of a construction of a endomorphisms with cyclic kernel on a CM-curve:: - sage: K. = NumberField(x^2+1) - sage: E = EllipticCurve(K, [1,0]) - sage: RK. = K[] - sage: f = X^2 - 2/5*i + 1/5 - sage: phi= E.isogeny(f) - sage: isom = phi.codomain().isomorphism_to(E) - sage: phi = isom * phi - sage: phi.codomain() == phi.domain() + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [1,0]) # optional - sage.rings.number_field + sage: RK. = K[] # optional - sage.rings.number_field + sage: f = X^2 - 2/5*i + 1/5 # optional - sage.rings.number_field + sage: phi= E.isogeny(f) # optional - sage.rings.number_field + sage: isom = phi.codomain().isomorphism_to(E) # optional - sage.rings.number_field + sage: phi = isom * phi # optional - sage.rings.number_field + sage: phi.codomain() == phi.domain() # optional - sage.rings.number_field True - sage: phi.rational_maps() - (((4/25*i + 3/25)*x^5 + (4/5*i - 2/5)*x^3 - x)/(x^4 + (-4/5*i + 2/5)*x^2 + (-4/25*i - 3/25)), ((11/125*i + 2/125)*x^6*y + (-23/125*i + 64/125)*x^4*y + (141/125*i + 162/125)*x^2*y + (3/25*i - 4/25)*y)/(x^6 + (-6/5*i + 3/5)*x^4 + (-12/25*i - 9/25)*x^2 + (2/125*i - 11/125))) + sage: phi.rational_maps() # optional - sage.rings.number_field + (((4/25*i + 3/25)*x^5 + (4/5*i - 2/5)*x^3 - x)/(x^4 + (-4/5*i + 2/5)*x^2 + (-4/25*i - 3/25)), + ((11/125*i + 2/125)*x^6*y + (-23/125*i + 64/125)*x^4*y + (141/125*i + 162/125)*x^2*y + (3/25*i - 4/25)*y)/(x^6 + (-6/5*i + 3/5)*x^4 + (-12/25*i - 9/25)*x^2 + (2/125*i - 11/125))) TESTS: @@ -809,19 +867,21 @@ class EllipticCurveIsogeny(EllipticCurveHom): sage: phi.codomain() Elliptic Curve defined by y^2 = x^3 - 4*x over Rational Field - sage: E = EllipticCurve(GF(31), [1,0,0,1,2]) - sage: phi = EllipticCurveIsogeny(E, [17, 1]) - sage: phi.domain() + sage: E = EllipticCurve(GF(31), [1,0,0,1,2]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, [17, 1]) # optional - sage.rings.finite_rings + sage: phi.domain() # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 + x*y = x^3 + x + 2 over Finite Field of size 31 - sage: phi.codomain() + sage: phi.codomain() # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 + x*y = x^3 + 24*x + 6 over Finite Field of size 31 Composition tests (see :trac:`16245`, cf. :trac:`34410`):: - sage: E = EllipticCurve(j=GF(7)(0)) - sage: phi = E.isogeny([E(0), E((0,1)), E((0,-1))]); phi - Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 - sage: phi2 = phi * phi; phi2 + sage: E = EllipticCurve(j=GF(7)(0)) # optional - sage.rings.finite_rings + sage: phi = E.isogeny([E(0), E((0,1)), E((0,-1))]); phi # optional - sage.rings.finite_rings + Isogeny of degree 3 + from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 + to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 + sage: phi2 = phi * phi; phi2 # optional - sage.rings.finite_rings Composite morphism of degree 9 = 3^2: From: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 To: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 @@ -829,15 +889,15 @@ class EllipticCurveIsogeny(EllipticCurveHom): Examples over relative number fields used not to work (see :trac:`16779`):: sage: pol26 = hilbert_class_polynomial(-4*26) - sage: pol = NumberField(pol26,'a').optimized_representation()[0].polynomial() - sage: K. = NumberField(pol) - sage: j = pol26.roots(K)[0][0] - sage: E = EllipticCurve(j=j) - sage: L. = K.extension(x^2+26) - sage: EL = E.change_ring(L) - sage: iso2 = EL.isogenies_prime_degree(2); len(iso2) + sage: pol = NumberField(pol26,'a').optimized_representation()[0].polynomial() # optional - sage.rings.number_field + sage: K. = NumberField(pol) # optional - sage.rings.number_field + sage: j = pol26.roots(K)[0][0] # optional - sage.rings.number_field + sage: E = EllipticCurve(j=j) # optional - sage.rings.number_field + sage: L. = K.extension(x^2 + 26) # optional - sage.rings.number_field + sage: EL = E.change_ring(L) # optional - sage.rings.number_field + sage: iso2 = EL.isogenies_prime_degree(2); len(iso2) # optional - sage.rings.number_field 1 - sage: iso3 = EL.isogenies_prime_degree(3); len(iso3) + sage: iso3 = EL.isogenies_prime_degree(3); len(iso3) # optional - sage.rings.number_field 2 Examples over function fields used not to work (see :trac:`11327`):: @@ -846,16 +906,28 @@ class EllipticCurveIsogeny(EllipticCurveHom): sage: E = EllipticCurve([0,0,0,-t^2,0]) sage: isogs = E.isogenies_prime_degree(2) sage: isogs[0] - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + (-t^2)*x over Rational function field in t over Rational Field to Elliptic Curve defined by y^2 = x^3 + 4*t^2*x over Rational function field in t over Rational Field + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + (-t^2)*x + over Rational function field in t over Rational Field + to Elliptic Curve defined by y^2 = x^3 + 4*t^2*x + over Rational function field in t over Rational Field sage: isogs[0].rational_maps() ((x^2 - t^2)/x, (x^2*y + t^2*y)/x^2) sage: duals = [phi.dual() for phi in isogs] sage: duals[0] - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 4*t^2*x over Rational function field in t over Rational Field to Elliptic Curve defined by y^2 = x^3 + (-t^2)*x over Rational function field in t over Rational Field + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 4*t^2*x + over Rational function field in t over Rational Field + to Elliptic Curve defined by y^2 = x^3 + (-t^2)*x + over Rational function field in t over Rational Field sage: duals[0].rational_maps() ((1/4*x^2 + t^2)/x, (1/8*x^2*y + (-1/2*t^2)*y)/x^2) sage: duals[0] - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 4*t^2*x over Rational function field in t over Rational Field to Elliptic Curve defined by y^2 = x^3 + (-t^2)*x over Rational function field in t over Rational Field + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 4*t^2*x + over Rational function field in t over Rational Field + to Elliptic Curve defined by y^2 = x^3 + (-t^2)*x + over Rational function field in t over Rational Field """ #################### @@ -944,29 +1016,43 @@ def __init__(self, E, kernel, codomain=None, degree=None, model=None, check=True EXAMPLES:: - sage: E = EllipticCurve(GF(2), [0,0,1,0,1]) - sage: phi = EllipticCurveIsogeny(E, [1,1]); phi - Isogeny of degree 3 from Elliptic Curve defined by y^2 + y = x^3 + 1 over Finite Field of size 2 to Elliptic Curve defined by y^2 + y = x^3 over Finite Field of size 2 + sage: E = EllipticCurve(GF(2), [0,0,1,0,1]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, [1,1]); phi # optional - sage.rings.finite_rings + Isogeny of degree 3 + from Elliptic Curve defined by y^2 + y = x^3 + 1 over Finite Field of size 2 + to Elliptic Curve defined by y^2 + y = x^3 over Finite Field of size 2 - sage: E = EllipticCurve(GF(31), [0,0,0,1,0]) - sage: P = E((2,17)) - sage: phi = EllipticCurveIsogeny(E, P); phi - Isogeny of degree 8 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 31 to Elliptic Curve defined by y^2 = x^3 + 10*x + 28 over Finite Field of size 31 + sage: E = EllipticCurve(GF(31), [0,0,0,1,0]) # optional - sage.rings.finite_rings + sage: P = E((2,17)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, P); phi # optional - sage.rings.finite_rings + Isogeny of degree 8 + from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 31 + to Elliptic Curve defined by y^2 = x^3 + 10*x + 28 over Finite Field of size 31 sage: E = EllipticCurve('17a1') sage: phi = EllipticCurveIsogeny(E, [41/3, -55, -1, -1, 1]); phi - Isogeny of degree 9 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - x - 14 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 56*x - 10124 over Rational Field + Isogeny of degree 9 + from Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - x - 14 + over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 56*x - 10124 + over Rational Field sage: E = EllipticCurve('37a1') sage: triv = EllipticCurveIsogeny(E, E(0)); triv - Isogeny of degree 1 from Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + Isogeny of degree 1 + from Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field sage: triv.rational_maps() (x, y) sage: E = EllipticCurve('49a3') sage: R. = QQ[] - sage: EllipticCurveIsogeny(E, X^3-13*X^2-58*X+503, check=False) - Isogeny of degree 7 from Elliptic Curve defined by y^2 + x*y = x^3 - x^2 - 107*x + 552 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 - x^2 - 5252*x - 178837 over Rational Field + sage: EllipticCurveIsogeny(E, X^3 - 13*X^2 - 58*X + 503, check=False) + Isogeny of degree 7 + from Elliptic Curve defined by y^2 + x*y = x^3 - x^2 - 107*x + 552 + over Rational Field + to Elliptic Curve defined by y^2 + x*y = x^3 - x^2 - 5252*x - 178837 + over Rational Field """ if not is_EllipticCurve(E): raise ValueError("given E is not an elliptic curve") @@ -1039,8 +1125,8 @@ def _eval(self, P): sage: E = EllipticCurve([1,0]); E Elliptic Curve defined by y^2 = x^3 + x over Rational Field sage: phi = E.isogeny(E(0,0)) - sage: P = E.change_ring(QQbar).lift_x(QQbar.random_element()) - sage: phi._eval(P).curve() + sage: P = E.change_ring(QQbar).lift_x(QQbar.random_element()) # optional - sage.rings.number_field + sage: phi._eval(P).curve() # optional - sage.rings.number_field Elliptic Curve defined by y^2 = x^3 + (-4)*x over Algebraic Field :: @@ -1048,8 +1134,8 @@ def _eval(self, P): sage: E = EllipticCurve(j=Mod(0,419)) sage: K = next(filter(bool, E(0).division_points(5))) sage: psi = E.isogeny(K) - sage: Ps = E.change_ring(GF(419**2))(0).division_points(5) - sage: {psi._eval(P).curve() for P in Ps} + sage: Ps = E.change_ring(GF(419**2))(0).division_points(5) # optional - sage.rings.number_field + sage: {psi._eval(P).curve() for P in Ps} # optional - sage.rings.number_field {Elliptic Curve defined by y^2 = x^3 + 140*x + 214 over Finite Field in z2 of size 419^2} """ if self._domain.defining_polynomial()(*P): @@ -1089,78 +1175,80 @@ def _call_(self, P): EXAMPLES:: - sage: E = EllipticCurve(GF(17), [1, 9, 5, 4, 3]) - sage: phi = EllipticCurveIsogeny(E, [6,13,1]) - sage: phi(E((1,0))) + sage: E = EllipticCurve(GF(17), [1, 9, 5, 4, 3]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, [6,13,1]) # optional - sage.rings.finite_rings + sage: phi(E((1,0))) # optional - sage.rings.finite_rings (15 : 13 : 1) - sage: E = EllipticCurve(GF(23), [0,0,0,1,0]) - sage: phi = EllipticCurveIsogeny(E, E((0,0))) - sage: phi(E((1,5))) + sage: E = EllipticCurve(GF(23), [0,0,0,1,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0))) # optional - sage.rings.finite_rings + sage: phi(E((1,5))) # optional - sage.rings.finite_rings (2 : 0 : 1) - sage: E = EllipticCurve(QQ, [0,0,0,3,0]) - sage: P = E((1,2)) - sage: phi = EllipticCurveIsogeny(E, [0,1]) - sage: phi(P) + sage: E = EllipticCurve(QQ, [0,0,0,3,0]) # optional - sage.rings.finite_rings + sage: P = E((1,2)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, [0,1]) # optional - sage.rings.finite_rings + sage: phi(P) # optional - sage.rings.finite_rings (4 : -4 : 1) - sage: phi(-P) + sage: phi(-P) # optional - sage.rings.finite_rings (4 : 4 : 1) - sage: E = EllipticCurve(GF(17), [0,-1,0,-3,-1]) - sage: Q = E((16,0)) - sage: tau = E.isogeny([Q], E) - sage: tau(Q) + sage: E = EllipticCurve(GF(17), [0,-1,0,-3,-1]) # optional - sage.rings.finite_rings + sage: Q = E((16,0)) # optional - sage.rings.finite_rings + sage: tau = E.isogeny([Q], E) # optional - sage.rings.finite_rings + sage: tau(Q) # optional - sage.rings.finite_rings (0 : 1 : 0) TESTS: Tests for :trac:`10888`:: - sage: K. = NumberField(x^2+3) - sage: E = EllipticCurve(K,[7,0]) - sage: phi = E.isogeny(E(0,0)) - sage: P = E(-3,4*th) - sage: phi(P) + sage: K. = NumberField(x^2 + 3) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [7,0]) # optional - sage.rings.number_field + sage: phi = E.isogeny(E(0,0)) # optional - sage.rings.number_field + sage: P = E(-3,4*th) # optional - sage.rings.number_field + sage: phi(P) # optional - sage.rings.number_field (-16/3 : 8/9*th : 1) - sage: Q = phi(P) - sage: phihat = phi.dual() - sage: phihat(Q) + sage: Q = phi(P) # optional - sage.rings.number_field + sage: phihat = phi.dual() # optional - sage.rings.number_field + sage: phihat(Q) # optional - sage.rings.number_field (-1/48 : 127/576*th : 1) Call a composed isogeny (added for :trac:`16238`):: - sage: E = EllipticCurve(j=GF(7)(0)) - sage: phi = E.isogeny([E(0), E((0,1)), E((0,-1))]) - sage: phi(E.points()[0]) + sage: E = EllipticCurve(j=GF(7)(0)) # optional - sage.rings.finite_rings + sage: phi = E.isogeny([E(0), E((0,1)), E((0,-1))]) # optional - sage.rings.finite_rings + sage: phi(E.points()[0]) # optional - sage.rings.finite_rings (0 : 1 : 0) - sage: phi2 = phi * phi - sage: phi2(E.points()[0]) + sage: phi2 = phi * phi # optional - sage.rings.finite_rings + sage: phi2(E.points()[0]) # optional - sage.rings.finite_rings (0 : 1 : 0) Coercion works fine with :meth:`_call_` (added for :trac:`16238`):: - sage: K. = NumberField(x^2+3) - sage: E = EllipticCurve(K,[7,0]) - sage: E2 = EllipticCurve(K,[5,0]) - sage: phi = E.isogeny(E(0)) - sage: phi(E2(0)) + sage: K. = NumberField(x^2 + 3) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [7,0]) # optional - sage.rings.number_field + sage: E2 = EllipticCurve(K, [5,0]) # optional - sage.rings.number_field + sage: phi = E.isogeny(E(0)) # optional - sage.rings.number_field + sage: phi(E2(0)) # optional - sage.rings.number_field (0 : 1 : 0) - sage: E2(20,90) + sage: E2(20,90) # optional - sage.rings.number_field (20 : 90 : 1) - sage: phi(E2(20,90)) + sage: phi(E2(20,90)) # optional - sage.rings.number_field Traceback (most recent call last): ... - TypeError: (20 : 90 : 1) fails to convert into the map's domain Elliptic Curve defined by y^2 = x^3 + 7*x over Number Field in th with defining polynomial x^2 + 3, but a `pushforward` method is not properly implemented + TypeError: (20 : 90 : 1) fails to convert into the map's domain + Elliptic Curve defined by y^2 = x^3 + 7*x over Number Field in th with defining polynomial x^2 + 3, + but a `pushforward` method is not properly implemented Check that copying the order over works:: - sage: E = EllipticCurve(GF(431), [1,0]) - sage: P, = E.gens() - sage: Q = 2^99*P; Q.order() + sage: E = EllipticCurve(GF(431), [1,0]) # optional - sage.rings.finite_rings + sage: P, = E.gens() # optional - sage.rings.finite_rings + sage: Q = 2^99*P; Q.order() # optional - sage.rings.finite_rings 27 - sage: phi = E.isogeny(3^99*P) - sage: phi(Q)._order + sage: phi = E.isogeny(3^99*P) # optional - sage.rings.finite_rings + sage: phi(Q)._order # optional - sage.rings.finite_rings 27 """ if P.is_zero(): @@ -1224,11 +1312,11 @@ def __getitem__(self, i): sage: phi[1] y - sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) - sage: phi = EllipticCurveIsogeny(E, E((0,0))) - sage: phi[0] + sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0))) # optional - sage.rings.finite_rings + sage: phi[0] # optional - sage.rings.finite_rings (x^2 + 3)/x - sage: phi[1] + sage: phi[1] # optional - sage.rings.finite_rings (x^2*y - 3*y)/x^2 """ return self.rational_maps()[i] @@ -1245,9 +1333,9 @@ def __iter__(self): x y - sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) - sage: phi = EllipticCurveIsogeny(E, E((0,0))) - sage: for c in phi: print(c) + sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0))) # optional - sage.rings.finite_rings + sage: for c in phi: print(c) # optional - sage.rings.finite_rings (x^2 + 3)/x (x^2*y - 3*y)/x^2 """ @@ -1263,19 +1351,19 @@ def __neg__(self): The following examples inherently exercise this function:: - sage: E = EllipticCurve(j=GF(17)(0)) - sage: phi = EllipticCurveIsogeny(E, E((-1,0)) ) - sage: negphi = -phi - sage: phi(E((0,1))) + negphi(E((0,1))) == 0 + sage: E = EllipticCurve(j=GF(17)(0)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((-1,0)) ) # optional - sage.rings.finite_rings + sage: negphi = -phi # optional - sage.rings.finite_rings + sage: phi(E((0,1))) + negphi(E((0,1))) == 0 # optional - sage.rings.finite_rings True - sage: E = EllipticCurve(j=GF(19)(1728)) - sage: R. = GF(19)[] - sage: phi = EllipticCurveIsogeny(E, x) - sage: negphi = -phi - sage: phi(E((3,7))) + negphi(E((3,12))) == phi(2*E((3,7))) + sage: E = EllipticCurve(j=GF(19)(1728)) # optional - sage.rings.finite_rings + sage: R. = GF(19)[] # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x) # optional - sage.rings.finite_rings + sage: negphi = -phi # optional - sage.rings.finite_rings + sage: phi(E((3,7))) + negphi(E((3,12))) == phi(2*E((3,7))) # optional - sage.rings.finite_rings True - sage: negphi(E((18,6))) + sage: negphi(E((18,6))) # optional - sage.rings.finite_rings (17 : 0 : 1) sage: R. = QQ[] @@ -1290,27 +1378,31 @@ def __neg__(self): sage: phi(P) + negphi(P) == 0 True - sage: E = EllipticCurve(GF(23), [0,0,0,1,0]) - sage: f = E.torsion_polynomial(3)/3 - sage: phi = EllipticCurveIsogeny(E, f, E) - sage: phi.rational_maps() == E.multiplication_by_m(3) + sage: E = EllipticCurve(GF(23), [0,0,0,1,0]) # optional - sage.rings.finite_rings + sage: f = E.torsion_polynomial(3)/3 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f, E) # optional - sage.rings.finite_rings + sage: phi.rational_maps() == E.multiplication_by_m(3) # optional - sage.rings.finite_rings False - sage: negphi = -phi - sage: negphi.rational_maps() == E.multiplication_by_m(3) + sage: negphi = -phi # optional - sage.rings.finite_rings + sage: negphi.rational_maps() == E.multiplication_by_m(3) # optional - sage.rings.finite_rings True - sage: E = EllipticCurve(GF(17), [-2, 3, -5, 7, -11]) - sage: R. = GF(17)[] - sage: f = x+6 - sage: phi = EllipticCurveIsogeny(E, f) - sage: phi - Isogeny of degree 2 from Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 7*x + 6 over Finite Field of size 17 to Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 4*x + 8 over Finite Field of size 17 - sage: phi.rational_maps() + sage: E = EllipticCurve(GF(17), [-2, 3, -5, 7, -11]) # optional - sage.rings.finite_rings + sage: R. = GF(17)[] # optional - sage.rings.finite_rings + sage: f = x+6 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: phi # optional - sage.rings.finite_rings + Isogeny of degree 2 + from Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 7*x + 6 over Finite Field of size 17 + to Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 4*x + 8 over Finite Field of size 17 + sage: phi.rational_maps() # optional - sage.rings.finite_rings ((x^2 + 6*x + 4)/(x + 6), (x^2*y - 5*x*y + 8*x - 2*y)/(x^2 - 5*x + 2)) - sage: negphi = -phi - sage: negphi - Isogeny of degree 2 from Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 7*x + 6 over Finite Field of size 17 to Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 4*x + 8 over Finite Field of size 17 - sage: negphi.rational_maps() + sage: negphi = -phi # optional - sage.rings.finite_rings + sage: negphi # optional - sage.rings.finite_rings + Isogeny of degree 2 + from Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 7*x + 6 over Finite Field of size 17 + to Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 4*x + 8 over Finite Field of size 17 + sage: negphi.rational_maps() # optional - sage.rings.finite_rings ((x^2 + 6*x + 4)/(x + 6), (2*x^3 - x^2*y - 5*x^2 + 5*x*y - 4*x + 2*y + 7)/(x^2 - 5*x + 2)) @@ -1326,14 +1418,14 @@ def __neg__(self): sage: ymap1 == -ymap2 - E.a1()*xmap2 - E.a3() True - sage: K. = NumberField(x^2 + 1) - sage: E = EllipticCurve(K, [0,0,0,1,0]) - sage: R. = K[] - sage: phi = EllipticCurveIsogeny(E, x-a) - sage: phi.rational_maps() + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,0,0,1,0]) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: phi = EllipticCurveIsogeny(E, x - a) # optional - sage.rings.number_field + sage: phi.rational_maps() # optional - sage.rings.number_field ((x^2 + (-a)*x - 2)/(x + (-a)), (x^2*y + (-2*a)*x*y + y)/(x^2 + (-2*a)*x - 1)) - sage: negphi = -phi - sage: negphi.rational_maps() + sage: negphi = -phi # optional - sage.rings.number_field + sage: negphi.rational_maps() # optional - sage.rings.number_field ((x^2 + (-a)*x - 2)/(x + (-a)), (-x^2*y + (2*a)*x*y - y)/(x^2 + (-2*a)*x - 1)) """ output = copy(self) @@ -1350,9 +1442,9 @@ def _repr_(self): EXAMPLES:: - sage: E = EllipticCurve(GF(31), [1,0,1,1,0]) - sage: phi = EllipticCurveIsogeny(E, E((0,0)) ) - sage: phi._repr_() + sage: E = EllipticCurve(GF(31), [1,0,1,1,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0)) ) # optional - sage.rings.finite_rings + sage: phi._repr_() # optional - sage.rings.finite_rings 'Isogeny of degree 17 from Elliptic Curve defined by y^2 + x*y + y = x^3 + x over Finite Field of size 31 to Elliptic Curve defined by y^2 + x*y + y = x^3 + 14*x + 9 over Finite Field of size 31' sage: E = EllipticCurve(QQ, [1,0,0,1,9]) @@ -1376,10 +1468,10 @@ def _latex_(self): sage: phi._latex_() '\\left( x , y \\right)' - sage: E = EllipticCurve(GF(17), [0,0,0,1,-1]) - sage: R. = GF(17)[] - sage: phi = EllipticCurveIsogeny(E, X+11) - sage: phi._latex_() + sage: E = EllipticCurve(GF(17), [0,0,0,1,-1]) # optional - sage.rings.finite_rings + sage: R. = GF(17)[] # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, X + 11) # optional - sage.rings.finite_rings + sage: phi._latex_() # optional - sage.rings.finite_rings '\\left( \\frac{x^{2} + 11 x + 7}{x + 11} , \\frac{x^{2} y + 5 x y + 12 y}{x^{2} + 5 x + 2} \\right)' """ fx,fy = self.rational_maps() @@ -1408,16 +1500,17 @@ def __clear_cached_values(self): sage: old_ratl_maps[1] == -phi.rational_maps()[1] True - sage: F = GF(127); R. = F[] - sage: E = EllipticCurve(j=F(1728)) - sage: f = x^5 + 43*x^4 + 97*x^3 + 81*x^2 + 42*x + 82 - sage: phi = EllipticCurveIsogeny(E, f) - sage: old_ratl_maps = phi.rational_maps() + sage: F = GF(127); R. = F[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(j=F(1728)) # optional - sage.rings.finite_rings + sage: f = x^5 + 43*x^4 + 97*x^3 + 81*x^2 + 42*x + 82 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: old_ratl_maps = phi.rational_maps() # optional - sage.rings.finite_rings sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: phi._set_post_isomorphism(WeierstrassIsomorphism(phi.codomain(), (-13,13,-13,13))) - sage: old_ratl_maps == phi.rational_maps() + sage: phi._set_post_isomorphism(WeierstrassIsomorphism(phi.codomain(), # optional - sage.rings.finite_rings + ....: (-13,13,-13,13))) + sage: old_ratl_maps == phi.rational_maps() # optional - sage.rings.finite_rings False - sage: phi._EllipticCurveIsogeny__clear_cached_values() + sage: phi._EllipticCurveIsogeny__clear_cached_values() # optional - sage.rings.finite_rings """ self.__ratl_maps = None self.__dual = None @@ -1432,17 +1525,17 @@ def __perform_inheritance_housekeeping(self): The following examples will implicitly exercise this function:: - sage: E = EllipticCurve(GF(43), [2,3,5,7,11]) - sage: R. = GF(43)[]; f = x + 42 - sage: phi = EllipticCurveIsogeny(E, f) - sage: phi._EllipticCurveIsogeny__perform_inheritance_housekeeping() + sage: E = EllipticCurve(GF(43), [2,3,5,7,11]) # optional - sage.rings.finite_rings + sage: R. = GF(43)[]; f = x + 42 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__perform_inheritance_housekeeping() # optional - sage.rings.finite_rings sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: E2 = phi.codomain() - sage: post_isom = WeierstrassIsomorphism(E2, (41, 37, 31, 29)) - sage: phi._set_post_isomorphism(post_isom) - sage: E1pr = WeierstrassIsomorphism(E, (-1, 2, -3, 4)).codomain() - sage: pre_isom = E1pr.isomorphism_to(E) - sage: phi._set_pre_isomorphism(pre_isom) + sage: E2 = phi.codomain() # optional - sage.rings.finite_rings + sage: post_isom = WeierstrassIsomorphism(E2, (41, 37, 31, 29)) # optional - sage.rings.finite_rings + sage: phi._set_post_isomorphism(post_isom) # optional - sage.rings.finite_rings + sage: E1pr = WeierstrassIsomorphism(E, (-1, 2, -3, 4)).codomain() # optional - sage.rings.finite_rings + sage: pre_isom = E1pr.isomorphism_to(E) # optional - sage.rings.finite_rings + sage: phi._set_pre_isomorphism(pre_isom) # optional - sage.rings.finite_rings """ EllipticCurveHom.__init__(self, self._domain, self._codomain) @@ -1453,31 +1546,31 @@ def __init_algebraic_structs(self, E): EXAMPLES:: - sage: E = EllipticCurve(j=GF(17)(0)) - sage: phi = EllipticCurveIsogeny(E, E((-1,0))) + sage: E = EllipticCurve(j=GF(17)(0)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((-1,0))) # optional - sage.rings.finite_rings The constructor calls this function itself, so the fields it sets are already defined:: - sage: phi._domain + sage: phi._domain # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 17 - sage: phi._EllipticCurveIsogeny__base_field + sage: phi._EllipticCurveIsogeny__base_field # optional - sage.rings.finite_rings Finite Field of size 17 - sage: phi._EllipticCurveIsogeny__poly_ring + sage: phi._EllipticCurveIsogeny__poly_ring # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 17 - sage: phi._EllipticCurveIsogeny__mpoly_ring + sage: phi._EllipticCurveIsogeny__mpoly_ring # optional - sage.rings.finite_rings Multivariate Polynomial Ring in x, y over Finite Field of size 17 Now, calling the initialization function does nothing more:: - sage: phi._EllipticCurveIsogeny__init_algebraic_structs(E) - sage: phi._domain + sage: phi._EllipticCurveIsogeny__init_algebraic_structs(E) # optional - sage.rings.finite_rings + sage: phi._domain # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 17 - sage: phi._EllipticCurveIsogeny__base_field + sage: phi._EllipticCurveIsogeny__base_field # optional - sage.rings.finite_rings Finite Field of size 17 - sage: phi._EllipticCurveIsogeny__poly_ring + sage: phi._EllipticCurveIsogeny__poly_ring # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 17 - sage: phi._EllipticCurveIsogeny__mpoly_ring + sage: phi._EllipticCurveIsogeny__mpoly_ring # optional - sage.rings.finite_rings Multivariate Polynomial Ring in x, y over Finite Field of size 17 sage: E = EllipticCurve(QQ, [0,0,0,1,0]) @@ -1492,17 +1585,17 @@ def __init_algebraic_structs(self, E): sage: phi._EllipticCurveIsogeny__mpoly_ring Multivariate Polynomial Ring in x, y over Rational Field - sage: F = GF(19); R. = F[] - sage: E = EllipticCurve(j=GF(19)(0)) - sage: phi = EllipticCurveIsogeny(E, x) - sage: phi._EllipticCurveIsogeny__init_algebraic_structs(E) - sage: phi._domain + sage: F = GF(19); R. = F[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(j=GF(19)(0)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x) # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__init_algebraic_structs(E) # optional - sage.rings.finite_rings + sage: phi._domain # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 19 - sage: phi._EllipticCurveIsogeny__base_field + sage: phi._EllipticCurveIsogeny__base_field # optional - sage.rings.finite_rings Finite Field of size 19 - sage: phi._EllipticCurveIsogeny__poly_ring + sage: phi._EllipticCurveIsogeny__poly_ring # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 19 - sage: phi._EllipticCurveIsogeny__mpoly_ring + sage: phi._EllipticCurveIsogeny__mpoly_ring # optional - sage.rings.finite_rings Multivariate Polynomial Ring in x, y over Finite Field of size 19 """ self._domain = E @@ -1520,17 +1613,17 @@ def __compute_codomain(self): These examples inherently exercise this function:: - sage: E = EllipticCurve(j=GF(7)(1728)) - sage: phi = EllipticCurveIsogeny(E, E((0,0))) - sage: phi.codomain() + sage: E = EllipticCurve(j=GF(7)(1728)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0))) # optional - sage.rings.finite_rings + sage: phi.codomain() # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 3*x over Finite Field of size 7 - sage: phi._EllipticCurveIsogeny__compute_codomain() + sage: phi._EllipticCurveIsogeny__compute_codomain() # optional - sage.rings.finite_rings - sage: R. = GF(7)[] - sage: phi = EllipticCurveIsogeny(E, x) - sage: phi.codomain() + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x) # optional - sage.rings.finite_rings + sage: phi.codomain() # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 3*x over Finite Field of size 7 - sage: phi._EllipticCurveIsogeny__compute_codomain() + sage: phi._EllipticCurveIsogeny__compute_codomain() # optional - sage.rings.finite_rings """ if self.__algorithm == 'velu': self._codomain = self.__compute_codomain_via_velu() @@ -1553,14 +1646,14 @@ def __initialize_rational_maps(self, precomputed_maps=None): The following examples inherently exercise this function:: - sage: E = EllipticCurve(j=GF(7)(1728)) - sage: phi = EllipticCurveIsogeny(E, E((0,0))) - sage: phi.rational_maps() # implicit doctest + sage: E = EllipticCurve(j=GF(7)(1728)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0))) # optional - sage.rings.finite_rings + sage: phi.rational_maps() # implicit doctest # optional - sage.rings.finite_rings ((x^2 + 1)/x, (x^2*y - y)/x^2) - sage: R. = GF(7)[] - sage: phi = EllipticCurveIsogeny(E, x) - sage: phi.rational_maps() # implicit doctest + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x) # optional - sage.rings.finite_rings + sage: phi.rational_maps() # implicit doctest # optional - sage.rings.finite_rings ((x^2 + 1)/x, (x^2*y - y)/x^2) sage: E = EllipticCurve([1,2,3,4,5]) @@ -1610,9 +1703,9 @@ def __init_kernel_polynomial(self): The following examples inherently exercise this function:: - sage: E = EllipticCurve(j=GF(7)(1728)) - sage: phi = EllipticCurveIsogeny(E, E((0,0))) - sage: phi.kernel_polynomial() # implicit doctest + sage: E = EllipticCurve(j=GF(7)(1728)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0))) # optional - sage.rings.finite_rings + sage: phi.kernel_polynomial() # implicit doctest # optional - sage.rings.finite_rings x """ if self.__kernel_polynomial is None: @@ -1628,16 +1721,16 @@ def __set_pre_isomorphism(self, domain, isomorphism): EXAMPLES:: - sage: E = EllipticCurve(GF(43), [2,3,5,7,11]) - sage: R. = GF(43)[]; f = x + 42 - sage: phi = EllipticCurveIsogeny(E, f) - sage: phi._EllipticCurveIsogeny__perform_inheritance_housekeeping() + sage: E = EllipticCurve(GF(43), [2,3,5,7,11]) # optional - sage.rings.finite_rings + sage: R. = GF(43)[]; f = x + 42 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__perform_inheritance_housekeeping() # optional - sage.rings.finite_rings sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: E1pr = WeierstrassIsomorphism(E, (-1, 2, -3, 4)).codomain() - sage: pre_isom = E1pr.isomorphism_to(E) - sage: phi._set_pre_isomorphism(pre_isom) - sage: phi._EllipticCurveIsogeny__set_pre_isomorphism(E, WeierstrassIsomorphism(E, (-1, 3, -3, 4))) - sage: E == phi.domain() + sage: E1pr = WeierstrassIsomorphism(E, (-1, 2, -3, 4)).codomain() # optional - sage.rings.finite_rings + sage: pre_isom = E1pr.isomorphism_to(E) # optional - sage.rings.finite_rings + sage: phi._set_pre_isomorphism(pre_isom) # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__set_pre_isomorphism(E, WeierstrassIsomorphism(E, (-1, 3, -3, 4))) # optional - sage.rings.finite_rings + sage: E == phi.domain() # optional - sage.rings.finite_rings True """ self._domain = domain @@ -1672,14 +1765,14 @@ def __set_post_isomorphism(self, codomain, isomorphism): The following examples inherently exercise this function:: - sage: E = EllipticCurve(j=GF(7)(1728)) - sage: phi = EllipticCurveIsogeny(E, E((0,0))) + sage: E = EllipticCurve(j=GF(7)(1728)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0))) # optional - sage.rings.finite_rings sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: E2 = phi.codomain() - sage: isom = WeierstrassIsomorphism(E2, (-1,2,-3,4)) - sage: phi._set_post_isomorphism(isom) - sage: phi._EllipticCurveIsogeny__set_post_isomorphism(E2, WeierstrassIsomorphism(phi.codomain(), (1,-2,3,-4))) - sage: E2 == phi.codomain() + sage: E2 = phi.codomain() # optional - sage.rings.finite_rings + sage: isom = WeierstrassIsomorphism(E2, (-1,2,-3,4)) # optional - sage.rings.finite_rings + sage: phi._set_post_isomorphism(isom) # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__set_post_isomorphism(E2, WeierstrassIsomorphism(phi.codomain(), (1,-2,3,-4))) # optional - sage.rings.finite_rings + sage: E2 == phi.codomain() # optional - sage.rings.finite_rings True """ self._codomain = codomain @@ -1708,28 +1801,38 @@ def __setup_post_isomorphism(self, codomain, model): The following examples inherently exercise this function:: - sage: E = EllipticCurve(j=GF(7)(1728)) - sage: E2 = EllipticCurve(GF(7), [0,0,0,5,0]) - sage: phi = EllipticCurveIsogeny(E, E((0,0)), E2); phi - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 7 - sage: E3 = EllipticCurve(GF(7), [0,0,0,6,0]) - sage: phi._EllipticCurveIsogeny__setup_post_isomorphism(E3, None) - sage: phi - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 6*x over Finite Field of size 7 - - sage: EllipticCurveIsogeny(E, E(0,0), model='montgomery') - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + x^2 + x over Finite Field of size 7 + sage: E = EllipticCurve(j=GF(7)(1728)) # optional - sage.rings.finite_rings + sage: E2 = EllipticCurve(GF(7), [0,0,0,5,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0)), E2); phi # optional - sage.rings.finite_rings + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7 + to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 7 + sage: E3 = EllipticCurve(GF(7), [0,0,0,6,0]) # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__setup_post_isomorphism(E3, None) # optional - sage.rings.finite_rings + sage: phi # optional - sage.rings.finite_rings + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7 + to Elliptic Curve defined by y^2 = x^3 + 6*x over Finite Field of size 7 + + sage: EllipticCurveIsogeny(E, E(0,0), model='montgomery') # optional - sage.rings.finite_rings + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7 + to Elliptic Curve defined by y^2 = x^3 + x^2 + x over Finite Field of size 7 sage: R. = QQ[] sage: E = EllipticCurve(j=1728) sage: f = x^3 - x sage: phi = EllipticCurveIsogeny(E, f, model='minimal'); phi - Isogeny of degree 4 from Elliptic Curve defined by y^2 = x^3 - x over Rational Field to Elliptic Curve defined by y^2 = x^3 - x over Rational Field + Isogeny of degree 4 + from Elliptic Curve defined by y^2 = x^3 - x over Rational Field + to Elliptic Curve defined by y^2 = x^3 - x over Rational Field sage: phi = EllipticCurveIsogeny(E, f, model=None) sage: phi._EllipticCurveIsogeny__setup_post_isomorphism(None, 'minimal') sage: phi - Isogeny of degree 4 from Elliptic Curve defined by y^2 = x^3 - x over Rational Field to Elliptic Curve defined by y^2 = x^3 - x over Rational Field + Isogeny of degree 4 + from Elliptic Curve defined by y^2 = x^3 - x over Rational Field + to Elliptic Curve defined by y^2 = x^3 - x over Rational Field """ if model is codomain is None: return @@ -1770,21 +1873,27 @@ def __init_from_kernel_list(self, kernel_gens): The following example inherently exercises this function:: - sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) - sage: phi = EllipticCurveIsogeny(E, E((0,0))); phi - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 6*x over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 4*x over Finite Field of size 7 - sage: phi._EllipticCurveIsogeny__init_from_kernel_list([E(0), E((0,0))]) + sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0))); phi # optional - sage.rings.finite_rings + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 6*x over Finite Field of size 7 + to Elliptic Curve defined by y^2 = x^3 + 4*x over Finite Field of size 7 + sage: phi._EllipticCurveIsogeny__init_from_kernel_list([E(0), E((0,0))]) # optional - sage.rings.finite_rings The following example demonstrates the necessity of avoiding any calls to P.order(), since such calls involve factoring the group order which could take a long time. :: - sage: p = 12 * next_prime(2^180) * next_prime(2^194) - 1 - sage: F = FiniteField(p, proof=False) - sage: E = EllipticCurve([F(1), F(0)]) - sage: P = E(0).division_points(3)[1] - sage: EllipticCurveIsogeny(E, P) - Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 461742260113997803268895001173557974278278194575766957660028841364655249961609425998827452443620996655395008156411 to Elliptic Curve defined by y^2 = x^3 + 80816485163488178037199320944019099858815874115367810482828676054000067654558381377552245721755005198633191074893*x + 301497584865165444049833326660609767433467459033532853758006118022998267706948164646650354324860226263546558337993 over Finite Field of size 461742260113997803268895001173557974278278194575766957660028841364655249961609425998827452443620996655395008156411 + sage: p = 12 * next_prime(2^180) * next_prime(2^194) - 1 # optional - sage.rings.finite_rings + sage: F = FiniteField(p, proof=False) # optional - sage.rings.finite_rings + sage: E = EllipticCurve([F(1), F(0)]) # optional - sage.rings.finite_rings + sage: P = E(0).division_points(3)[1] # optional - sage.rings.finite_rings + sage: EllipticCurveIsogeny(E, P) # optional - sage.rings.finite_rings + Isogeny of degree 3 + from Elliptic Curve defined by y^2 = x^3 + x + over Finite Field of size 461742260113997803268895001173557974278278194575766957660028841364655249961609425998827452443620996655395008156411 + to Elliptic Curve defined by y^2 = x^3 + 80816485163488178037199320944019099858815874115367810482828676054000067654558381377552245721755005198633191074893*x + 301497584865165444049833326660609767433467459033532853758006118022998267706948164646650354324860226263546558337993 + over Finite Field of size 461742260113997803268895001173557974278278194575766957660028841364655249961609425998827452443620996655395008156411 """ if self.__check : for P in kernel_gens: @@ -1826,11 +1935,13 @@ def __sort_kernel_list(self): The following example inherently exercises this function:: - sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) - sage: P = E((4,2)) - sage: phi = EllipticCurveIsogeny(E, P); phi - Isogeny of degree 4 from Elliptic Curve defined by y^2 = x^3 + 6*x over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 7 - sage: phi._EllipticCurveIsogeny__sort_kernel_list() + sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) # optional - sage.rings.finite_rings + sage: P = E((4,2)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, P); phi # optional - sage.rings.finite_rings + Isogeny of degree 4 + from Elliptic Curve defined by y^2 = x^3 + 6*x over Finite Field of size 7 + to Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 7 + sage: phi._EllipticCurveIsogeny__sort_kernel_list() # optional - sage.rings.finite_rings """ a1, a2, a3, a4, _ = self._domain.a_invariants() @@ -1876,12 +1987,12 @@ def __compute_codomain_via_velu(self): The following example inherently exercises this function:: - sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) - sage: P = E((4,2)) - sage: phi = EllipticCurveIsogeny(E, P) - sage: phi.codomain() + sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) # optional - sage.rings.finite_rings + sage: P = E((4,2)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, P) # optional - sage.rings.finite_rings + sage: phi.codomain() # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 7 - sage: phi._EllipticCurveIsogeny__compute_codomain_via_velu() + sage: phi._EllipticCurveIsogeny__compute_codomain_via_velu() # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 7 """ return compute_codomain_formula(self._domain, self.__v, self.__w) @@ -1896,22 +2007,22 @@ def __velu_sum_helper(xQ, Qvalues, a1, a3, x, y): The following example inherently exercises this function:: - sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) - sage: P = E((4,2)) - sage: phi = EllipticCurveIsogeny(E, P) - sage: Q = E((0,0)); phi(Q) + sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) # optional - sage.rings.finite_rings + sage: P = E((4,2)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, P) # optional - sage.rings.finite_rings + sage: Q = E((0,0)); phi(Q) # optional - sage.rings.finite_rings (0 : 0 : 1) - sage: phi.rational_maps() + sage: phi.rational_maps() # optional - sage.rings.finite_rings ((x^4 - 2*x^3 + x^2 - 3*x)/(x^3 - 2*x^2 + 3*x - 2), (x^5*y - 2*x^3*y - x^2*y - 2*x*y + 2*y)/(x^5 + 3*x^3 + 3*x^2 + x - 1)) - sage: F = GF(7) - sage: E = EllipticCurve(F, [0,0,0,1,0]) - sage: phi = EllipticCurveIsogeny(E, E((0,0)) ) - sage: Qvals = phi._EllipticCurveIsogeny__kernel_mod_sign[0] - sage: phi._EllipticCurveIsogeny__velu_sum_helper(0, Qvals, 0, 0, F(5), F(5)) + sage: F = GF(7) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [0,0,0,1,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0)) ) # optional - sage.rings.finite_rings + sage: Qvals = phi._EllipticCurveIsogeny__kernel_mod_sign[0] # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__velu_sum_helper(0, Qvals, 0, 0, F(5), F(5)) # optional - sage.rings.finite_rings (3, 3) - sage: R. = GF(7)[] - sage: phi._EllipticCurveIsogeny__velu_sum_helper(0, Qvals, 0, 0, x, y) + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__velu_sum_helper(0, Qvals, 0, 0, x, y) # optional - sage.rings.finite_rings (1/x, y/x^2) """ yQ, gxQ, gyQ, vQ, uQ = Qvalues @@ -1944,17 +2055,17 @@ def __compute_via_velu_numeric(self, xP, yP): The following example inherently exercises this function:: - sage: F = GF(7) - sage: E = EllipticCurve(F, [0,0,0,-1,0]) - sage: P = E((4,2)) - sage: phi = EllipticCurveIsogeny(E, P) - sage: Q = E((0,0)); phi(Q) + sage: F = GF(7) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [0,0,0,-1,0]) # optional - sage.rings.finite_rings + sage: P = E((4,2)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, P) # optional - sage.rings.finite_rings + sage: Q = E((0,0)); phi(Q) # optional - sage.rings.finite_rings (0 : 0 : 1) - sage: Q = E((-1,0)); phi(Q) + sage: Q = E((-1,0)); phi(Q) # optional - sage.rings.finite_rings (0 : 0 : 1) - sage: phi._EllipticCurveIsogeny__compute_via_velu_numeric(F(0), F(0)) + sage: phi._EllipticCurveIsogeny__compute_via_velu_numeric(F(0), F(0)) # optional - sage.rings.finite_rings (0, 0) - sage: phi._EllipticCurveIsogeny__compute_via_velu_numeric(F(-1), F(0)) + sage: phi._EllipticCurveIsogeny__compute_via_velu_numeric(F(-1), F(0)) # optional - sage.rings.finite_rings (0, 0) """ # first check if the point is in the kernel @@ -1971,18 +2082,18 @@ def __compute_via_velu(self, xP, yP): The following example inherently exercises this function:: - sage: F = GF(7) - sage: E = EllipticCurve(F, [0,0,0,-1,0]) - sage: P = E((4,2)) - sage: phi = EllipticCurveIsogeny(E, P) - sage: Q = E((0,0)); phi(Q) + sage: F = GF(7) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [0,0,0,-1,0]) # optional - sage.rings.finite_rings + sage: P = E((4,2)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, P) # optional - sage.rings.finite_rings + sage: Q = E((0,0)); phi(Q) # optional - sage.rings.finite_rings (0 : 0 : 1) - sage: phi.rational_maps() + sage: phi.rational_maps() # optional - sage.rings.finite_rings ((x^4 - 2*x^3 + x^2 - 3*x)/(x^3 - 2*x^2 + 3*x - 2), (x^5*y - 2*x^3*y - x^2*y - 2*x*y + 2*y)/(x^5 + 3*x^3 + 3*x^2 + x - 1)) - sage: phi._EllipticCurveIsogeny__compute_via_velu(F(0), F(0)) + sage: phi._EllipticCurveIsogeny__compute_via_velu(F(0), F(0)) # optional - sage.rings.finite_rings (0, 0) - sage: R. = GF(7)[] - sage: phi._EllipticCurveIsogeny__compute_via_velu(x, y) + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__compute_via_velu(x, y) # optional - sage.rings.finite_rings ((x^4 - 2*x^3 + x^2 - 3*x)/(x^3 - 2*x^2 + 3*x - 2), (x^5*y - 2*x^3*y - x^2*y - 2*x*y + 2*y)/(x^5 + 3*x^3 + 3*x^2 + x - 1)) @@ -1990,24 +2101,24 @@ def __compute_via_velu(self, xP, yP): Check for :trac:`33214`:: - sage: z2 = GF(71^2).gen() - sage: E = EllipticCurve(GF(71^2), [5,5]) - sage: phi = E.isogeny(E.lift_x(0)) - sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: pre = WeierstrassIsomorphism(None, (z2,7,8,9), E) - sage: phi = phi * pre - sage: P = phi.domain()(1, 46*z2+49) - sage: phi(P) # indirect doctest + sage: z2 = GF(71^2).gen() # optional - sage.rings.finite_rings + sage: E = EllipticCurve(GF(71^2), [5,5]) # optional - sage.rings.finite_rings + sage: phi = E.isogeny(E.lift_x(0)) # optional - sage.rings.finite_rings + sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism # optional - sage.rings.finite_rings + sage: pre = WeierstrassIsomorphism(None, (z2,7,8,9), E) # optional - sage.rings.finite_rings + sage: phi = phi * pre # optional - sage.rings.finite_rings + sage: P = phi.domain()(1, 46*z2+49) # optional - sage.rings.finite_rings + sage: phi(P) # indirect doctest # optional - sage.rings.finite_rings (33 : 61*z2 + 10 : 1) The rational maps are also computed via this code path; check that they are plausible (this failed prior to :trac:`33214`):: - sage: fx,fy = phi.rational_maps() # indirect doctest - sage: R. = GF(71^2)[] - sage: E0, E2 = phi.domain(), phi.codomain() - sage: eqs = [EE.defining_polynomial()(x,y,1) for EE in (E0,E2)] - sage: eqs[1](fx,fy).numerator() % eqs[0] + sage: fx,fy = phi.rational_maps() # indirect doctest # optional - sage.rings.finite_rings + sage: R. = GF(71^2)[] # optional - sage.rings.finite_rings + sage: E0, E2 = phi.domain(), phi.codomain() # optional - sage.rings.finite_rings + sage: eqs = [EE.defining_polynomial()(x,y,1) for EE in (E0,E2)] # optional - sage.rings.finite_rings + sage: eqs[1](fx,fy).numerator() % eqs[0] # optional - sage.rings.finite_rings 0 """ if self.__pre_isomorphism is None: @@ -2037,12 +2148,12 @@ def __initialize_rational_maps_via_velu(self): The following example inherently exercises this function:: - sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) - sage: P = E((4,2)) - sage: phi = EllipticCurveIsogeny(E, P) - sage: phi.rational_maps() + sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) # optional - sage.rings.finite_rings + sage: P = E((4,2)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, P) # optional - sage.rings.finite_rings + sage: phi.rational_maps() # optional - sage.rings.finite_rings ((x^4 - 2*x^3 + x^2 - 3*x)/(x^3 - 2*x^2 + 3*x - 2), (x^5*y - 2*x^3*y - x^2*y - 2*x*y + 2*y)/(x^5 + 3*x^3 + 3*x^2 + x - 1)) - sage: phi._EllipticCurveIsogeny__initialize_rational_maps_via_velu() + sage: phi._EllipticCurveIsogeny__initialize_rational_maps_via_velu() # optional - sage.rings.finite_rings ((x^4 + 5*x^3 + x^2 + 4*x)/(x^3 + 5*x^2 + 3*x + 5), (x^5*y - 2*x^3*y - x^2*y - 2*x*y + 2*y)/(x^5 + 3*x^3 + 3*x^2 + x - 1)) """ x = self.__poly_ring.gen() @@ -2058,10 +2169,10 @@ def __init_kernel_polynomial_velu(self): The following example inherently exercises this function:: - sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) - sage: P = E((4,2)) - sage: phi = EllipticCurveIsogeny(E, P) - sage: phi.kernel_polynomial() # implicit doctest + sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) # optional - sage.rings.finite_rings + sage: P = E((4,2)) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, P) # optional - sage.rings.finite_rings + sage: phi.kernel_polynomial() # implicit doctest # optional - sage.rings.finite_rings x^2 + 2*x + 4 """ poly_ring, x = self.__poly_ring.objgen() @@ -2091,18 +2202,22 @@ def __init_from_kernel_polynomial(self, kernel_polynomial): These examples inherently exercise this private function:: - sage: R. = GF(7)[] - sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) - sage: phi = EllipticCurveIsogeny(E, x);phi - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 6*x over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 4*x over Finite Field of size 7 + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(GF(7), [0,0,0,-1,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x);phi # optional - sage.rings.finite_rings + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 6*x over Finite Field of size 7 + to Elliptic Curve defined by y^2 = x^3 + 4*x over Finite Field of size 7 - sage: phi._EllipticCurveIsogeny__init_from_kernel_polynomial(x) + sage: phi._EllipticCurveIsogeny__init_from_kernel_polynomial(x) # optional - sage.rings.finite_rings - sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) - sage: phi = EllipticCurveIsogeny(E, x+6, degree=3); phi - Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 1 over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 4*x + 2 over Finite Field of size 7 + sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x+6, degree=3); phi # optional - sage.rings.finite_rings + Isogeny of degree 3 + from Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 1 over Finite Field of size 7 + to Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 4*x + 2 over Finite Field of size 7 - sage: phi._EllipticCurveIsogeny__init_from_kernel_polynomial(x+6) + sage: phi._EllipticCurveIsogeny__init_from_kernel_polynomial(x+6) # optional - sage.rings.finite_rings """ poly_ring = self.__poly_ring E = self._domain @@ -2189,33 +2304,39 @@ def __init_even_kernel_polynomial(self, E, psi_G): These examples inherently exercise this private function:: - sage: R. = GF(7)[] - sage: E = EllipticCurve(GF(7), [-1,0]) - sage: phi = EllipticCurveIsogeny(E, x); phi - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 6*x over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 4*x over Finite Field of size 7 + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(GF(7), [-1,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x); phi # optional - sage.rings.finite_rings + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 6*x over Finite Field of size 7 + to Elliptic Curve defined by y^2 = x^3 + 4*x over Finite Field of size 7 sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import two_torsion_part - sage: psig = two_torsion_part(E,x) - sage: phi._EllipticCurveIsogeny__init_even_kernel_polynomial(E,psig) + sage: psig = two_torsion_part(E,x) # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__init_even_kernel_polynomial(E,psig) # optional - sage.rings.finite_rings (x^3 + 6*x, x^3*y + x*y, 6, 0, 1, 2) - sage: F = GF(2^4, 'alpha'); R. = F[] - sage: E = EllipticCurve(F, [1,1,0,1,0]) - sage: phi = EllipticCurveIsogeny(E, x); phi - Isogeny of degree 2 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + x over Finite Field in alpha of size 2^4 to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 1 over Finite Field in alpha of size 2^4 + sage: F = GF(2^4, 'alpha'); R. = F[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [1,1,0,1,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x); phi # optional - sage.rings.finite_rings + Isogeny of degree 2 + from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + x over Finite Field in alpha of size 2^4 + to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 1 over Finite Field in alpha of size 2^4 - sage: psig = two_torsion_part(E,x) - sage: phi._EllipticCurveIsogeny__init_even_kernel_polynomial(E,psig) + sage: psig = two_torsion_part(E,x) # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__init_even_kernel_polynomial(E,psig) # optional - sage.rings.finite_rings (x^3 + x, x^3*y + x^2 + x*y, 1, 0, 1, 2) - sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) - sage: R. = GF(7)[] - sage: f = x^3 + 6*x^2 + 1 - sage: phi = EllipticCurveIsogeny(E, f); phi - Isogeny of degree 4 from Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 1 over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 2*x + 5 over Finite Field of size 7 - sage: psig = two_torsion_part(E,f) - sage: psig = two_torsion_part(E,f) - sage: phi._EllipticCurveIsogeny__init_even_kernel_polynomial(E,psig) + sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) # optional - sage.rings.finite_rings + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: f = x^3 + 6*x^2 + 1 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f); phi # optional - sage.rings.finite_rings + Isogeny of degree 4 + from Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 1 over Finite Field of size 7 + to Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 2*x + 5 over Finite Field of size 7 + sage: psig = two_torsion_part(E,f) # optional - sage.rings.finite_rings + sage: psig = two_torsion_part(E,f) # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__init_even_kernel_polynomial(E,psig) # optional - sage.rings.finite_rings (x^7 + 5*x^6 + 2*x^5 + 6*x^4 + 3*x^3 + 5*x^2 + 6*x + 3, x^9*y - 3*x^8*y + 2*x^7*y - 3*x^3*y + 2*x^2*y + x*y - y, 1, 6, 3, 4) """ # check if the polynomial really divides the two_torsion_polynomial @@ -2300,33 +2421,39 @@ def __init_odd_kernel_polynomial(self, E, psi): These examples inherently exercise this private function:: - sage: R. = GF(7)[] - sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) - sage: phi = EllipticCurveIsogeny(E, x+6, degree=3); phi - Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 1 over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 4*x + 2 over Finite Field of size 7 + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x+6, degree=3); phi # optional - sage.rings.finite_rings + Isogeny of degree 3 + from Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 1 over Finite Field of size 7 + to Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 4*x + 2 over Finite Field of size 7 - sage: R. = GF(7)[] - sage: phi._EllipticCurveIsogeny__init_odd_kernel_polynomial(E, x+6) + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__init_odd_kernel_polynomial(E, x+6) # optional - sage.rings.finite_rings (x^3 + 5*x^2 + 3*x + 2, x^3*y - 3*x^2*y + x*y, 2, 6, 1, 3) - sage: F = GF(2^4, 'alpha'); R. = F[] - sage: alpha = F.gen() - sage: E = EllipticCurve(F, [1,1,F.gen(),F.gen()^2+1,1]) - sage: f = x + alpha^2 + 1 - sage: phi = EllipticCurveIsogeny(E, f); phi - Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + alpha*y = x^3 + x^2 + (alpha^2+1)*x + 1 over Finite Field in alpha of size 2^4 to Elliptic Curve defined by y^2 + x*y + alpha*y = x^3 + x^2 + alpha*x + alpha^3 over Finite Field in alpha of size 2^4 - - sage: R. = F[] - sage: f = x + alpha^2 + 1 - sage: phi._EllipticCurveIsogeny__init_odd_kernel_polynomial(E, f) + sage: F = GF(2^4, 'alpha'); R. = F[] # optional - sage.rings.finite_rings + sage: alpha = F.gen() # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [1,1,F.gen(),F.gen()^2+1,1]) # optional - sage.rings.finite_rings + sage: f = x + alpha^2 + 1 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f); phi # optional - sage.rings.finite_rings + Isogeny of degree 3 + from Elliptic Curve defined by y^2 + x*y + alpha*y = x^3 + x^2 + (alpha^2+1)*x + 1 over Finite Field in alpha of size 2^4 + to Elliptic Curve defined by y^2 + x*y + alpha*y = x^3 + x^2 + alpha*x + alpha^3 over Finite Field in alpha of size 2^4 + + sage: R. = F[] # optional - sage.rings.finite_rings + sage: f = x + alpha^2 + 1 # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__init_odd_kernel_polynomial(E, f) # optional - sage.rings.finite_rings (x^3 + (alpha^2 + 1)*x + alpha^3 + alpha^2 + alpha, x^3*y + (alpha^2 + 1)*x^2*y + (alpha^2 + alpha + 1)*x^2 + (alpha^2 + 1)*x*y + (alpha^2 + alpha)*x + alpha*y + alpha, alpha^2 + alpha + 1, alpha^3 + alpha^2 + alpha, 1, 3) - sage: E = EllipticCurve(j=-262537412640768000) - sage: f = E.isogenies_prime_degree()[0].kernel_polynomial() - sage: f.degree() + sage: E = EllipticCurve(j=-262537412640768000) # optional - sage.rings.finite_rings + sage: f = E.isogenies_prime_degree()[0].kernel_polynomial() # optional - sage.rings.finite_rings + sage: f.degree() # optional - sage.rings.finite_rings 81 - sage: E.isogeny(kernel=f, check=False) - Isogeny of degree 163 from Elliptic Curve defined by y^2 + y = x^3 - 2174420*x + 1234136692 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 57772164980*x - 5344733777551611 over Rational Field + sage: E.isogeny(kernel=f, check=False) # optional - sage.rings.finite_rings + Isogeny of degree 163 + from Elliptic Curve defined by y^2 + y = x^3 - 2174420*x + 1234136692 over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - 57772164980*x - 5344733777551611 over Rational Field """ n = psi.degree() d = 2*n + 1 @@ -2396,17 +2523,19 @@ def __compute_omega_fast(self, E, psi, psi_pr, phi, phi_pr): These examples inherently exercise this private function:: - sage: R. = GF(7)[] - sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) - sage: phi = EllipticCurveIsogeny(E, x+6, degree=3); phi - Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 1 over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 4*x + 2 over Finite Field of size 7 - - sage: R. = GF(7)[] - sage: psi = phi._EllipticCurveIsogeny__psi - sage: psi_pr = psi.derivative() - sage: fi = phi._EllipticCurveIsogeny__phi - sage: fi_pr = fi.derivative() - sage: phi._EllipticCurveIsogeny__compute_omega_fast(E, psi, psi_pr, fi, fi_pr) + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x+6, degree=3); phi # optional - sage.rings.finite_rings + Isogeny of degree 3 + from Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 1 over Finite Field of size 7 + to Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 4*x + 2 over Finite Field of size 7 + + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: psi = phi._EllipticCurveIsogeny__psi # optional - sage.rings.finite_rings + sage: psi_pr = psi.derivative() # optional - sage.rings.finite_rings + sage: fi = phi._EllipticCurveIsogeny__phi # optional - sage.rings.finite_rings + sage: fi_pr = fi.derivative() # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__compute_omega_fast(E, psi, psi_pr, fi, fi_pr) # optional - sage.rings.finite_rings x^3*y - 3*x^2*y + x*y """ a1 = E.a1() @@ -2443,30 +2572,35 @@ def __compute_omega_general(self, E, psi, psi_pr, phi, phi_pr): These examples inherently exercise this private function:: - sage: F = GF(2^4, 'alpha'); R. = F[] - sage: alpha = F.gen() - sage: E = EllipticCurve(F, [1, 1, F.gen(), F.gen()^2+1, 1]) - sage: f = x + alpha^2 + 1 - sage: phi = EllipticCurveIsogeny(E, f); phi - Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + alpha*y = x^3 + x^2 + (alpha^2+1)*x + 1 over Finite Field in alpha of size 2^4 to Elliptic Curve defined by y^2 + x*y + alpha*y = x^3 + x^2 + alpha*x + alpha^3 over Finite Field in alpha of size 2^4 - - sage: R. = F[] - sage: psi = phi._EllipticCurveIsogeny__psi - sage: psi_pr = psi.derivative() - sage: fi = phi._EllipticCurveIsogeny__phi - sage: fi_pr = fi.derivative() - sage: phi._EllipticCurveIsogeny__compute_omega_general(E, psi, psi_pr, fi, fi_pr) + sage: F = GF(2^4, 'alpha'); R. = F[] # optional - sage.rings.finite_rings + sage: alpha = F.gen() # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [1, 1, F.gen(), F.gen()^2+1, 1]) # optional - sage.rings.finite_rings + sage: f = x + alpha^2 + 1 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f); phi # optional - sage.rings.finite_rings + Isogeny of degree 3 + from Elliptic Curve defined by y^2 + x*y + alpha*y = x^3 + x^2 + (alpha^2+1)*x + 1 over Finite Field in alpha of size 2^4 + to Elliptic Curve defined by y^2 + x*y + alpha*y = x^3 + x^2 + alpha*x + alpha^3 over Finite Field in alpha of size 2^4 + + sage: R. = F[] # optional - sage.rings.finite_rings + sage: psi = phi._EllipticCurveIsogeny__psi # optional - sage.rings.finite_rings + sage: psi_pr = psi.derivative() # optional - sage.rings.finite_rings + sage: fi = phi._EllipticCurveIsogeny__phi # optional - sage.rings.finite_rings + sage: fi_pr = fi.derivative() # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__compute_omega_general(E, psi, psi_pr, fi, fi_pr) # optional - sage.rings.finite_rings x^3*y + (alpha^2 + 1)*x^2*y + (alpha^2 + alpha + 1)*x^2 + (alpha^2 + 1)*x*y + (alpha^2 + alpha)*x + alpha*y + alpha A bug fixed in :trac:`7907`:: - sage: F = GF(128,'a') - sage: a = F.gen() - sage: E = EllipticCurve([1,0,0,0,(a**6+a**4+a**2+a)]) - sage: x = polygen(F) - sage: ker = x^6 + (a^6 + a^5 + a^4 + a^3 + a^2 + a)*x^5 + (a^6 + a^5 + a^2 + 1)*x^4 + (a^6 + a^5 + a^4 + a^3 + a^2 + 1)*x^3 + (a^6 + a^3 + a)*x^2 + (a^4 + a^3 + 1)*x + a^5 + a^4 + a - sage: E.isogeny(ker) - Isogeny of degree 13 from Elliptic Curve defined by y^2 + x*y = x^3 + (a^6+a^4+a^2+a) over Finite Field in a of size 2^7 to Elliptic Curve defined by y^2 + x*y = x^3 + (a^6+a^5+a^4+a^3+a^2+a)*x + (a^5+a^3) over Finite Field in a of size 2^7 + sage: F = GF(128,'a') # optional - sage.rings.finite_rings + sage: a = F.gen() # optional - sage.rings.finite_rings + sage: E = EllipticCurve([1,0,0,0,(a**6+a**4+a**2+a)]) # optional - sage.rings.finite_rings + sage: x = polygen(F) # optional - sage.rings.finite_rings + sage: ker = (x^6 + (a^6 + a^5 + a^4 + a^3 + a^2 + a)*x^5 + (a^6 + a^5 + a^2 + 1)*x^4 # optional - sage.rings.finite_rings + ....: + (a^6 + a^5 + a^4 + a^3 + a^2 + 1)*x^3 + (a^6 + a^3 + a)*x^2 + (a^4 + a^3 + 1)*x + a^5 + a^4 + a) + sage: E.isogeny(ker) # optional - sage.rings.finite_rings + Isogeny of degree 13 + from Elliptic Curve defined by y^2 + x*y = x^3 + (a^6+a^4+a^2+a) over Finite Field in a of size 2^7 + to Elliptic Curve defined by y^2 + x*y = x^3 + (a^6+a^5+a^4+a^3+a^2+a)*x + (a^5+a^3) over Finite Field in a of size 2^7 """ a1, a2, a3, a4, a6 = E.a_invariants() b2, b4, _, _ = E.b_invariants() @@ -2519,16 +2653,16 @@ def __compute_via_kohel_numeric(self, xP, yP): These examples inherently exercise this private function:: - sage: R. = GF(7)[] - sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) - sage: phi = EllipticCurveIsogeny(E, x+6, degree=3) - sage: P = E((0,1)); phi(P) + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x+6, degree=3) # optional - sage.rings.finite_rings + sage: P = E((0,1)); phi(P) # optional - sage.rings.finite_rings (2 : 0 : 1) - sage: P = E((1,1)); phi(P) + sage: P = E((1,1)); phi(P) # optional - sage.rings.finite_rings (0 : 1 : 0) - sage: phi._EllipticCurveIsogeny__compute_via_kohel_numeric(0, 1) + sage: phi._EllipticCurveIsogeny__compute_via_kohel_numeric(0, 1) # optional - sage.rings.finite_rings (2, 0) - sage: phi._EllipticCurveIsogeny__compute_via_kohel_numeric(1, 1) + sage: phi._EllipticCurveIsogeny__compute_via_kohel_numeric(1, 1) # optional - sage.rings.finite_rings () """ # first check if the point is in the kernel @@ -2545,17 +2679,17 @@ def __compute_via_kohel(self, xP, yP): These examples inherently exercise this private function:: - sage: R. = GF(7)[] - sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) - sage: phi = EllipticCurveIsogeny(E, x+6, degree=3) - sage: P = E((0,1)); phi(P) + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x+6, degree=3) # optional - sage.rings.finite_rings + sage: P = E((0,1)); phi(P) # optional - sage.rings.finite_rings (2 : 0 : 1) - sage: phi.rational_maps() + sage: phi.rational_maps() # optional - sage.rings.finite_rings ((x^3 - 2*x^2 + 3*x + 2)/(x^2 - 2*x + 1), (x^3*y - 3*x^2*y + x*y)/(x^3 - 3*x^2 + 3*x - 1)) - sage: phi._EllipticCurveIsogeny__compute_via_kohel(0,1) + sage: phi._EllipticCurveIsogeny__compute_via_kohel(0,1) # optional - sage.rings.finite_rings (2, 0) - sage: R. = GF(7)[] - sage: phi._EllipticCurveIsogeny__compute_via_kohel(x,y) + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: phi._EllipticCurveIsogeny__compute_via_kohel(x,y) # optional - sage.rings.finite_rings ((x^3 - 2*x^2 + 3*x + 2)/(x^2 - 2*x + 1), (x^3*y - 3*x^2*y + x*y)/(x^3 - 3*x^2 + 3*x - 1)) """ a = self.__phi(xP) @@ -2572,12 +2706,12 @@ def __initialize_rational_maps_via_kohel(self): These examples inherently exercise this private function:: - sage: R. = GF(7)[] - sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) - sage: phi = EllipticCurveIsogeny(E, x+6, degree=3) - sage: phi.rational_maps() + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x+6, degree=3) # optional - sage.rings.finite_rings + sage: phi.rational_maps() # optional - sage.rings.finite_rings ((x^3 - 2*x^2 + 3*x + 2)/(x^2 - 2*x + 1), (x^3*y - 3*x^2*y + x*y)/(x^3 - 3*x^2 + 3*x - 1)) - sage: phi._EllipticCurveIsogeny__initialize_rational_maps_via_kohel() + sage: phi._EllipticCurveIsogeny__initialize_rational_maps_via_kohel() # optional - sage.rings.finite_rings ((x^3 + 5*x^2 + 3*x + 2)/(x^2 + 5*x + 1), (x^3*y - 3*x^2*y + x*y)/(x^3 - 3*x^2 + 3*x - 1)) """ x = self.__poly_ring.gen() @@ -2596,12 +2730,12 @@ def __compute_codomain_via_kohel(self): These examples inherently exercise this private function:: - sage: R. = GF(7)[] - sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) - sage: phi = EllipticCurveIsogeny(E, x+6, degree=3) - sage: phi.codomain() + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(GF(7), [0,-1,0,0,1]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x+6, degree=3) # optional - sage.rings.finite_rings + sage: phi.codomain() # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 4*x + 2 over Finite Field of size 7 - sage: phi._EllipticCurveIsogeny__compute_codomain_via_kohel() + sage: phi._EllipticCurveIsogeny__compute_codomain_via_kohel() # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 4*x + 2 over Finite Field of size 7 """ return compute_codomain_formula(self._domain, self.__v, self.__w) @@ -2629,9 +2763,9 @@ def rational_maps(self): sage: phi.rational_maps() (x, y) - sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) - sage: phi = EllipticCurveIsogeny(E, E((0,0))) - sage: phi.rational_maps() + sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0))) # optional - sage.rings.finite_rings + sage: phi.rational_maps() # optional - sage.rings.finite_rings ((x^2 + 3)/x, (x^2*y - 3*y)/x^2) """ self.__initialize_rational_maps() @@ -2656,9 +2790,9 @@ def x_rational_map(self): sage: phi.x_rational_map() x - sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) - sage: phi = EllipticCurveIsogeny(E, E((0,0))) - sage: phi.x_rational_map() + sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0))) # optional - sage.rings.finite_rings + sage: phi.x_rational_map() # optional - sage.rings.finite_rings (x^2 + 3)/x """ self.__initialize_rational_maps() @@ -2677,13 +2811,13 @@ def scaling_factor(self): EXAMPLES:: - sage: E = EllipticCurve(GF(257^2), [0,1]) - sage: phi = E.isogeny(E.lift_x(240)) - sage: phi.degree() + sage: E = EllipticCurve(GF(257^2), [0,1]) # optional - sage.rings.finite_rings + sage: phi = E.isogeny(E.lift_x(240)) # optional - sage.rings.finite_rings + sage: phi.degree() # optional - sage.rings.finite_rings 43 - sage: phi.scaling_factor() + sage: phi.scaling_factor() # optional - sage.rings.finite_rings 1 - sage: phi.dual().scaling_factor() + sage: phi.dual().scaling_factor() # optional - sage.rings.finite_rings 43 ALGORITHM: The "inner" isogeny is normalized by construction, @@ -2713,14 +2847,14 @@ def kernel_polynomial(self): sage: phi.kernel_polynomial() x^2 - 21*x + 80 - sage: E = EllipticCurve(GF(17), [1,-1,1,-1,1]) - sage: phi = EllipticCurveIsogeny(E, [1]) - sage: phi.kernel_polynomial() + sage: E = EllipticCurve(GF(17), [1,-1,1,-1,1]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, [1]) # optional - sage.rings.finite_rings + sage: phi.kernel_polynomial() # optional - sage.rings.finite_rings 1 - sage: E = EllipticCurve(GF(31), [0,0,0,3,0]) - sage: phi = EllipticCurveIsogeny(E, [0,3,0,1]) - sage: phi.kernel_polynomial() + sage: E = EllipticCurve(GF(31), [0,0,0,3,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, [0,3,0,1]) # optional - sage.rings.finite_rings + sage: phi.kernel_polynomial() # optional - sage.rings.finite_rings x^3 + 3*x """ if self.__kernel_polynomial is None: @@ -2737,9 +2871,9 @@ def is_separable(self): EXAMPLES:: - sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) - sage: phi = EllipticCurveIsogeny(E, E((0,0))) - sage: phi.is_separable() + sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, E((0,0))) # optional - sage.rings.finite_rings + sage: phi.is_separable() # optional - sage.rings.finite_rings True :: @@ -2761,53 +2895,62 @@ def _set_pre_isomorphism(self, preWI): TESTS:: - sage: E = EllipticCurve(GF(31), [1,1,0,1,-1]) - sage: R. = GF(31)[] - sage: f = x^3 + 9*x^2 + x + 30 - sage: phi = EllipticCurveIsogeny(E, f) - sage: Epr = E.short_weierstrass_model() - sage: isom = Epr.isomorphism_to(E) - sage: phi._set_pre_isomorphism(isom) - sage: phi.rational_maps() - ((-6*x^4 - 3*x^3 + 12*x^2 + 10*x - 1)/(x^3 + x - 12), (3*x^7 + x^6*y - 14*x^6 - 3*x^5 + 5*x^4*y + 7*x^4 + 8*x^3*y - 8*x^3 - 5*x^2*y + 5*x^2 - 14*x*y + 14*x - 6*y - 6)/(x^6 + 2*x^4 + 7*x^3 + x^2 + 7*x - 11)) - sage: phi(Epr((0,22))) + sage: E = EllipticCurve(GF(31), [1,1,0,1,-1]) # optional - sage.rings.finite_rings + sage: R. = GF(31)[] # optional - sage.rings.finite_rings + sage: f = x^3 + 9*x^2 + x + 30 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: Epr = E.short_weierstrass_model() # optional - sage.rings.finite_rings + sage: isom = Epr.isomorphism_to(E) # optional - sage.rings.finite_rings + sage: phi._set_pre_isomorphism(isom) # optional - sage.rings.finite_rings + sage: phi.rational_maps() # optional - sage.rings.finite_rings + ((-6*x^4 - 3*x^3 + 12*x^2 + 10*x - 1)/(x^3 + x - 12), + (3*x^7 + x^6*y - 14*x^6 - 3*x^5 + 5*x^4*y + 7*x^4 + 8*x^3*y - 8*x^3 - 5*x^2*y + 5*x^2 - 14*x*y + 14*x - 6*y - 6)/(x^6 + 2*x^4 + 7*x^3 + x^2 + 7*x - 11)) + sage: phi(Epr((0,22))) # optional - sage.rings.finite_rings (13 : 21 : 1) - sage: phi(Epr((3,7))) + sage: phi(Epr((3,7))) # optional - sage.rings.finite_rings (14 : 17 : 1) - sage: E = EllipticCurve(GF(29), [0,0,0,1,0]) - sage: R. = GF(29)[] - sage: f = x^2 + 5 - sage: phi = EllipticCurveIsogeny(E, f) - sage: phi - Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 29 to Elliptic Curve defined by y^2 = x^3 + 20*x over Finite Field of size 29 + sage: E = EllipticCurve(GF(29), [0,0,0,1,0]) # optional - sage.rings.finite_rings + sage: R. = GF(29)[] # optional - sage.rings.finite_rings + sage: f = x^2 + 5 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: phi # optional - sage.rings.finite_rings + Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 29 + to Elliptic Curve defined by y^2 = x^3 + 20*x over Finite Field of size 29 sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: inv_isom = WeierstrassIsomorphism(E, (1,-2,5,10)) - sage: Epr = inv_isom.codomain() - sage: isom = Epr.isomorphism_to(E) - sage: phi._set_pre_isomorphism(isom) - sage: phi - Isogeny of degree 5 from Elliptic Curve defined by y^2 + 10*x*y + 20*y = x^3 + 27*x^2 + 6 over Finite Field of size 29 to Elliptic Curve defined by y^2 = x^3 + 20*x over Finite Field of size 29 - sage: phi(Epr((12,1))) + sage: inv_isom = WeierstrassIsomorphism(E, (1,-2,5,10)) # optional - sage.rings.finite_rings + sage: Epr = inv_isom.codomain() # optional - sage.rings.finite_rings + sage: isom = Epr.isomorphism_to(E) # optional - sage.rings.finite_rings + sage: phi._set_pre_isomorphism(isom) # optional - sage.rings.finite_rings + sage: phi # optional - sage.rings.finite_rings + Isogeny of degree 5 + from Elliptic Curve defined by y^2 + 10*x*y + 20*y = x^3 + 27*x^2 + 6 over Finite Field of size 29 + to Elliptic Curve defined by y^2 = x^3 + 20*x over Finite Field of size 29 + sage: phi(Epr((12,1))) # optional - sage.rings.finite_rings (26 : 0 : 1) - sage: phi(Epr((2,9))) + sage: phi(Epr((2,9))) # optional - sage.rings.finite_rings (0 : 0 : 1) - sage: phi(Epr((21,12))) + sage: phi(Epr((21,12))) # optional - sage.rings.finite_rings (3 : 0 : 1) - sage: phi.rational_maps()[0] + sage: phi.rational_maps()[0] # optional - sage.rings.finite_rings (x^5 - 10*x^4 - 6*x^3 - 7*x^2 - x + 3)/(x^4 - 8*x^3 + 5*x^2 - 14*x - 6) sage: E = EllipticCurve('11a1') sage: R. = QQ[] sage: f = x^2 - 21*x + 80 sage: phi = EllipticCurveIsogeny(E, f); phi - Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field + Isogeny of degree 5 + from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism sage: Epr = E.short_weierstrass_model() sage: isom = Epr.isomorphism_to(E) sage: phi._set_pre_isomorphism(isom) sage: phi - Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 - 13392*x - 1080432 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field + Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 - 13392*x - 1080432 over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field sage: phi(Epr((168,1188))) (0 : 1 : 0) """ @@ -2841,24 +2984,26 @@ def _set_post_isomorphism(self, postWI): TESTS:: - sage: E = EllipticCurve(j=GF(31)(0)) - sage: R. = GF(31)[] - sage: phi = EllipticCurveIsogeny(E, x+18) + sage: E = EllipticCurve(j=GF(31)(0)) # optional - sage.rings.finite_rings + sage: R. = GF(31)[] # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, x+18) # optional - sage.rings.finite_rings sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: phi._set_post_isomorphism(WeierstrassIsomorphism(phi.codomain(), (6,8,10,12))) - sage: phi - Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 31 to Elliptic Curve defined by y^2 + 24*x*y + 7*y = x^3 + 22*x^2 + 16*x + 20 over Finite Field of size 31 - - sage: E = EllipticCurve(j=GF(47)(0)) - sage: f = E.torsion_polynomial(3)/3 - sage: phi = EllipticCurveIsogeny(E, f) - sage: E2 = phi.codomain() - sage: post_isom = E2.isomorphism_to(E) - sage: phi._set_post_isomorphism(post_isom) - sage: phi.rational_maps() == E.multiplication_by_m(3) + sage: phi._set_post_isomorphism(WeierstrassIsomorphism(phi.codomain(), (6,8,10,12))) # optional - sage.rings.finite_rings + sage: phi # optional - sage.rings.finite_rings + Isogeny of degree 3 + from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 31 + to Elliptic Curve defined by y^2 + 24*x*y + 7*y = x^3 + 22*x^2 + 16*x + 20 over Finite Field of size 31 + + sage: E = EllipticCurve(j=GF(47)(0)) # optional - sage.rings.finite_rings + sage: f = E.torsion_polynomial(3)/3 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: E2 = phi.codomain() # optional - sage.rings.finite_rings + sage: post_isom = E2.isomorphism_to(E) # optional - sage.rings.finite_rings + sage: phi._set_post_isomorphism(post_isom) # optional - sage.rings.finite_rings + sage: phi.rational_maps() == E.multiplication_by_m(3) # optional - sage.rings.finite_rings False - sage: phi = -phi - sage: phi.rational_maps() == E.multiplication_by_m(3) + sage: phi = -phi # optional - sage.rings.finite_rings + sage: phi.rational_maps() == E.multiplication_by_m(3) # optional - sage.rings.finite_rings True sage: R. = QQ[] @@ -2869,7 +3014,9 @@ def _set_post_isomorphism(self, postWI): sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism sage: post_isom = WeierstrassIsomorphism(phi.codomain(), (a,2,3,5)) sage: phi - Isogeny of degree 4 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in a with defining polynomial x^2 + 2 to Elliptic Curve defined by y^2 = x^3 + (-44)*x + 112 over Number Field in a with defining polynomial x^2 + 2 + Isogeny of degree 4 + from Elliptic Curve defined by y^2 = x^3 + x over Number Field in a with defining polynomial x^2 + 2 + to Elliptic Curve defined by y^2 = x^3 + (-44)*x + 112 over Number Field in a with defining polynomial x^2 + 2 """ WIdom = postWI.domain() WIcod = postWI.codomain() @@ -2923,71 +3070,82 @@ def dual(self): sage: (Xm, Ym) == E.multiplication_by_m(5) True - sage: E = EllipticCurve(GF(37), [0,0,0,1,8]) - sage: R. = GF(37)[] - sage: f = x^3 + x^2 + 28*x + 33 - sage: phi = EllipticCurveIsogeny(E, f) - sage: phi_hat = phi.dual() - sage: phi_hat.codomain() == phi.domain() + sage: E = EllipticCurve(GF(37), [0,0,0,1,8]) # optional - sage.rings.finite_rings + sage: R. = GF(37)[] # optional - sage.rings.finite_rings + sage: f = x^3 + x^2 + 28*x + 33 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: phi_hat = phi.dual() # optional - sage.rings.finite_rings + sage: phi_hat.codomain() == phi.domain() # optional - sage.rings.finite_rings True - sage: phi_hat.domain() == phi.codomain() + sage: phi_hat.domain() == phi.codomain() # optional - sage.rings.finite_rings True - sage: (X, Y) = phi.rational_maps() - sage: (Xhat, Yhat) = phi_hat.rational_maps() - sage: Xm = Xhat.subs(x=X, y=Y) - sage: Ym = Yhat.subs(x=X, y=Y) - sage: (Xm, Ym) == E.multiplication_by_m(7) + sage: (X, Y) = phi.rational_maps() # optional - sage.rings.finite_rings + sage: (Xhat, Yhat) = phi_hat.rational_maps() # optional - sage.rings.finite_rings + sage: Xm = Xhat.subs(x=X, y=Y) # optional - sage.rings.finite_rings + sage: Ym = Yhat.subs(x=X, y=Y) # optional - sage.rings.finite_rings + sage: (Xm, Ym) == E.multiplication_by_m(7) # optional - sage.rings.finite_rings True - sage: E = EllipticCurve(GF(31), [0,0,0,1,8]) - sage: R. = GF(31)[] - sage: f = x^2 + 17*x + 29 - sage: phi = EllipticCurveIsogeny(E, f) - sage: phi_hat = phi.dual() - sage: phi_hat.codomain() == phi.domain() + sage: E = EllipticCurve(GF(31), [0,0,0,1,8]) # optional - sage.rings.finite_rings + sage: R. = GF(31)[] # optional - sage.rings.finite_rings + sage: f = x^2 + 17*x + 29 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: phi_hat = phi.dual() # optional - sage.rings.finite_rings + sage: phi_hat.codomain() == phi.domain() # optional - sage.rings.finite_rings True - sage: phi_hat.domain() == phi.codomain() + sage: phi_hat.domain() == phi.codomain() # optional - sage.rings.finite_rings True - sage: (X, Y) = phi.rational_maps() - sage: (Xhat, Yhat) = phi_hat.rational_maps() - sage: Xm = Xhat.subs(x=X, y=Y) - sage: Ym = Yhat.subs(x=X, y=Y) - sage: (Xm, Ym) == E.multiplication_by_m(5) + sage: (X, Y) = phi.rational_maps() # optional - sage.rings.finite_rings + sage: (Xhat, Yhat) = phi_hat.rational_maps() # optional - sage.rings.finite_rings + sage: Xm = Xhat.subs(x=X, y=Y) # optional - sage.rings.finite_rings + sage: Ym = Yhat.subs(x=X, y=Y) # optional - sage.rings.finite_rings + sage: (Xm, Ym) == E.multiplication_by_m(5) # optional - sage.rings.finite_rings True Inseparable duals should be computed correctly:: - sage: z2 = GF(71^2).gen() - sage: E = EllipticCurve(j=57*z2+51) - sage: E.isogeny(3*E.lift_x(0)).dual() + sage: z2 = GF(71^2).gen() # optional - sage.rings.finite_rings + sage: E = EllipticCurve(j=57*z2+51) # optional - sage.rings.finite_rings + sage: E.isogeny(3*E.lift_x(0)).dual() # optional - sage.rings.finite_rings Composite morphism of degree 71 = 71*1^2: - From: Elliptic Curve defined by y^2 = x^3 + (32*z2+67)*x + (24*z2+37) over Finite Field in z2 of size 71^2 - To: Elliptic Curve defined by y^2 = x^3 + (41*z2+56)*x + (18*z2+42) over Finite Field in z2 of size 71^2 - sage: E.isogeny(E.lift_x(0)).dual() + From: Elliptic Curve defined by y^2 = x^3 + (32*z2+67)*x + (24*z2+37) + over Finite Field in z2 of size 71^2 + To: Elliptic Curve defined by y^2 = x^3 + (41*z2+56)*x + (18*z2+42) + over Finite Field in z2 of size 71^2 + sage: E.isogeny(E.lift_x(0)).dual() # optional - sage.rings.finite_rings Composite morphism of degree 213 = 71*3: - From: Elliptic Curve defined by y^2 = x^3 + (58*z2+31)*x + (34*z2+58) over Finite Field in z2 of size 71^2 - To: Elliptic Curve defined by y^2 = x^3 + (41*z2+56)*x + (18*z2+42) over Finite Field in z2 of size 71^2 + From: Elliptic Curve defined by y^2 = x^3 + (58*z2+31)*x + (34*z2+58) + over Finite Field in z2 of size 71^2 + To: Elliptic Curve defined by y^2 = x^3 + (41*z2+56)*x + (18*z2+42) + over Finite Field in z2 of size 71^2 ...even if pre- or post-isomorphisms are present:: sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: phi = E.isogeny(E.lift_x(0)) - sage: pre = ~WeierstrassIsomorphism(phi.domain(), (z2,2,3,4)) - sage: post = WeierstrassIsomorphism(phi.codomain(), (5,6,7,8)) - sage: phi = post * phi * pre - sage: phi.dual() + sage: phi = E.isogeny(E.lift_x(0)) # optional - sage.rings.finite_rings + sage: pre = ~WeierstrassIsomorphism(phi.domain(), (z2,2,3,4)) # optional - sage.rings.finite_rings + sage: post = WeierstrassIsomorphism(phi.codomain(), (5,6,7,8)) # optional - sage.rings.finite_rings + sage: phi = post * phi * pre # optional - sage.rings.finite_rings + sage: phi.dual() # optional - sage.rings.finite_rings Composite morphism of degree 213 = 71*3: - From: Elliptic Curve defined by y^2 + 17*x*y + 45*y = x^3 + 30*x^2 + (6*z2+64)*x + (48*z2+65) over Finite Field in z2 of size 71^2 - To: Elliptic Curve defined by y^2 + (60*z2+22)*x*y + (69*z2+37)*y = x^3 + (32*z2+48)*x^2 + (19*z2+58)*x + (56*z2+22) over Finite Field in z2 of size 71^2 + From: Elliptic Curve defined + by y^2 + 17*x*y + 45*y = x^3 + 30*x^2 + (6*z2+64)*x + (48*z2+65) + over Finite Field in z2 of size 71^2 + To: Elliptic Curve defined + by y^2 + (60*z2+22)*x*y + (69*z2+37)*y = x^3 + (32*z2+48)*x^2 + + (19*z2+58)*x + (56*z2+22) + over Finite Field in z2 of size 71^2 TESTS: Test for :trac:`23928`:: - sage: E = EllipticCurve(j=GF(431**2)(4)) - sage: phi = E.isogeny(E.lift_x(0)) - sage: phi.dual() - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 427*x over Finite Field in z2 of size 431^2 to Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2 + sage: E = EllipticCurve(j=GF(431**2)(4)) # optional - sage.rings.finite_rings + sage: phi = E.isogeny(E.lift_x(0)) # optional - sage.rings.finite_rings + sage: phi.dual() # optional - sage.rings.finite_rings + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 427*x over Finite Field in z2 of size 431^2 + to Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2 Test (for :trac:`7096`):: @@ -2996,30 +3154,34 @@ def dual(self): sage: phi.dual().dual() == phi True - sage: k = GF(103) - sage: E = EllipticCurve(k,[11,11]) - sage: phi = E.isogeny(E(4,4)) - sage: phi - Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 11*x + 11 over Finite Field of size 103 to Elliptic Curve defined by y^2 = x^3 + 25*x + 80 over Finite Field of size 103 + sage: k = GF(103) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(k,[11,11]) # optional - sage.rings.finite_rings + sage: phi = E.isogeny(E(4,4)) # optional - sage.rings.finite_rings + sage: phi # optional - sage.rings.finite_rings + Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + 11*x + 11 over Finite Field of size 103 + to Elliptic Curve defined by y^2 = x^3 + 25*x + 80 over Finite Field of size 103 sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: phi = WeierstrassIsomorphism(phi.codomain(),(5,0,1,2)) * phi - sage: phi.dual().dual() == phi + sage: phi = WeierstrassIsomorphism(phi.codomain(),(5,0,1,2)) * phi # optional - sage.rings.finite_rings + sage: phi.dual().dual() == phi # optional - sage.rings.finite_rings True - sage: E = EllipticCurve(GF(103),[1,0,0,1,-1]) - sage: phi = E.isogeny(E(60,85)) - sage: phi.dual() - Isogeny of degree 7 from Elliptic Curve defined by y^2 + x*y = x^3 + 84*x + 34 over Finite Field of size 103 to Elliptic Curve defined by y^2 + x*y = x^3 + x + 102 over Finite Field of size 103 + sage: E = EllipticCurve(GF(103),[1,0,0,1,-1]) # optional - sage.rings.finite_rings + sage: phi = E.isogeny(E(60,85)) # optional - sage.rings.finite_rings + sage: phi.dual() # optional - sage.rings.finite_rings + Isogeny of degree 7 + from Elliptic Curve defined by y^2 + x*y = x^3 + 84*x + 34 over Finite Field of size 103 + to Elliptic Curve defined by y^2 + x*y = x^3 + x + 102 over Finite Field of size 103 Check that :trac:`17293` is fixed:: - sage: k. = QuadraticField(2) - sage: E = EllipticCurve(k, [-3*s*(4 + 5*s), 2*s*(2 + 14*s + 11*s^2)]) - sage: phi = E.isogenies_prime_degree(3)[0] - sage: (-phi).dual() == -phi.dual() + sage: k. = QuadraticField(2) # optional - sage.rings.number_field + sage: E = EllipticCurve(k, [-3*s*(4 + 5*s), 2*s*(2 + 14*s + 11*s^2)]) # optional - sage.rings.number_field + sage: phi = E.isogenies_prime_degree(3)[0] # optional - sage.rings.number_field + sage: (-phi).dual() == -phi.dual() # optional - sage.rings.number_field True - sage: phi._EllipticCurveIsogeny__clear_cached_values() # forget the dual - sage: -phi.dual() == (-phi).dual() + sage: phi._EllipticCurveIsogeny__clear_cached_values() # forget the dual # optional - sage.rings.number_field + sage: -phi.dual() == (-phi).dual() # optional - sage.rings.number_field True """ if self.__base_field.characteristic() in (2, 3): @@ -3112,23 +3274,29 @@ def _composition_impl(left, right): EXAMPLES:: - sage: E = EllipticCurve(GF(127), [5,2]) - sage: phi = E.isogeny(E.lift_x(47)); E2 = phi.codomain() - sage: iso1 = E.change_weierstrass_model(1,1,1,1).isomorphism_to(E) - sage: iso2 = E2.isomorphism_to(E2.change_weierstrass_model(39,0,0,0)) - sage: phi * iso1 # indirect doctest - Isogeny of degree 11 from Elliptic Curve defined by y^2 + 2*x*y + 2*y = x^3 + 2*x^2 + 6*x + 7 over Finite Field of size 127 to Elliptic Curve defined by y^2 = x^3 + 37*x + 85 over Finite Field of size 127 - sage: iso2 * phi # indirect doctest - Isogeny of degree 11 from Elliptic Curve defined by y^2 = x^3 + 5*x + 2 over Finite Field of size 127 to Elliptic Curve defined by y^2 = x^3 + 117*x + 58 over Finite Field of size 127 - sage: iso2 * phi * iso1 # indirect doctest - Isogeny of degree 11 from Elliptic Curve defined by y^2 + 2*x*y + 2*y = x^3 + 2*x^2 + 6*x + 7 over Finite Field of size 127 to Elliptic Curve defined by y^2 = x^3 + 117*x + 58 over Finite Field of size 127 + sage: E = EllipticCurve(GF(127), [5,2]) # optional - sage.rings.finite_rings + sage: phi = E.isogeny(E.lift_x(47)); E2 = phi.codomain() # optional - sage.rings.finite_rings + sage: iso1 = E.change_weierstrass_model(1,1,1,1).isomorphism_to(E) # optional - sage.rings.finite_rings + sage: iso2 = E2.isomorphism_to(E2.change_weierstrass_model(39,0,0,0)) # optional - sage.rings.finite_rings + sage: phi * iso1 # indirect doctest # optional - sage.rings.finite_rings + Isogeny of degree 11 + from Elliptic Curve defined by y^2 + 2*x*y + 2*y = x^3 + 2*x^2 + 6*x + 7 over Finite Field of size 127 + to Elliptic Curve defined by y^2 = x^3 + 37*x + 85 over Finite Field of size 127 + sage: iso2 * phi # indirect doctest # optional - sage.rings.finite_rings + Isogeny of degree 11 + from Elliptic Curve defined by y^2 = x^3 + 5*x + 2 over Finite Field of size 127 + to Elliptic Curve defined by y^2 = x^3 + 117*x + 58 over Finite Field of size 127 + sage: iso2 * phi * iso1 # indirect doctest # optional - sage.rings.finite_rings + Isogeny of degree 11 + from Elliptic Curve defined by y^2 + 2*x*y + 2*y = x^3 + 2*x^2 + 6*x + 7 over Finite Field of size 127 + to Elliptic Curve defined by y^2 = x^3 + 117*x + 58 over Finite Field of size 127 TESTS: We should return ``NotImplemented`` when passed a combination of elliptic-curve morphism types that we don't handle here:: - sage: phi._composition_impl(iso1, iso1**-1) + sage: phi._composition_impl(iso1, iso1**-1) # optional - sage.rings.finite_rings NotImplemented """ if isinstance(left, WeierstrassIsomorphism) and isinstance(right, EllipticCurveIsogeny): @@ -3183,22 +3351,22 @@ def compute_isogeny_stark(E1, E2, ell): sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import compute_isogeny_stark, compute_sequence_of_maps - sage: E = EllipticCurve(GF(97), [1,0,1,1,0]) - sage: R. = GF(97)[]; f = x^5 + 27*x^4 + 61*x^3 + 58*x^2 + 28*x + 21 - sage: phi = EllipticCurveIsogeny(E, f) - sage: E2 = phi.codomain() - sage: (isom1, isom2, E1pr, E2pr, ker_poly) = compute_sequence_of_maps(E, E2, 11) - sage: compute_isogeny_stark(E1pr, E2pr, 11) + sage: E = EllipticCurve(GF(97), [1,0,1,1,0]) # optional - sage.rings.finite_rings + sage: R. = GF(97)[]; f = x^5 + 27*x^4 + 61*x^3 + 58*x^2 + 28*x + 21 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: E2 = phi.codomain() # optional - sage.rings.finite_rings + sage: isom1, isom2, E1pr, E2pr, ker_poly = compute_sequence_of_maps(E, E2, 11) # optional - sage.rings.finite_rings + sage: compute_isogeny_stark(E1pr, E2pr, 11) # optional - sage.rings.finite_rings x^10 + 37*x^9 + 53*x^8 + 66*x^7 + 66*x^6 + 17*x^5 + 57*x^4 + 6*x^3 + 89*x^2 + 53*x + 8 - sage: E = EllipticCurve(GF(37), [0,0,0,1,8]) - sage: R. = GF(37)[] - sage: f = (x + 14) * (x + 30) - sage: phi = EllipticCurveIsogeny(E, f) - sage: E2 = phi.codomain() - sage: compute_isogeny_stark(E, E2, 5) + sage: E = EllipticCurve(GF(37), [0,0,0,1,8]) # optional - sage.rings.finite_rings + sage: R. = GF(37)[] # optional - sage.rings.finite_rings + sage: f = (x + 14) * (x + 30) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: E2 = phi.codomain() # optional - sage.rings.finite_rings + sage: compute_isogeny_stark(E, E2, 5) # optional - sage.rings.finite_rings x^4 + 14*x^3 + x^2 + 34*x + 21 - sage: f**2 + sage: f**2 # optional - sage.rings.finite_rings x^4 + 14*x^3 + x^2 + 34*x + 21 sage: E = EllipticCurve(QQ, [0,0,0,1,0]) @@ -3280,11 +3448,11 @@ def split_kernel_polynomial(poly): Check that this behaves identically to ``.radical()``:: sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import split_kernel_polynomial - sage: q = next_prime(randrange(3,10^3)) - sage: e = randrange(1,5) - sage: R = GF(q^e,'a')['x'] - sage: f = R.random_element(randrange(10,100)).monic() - sage: split_kernel_polynomial(f) == f.radical() + sage: q = next_prime(randrange(3,10^3)) # optional - sage.rings.finite_rings + sage: e = randrange(1,5) # optional - sage.rings.finite_rings + sage: R = GF(q^e,'a')['x'] # optional - sage.rings.finite_rings + sage: f = R.random_element(randrange(10,100)).monic() # optional - sage.rings.finite_rings + sage: split_kernel_polynomial(f) == f.radical() # optional - sage.rings.finite_rings doctest:warning ... DeprecationWarning: ... True @@ -3324,40 +3492,40 @@ def compute_isogeny_kernel_polynomial(E1, E2, ell, algorithm="stark"): sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import compute_isogeny_kernel_polynomial - sage: E = EllipticCurve(GF(37), [0,0,0,1,8]) - sage: R. = GF(37)[] - sage: f = (x + 14) * (x + 30) - sage: phi = EllipticCurveIsogeny(E, f) - sage: E2 = phi.codomain() - sage: compute_isogeny_kernel_polynomial(E, E2, 5) + sage: E = EllipticCurve(GF(37), [0,0,0,1,8]) # optional - sage.rings.finite_rings + sage: R. = GF(37)[] # optional - sage.rings.finite_rings + sage: f = (x + 14) * (x + 30) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: E2 = phi.codomain() # optional - sage.rings.finite_rings + sage: compute_isogeny_kernel_polynomial(E, E2, 5) # optional - sage.rings.finite_rings x^2 + 7*x + 13 - sage: f + sage: f # optional - sage.rings.finite_rings x^2 + 7*x + 13 sage: R. = QQ[] - sage: K. = NumberField(x^2 + 1) - sage: E = EllipticCurve(K, [0,0,0,1,0]) - sage: E2 = EllipticCurve(K, [0,0,0,16,0]) - sage: compute_isogeny_kernel_polynomial(E, E2, 4) + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,0,0,1,0]) # optional - sage.rings.number_field + sage: E2 = EllipticCurve(K, [0,0,0,16,0]) # optional - sage.rings.number_field + sage: compute_isogeny_kernel_polynomial(E, E2, 4) # optional - sage.rings.number_field x^3 + x TESTS: Check that :meth:`Polynomial.radical` is doing the right thing for us:: - sage: E = EllipticCurve(GF(37), [0,0,0,1,8]) - sage: R. = GF(37)[] - sage: f = (x + 10) * (x + 12) * (x + 16) - sage: phi = EllipticCurveIsogeny(E, f) - sage: E2 = phi.codomain() + sage: E = EllipticCurve(GF(37), [0,0,0,1,8]) # optional - sage.rings.finite_rings + sage: R. = GF(37)[] # optional - sage.rings.finite_rings + sage: f = (x + 10) * (x + 12) * (x + 16) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: E2 = phi.codomain() # optional - sage.rings.finite_rings sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import compute_isogeny_stark - sage: ker_poly = compute_isogeny_stark(E, E2, 7); ker_poly + sage: ker_poly = compute_isogeny_stark(E, E2, 7); ker_poly # optional - sage.rings.finite_rings x^6 + 2*x^5 + 20*x^4 + 11*x^3 + 36*x^2 + 35*x + 16 - sage: ker_poly.factor() + sage: ker_poly.factor() # optional - sage.rings.finite_rings (x + 10)^2 * (x + 12)^2 * (x + 16)^2 - sage: poly = ker_poly.radical(); poly + sage: poly = ker_poly.radical(); poly # optional - sage.rings.finite_rings x^3 + x^2 + 28*x + 33 - sage: poly.factor() + sage: poly.factor() # optional - sage.rings.finite_rings (x + 10) * (x + 12) * (x + 16) """ if algorithm == 'starks': @@ -3405,32 +3573,40 @@ def compute_intermediate_curves(E1, E2): EXAMPLES:: sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import compute_intermediate_curves - sage: E = EllipticCurve(GF(83), [1,0,1,1,0]) - sage: R. = GF(83)[]; f = x+24 - sage: phi = EllipticCurveIsogeny(E, f) - sage: E2 = phi.codomain() - sage: compute_intermediate_curves(E, E2) + sage: E = EllipticCurve(GF(83), [1,0,1,1,0]) # optional - sage.rings.finite_rings + sage: R. = GF(83)[]; f = x + 24 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: E2 = phi.codomain() # optional - sage.rings.finite_rings + sage: compute_intermediate_curves(E, E2) # optional - sage.rings.finite_rings (Elliptic Curve defined by y^2 = x^3 + 62*x + 74 over Finite Field of size 83, Elliptic Curve defined by y^2 = x^3 + 65*x + 69 over Finite Field of size 83, Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x over Finite Field of size 83 - To: Elliptic Curve defined by y^2 = x^3 + 62*x + 74 over Finite Field of size 83 + From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x + over Finite Field of size 83 + To: Elliptic Curve defined by y^2 = x^3 + 62*x + 74 + over Finite Field of size 83 Via: (u,r,s,t) = (1, 76, 41, 3), Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 = x^3 + 65*x + 69 over Finite Field of size 83 - To: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + 16 over Finite Field of size 83 + From: Elliptic Curve defined by y^2 = x^3 + 65*x + 69 + over Finite Field of size 83 + To: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + 16 + over Finite Field of size 83 Via: (u,r,s,t) = (1, 7, 42, 42)) sage: R. = QQ[] - sage: K. = NumberField(x^2 + 1) - sage: E = EllipticCurve(K, [0,0,0,1,0]) - sage: E2 = EllipticCurve(K, [0,0,0,16,0]) - sage: compute_intermediate_curves(E, E2) - (Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1, - Elliptic Curve defined by y^2 = x^3 + 16*x over Number Field in i with defining polynomial x^2 + 1, - Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1 + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,0,0,1,0]) # optional - sage.rings.number_field + sage: E2 = EllipticCurve(K, [0,0,0,16,0]) # optional - sage.rings.number_field + sage: compute_intermediate_curves(E, E2) # optional - sage.rings.number_field + (Elliptic Curve defined by y^2 = x^3 + x + over Number Field in i with defining polynomial x^2 + 1, + Elliptic Curve defined by y^2 = x^3 + 16*x + over Number Field in i with defining polynomial x^2 + 1, + Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x + over Number Field in i with defining polynomial x^2 + 1 Via: (u,r,s,t) = (1, 0, 0, 0), - Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + 16*x over Number Field in i with defining polynomial x^2 + 1 + Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + 16*x + over Number Field in i with defining polynomial x^2 + 1 Via: (u,r,s,t) = (1, 0, 0, 0)) """ if E1.base_ring().characteristic() in (2, 3): @@ -3493,41 +3669,53 @@ def compute_sequence_of_maps(E1, E2, ell): sage: E2 = phi.codomain() sage: compute_sequence_of_maps(E, E2, 5) (Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field - To: Elliptic Curve defined by y^2 = x^3 - 31/3*x - 2501/108 over Rational Field + From: Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 + over Rational Field + To: Elliptic Curve defined by y^2 = x^3 - 31/3*x - 2501/108 + over Rational Field Via: (u,r,s,t) = (1, 1/3, 0, -1/2), Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 = x^3 - 23461/3*x - 28748141/108 over Rational Field - To: Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field + From: Elliptic Curve defined by y^2 = x^3 - 23461/3*x - 28748141/108 + over Rational Field + To: Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 + over Rational Field Via: (u,r,s,t) = (1, -1/3, 0, 1/2), Elliptic Curve defined by y^2 = x^3 - 31/3*x - 2501/108 over Rational Field, Elliptic Curve defined by y^2 = x^3 - 23461/3*x - 28748141/108 over Rational Field, x^2 - 61/3*x + 658/9) - sage: K. = NumberField(x^2 + 1) - sage: E = EllipticCurve(K, [0,0,0,1,0]) - sage: E2 = EllipticCurve(K, [0,0,0,16,0]) - sage: compute_sequence_of_maps(E, E2, 4) - (Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1 + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,0,0,1,0]) # optional - sage.rings.number_field + sage: E2 = EllipticCurve(K, [0,0,0,16,0]) # optional - sage.rings.number_field + sage: compute_sequence_of_maps(E, E2, 4) # optional - sage.rings.number_field + (Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x + over Number Field in i with defining polynomial x^2 + 1 Via: (u,r,s,t) = (1, 0, 0, 0), - Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + 16*x over Number Field in i with defining polynomial x^2 + 1 + Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + 16*x + over Number Field in i with defining polynomial x^2 + 1 Via: (u,r,s,t) = (1, 0, 0, 0), - Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1, - Elliptic Curve defined by y^2 = x^3 + 16*x over Number Field in i with defining polynomial x^2 + 1, + Elliptic Curve defined by y^2 = x^3 + x + over Number Field in i with defining polynomial x^2 + 1, + Elliptic Curve defined by y^2 = x^3 + 16*x + over Number Field in i with defining polynomial x^2 + 1, x^3 + x) - sage: E = EllipticCurve(GF(97), [1,0,1,1,0]) - sage: R. = GF(97)[]; f = x^5 + 27*x^4 + 61*x^3 + 58*x^2 + 28*x + 21 - sage: phi = EllipticCurveIsogeny(E, f) - sage: E2 = phi.codomain() - sage: compute_sequence_of_maps(E, E2, 11) + sage: E = EllipticCurve(GF(97), [1,0,1,1,0]) # optional - sage.rings.finite_rings + sage: R. = GF(97)[]; f = x^5 + 27*x^4 + 61*x^3 + 58*x^2 + 28*x + 21 # optional - sage.rings.finite_rings + sage: phi = EllipticCurveIsogeny(E, f) # optional - sage.rings.finite_rings + sage: E2 = phi.codomain() # optional - sage.rings.finite_rings + sage: compute_sequence_of_maps(E, E2, 11) # optional - sage.rings.finite_rings (Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x over Finite Field of size 97 - To: Elliptic Curve defined by y^2 = x^3 + 52*x + 31 over Finite Field of size 97 + From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x + over Finite Field of size 97 + To: Elliptic Curve defined by y^2 = x^3 + 52*x + 31 + over Finite Field of size 97 Via: (u,r,s,t) = (1, 8, 48, 44), Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 = x^3 + 41*x + 66 over Finite Field of size 97 - To: Elliptic Curve defined by y^2 + x*y + y = x^3 + 87*x + 26 over Finite Field of size 97 + From: Elliptic Curve defined by y^2 = x^3 + 41*x + 66 + over Finite Field of size 97 + To: Elliptic Curve defined by y^2 + x*y + y = x^3 + 87*x + 26 + over Finite Field of size 97 Via: (u,r,s,t) = (1, 89, 49, 49), Elliptic Curve defined by y^2 = x^3 + 52*x + 31 over Finite Field of size 97, Elliptic Curve defined by y^2 = x^3 + 41*x + 66 over Finite Field of size 97, @@ -3559,7 +3747,8 @@ def fill_isogeny_matrix(M): EXAMPLES:: - sage: M = Matrix([[0, 2, 3, 3, 0, 0], [2, 0, 0, 0, 3, 3], [3, 0, 0, 0, 2, 0], [3, 0, 0, 0, 0, 2], [0, 3, 2, 0, 0, 0], [0, 3, 0, 2, 0, 0]]); M + sage: M = Matrix([[0, 2, 3, 3, 0, 0], [2, 0, 0, 0, 3, 3], [3, 0, 0, 0, 2, 0], + ....: [3, 0, 0, 0, 0, 2], [0, 3, 2, 0, 0, 0], [0, 3, 0, 2, 0, 0]]); M [0 2 3 3 0 0] [2 0 0 0 3 3] [3 0 0 0 2 0] @@ -3614,7 +3803,8 @@ def unfill_isogeny_matrix(M): EXAMPLES:: - sage: M = Matrix([[0, 2, 3, 3, 0, 0], [2, 0, 0, 0, 3, 3], [3, 0, 0, 0, 2, 0], [3, 0, 0, 0, 0, 2], [0, 3, 2, 0, 0, 0], [0, 3, 0, 2, 0, 0]]); M + sage: M = Matrix([[0, 2, 3, 3, 0, 0], [2, 0, 0, 0, 3, 3], [3, 0, 0, 0, 2, 0], + ....: [3, 0, 0, 0, 0, 2], [0, 3, 2, 0, 0, 0], [0, 3, 0, 2, 0, 0]]); M [0 2 3 3 0 0] [2 0 0 0 3 3] [3 0 0 0 2 0] diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 49958afae66..7a98d1d1bfe 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -1,8 +1,8 @@ r""" Elliptic curves over a general field -This module defines the class ``EllipticCurve_field``, based on -``EllipticCurve_generic``, for elliptic curves over general fields. +This module defines the class :class:`EllipticCurve_field`, based on +:class:`EllipticCurve_generic`, for elliptic curves over general fields. """ #***************************************************************************** # Copyright (C) 2006 William Stein @@ -46,8 +46,8 @@ def genus(self): EXAMPLES:: - sage: E = EllipticCurve(GF(3), [0, -1, 0, -346, 2652]) - sage: E.genus() + sage: E = EllipticCurve(GF(3), [0, -1, 0, -346, 2652]) # optional - sage.rings.finite_rings + sage: E.genus() # optional - sage.rings.finite_rings 1 sage: R = FractionField(QQ['z']) @@ -96,46 +96,52 @@ def quadratic_twist(self, D=None): EXAMPLES:: - sage: E = EllipticCurve([GF(1103)(1), 0, 0, 107, 340]); E - Elliptic Curve defined by y^2 + x*y = x^3 + 107*x + 340 over Finite Field of size 1103 - sage: F=E.quadratic_twist(-1); F - Elliptic Curve defined by y^2 = x^3 + 1102*x^2 + 609*x + 300 over Finite Field of size 1103 - sage: E.is_isomorphic(F) + sage: E = EllipticCurve([GF(1103)(1), 0, 0, 107, 340]); E # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 + x*y = x^3 + 107*x + 340 + over Finite Field of size 1103 + sage: F = E.quadratic_twist(-1); F # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 = x^3 + 1102*x^2 + 609*x + 300 + over Finite Field of size 1103 + sage: E.is_isomorphic(F) # optional - sage.rings.finite_rings False - sage: E.is_isomorphic(F,GF(1103^2,'a')) + sage: E.is_isomorphic(F, GF(1103^2,'a')) # optional - sage.rings.finite_rings True A characteristic 2 example:: - sage: E=EllipticCurve(GF(2),[1,0,1,1,1]) - sage: E1=E.quadratic_twist(1) - sage: E.is_isomorphic(E1) + sage: E = EllipticCurve(GF(2), [1,0,1,1,1]) # optional - sage.rings.finite_rings + sage: E1 = E.quadratic_twist(1) # optional - sage.rings.finite_rings + sage: E.is_isomorphic(E1) # optional - sage.rings.finite_rings False - sage: E.is_isomorphic(E1,GF(4,'a')) + sage: E.is_isomorphic(E1, GF(4,'a')) # optional - sage.rings.finite_rings True Over finite fields, the twisting parameter may be omitted:: - sage: k. = GF(2^10) - sage: E = EllipticCurve(k,[a^2,a,1,a+1,1]) - sage: Et = E.quadratic_twist() - sage: Et # random (only determined up to isomorphism) - Elliptic Curve defined by y^2 + x*y = x^3 + (a^7+a^4+a^3+a^2+a+1)*x^2 + (a^8+a^6+a^4+1) over Finite Field in a of size 2^10 - sage: E.is_isomorphic(Et) + sage: k. = GF(2^10) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(k, [a^2,a,1,a+1,1]) # optional - sage.rings.finite_rings + sage: Et = E.quadratic_twist() # optional - sage.rings.finite_rings + sage: Et # random (only determined up to isomorphism) # optional - sage.rings.finite_rings + Elliptic Curve defined + by y^2 + x*y = x^3 + (a^7+a^4+a^3+a^2+a+1)*x^2 + (a^8+a^6+a^4+1) + over Finite Field in a of size 2^10 + sage: E.is_isomorphic(Et) # optional - sage.rings.finite_rings False - sage: E.j_invariant()==Et.j_invariant() + sage: E.j_invariant() == Et.j_invariant() # optional - sage.rings.finite_rings True - sage: p=next_prime(10^10) - sage: k = GF(p) - sage: E = EllipticCurve(k,[1,2,3,4,5]) - sage: Et = E.quadratic_twist() - sage: Et # random (only determined up to isomorphism) - Elliptic Curve defined by y^2 = x^3 + 7860088097*x^2 + 9495240877*x + 3048660957 over Finite Field of size 10000000019 - sage: E.is_isomorphic(Et) + sage: p = next_prime(10^10) # optional - sage.rings.finite_rings + sage: k = GF(p) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(k, [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: Et = E.quadratic_twist() # optional - sage.rings.finite_rings + sage: Et # random (only determined up to isomorphism) # optional - sage.rings.finite_rings + Elliptic Curve defined + by y^2 = x^3 + 7860088097*x^2 + 9495240877*x + 3048660957 + over Finite Field of size 10000000019 + sage: E.is_isomorphic(Et) # optional - sage.rings.finite_rings False - sage: k2 = GF(p^2,'a') - sage: E.change_ring(k2).is_isomorphic(Et.change_ring(k2)) + sage: k2 = GF(p^2,'a') # optional - sage.rings.finite_rings + sage: E.change_ring(k2).is_isomorphic(Et.change_ring(k2)) # optional - sage.rings.finite_rings True """ K = self.base_ring() @@ -199,11 +205,11 @@ def two_torsion_rank(self): EXAMPLES:: - sage: E=EllipticCurve('11a1') + sage: E = EllipticCurve('11a1') sage: E.two_torsion_rank() 0 - sage: K.=QQ.extension(E.division_polynomial(2).monic()) - sage: E.base_extend(K).two_torsion_rank() + sage: K. = QQ.extension(E.division_polynomial(2).monic()) # optional - sage.rings.number_field + sage: E.base_extend(K).two_torsion_rank() # optional - sage.rings.number_field 1 sage: E.reduction(53).two_torsion_rank() 2 @@ -213,8 +219,9 @@ def two_torsion_rank(self): sage: E = EllipticCurve('14a1') sage: E.two_torsion_rank() 1 - sage: K.=QQ.extension(E.division_polynomial(2).monic().factor()[1][0]) - sage: E.base_extend(K).two_torsion_rank() + sage: f = E.division_polynomial(2).monic().factor()[1][0] + sage: K. = QQ.extension(f) # optional - sage.rings.number_field + sage: E.base_extend(K).two_torsion_rank() # optional - sage.rings.number_field 2 :: @@ -241,15 +248,15 @@ def quartic_twist(self, D): EXAMPLES:: - sage: E=EllipticCurve_from_j(GF(13)(1728)); E - Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 13 - sage: E1=E.quartic_twist(2); E1 - Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 13 - sage: E.is_isomorphic(E1) + sage: E = EllipticCurve_from_j(GF(13)(1728)); E # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 13 + sage: E1 = E.quartic_twist(2); E1 # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 13 + sage: E.is_isomorphic(E1) # optional - sage.rings.finite_rings False - sage: E.is_isomorphic(E1,GF(13^2,'a')) + sage: E.is_isomorphic(E1, GF(13^2,'a')) # optional - sage.rings.finite_rings False - sage: E.is_isomorphic(E1,GF(13^4,'a')) + sage: E.is_isomorphic(E1, GF(13^4,'a')) # optional - sage.rings.finite_rings True """ K=self.base_ring() @@ -284,17 +291,17 @@ def sextic_twist(self, D): EXAMPLES:: - sage: E=EllipticCurve_from_j(GF(13)(0)); E + sage: E = EllipticCurve_from_j(GF(13)(0)); E # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 13 - sage: E1=E.sextic_twist(2); E1 + sage: E1 = E.sextic_twist(2); E1 # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 11 over Finite Field of size 13 - sage: E.is_isomorphic(E1) + sage: E.is_isomorphic(E1) # optional - sage.rings.finite_rings False - sage: E.is_isomorphic(E1,GF(13^2,'a')) + sage: E.is_isomorphic(E1, GF(13^2,'a')) # optional - sage.rings.finite_rings False - sage: E.is_isomorphic(E1,GF(13^4,'a')) + sage: E.is_isomorphic(E1, GF(13^4,'a')) # optional - sage.rings.finite_rings False - sage: E.is_isomorphic(E1,GF(13^6,'a')) + sage: E.is_isomorphic(E1, GF(13^6,'a')) # optional - sage.rings.finite_rings True """ K=self.base_ring() @@ -344,10 +351,10 @@ def is_quadratic_twist(self, other): sage: E.is_quadratic_twist(Et) -6 - sage: E1=EllipticCurve([0,0,1,0,0]) + sage: E1 = EllipticCurve([0,0,1,0,0]) sage: E1.j_invariant() 0 - sage: E2=EllipticCurve([0,0,0,0,2]) + sage: E2 = EllipticCurve([0,0,0,0,2]) sage: E1.is_quadratic_twist(E2) 2 sage: E1.is_quadratic_twist(E1) @@ -357,52 +364,52 @@ def is_quadratic_twist(self, other): :: - sage: E1=EllipticCurve([0,0,0,1,0]) + sage: E1 = EllipticCurve([0,0,0,1,0]) sage: E1.j_invariant() 1728 - sage: E2=EllipticCurve([0,0,0,2,0]) + sage: E2 = EllipticCurve([0,0,0,2,0]) sage: E1.is_quadratic_twist(E2) 0 - sage: E2=EllipticCurve([0,0,0,25,0]) + sage: E2 = EllipticCurve([0,0,0,25,0]) sage: E1.is_quadratic_twist(E2) 5 :: - sage: F = GF(101) - sage: E1 = EllipticCurve(F,[4,7]) - sage: E2 = E1.quadratic_twist() - sage: D = E1.is_quadratic_twist(E2); D!=0 + sage: F = GF(101) # optional - sage.rings.finite_rings + sage: E1 = EllipticCurve(F, [4,7]) # optional - sage.rings.finite_rings + sage: E2 = E1.quadratic_twist() # optional - sage.rings.finite_rings + sage: D = E1.is_quadratic_twist(E2); D != 0 # optional - sage.rings.finite_rings True - sage: F = GF(101) - sage: E1 = EllipticCurve(F,[4,7]) - sage: E2 = E1.quadratic_twist() - sage: D = E1.is_quadratic_twist(E2) - sage: E1.quadratic_twist(D).is_isomorphic(E2) + sage: F = GF(101) # optional - sage.rings.finite_rings + sage: E1 = EllipticCurve(F, [4,7]) # optional - sage.rings.finite_rings + sage: E2 = E1.quadratic_twist() # optional - sage.rings.finite_rings + sage: D = E1.is_quadratic_twist(E2) # optional - sage.rings.finite_rings + sage: E1.quadratic_twist(D).is_isomorphic(E2) # optional - sage.rings.finite_rings True - sage: E1.is_isomorphic(E2) + sage: E1.is_isomorphic(E2) # optional - sage.rings.finite_rings False - sage: F2 = GF(101^2,'a') - sage: E1.change_ring(F2).is_isomorphic(E2.change_ring(F2)) + sage: F2 = GF(101^2,'a') # optional - sage.rings.finite_rings + sage: E1.change_ring(F2).is_isomorphic(E2.change_ring(F2)) # optional - sage.rings.finite_rings True A characteristic 3 example:: - sage: F = GF(3^5,'a') - sage: E1 = EllipticCurve_from_j(F(1)) - sage: E2 = E1.quadratic_twist(-1) - sage: D = E1.is_quadratic_twist(E2); D!=0 + sage: F = GF(3^5,'a') # optional - sage.rings.finite_rings + sage: E1 = EllipticCurve_from_j(F(1)) # optional - sage.rings.finite_rings + sage: E2 = E1.quadratic_twist(-1) # optional - sage.rings.finite_rings + sage: D = E1.is_quadratic_twist(E2); D != 0 # optional - sage.rings.finite_rings True - sage: E1.quadratic_twist(D).is_isomorphic(E2) + sage: E1.quadratic_twist(D).is_isomorphic(E2) # optional - sage.rings.finite_rings True :: - sage: E1 = EllipticCurve_from_j(F(0)) - sage: E2 = E1.quadratic_twist() - sage: D = E1.is_quadratic_twist(E2); D + sage: E1 = EllipticCurve_from_j(F(0)) # optional - sage.rings.finite_rings + sage: E2 = E1.quadratic_twist() # optional - sage.rings.finite_rings + sage: D = E1.is_quadratic_twist(E2); D # optional - sage.rings.finite_rings 1 - sage: E1.is_isomorphic(E2) + sage: E1.is_isomorphic(E2) # optional - sage.rings.finite_rings True """ from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve @@ -488,11 +495,11 @@ def is_quartic_twist(self, other): EXAMPLES:: - sage: E = EllipticCurve_from_j(GF(13)(1728)) - sage: E1 = E.quartic_twist(2) - sage: D = E.is_quartic_twist(E1); D!=0 + sage: E = EllipticCurve_from_j(GF(13)(1728)) # optional - sage.rings.finite_rings + sage: E1 = E.quartic_twist(2) # optional - sage.rings.finite_rings + sage: D = E.is_quartic_twist(E1); D!=0 # optional - sage.rings.finite_rings True - sage: E.quartic_twist(D).is_isomorphic(E1) + sage: E.quartic_twist(D).is_isomorphic(E1) # optional - sage.rings.finite_rings True :: @@ -557,11 +564,11 @@ def is_sextic_twist(self, other): EXAMPLES:: - sage: E = EllipticCurve_from_j(GF(13)(0)) - sage: E1 = E.sextic_twist(2) - sage: D = E.is_sextic_twist(E1); D!=0 + sage: E = EllipticCurve_from_j(GF(13)(0)) # optional - sage.rings.finite_rings + sage: E1 = E.sextic_twist(2) # optional - sage.rings.finite_rings + sage: D = E.is_sextic_twist(E1); D != 0 # optional - sage.rings.finite_rings True - sage: E.sextic_twist(D).is_isomorphic(E1) + sage: E.sextic_twist(D).is_isomorphic(E1) # optional - sage.rings.finite_rings True :: @@ -642,48 +649,52 @@ def descend_to(self, K, f=None): :: - sage: F. = QuadraticField(23) - sage: G. = F.extension(x^3+5) - sage: E = EllipticCurve(j=1728*b).change_ring(G) - sage: EF = E.descend_to(F); EF - [Elliptic Curve defined by y^2 = x^3 + (27*b-621)*x + (-1296*b+2484) over Number Field in b with defining polynomial x^2 - 23 with b = 4.795831523312720?] - sage: all(Ei.change_ring(G).is_isomorphic(E) for Ei in EF) + sage: F. = QuadraticField(23) # optional - sage.rings.number_field + sage: G. = F.extension(x^3 + 5) + sage: E = EllipticCurve(j=1728*b).change_ring(G) # optional - sage.rings.number_field + sage: EF = E.descend_to(F); EF # optional - sage.rings.number_field + [Elliptic Curve defined by y^2 = x^3 + (27*b-621)*x + (-1296*b+2484) + over Number Field in b with defining polynomial x^2 - 23 + with b = 4.795831523312720?] + sage: all(Ei.change_ring(G).is_isomorphic(E) for Ei in EF) # optional - sage.rings.number_field True :: - sage: L. = NumberField(x^4 - 7) - sage: K. = NumberField(x^2 - 7, embedding=a^2) - sage: E = EllipticCurve([a^6,0]) - sage: EK = E.descend_to(K); EK - [Elliptic Curve defined by y^2 = x^3 + b*x over Number Field in b with defining polynomial x^2 - 7 with b = a^2, - Elliptic Curve defined by y^2 = x^3 + 7*b*x over Number Field in b with defining polynomial x^2 - 7 with b = a^2] - sage: all(Ei.change_ring(L).is_isomorphic(E) for Ei in EK) + sage: L. = NumberField(x^4 - 7) # optional - sage.rings.number_field + sage: K. = NumberField(x^2 - 7, embedding=a^2) # optional - sage.rings.number_field + sage: E = EllipticCurve([a^6, 0]) # optional - sage.rings.number_field + sage: EK = E.descend_to(K); EK # optional - sage.rings.number_field + [Elliptic Curve defined by y^2 = x^3 + b*x over Number Field in b + with defining polynomial x^2 - 7 with b = a^2, + Elliptic Curve defined by y^2 = x^3 + 7*b*x over Number Field in b + with defining polynomial x^2 - 7 with b = a^2] + sage: all(Ei.change_ring(L).is_isomorphic(E) for Ei in EK) # optional - sage.rings.number_field True :: - sage: K. = QuadraticField(17) - sage: E = EllipticCurve(j = 2*a) - sage: E.descend_to(QQ) + sage: K. = QuadraticField(17) # optional - sage.rings.number_field + sage: E = EllipticCurve(j=2*a) # optional - sage.rings.number_field + sage: E.descend_to(QQ) # optional - sage.rings.number_field [] TESTS: Check that :trac:`16456` is fixed:: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve('11a1').quadratic_twist(2) - sage: EK = E.change_ring(K) - sage: EK2 = EK.change_weierstrass_model((a,a,a,a+1)) - sage: EK2.descend_to(QQ) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve('11a1').quadratic_twist(2) # optional - sage.rings.number_field + sage: EK = E.change_ring(K) # optional - sage.rings.number_field + sage: EK2 = EK.change_weierstrass_model((a,a,a,a+1)) # optional - sage.rings.number_field + sage: EK2.descend_to(QQ) # optional - sage.rings.number_field [Elliptic Curve defined by y^2 = x^3 + x^2 - 41*x - 199 over Rational Field] - sage: k. = QuadraticField(-1) - sage: E = EllipticCurve(k,[0,0,0,1,0]) - sage: E.descend_to(QQ) + sage: k. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve(k,[0,0,0,1,0]) # optional - sage.rings.number_field + sage: E.descend_to(QQ) # optional - sage.rings.number_field [Elliptic Curve defined by y^2 = x^3 + x over Rational Field, - Elliptic Curve defined by y^2 = x^3 - 4*x over Rational Field] + Elliptic Curve defined by y^2 = x^3 - 4*x over Rational Field] """ if not K.is_field(): raise TypeError("Input must be a field.") @@ -808,88 +819,104 @@ def division_field(self, l, names='t', map=False, **kwds): the 2-division polynomial (therefore, it has degree 1, 2, 3 or 6):: sage: E = EllipticCurve('15a1') - sage: K. = E.division_field(2); K + sage: K. = E.division_field(2); K # optional - sage.rings.number_field Number Field in b with defining polynomial x sage: E = EllipticCurve('14a1') - sage: K. = E.division_field(2); K + sage: K. = E.division_field(2); K # optional - sage.rings.number_field Number Field in b with defining polynomial x^2 + 5*x + 92 sage: E = EllipticCurve('196b1') - sage: K. = E.division_field(2); K + sage: K. = E.division_field(2); K # optional - sage.rings.number_field Number Field in b with defining polynomial x^3 + x^2 - 114*x - 127 sage: E = EllipticCurve('19a1') - sage: K. = E.division_field(2); K - Number Field in b with defining polynomial x^6 + 10*x^5 + 24*x^4 - 212*x^3 + 1364*x^2 + 24072*x + 104292 + sage: K. = E.division_field(2); K # optional - sage.rings.number_field + Number Field in b with defining polynomial + x^6 + 10*x^5 + 24*x^4 - 212*x^3 + 1364*x^2 + 24072*x + 104292 For odd primes `\ell`, the division field is either the splitting field of the `\ell`-division polynomial, or a quadratic extension of it. :: sage: E = EllipticCurve('50a1') - sage: F. = E.division_polynomial(3).splitting_field(simplify_all=True); F - Number Field in a with defining polynomial x^6 - 3*x^5 + 4*x^4 - 3*x^3 - 2*x^2 + 3*x + 3 - sage: K. = E.division_field(3, simplify_all=True); K - Number Field in b with defining polynomial x^6 - 3*x^5 + 4*x^4 - 3*x^3 - 2*x^2 + 3*x + 3 + sage: F. = E.division_polynomial(3).splitting_field(simplify_all=True); F # optional - sage.rings.number_field + Number Field in a + with defining polynomial x^6 - 3*x^5 + 4*x^4 - 3*x^3 - 2*x^2 + 3*x + 3 + sage: K. = E.division_field(3, simplify_all=True); K # optional - sage.rings.number_field + Number Field in b + with defining polynomial x^6 - 3*x^5 + 4*x^4 - 3*x^3 - 2*x^2 + 3*x + 3 If we take any quadratic twist, the splitting field of the 3-division polynomial remains the same, but the 3-division field becomes a quadratic extension:: - sage: E = E.quadratic_twist(5) # 50b3 - sage: F. = E.division_polynomial(3).splitting_field(simplify_all=True); F - Number Field in a with defining polynomial x^6 - 3*x^5 + 4*x^4 - 3*x^3 - 2*x^2 + 3*x + 3 - sage: K. = E.division_field(3, simplify_all=True); K - Number Field in b with defining polynomial x^12 - 3*x^11 + 8*x^10 - 15*x^9 + 30*x^8 - 63*x^7 + 109*x^6 - 144*x^5 + 150*x^4 - 120*x^3 + 68*x^2 - 24*x + 4 + sage: E = E.quadratic_twist(5) # 50b3 # optional - sage.rings.number_field + sage: F. = E.division_polynomial(3).splitting_field(simplify_all=True); F # optional - sage.rings.number_field + Number Field in a + with defining polynomial x^6 - 3*x^5 + 4*x^4 - 3*x^3 - 2*x^2 + 3*x + 3 + sage: K. = E.division_field(3, simplify_all=True); K # optional - sage.rings.number_field + Number Field in b with defining polynomial x^12 - 3*x^11 + 8*x^10 - 15*x^9 + + 30*x^8 - 63*x^7 + 109*x^6 - 144*x^5 + 150*x^4 - 120*x^3 + 68*x^2 - 24*x + 4 Try another quadratic twist, this time over a subfield of `F`:: - sage: G.,_,_ = F.subfields(3)[0] - sage: E = E.base_extend(G).quadratic_twist(c); E - Elliptic Curve defined by y^2 = x^3 + 5*a0*x^2 + (-200*a0^2)*x + (-42000*a0^2+42000*a0+126000) over Number Field in a0 with defining polynomial x^3 - 3*x^2 + 3*x + 9 - sage: K. = E.division_field(3, simplify_all=True); K - Number Field in b with defining polynomial x^12 + 5*x^10 + 40*x^8 + 315*x^6 + 750*x^4 + 675*x^2 + 2025 + sage: G.,_,_ = F.subfields(3)[0] # optional - sage.rings.number_field + sage: E = E.base_extend(G).quadratic_twist(c); E # optional - sage.rings.number_field + Elliptic Curve defined + by y^2 = x^3 + 5*a0*x^2 + (-200*a0^2)*x + (-42000*a0^2+42000*a0+126000) + over Number Field in a0 with defining polynomial x^3 - 3*x^2 + 3*x + 9 + sage: K. = E.division_field(3, simplify_all=True); K # optional - sage.rings.number_field + Number Field in b with defining polynomial + x^12 + 5*x^10 + 40*x^8 + 315*x^6 + 750*x^4 + 675*x^2 + 2025 Some higher-degree examples:: - sage: E = EllipticCurve('11a1') - sage: K. = E.division_field(2); K - Number Field in b with defining polynomial x^6 + 2*x^5 - 48*x^4 - 436*x^3 + 1668*x^2 + 28792*x + 73844 - sage: K. = E.division_field(3); K # long time (3s on sage.math, 2014) + sage: E = EllipticCurve('11a1') # optional - sage.rings.number_field + sage: K. = E.division_field(2); K # optional - sage.rings.number_field + Number Field in b with defining polynomial + x^6 + 2*x^5 - 48*x^4 - 436*x^3 + 1668*x^2 + 28792*x + 73844 + sage: K. = E.division_field(3); K # long time (3s on sage.math, 2014) # optional - sage.rings.number_field Number Field in b with defining polynomial x^48 ... - sage: K. = E.division_field(5); K + sage: K. = E.division_field(5); K # optional - sage.rings.number_field Number Field in b with defining polynomial x^4 - x^3 + x^2 - x + 1 - sage: E.division_field(5, 'b', simplify=False) + sage: E.division_field(5, 'b', simplify=False) # optional - sage.rings.number_field Number Field in b with defining polynomial x^4 + x^3 + 11*x^2 + 41*x + 101 - sage: E.base_extend(K).torsion_subgroup() # long time (2s on sage.math, 2014) - Torsion Subgroup isomorphic to Z/5 + Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in b with defining polynomial x^4 - x^3 + x^2 - x + 1 + sage: E.base_extend(K).torsion_subgroup() # long time (2s on sage.math, 2014) # optional - sage.rings.number_field + Torsion Subgroup isomorphic to Z/5 + Z/5 associated to the Elliptic Curve + defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) + over Number Field in b with defining polynomial x^4 - x^3 + x^2 - x + 1 - sage: E = EllipticCurve('27a1') - sage: K. = E.division_field(3); K + sage: E = EllipticCurve('27a1') # optional - sage.rings.number_field + sage: K. = E.division_field(3); K # optional - sage.rings.number_field Number Field in b with defining polynomial x^2 + 3*x + 9 - sage: K. = E.division_field(2); K - Number Field in b with defining polynomial x^6 + 6*x^5 + 24*x^4 - 52*x^3 - 228*x^2 + 744*x + 3844 - sage: K. = E.division_field(2, simplify_all=True); K + sage: K. = E.division_field(2); K # optional - sage.rings.number_field + Number Field in b with defining polynomial + x^6 + 6*x^5 + 24*x^4 - 52*x^3 - 228*x^2 + 744*x + 3844 + sage: K. = E.division_field(2, simplify_all=True); K # optional - sage.rings.number_field Number Field in b with defining polynomial x^6 - 3*x^5 + 5*x^3 - 3*x + 1 - sage: K. = E.division_field(5); K # long time (4s on sage.math, 2014) + sage: K. = E.division_field(5); K # long time (4s on sage.math, 2014) # optional - sage.rings.number_field Number Field in b with defining polynomial x^48 ... - sage: K. = E.division_field(7); K # long time (8s on sage.math, 2014) + sage: K. = E.division_field(7); K # long time (8s on sage.math, 2014) # optional - sage.rings.number_field Number Field in b with defining polynomial x^72 ... Over a number field:: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2 + 1) - sage: E = EllipticCurve([0,0,0,0,i]) - sage: L. = E.division_field(2); L + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,0,0,0,i]) # optional - sage.rings.number_field + sage: L. = E.division_field(2); L # optional - sage.rings.number_field Number Field in b with defining polynomial x^4 - x^2 + 1 - sage: L., phi = E.division_field(2, map=True); phi + sage: L., phi = E.division_field(2, map=True); phi # optional - sage.rings.number_field Ring morphism: From: Number Field in i with defining polynomial x^2 + 1 To: Number Field in b with defining polynomial x^4 - x^2 + 1 Defn: i |--> -b^3 - sage: L., phi = E.division_field(3, map=True) - sage: L - Number Field in b with defining polynomial x^24 - 6*x^22 - 12*x^21 - 21*x^20 + 216*x^19 + 48*x^18 + 804*x^17 + 1194*x^16 - 13488*x^15 + 21222*x^14 + 44196*x^13 - 47977*x^12 - 102888*x^11 + 173424*x^10 - 172308*x^9 + 302046*x^8 + 252864*x^7 - 931182*x^6 + 180300*x^5 + 879567*x^4 - 415896*x^3 + 1941012*x^2 + 650220*x + 443089 - sage: phi + sage: L., phi = E.division_field(3, map=True) # optional - sage.rings.number_field + sage: L # optional - sage.rings.number_field + Number Field in b with defining polynomial x^24 - 6*x^22 - 12*x^21 + - 21*x^20 + 216*x^19 + 48*x^18 + 804*x^17 + 1194*x^16 - 13488*x^15 + + 21222*x^14 + 44196*x^13 - 47977*x^12 - 102888*x^11 + 173424*x^10 + - 172308*x^9 + 302046*x^8 + 252864*x^7 - 931182*x^6 + 180300*x^5 + + 879567*x^4 - 415896*x^3 + 1941012*x^2 + 650220*x + 443089 + sage: phi # optional - sage.rings.number_field Ring morphism: From: Number Field in i with defining polynomial x^2 + 1 To: Number Field in b with defining polynomial x^24 ... @@ -897,8 +924,8 @@ def division_field(self, l, names='t', map=False, **kwds): Over a finite field:: - sage: E = EllipticCurve(GF(431^2), [1,0]) - sage: E.division_field(5, map=True) + sage: E = EllipticCurve(GF(431^2), [1,0]) # optional - sage.rings.finite_rings + sage: E.division_field(5, map=True) # optional - sage.rings.finite_rings (Finite Field in t of size 431^4, Ring morphism: From: Finite Field in z2 of size 431^2 @@ -907,8 +934,8 @@ def division_field(self, l, names='t', map=False, **kwds): :: - sage: E = EllipticCurve(GF(433^2), [1,0]) - sage: K. = E.division_field(7); K + sage: E = EllipticCurve(GF(433^2), [1,0]) # optional - sage.rings.finite_rings + sage: K. = E.division_field(7); K # optional - sage.rings.finite_rings Finite Field in v of size 433^16 .. SEEALSO:: @@ -946,20 +973,20 @@ def division_field(self, l, names='t', map=False, **kwds): ....: assert False ....: deg = lcm(el.minpoly().degree() for el in sum(map(list,Ps),[])) ....: assert max(deg, E.base_field().degree()) == K.degree() - sage: q = next_prime_power(randrange(1, 10^9)) - sage: F. = GF(q) - sage: while True: + sage: q = next_prime_power(randrange(1, 10^9)) # optional - sage.rings.finite_rings + sage: F. = GF(q) # optional - sage.rings.finite_rings + sage: while True: # optional - sage.rings.finite_rings ....: try: ....: E = EllipticCurve([F.random_element() for _ in range(5)]) ....: except ArithmeticError: ....: continue ....: break - sage: l = random_prime(8) - sage: K = E.division_field(l) - sage: n = E.cardinality(extension_degree=K.degree()//F.degree()) - sage: (l^2 if q%l else 0 + E.is_ordinary()).divides(n) + sage: l = random_prime(8) # optional - sage.rings.finite_rings + sage: K = E.division_field(l) # optional - sage.rings.finite_rings + sage: n = E.cardinality(extension_degree=K.degree()//F.degree()) # optional - sage.rings.finite_rings + sage: (l^2 if q%l else 0 + E.is_ordinary()).divides(n) # optional - sage.rings.finite_rings True - sage: check(E, l, K) # long time + sage: check(E, l, K) # long time # optional - sage.rings.finite_rings AUTHORS: @@ -1087,12 +1114,12 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al - ``degree`` -- an integer (default: ``None``). - - If ``kernel`` is ``None``, then this is the degree of the isogeny - from this curve to ``codomain``. + - If ``kernel`` is ``None``, then this is the degree of the isogeny + from this curve to ``codomain``. - - If ``kernel`` is not ``None``, then this is used to determine - whether or not to skip a `\gcd` of the given kernel polynomial - with the two-torsion polynomial of this curve. + - If ``kernel`` is not ``None``, then this is used to determine + whether or not to skip a `\gcd` of the given kernel polynomial + with the two-torsion polynomial of this curve. - ``model`` -- a string (default: ``None``). Supported values (cf. :func:`~sage.schemes.elliptic_curves.ell_field.compute_model`): @@ -1133,11 +1160,11 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al EXAMPLES:: - sage: F = GF(2^5, 'alpha'); alpha = F.gen() - sage: E = EllipticCurve(F, [1,0,1,1,1]) - sage: R. = F[] - sage: phi = E.isogeny(x+1) - sage: phi.rational_maps() + sage: F = GF(2^5, 'alpha'); alpha = F.gen() # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [1,0,1,1,1]) # optional - sage.rings.finite_rings + sage: R. = F[] # optional - sage.rings.finite_rings + sage: phi = E.isogeny(x + 1) # optional - sage.rings.finite_rings + sage: phi.rational_maps() # optional - sage.rings.finite_rings ((x^2 + x + 1)/(x + 1), (x^2*y + x)/(x^2 + 1)) :: @@ -1145,35 +1172,45 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al sage: E = EllipticCurve('11a1') sage: P = E.torsion_points()[1] sage: E.isogeny(P) - Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field + Isogeny of degree 5 + from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 + over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 + over Rational Field :: - sage: E = EllipticCurve(GF(19),[1,1]) - sage: P = E(15,3); Q = E(2,12); - sage: (P.order(), Q.order()) + sage: E = EllipticCurve(GF(19),[1,1]) # optional - sage.rings.finite_rings + sage: P = E(15,3); Q = E(2,12) # optional - sage.rings.finite_rings + sage: (P.order(), Q.order()) # optional - sage.rings.finite_rings (7, 3) - sage: phi = E.isogeny([P,Q]); phi - Isogeny of degree 21 from Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 19 to Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 19 - sage: phi(E.random_point()) # all points defined over GF(19) are in the kernel + sage: phi = E.isogeny([P,Q]); phi # optional - sage.rings.finite_rings + Isogeny of degree 21 + from Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 19 + to Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 19 + sage: phi(E.random_point()) # all points defined over GF(19) are in the kernel # optional - sage.rings.finite_rings (0 : 1 : 0) :: - sage: E = EllipticCurve(GF(2^32-5), [170246996, 2036646110]) - sage: P = E.lift_x(2) - sage: E.isogeny(P, algorithm="factored") + sage: E = EllipticCurve(GF(2^32 - 5), [170246996, 2036646110]) # optional - sage.rings.finite_rings + sage: P = E.lift_x(2) # optional - sage.rings.finite_rings + sage: E.isogeny(P, algorithm="factored") # optional - sage.rings.finite_rings Composite morphism of degree 1073721825 = 3^4*5^2*11*19*43*59: - From: Elliptic Curve defined by y^2 = x^3 + 170246996*x + 2036646110 over Finite Field of size 4294967291 - To: Elliptic Curve defined by y^2 = x^3 + 272790262*x + 1903695400 over Finite Field of size 4294967291 + From: Elliptic Curve defined by y^2 = x^3 + 170246996*x + 2036646110 + over Finite Field of size 4294967291 + To: Elliptic Curve defined by y^2 = x^3 + 272790262*x + 1903695400 + over Finite Field of size 4294967291 Not all polynomials define a finite subgroup (:trac:`6384`):: - sage: E = EllipticCurve(GF(31),[1,0,0,1,2]) - sage: phi = E.isogeny([14,27,4,1]) + sage: E = EllipticCurve(GF(31), [1,0,0,1,2]) # optional - sage.rings.finite_rings + sage: phi = E.isogeny([14,27,4,1]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: the polynomial x^3 + 4*x^2 + 27*x + 14 does not define a finite subgroup of Elliptic Curve defined by y^2 + x*y = x^3 + x + 2 over Finite Field of size 31 + ValueError: the polynomial x^3 + 4*x^2 + 27*x + 14 does not define a finite + subgroup of Elliptic Curve defined by y^2 + x*y = x^3 + x + 2 + over Finite Field of size 31 .. SEEALSO:: @@ -1188,20 +1225,22 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al invalid morphism. See also :trac:`11578`:: sage: R. = QQ[] - sage: K. = NumberField(x^2-x-1) - sage: E = EllipticCurve(K, [-13392, -1080432]) - sage: R. = K[] - sage: phi = E.isogeny( (x-564)*(x - 396/5*a + 348/5) ) + sage: K. = NumberField(x^2 - x - 1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [-13392, -1080432]) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: phi = E.isogeny( (x-564)*(x - 396/5*a + 348/5) ) # optional - sage.rings.number_field Traceback (most recent call last): ... - ValueError: the polynomial x^2 + (-396/5*a - 2472/5)*x + 223344/5*a - 196272/5 does not define a finite subgroup of Elliptic Curve defined by y^2 = x^3 + (-13392)*x + (-1080432) over Number Field in a with defining polynomial x^2 - x - 1 + ValueError: the polynomial x^2 + (-396/5*a - 2472/5)*x + 223344/5*a - 196272/5 does not + define a finite subgroup of Elliptic Curve defined by y^2 = x^3 + (-13392)*x + (-1080432) + over Number Field in a with defining polynomial x^2 - x - 1 We check that the cached order is correctly copied over:: - sage: E = EllipticCurve(GF(2^127-1), [1,2,3,4,5]) - sage: E.set_order(170141183460469231746191640949390434666) - sage: phi = E.isogeny(E.lift_x(77347718128277853096420969229987528666)) - sage: phi.codomain()._order + sage: E = EllipticCurve(GF(2^127-1), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: E.set_order(170141183460469231746191640949390434666) # optional - sage.rings.finite_rings + sage: phi = E.isogeny(E.lift_x(77347718128277853096420969229987528666)) # optional - sage.rings.finite_rings + sage: phi.codomain()._order # optional - sage.rings.finite_rings 170141183460469231746191640949390434666 """ if algorithm is not None and degree is not None: @@ -1224,8 +1263,7 @@ def isogeny_codomain(self, kernel, degree=None): INPUT: - ``kernel`` -- Either a list of points in the kernel of the isogeny, - or a kernel polynomial (specified as either a - univariate polynomial or a coefficient list.) + or a kernel polynomial (specified as either a univariate polynomial or a coefficient list.) OUTPUT: @@ -1237,26 +1275,28 @@ def isogeny_codomain(self, kernel, degree=None): sage: E = EllipticCurve('17a1') sage: R. = QQ[] sage: E2 = E.isogeny_codomain(x - 11/4); E2 - Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 1461/16*x - 19681/64 over Rational Field + Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 1461/16*x - 19681/64 + over Rational Field TESTS: We check that the cached order is correctly copied over:: - sage: E = EllipticCurve(GF(2^127-1), [1,2,3,4,5]) - sage: E.set_order(170141183460469231746191640949390434666) - sage: E2 = E.isogeny_codomain(E.lift_x(77347718128277853096420969229987528666)) - sage: E2._order + sage: E = EllipticCurve(GF(2^127 - 1), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: E.set_order(170141183460469231746191640949390434666) # optional - sage.rings.finite_rings + sage: E2 = E.isogeny_codomain(E.lift_x(77347718128277853096420969229987528666)) # optional - sage.rings.finite_rings + sage: E2._order # optional - sage.rings.finite_rings 170141183460469231746191640949390434666 Test deprecation warning for obsolete argument:: - sage: E.isogeny_codomain(E.lift_x(77347718128277853096420969229987528666), degree=11) + sage: E.isogeny_codomain(E.lift_x(77347718128277853096420969229987528666), degree=11) # optional - sage.rings.finite_rings doctest:warning ... DeprecationWarning: The "degree" argument to .isogeny_codomain() does nothing and will be removed. ... - Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 20731788786372791581385345584850817122*x + 125200507378516567345719286707201096361 over Finite Field of size 170141183460469231731687303715884105727 + Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 20731788786372791581385345584850817122*x + 125200507378516567345719286707201096361 + over Finite Field of size 170141183460469231731687303715884105727 """ if degree is not None: from sage.misc.superseded import deprecation @@ -1295,124 +1335,223 @@ def isogenies_prime_degree(self, l=None, max_l=31): Examples over finite fields:: - sage: E = EllipticCurve(GF(next_prime(1000000)), [7,8]) - sage: E.isogenies_prime_degree(2) - [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003] - sage: E.isogenies_prime_degree(3) + sage: E = EllipticCurve(GF(next_prime(1000000)), [7,8]) # optional - sage.rings.finite_rings + sage: E.isogenies_prime_degree(2) # optional - sage.rings.finite_rings + [Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003] + sage: E.isogenies_prime_degree(3) # optional - sage.rings.finite_rings [] - sage: E.isogenies_prime_degree(5) + sage: E.isogenies_prime_degree(5) # optional - sage.rings.finite_rings [] - sage: E.isogenies_prime_degree(7) + sage: E.isogenies_prime_degree(7) # optional - sage.rings.finite_rings [] - sage: E.isogenies_prime_degree(11) + sage: E.isogenies_prime_degree(11) # optional - sage.rings.finite_rings [] - sage: E.isogenies_prime_degree(13) - [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003, - Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003] - sage: E.isogenies_prime_degree(max_l=13) - [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003, - Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003, - Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003] - sage: E.isogenies_prime_degree() # Default limit of 31 - [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003, - Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003, - Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003, - Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 347438*x + 594729 over Finite Field of size 1000003, - Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 674846*x + 7392 over Finite Field of size 1000003, - Isogeny of degree 23 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 390065*x + 605596 over Finite Field of size 1000003] - - sage: E = EllipticCurve(GF(17), [2,0]) - sage: E.isogenies_prime_degree(3) + sage: E.isogenies_prime_degree(13) # optional - sage.rings.finite_rings + [Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003, + Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003] + sage: E.isogenies_prime_degree(max_l=13) # optional - sage.rings.finite_rings + [Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003, + Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003, + Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003] + sage: E.isogenies_prime_degree() # Default limit of 31 # optional - sage.rings.finite_rings + [Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003, + Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003, + Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003, + Isogeny of degree 17 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 347438*x + 594729 over Finite Field of size 1000003, + Isogeny of degree 17 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 674846*x + 7392 over Finite Field of size 1000003, + Isogeny of degree 23 + from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 + to Elliptic Curve defined by y^2 = x^3 + 390065*x + 605596 over Finite Field of size 1000003] + + sage: E = EllipticCurve(GF(17), [2,0]) # optional - sage.rings.finite_rings + sage: E.isogenies_prime_degree(3) # optional - sage.rings.finite_rings [] - sage: E.isogenies_prime_degree(2) - [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 to Elliptic Curve defined by y^2 = x^3 + 9*x over Finite Field of size 17, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 to Elliptic Curve defined by y^2 = x^3 + 5*x + 9 over Finite Field of size 17, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 to Elliptic Curve defined by y^2 = x^3 + 5*x + 8 over Finite Field of size 17] + sage: E.isogenies_prime_degree(2) # optional - sage.rings.finite_rings + [Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 + to Elliptic Curve defined by y^2 = x^3 + 9*x over Finite Field of size 17, + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 + to Elliptic Curve defined by y^2 = x^3 + 5*x + 9 over Finite Field of size 17, + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 + to Elliptic Curve defined by y^2 = x^3 + 5*x + 8 over Finite Field of size 17] The base field matters, over a field extension we find more isogenies:: - sage: E = EllipticCurve(GF(13), [2,8]) - sage: E.isogenies_prime_degree(max_l=3) - [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field of size 13 to Elliptic Curve defined by y^2 = x^3 + 7*x + 4 over Finite Field of size 13, - Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field of size 13 to Elliptic Curve defined by y^2 = x^3 + 9*x + 11 over Finite Field of size 13] - sage: E = EllipticCurve(GF(13^6), [2,8]) - sage: E.isogenies_prime_degree(max_l=3) - [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 to Elliptic Curve defined by y^2 = x^3 + 7*x + 4 over Finite Field in z6 of size 13^6, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 to Elliptic Curve defined by y^2 = x^3 + (2*z6^5+6*z6^4+9*z6^3+8*z6+7)*x + (3*z6^5+9*z6^4+7*z6^3+12*z6+7) over Finite Field in z6 of size 13^6, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 to Elliptic Curve defined by y^2 = x^3 + (11*z6^5+7*z6^4+4*z6^3+5*z6+9)*x + (10*z6^5+4*z6^4+6*z6^3+z6+10) over Finite Field in z6 of size 13^6, - Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 to Elliptic Curve defined by y^2 = x^3 + 9*x + 11 over Finite Field in z6 of size 13^6, - Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 to Elliptic Curve defined by y^2 = x^3 + (3*z6^5+5*z6^4+8*z6^3+11*z6^2+5*z6+12)*x + (12*z6^5+6*z6^4+8*z6^3+4*z6^2+7*z6+6) over Finite Field in z6 of size 13^6, - Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 to Elliptic Curve defined by y^2 = x^3 + (7*z6^4+12*z6^3+7*z6^2+4)*x + (6*z6^5+10*z6^3+12*z6^2+10*z6+8) over Finite Field in z6 of size 13^6, - Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 to Elliptic Curve defined by y^2 = x^3 + (10*z6^5+z6^4+6*z6^3+8*z6^2+8*z6)*x + (8*z6^5+7*z6^4+8*z6^3+10*z6^2+9*z6+7) over Finite Field in z6 of size 13^6] + sage: E = EllipticCurve(GF(13), [2,8]) # optional - sage.rings.finite_rings + sage: E.isogenies_prime_degree(max_l=3) # optional - sage.rings.finite_rings + [Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field of size 13 + to Elliptic Curve defined by y^2 = x^3 + 7*x + 4 over Finite Field of size 13, + Isogeny of degree 3 + from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field of size 13 + to Elliptic Curve defined by y^2 = x^3 + 9*x + 11 over Finite Field of size 13] + sage: E = EllipticCurve(GF(13^6), [2,8]) # optional - sage.rings.finite_rings + sage: E.isogenies_prime_degree(max_l=3) # optional - sage.rings.finite_rings + [Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 + to Elliptic Curve defined by y^2 = x^3 + 7*x + 4 over Finite Field in z6 of size 13^6, + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 + to Elliptic Curve defined by y^2 = x^3 + (2*z6^5+6*z6^4+9*z6^3+8*z6+7)*x + (3*z6^5+9*z6^4+7*z6^3+12*z6+7) over Finite Field in z6 of size 13^6, + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 + to Elliptic Curve defined by y^2 = x^3 + (11*z6^5+7*z6^4+4*z6^3+5*z6+9)*x + (10*z6^5+4*z6^4+6*z6^3+z6+10) over Finite Field in z6 of size 13^6, + Isogeny of degree 3 + from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 + to Elliptic Curve defined by y^2 = x^3 + 9*x + 11 over Finite Field in z6 of size 13^6, + Isogeny of degree 3 + from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 + to Elliptic Curve defined by y^2 = x^3 + (3*z6^5+5*z6^4+8*z6^3+11*z6^2+5*z6+12)*x + (12*z6^5+6*z6^4+8*z6^3+4*z6^2+7*z6+6) over Finite Field in z6 of size 13^6, + Isogeny of degree 3 + from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 + to Elliptic Curve defined by y^2 = x^3 + (7*z6^4+12*z6^3+7*z6^2+4)*x + (6*z6^5+10*z6^3+12*z6^2+10*z6+8) over Finite Field in z6 of size 13^6, + Isogeny of degree 3 + from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in z6 of size 13^6 + to Elliptic Curve defined by y^2 = x^3 + (10*z6^5+z6^4+6*z6^3+8*z6^2+8*z6)*x + (8*z6^5+7*z6^4+8*z6^3+10*z6^2+9*z6+7) over Finite Field in z6 of size 13^6] If the degree equals the characteristic, we find only separable isogenies:: - sage: E = EllipticCurve(GF(13), [2,8]) - sage: E.isogenies_prime_degree(13) - [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field of size 13 to Elliptic Curve defined by y^2 = x^3 + 6*x + 5 over Finite Field of size 13] - sage: E = EllipticCurve(GF(5), [1,1]) - sage: E.isogenies_prime_degree(5) - [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5 to Elliptic Curve defined by y^2 = x^3 + x + 4 over Finite Field of size 5] - sage: k. = GF(3^4) - sage: E = EllipticCurve(k, [0,1,0,0,a]) - sage: E.isogenies_prime_degree(3) - [Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + x^2 + a over Finite Field in a of size 3^4 to Elliptic Curve defined by y^2 = x^3 + x^2 + (2*a^3+a^2+2)*x + (a^2+2) over Finite Field in a of size 3^4] + sage: E = EllipticCurve(GF(13), [2,8]) # optional - sage.rings.finite_rings + sage: E.isogenies_prime_degree(13) # optional - sage.rings.finite_rings + [Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field of size 13 + to Elliptic Curve defined by y^2 = x^3 + 6*x + 5 over Finite Field of size 13] + sage: E = EllipticCurve(GF(5), [1,1]) # optional - sage.rings.finite_rings + sage: E.isogenies_prime_degree(5) # optional - sage.rings.finite_rings + [Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5 + to Elliptic Curve defined by y^2 = x^3 + x + 4 over Finite Field of size 5] + sage: k. = GF(3^4) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(k, [0,1,0,0,a]) # optional - sage.rings.finite_rings + sage: E.isogenies_prime_degree(3) # optional - sage.rings.finite_rings + [Isogeny of degree 3 + from Elliptic Curve defined by y^2 = x^3 + x^2 + a + over Finite Field in a of size 3^4 + to Elliptic Curve defined by y^2 = x^3 + x^2 + (2*a^3+a^2+2)*x + (a^2+2) + over Finite Field in a of size 3^4] In the supersingular case, there are no separable isogenies of degree equal to the characteristic:: - sage: E = EllipticCurve(GF(5), [0,1]) - sage: E.isogenies_prime_degree(5) + sage: E = EllipticCurve(GF(5), [0,1]) # optional - sage.rings.finite_rings + sage: E.isogenies_prime_degree(5) # optional - sage.rings.finite_rings [] An example over a rational function field:: - sage: R. = GF(5)[] - sage: K = R.fraction_field() - sage: E = EllipticCurve(K, [1, t^5]) - sage: E.isogenies_prime_degree(5) - [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x + t^5 over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 to Elliptic Curve defined by y^2 = x^3 + x + 4*t over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5] + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: K = R.fraction_field() # optional - sage.rings.finite_rings + sage: E = EllipticCurve(K, [1, t^5]) # optional - sage.rings.finite_rings + sage: E.isogenies_prime_degree(5) # optional - sage.rings.finite_rings + [Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + x + t^5 over Fraction Field + of Univariate Polynomial Ring in t over Finite Field of size 5 + to Elliptic Curve defined by y^2 = x^3 + x + 4*t over Fraction Field + of Univariate Polynomial Ring in t over Finite Field of size 5] Examples over number fields (other than QQ):: - sage: QQroot2. = NumberField(x^2-2) - sage: E = EllipticCurve(QQroot2, j=8000) - sage: E.isogenies_prime_degree() - [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + (-150528000)*x + (-629407744000) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 = x^3 + (-36750)*x + 2401000 over Number Field in e with defining polynomial x^2 - 2, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + (-150528000)*x + (-629407744000) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 = x^3 + (220500*e-257250)*x + (54022500*e-88837000) over Number Field in e with defining polynomial x^2 - 2, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + (-150528000)*x + (-629407744000) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 = x^3 + (-220500*e-257250)*x + (-54022500*e-88837000) over Number Field in e with defining polynomial x^2 - 2] - - sage: E = EllipticCurve(QQroot2, [1,0,1,4, -6]); E - Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 - sage: E.isogenies_prime_degree(2) - [Isogeny of degree 2 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-36)*x + (-70) over Number Field in e with defining polynomial x^2 - 2] - sage: E.isogenies_prime_degree(3) - [Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-1)*x over Number Field in e with defining polynomial x^2 - 2, - Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-171)*x + (-874) over Number Field in e with defining polynomial x^2 - 2] + sage: QQroot2. = NumberField(x^2 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve(QQroot2, j=8000) # optional - sage.rings.number_field + sage: E.isogenies_prime_degree() # optional - sage.rings.number_field + [Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + (-150528000)*x + (-629407744000) + over Number Field in e with defining polynomial x^2 - 2 + to Elliptic Curve defined by y^2 = x^3 + (-36750)*x + 2401000 + over Number Field in e with defining polynomial x^2 - 2, + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + (-150528000)*x + (-629407744000) + over Number Field in e with defining polynomial x^2 - 2 + to Elliptic Curve defined by y^2 = x^3 + (220500*e-257250)*x + (54022500*e-88837000) + over Number Field in e with defining polynomial x^2 - 2, + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + (-150528000)*x + (-629407744000) + over Number Field in e with defining polynomial x^2 - 2 + to Elliptic Curve defined by y^2 = x^3 + (-220500*e-257250)*x + (-54022500*e-88837000) + over Number Field in e with defining polynomial x^2 - 2] + + sage: E = EllipticCurve(QQroot2, [1,0,1,4, -6]); E # optional - sage.rings.number_field + Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) + over Number Field in e with defining polynomial x^2 - 2 + sage: E.isogenies_prime_degree(2) # optional - sage.rings.number_field + [Isogeny of degree 2 + from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) + over Number Field in e with defining polynomial x^2 - 2 + to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-36)*x + (-70) + over Number Field in e with defining polynomial x^2 - 2] + sage: E.isogenies_prime_degree(3) # optional - sage.rings.number_field + [Isogeny of degree 3 + from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) + over Number Field in e with defining polynomial x^2 - 2 + to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-1)*x + over Number Field in e with defining polynomial x^2 - 2, + Isogeny of degree 3 + from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) + over Number Field in e with defining polynomial x^2 - 2 + to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-171)*x + (-874) + over Number Field in e with defining polynomial x^2 - 2] These are not implemented yet:: - sage: E = EllipticCurve(QQbar, [1,18]); E + sage: E = EllipticCurve(QQbar, [1,18]); E # optional - sage.rings.number_field Elliptic Curve defined by y^2 = x^3 + x + 18 over Algebraic Field - sage: E.isogenies_prime_degree() + sage: E.isogenies_prime_degree() # optional - sage.rings.number_field Traceback (most recent call last): ... NotImplementedError: This code could be implemented for QQbar, but has not been yet. sage: E = EllipticCurve(CC, [1,18]); E - Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 18.0000000000000 over Complex Field with 53 bits of precision + Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 18.0000000000000 + over Complex Field with 53 bits of precision sage: E.isogenies_prime_degree(11) Traceback (most recent call last): ... - NotImplementedError: This code could be implemented for general complex fields, but has not been yet. + NotImplementedError: This code could be implemented for general complex fields, + but has not been yet. TESTS:: @@ -1459,7 +1598,7 @@ def is_isogenous(self, other, field=None): - ``field`` (default None) -- Currently not implemented. A field containing the base fields of the two elliptic curves onto which the two curves may be extended to test if they - are isogenous over this field. By default is_isogenous will + are isogenous over this field. By default ``is_isogenous`` will not try to find this field unless one of the curves can be be extended into the base field of the other, in which case it will test over the larger base field. @@ -1476,18 +1615,22 @@ def is_isogenous(self, other, field=None): EXAMPLES:: sage: E1 = EllipticCurve(CC, [1,18]); E1 - Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 18.0000000000000 over Complex Field with 53 bits of precision + Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 18.0000000000000 + over Complex Field with 53 bits of precision sage: E2 = EllipticCurve(CC, [2,7]); E2 - Elliptic Curve defined by y^2 = x^3 + 2.00000000000000*x + 7.00000000000000 over Complex Field with 53 bits of precision + Elliptic Curve defined by y^2 = x^3 + 2.00000000000000*x + 7.00000000000000 + over Complex Field with 53 bits of precision sage: E1.is_isogenous(E2) Traceback (most recent call last): ... NotImplementedError: Only implemented for isomorphic curves over general fields. sage: E1 = EllipticCurve(Frac(PolynomialRing(ZZ,'t')), [2,19]); E1 - Elliptic Curve defined by y^2 = x^3 + 2*x + 19 over Fraction Field of Univariate Polynomial Ring in t over Integer Ring + Elliptic Curve defined by y^2 = x^3 + 2*x + 19 + over Fraction Field of Univariate Polynomial Ring in t over Integer Ring sage: E2 = EllipticCurve(CC, [23,4]); E2 - Elliptic Curve defined by y^2 = x^3 + 23.0000000000000*x + 4.00000000000000 over Complex Field with 53 bits of precision + Elliptic Curve defined by y^2 = x^3 + 23.0000000000000*x + 4.00000000000000 + over Complex Field with 53 bits of precision sage: E1.is_isogenous(E2) Traceback (most recent call last): ... @@ -1517,7 +1660,7 @@ def weierstrass_p(self, prec=20, algorithm=None): OUTPUT: - a Laurent series in one variable `z` with coefficients in the + A Laurent series in one variable `z` with coefficients in the base field `k` of `E`. EXAMPLES:: @@ -1531,11 +1674,17 @@ def weierstrass_p(self, prec=20, algorithm=None): sage: Esh.weierstrass_p(prec=8) z^-2 + 13392/5*z^2 + 1080432/7*z^4 + 59781888/25*z^6 + O(z^8) sage: E.weierstrass_p(prec=20, algorithm='fast') - z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + 77531/41580*z^8 + 1202285717/928746000*z^10 + 2403461/2806650*z^12 + 30211462703/43418875500*z^14 + 3539374016033/7723451736000*z^16 + 413306031683977/1289540602350000*z^18 + O(z^20) + z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + 77531/41580*z^8 + + 1202285717/928746000*z^10 + 2403461/2806650*z^12 + 30211462703/43418875500*z^14 + + 3539374016033/7723451736000*z^16 + 413306031683977/1289540602350000*z^18 + O(z^20) sage: E.weierstrass_p(prec=20, algorithm='pari') - z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + 77531/41580*z^8 + 1202285717/928746000*z^10 + 2403461/2806650*z^12 + 30211462703/43418875500*z^14 + 3539374016033/7723451736000*z^16 + 413306031683977/1289540602350000*z^18 + O(z^20) + z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + 77531/41580*z^8 + + 1202285717/928746000*z^10 + 2403461/2806650*z^12 + 30211462703/43418875500*z^14 + + 3539374016033/7723451736000*z^16 + 413306031683977/1289540602350000*z^18 + O(z^20) sage: E.weierstrass_p(prec=20, algorithm='quadratic') - z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + 77531/41580*z^8 + 1202285717/928746000*z^10 + 2403461/2806650*z^12 + 30211462703/43418875500*z^14 + 3539374016033/7723451736000*z^16 + 413306031683977/1289540602350000*z^18 + O(z^20) + z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + 77531/41580*z^8 + + 1202285717/928746000*z^10 + 2403461/2806650*z^12 + 30211462703/43418875500*z^14 + + 3539374016033/7723451736000*z^16 + 413306031683977/1289540602350000*z^18 + O(z^20) """ from .ell_wp import weierstrass_p return weierstrass_p(self, prec=prec, algorithm=algorithm) @@ -1551,37 +1700,37 @@ def hasse_invariant(self): characteristic, and is an element of the field which is zero if and only if the curve is supersingular. Over a field of characteristic zero, where the Hasse invariant is undefined, - a ``ValueError`` is returned. + a ``ValueError`` is raised. EXAMPLES:: - sage: E = EllipticCurve([Mod(1,2),Mod(1,2),0,0,Mod(1,2)]) + sage: E = EllipticCurve([Mod(1,2), Mod(1,2), 0, 0, Mod(1,2)]) sage: E.hasse_invariant() 1 - sage: E = EllipticCurve([0,0,Mod(1,3),Mod(1,3),Mod(1,3)]) + sage: E = EllipticCurve([0, 0, Mod(1,3), Mod(1,3), Mod(1,3)]) sage: E.hasse_invariant() 0 - sage: E = EllipticCurve([0,0,Mod(1,5),0,Mod(2,5)]) + sage: E = EllipticCurve([0, 0, Mod(1,5), 0, Mod(2,5)]) sage: E.hasse_invariant() 0 - sage: E = EllipticCurve([0,0,Mod(1,5),Mod(1,5),Mod(2,5)]) + sage: E = EllipticCurve([0, 0, Mod(1,5), Mod(1,5), Mod(2,5)]) sage: E.hasse_invariant() 2 Some examples over larger fields:: - sage: EllipticCurve(GF(101),[0,0,0,0,1]).hasse_invariant() + sage: EllipticCurve(GF(101), [0,0,0,0,1]).hasse_invariant() # optional - sage.rings.finite_rings 0 - sage: EllipticCurve(GF(101),[0,0,0,1,1]).hasse_invariant() + sage: EllipticCurve(GF(101), [0,0,0,1,1]).hasse_invariant() # optional - sage.rings.finite_rings 98 - sage: EllipticCurve(GF(103),[0,0,0,0,1]).hasse_invariant() + sage: EllipticCurve(GF(103), [0,0,0,0,1]).hasse_invariant() # optional - sage.rings.finite_rings 20 - sage: EllipticCurve(GF(103),[0,0,0,1,1]).hasse_invariant() + sage: EllipticCurve(GF(103), [0,0,0,1,1]).hasse_invariant() # optional - sage.rings.finite_rings 17 - sage: F. = GF(107^2) - sage: EllipticCurve(F,[0,0,0,a,1]).hasse_invariant() + sage: F. = GF(107^2) # optional - sage.rings.finite_rings + sage: EllipticCurve(F, [0,0,0,a,1]).hasse_invariant() # optional - sage.rings.finite_rings 62*a + 75 - sage: EllipticCurve(F,[0,0,0,0,a]).hasse_invariant() + sage: EllipticCurve(F, [0,0,0,0,a]).hasse_invariant() # optional - sage.rings.finite_rings 0 Over fields of characteristic zero, the Hasse invariant is @@ -1635,24 +1784,22 @@ class of curves. If the j-invariant is not unique in the isogeny class, append ``*`` to it to indicate a twist. Otherwise, if ``False`` label vertices by the equation of a representative curve. - OUTPUT: - - A ``Graph`` or ``Digraph`` + OUTPUT: A :class:`Graph` or :class:`DiGraph`. EXAMPLES: Ordinary curve over finite extension field of degree 2:: - sage: E = EllipticCurve(GF(59^2, "i", x^2 + 1), j=5) - sage: G = E.isogeny_ell_graph(5, directed=False, label_by_j=True) - sage: G + sage: E = EllipticCurve(GF(59^2, "i", x^2 + 1), j=5) # optional - sage.rings.finite_rings + sage: G = E.isogeny_ell_graph(5, directed=False, label_by_j=True) # optional - sage.graphs sage.rings.finite_rings + sage: G # optional - sage.graphs sage.rings.finite_rings Graph on 20 vertices - sage: G.vertices(sort=True) + sage: G.vertices(sort=True) # optional - sage.graphs sage.rings.finite_rings ['1', '12', ... 'i + 55'] - sage: G.edges(sort=True) + sage: G.edges(sort=True) # optional - sage.graphs sage.rings.finite_rings [('1', '28*i + 11', None), ('1', '31*i + 11', None), ... @@ -1660,26 +1807,26 @@ class of curves. If the j-invariant is not unique in the isogeny Supersingular curve over prime field:: - sage: E = EllipticCurve(GF(419), j=1728) - sage: G3 = E.isogeny_ell_graph(3, directed=False, label_by_j=True) - sage: G3 + sage: E = EllipticCurve(GF(419), j=1728) # optional - sage.rings.finite_rings + sage: G3 = E.isogeny_ell_graph(3, directed=False, label_by_j=True) # optional - sage.graphs sage.rings.finite_rings + sage: G3 # optional - sage.graphs sage.rings.finite_rings Graph on 27 vertices - sage: G3.vertices(sort=True) + sage: G3.vertices(sort=True) # optional - sage.graphs sage.rings.finite_rings ['0', '0*', ... '98*'] - sage: G3.edges(sort=True) + sage: G3.edges(sort=True) # optional - sage.graphs sage.rings.finite_rings [('0', '0*', None), ('0', '13', None), ... ('48*', '98*', None)] - sage: G5 = E.isogeny_ell_graph(5, directed=False, label_by_j=True) - sage: G5 + sage: G5 = E.isogeny_ell_graph(5, directed=False, label_by_j=True) # optional - sage.graphs sage.rings.finite_rings + sage: G5 # optional - sage.graphs sage.rings.finite_rings Graph on 9 vertices - sage: G5.vertices(sort=True) + sage: G5.vertices(sort=True) # optional - sage.graphs sage.rings.finite_rings ['13', '13*', '407', '407*', '52', '62', '62*', '98', '98*'] - sage: G5.edges(sort=True) + sage: G5.edges(sort=True) # optional - sage.graphs sage.rings.finite_rings [('13', '52', None), ('13', '98', None), ... @@ -1687,32 +1834,32 @@ class of curves. If the j-invariant is not unique in the isogeny Supersingular curve over finite extension field of degree 2:: - sage: K = GF(431^2, "i", x^2 + 1) - sage: E = EllipticCurve(K, j=0) - sage: E.is_supersingular() + sage: K = GF(431^2, "i", x^2 + 1) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(K, j=0) # optional - sage.rings.finite_rings + sage: E.is_supersingular() # optional - sage.rings.finite_rings True - sage: G = E.isogeny_ell_graph(2, directed=True, label_by_j=True) - sage: G + sage: G = E.isogeny_ell_graph(2, directed=True, label_by_j=True) # optional - sage.graphs sage.rings.finite_rings + sage: G # optional - sage.graphs sage.rings.finite_rings Looped multi-digraph on 37 vertices - sage: G.vertices(sort=True) + sage: G.vertices(sort=True) # optional - sage.graphs sage.rings.finite_rings ['0', '102', ... '87*i + 190'] - sage: G.edges(sort=True) + sage: G.edges(sort=True) # optional - sage.graphs sage.rings.finite_rings [('0', '125', None), ('0', '125', None), ... '81*i + 65', None)] - sage: H = E.isogeny_ell_graph(2, directed=False, label_by_j=True) - sage: H + sage: H = E.isogeny_ell_graph(2, directed=False, label_by_j=True) # optional - sage.graphs sage.rings.finite_rings + sage: H # optional - sage.graphs sage.rings.finite_rings Looped multi-graph on 37 vertices - sage: H.vertices(sort=True) + sage: H.vertices(sort=True) # optional - sage.graphs sage.rings.finite_rings ['0', '102', ... '87*i + 190'] - sage: H.edges(sort=True) + sage: H.edges(sort=True) # optional - sage.graphs sage.rings.finite_rings [('0', '125', None), ('102', '125', None), ... @@ -1720,49 +1867,49 @@ class of curves. If the j-invariant is not unique in the isogeny Curve over a quadratic number field:: - sage: K. = NumberField(x^2 - 2) - sage: E = EllipticCurve(K, [1,0,1,4, -6]) - sage: G2 = E.isogeny_ell_graph(2, directed=False) - sage: G2.vertices(sort=True) + sage: K. = NumberField(x^2 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [1, 0, 1, 4, -6]) # optional - sage.rings.number_field + sage: G2 = E.isogeny_ell_graph(2, directed=False) # optional - sage.graphs sage.rings.number_field + sage: G2.vertices(sort=True) # optional - sage.graphs sage.rings.number_field ['y^2 + x*y + y = x^3 + (-130*e-356)*x + (-2000*e-2038)', 'y^2 + x*y + y = x^3 + (-36)*x + (-70)', 'y^2 + x*y + y = x^3 + (130*e-356)*x + (2000*e-2038)', 'y^2 + x*y + y = x^3 + 4*x + (-6)'] - sage: G2.edges(sort=True) + sage: G2.edges(sort=True) # optional - sage.graphs sage.rings.number_field [('y^2 + x*y + y = x^3 + (-130*e-356)*x + (-2000*e-2038)', - 'y^2 + x*y + y = x^3 + (-36)*x + (-70)', None), + 'y^2 + x*y + y = x^3 + (-36)*x + (-70)', None), ('y^2 + x*y + y = x^3 + (-36)*x + (-70)', - 'y^2 + x*y + y = x^3 + (130*e-356)*x + (2000*e-2038)', None), + 'y^2 + x*y + y = x^3 + (130*e-356)*x + (2000*e-2038)', None), ('y^2 + x*y + y = x^3 + (-36)*x + (-70)', - 'y^2 + x*y + y = x^3 + 4*x + (-6)', None)] - sage: G3 = E.isogeny_ell_graph(3, directed=False) - sage: G3.vertices(sort=True) + 'y^2 + x*y + y = x^3 + 4*x + (-6)', None)] + sage: G3 = E.isogeny_ell_graph(3, directed=False) # optional - sage.graphs sage.rings.number_field + sage: G3.vertices(sort=True) # optional - sage.graphs sage.rings.number_field ['y^2 + x*y + y = x^3 + (-1)*x', 'y^2 + x*y + y = x^3 + (-171)*x + (-874)', 'y^2 + x*y + y = x^3 + 4*x + (-6)'] - sage: G3.edges(sort=True) + sage: G3.edges(sort=True) # optional - sage.graphs sage.rings.number_field [('y^2 + x*y + y = x^3 + (-1)*x', - 'y^2 + x*y + y = x^3 + 4*x + (-6)', None), + 'y^2 + x*y + y = x^3 + 4*x + (-6)', None), ('y^2 + x*y + y = x^3 + (-171)*x + (-874)', - 'y^2 + x*y + y = x^3 + 4*x + (-6)', None)] + 'y^2 + x*y + y = x^3 + 4*x + (-6)', None)] TESTS:: - sage: E = EllipticCurve(GF(11), j=0) - sage: G0 = E.isogeny_ell_graph(2, directed=False) - sage: G0.is_directed() + sage: E = EllipticCurve(GF(11), j=0) # optional - sage.rings.finite_rings + sage: G0 = E.isogeny_ell_graph(2, directed=False) # optional - sage.graphs sage.rings.finite_rings + sage: G0.is_directed() # optional - sage.graphs sage.rings.finite_rings False - sage: G1 = E.isogeny_ell_graph(2, directed=True) - sage: G1.is_directed() + sage: G1 = E.isogeny_ell_graph(2, directed=True) # optional - sage.graphs sage.rings.finite_rings + sage: G1.is_directed() # optional - sage.graphs sage.rings.finite_rings True - sage: G2 = E.isogeny_ell_graph(2, label_by_j=False) - sage: G2.vertices(sort=True) + sage: G2 = E.isogeny_ell_graph(2, label_by_j=False) # optional - sage.graphs sage.rings.finite_rings + sage: G2.vertices(sort=True) # optional - sage.graphs sage.rings.finite_rings ['y^2 = x^3 + 1', 'y^2 = x^3 + 2', 'y^2 = x^3 + 5*x', 'y^2 = x^3 + 7*x'] - sage: G3 = E.isogeny_ell_graph(2, label_by_j=True) - sage: G3.vertices(sort=True) + sage: G3 = E.isogeny_ell_graph(2, label_by_j=True) # optional - sage.graphs sage.rings.finite_rings + sage: G3.vertices(sort=True) # optional - sage.graphs sage.rings.finite_rings ['0', '0*', '1', '1*'] """ diff --git a/src/sage/schemes/elliptic_curves/ell_finite_field.py b/src/sage/schemes/elliptic_curves/ell_finite_field.py index cc914f59830..67311df1789 100644 --- a/src/sage/schemes/elliptic_curves/ell_finite_field.py +++ b/src/sage/schemes/elliptic_curves/ell_finite_field.py @@ -940,7 +940,9 @@ def abelian_group(self): sage: E = EllipticCurve(GF(11),[2,5]) sage: E.abelian_group() - Additive abelian group isomorphic to Z/10 embedded in Abelian group of points on Elliptic Curve defined by y^2 = x^3 + 2*x + 5 over Finite Field of size 11 + Additive abelian group isomorphic to Z/10 embedded in + Abelian group of points on Elliptic Curve defined by y^2 = x^3 + 2*x + 5 + over Finite Field of size 11 :: @@ -964,9 +966,10 @@ def abelian_group(self): The group can be trivial:: - sage: E = EllipticCurve(GF(2),[0,0,1,1,1]) + sage: E = EllipticCurve(GF(2), [0,0,1,1,1]) sage: E.abelian_group() - Trivial group embedded in Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 + x + 1 over Finite Field of size 2 + Trivial group embedded in Abelian group of points on + Elliptic Curve defined by y^2 + y = x^3 + x + 1 over Finite Field of size 2 Of course, there are plenty of points if we extend the field:: @@ -987,14 +990,15 @@ def abelian_group(self): sage: K. = QuadraticField(-1) sage: OK = K.ring_of_integers() - sage: P=K.factor(10007)[0][0] + sage: P = K.factor(10007)[0][0] sage: OKmodP = OK.residue_field(P) - sage: E = EllipticCurve([0,0,0,i,i+3]) + sage: E = EllipticCurve([0, 0, 0, i, i + 3]) sage: Emod = E.change_ring(OKmodP); Emod - Elliptic Curve defined by y^2 = x^3 + ibar*x + (ibar+3) over Residue field in ibar of Fractional ideal (10007) + Elliptic Curve defined by y^2 = x^3 + ibar*x + (ibar+3) + over Residue field in ibar of Fractional ideal (10007) sage: Emod.abelian_group() #random generators (Multiplicative Abelian group isomorphic to C50067594 x C2, - ((3152*ibar + 7679 : 7330*ibar + 7913 : 1), (8466*ibar + 1770 : 0 : 1))) + ((3152*ibar + 7679 : 7330*ibar + 7913 : 1), (8466*ibar + 1770 : 0 : 1))) """ gens = self.gens() @@ -1037,7 +1041,9 @@ def torsion_basis(self, n): sage: E = EllipticCurve(GF(62207^2), [1,0]) sage: E.abelian_group() - Additive abelian group isomorphic to Z/62208 + Z/62208 embedded in Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 62207^2 + Additive abelian group isomorphic to Z/62208 + Z/62208 embedded in + Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x + over Finite Field in z2 of size 62207^2 sage: PA,QA = E.torsion_basis(2^8) sage: PA.weil_pairing(QA, 2^8).multiplicative_order() 256 @@ -1268,7 +1274,7 @@ def is_ordinary(self, proof=True): def set_order(self, value, *, check=True, num_checks=8): r""" - Set the value of self._order to value. + Set the value of ``self._order`` to ``value``. Use this when you know a priori the order of the curve to avoid a potentially expensive order calculation. @@ -1341,7 +1347,7 @@ def set_order(self, value, *, check=True, num_checks=8): It is also very likely an error to pass a value which is not the actual order of this curve. How unlikely is determined by - num_checks, the factorization of the actual order, and the + ``num_checks``, the factorization of the actual order, and the actual group structure:: sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 6 @@ -1359,7 +1365,7 @@ def set_order(self, value, *, check=True, num_checks=8): sage: E.order() 12 - Or, the order can be set incorrectly along with num_checks set + Or, the order can be set incorrectly along with ``num_checks`` set too small:: sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 6 @@ -1367,7 +1373,7 @@ def set_order(self, value, *, check=True, num_checks=8): sage: E.order() 4 - The value of num_checks must be an integer. Negative values + The value of ``num_checks`` must be an integer. Negative values are interpreted as zero, which means don't do any checking:: sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 6 @@ -1666,9 +1672,9 @@ def twists(self): sage: K = GF(3**5) sage: [E.ainvs() for E in EllipticCurve(j=K(0)).twists()] # random [(0, 0, 0, 1, 0), - (0, 0, 0, 2, 0), - (0, 0, 0, 2, z5^4 + z5^3 + z5^2), - (0, 0, 0, 2, 2*z5^4 + 2*z5^3 + 2*z5^2)] + (0, 0, 0, 2, 0), + (0, 0, 0, 2, z5^4 + z5^3 + z5^2), + (0, 0, 0, 2, 2*z5^4 + 2*z5^3 + 2*z5^2)] sage: K = GF(3**4) sage: [E.ainvs() for E in EllipticCurve(j=K(1)).twists()] @@ -1677,11 +1683,11 @@ def twists(self): sage: K = GF(3**4) sage: [E.ainvs() for E in EllipticCurve(j=K(0)).twists()] # random [(0, 0, 0, 1, 0), - (0, 0, 0, 2, 2*z4^3 + 2*z4^2 + 2*z4 + 2), - (0, 0, 0, 1, 0), - (0, 0, 0, 1, 2*z4^3 + 2*z4^2 + 2*z4 + 2), - (0, 0, 0, z4, 0), - (0, 0, 0, z4^3, 0)] + (0, 0, 0, 2, 2*z4^3 + 2*z4^2 + 2*z4 + 2), + (0, 0, 0, 1, 0), + (0, 0, 0, 1, 2*z4^3 + 2*z4^2 + 2*z4 + 2), + (0, 0, 0, z4, 0), + (0, 0, 0, z4^3, 0)] In characteristic 2, the number of twists is 2 except for `j=0=1728`, when there are either 3 or 7 depending on whether the @@ -1702,12 +1708,12 @@ def twists(self): sage: K = GF(2**8) sage: [E.ainvs() for E in EllipticCurve(j=K(0)).twists()] # random [(0, 0, 1, 0, 0), - (0, 0, 1, 0, z8^5 + z8^4 + z8^3), - (0, 0, 1, z8^6 + z8^5 + z8^2 + 1, 0), - (0, 0, z8^4 + z8^3 + z8^2 + 1, 0, 0), - (0, 0, z8^4 + z8^3 + z8^2 + 1, 0, z8^3 + z8^2 + 1), - (0, 0, z8^6 + z8^3 + z8^2, 0, 0), - (0, 0, z8^6 + z8^3 + z8^2, 0, z8^3 + z8^2)] + (0, 0, 1, 0, z8^5 + z8^4 + z8^3), + (0, 0, 1, z8^6 + z8^5 + z8^2 + 1, 0), + (0, 0, z8^4 + z8^3 + z8^2 + 1, 0, 0), + (0, 0, z8^4 + z8^3 + z8^2 + 1, 0, z8^3 + z8^2 + 1), + (0, 0, z8^6 + z8^3 + z8^2, 0, 0), + (0, 0, z8^6 + z8^3 + z8^2, 0, z8^3 + z8^2)] TESTS: @@ -1789,18 +1795,18 @@ def curves_with_j_0(K): sage: from sage.schemes.elliptic_curves.ell_finite_field import curves_with_j_0 sage: sorted(curves_with_j_0(GF(7)), key = lambda E: E.a_invariants()) [Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7, - Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field of size 7, - Elliptic Curve defined by y^2 = x^3 + 3 over Finite Field of size 7, - Elliptic Curve defined by y^2 = x^3 + 4 over Finite Field of size 7, - Elliptic Curve defined by y^2 = x^3 + 5 over Finite Field of size 7, - Elliptic Curve defined by y^2 = x^3 + 6 over Finite Field of size 7] + Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field of size 7, + Elliptic Curve defined by y^2 = x^3 + 3 over Finite Field of size 7, + Elliptic Curve defined by y^2 = x^3 + 4 over Finite Field of size 7, + Elliptic Curve defined by y^2 = x^3 + 5 over Finite Field of size 7, + Elliptic Curve defined by y^2 = x^3 + 6 over Finite Field of size 7] sage: curves_with_j_0(GF(25)) [Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in z2 of size 5^2, - Elliptic Curve defined by y^2 = x^3 + z2 over Finite Field in z2 of size 5^2, - Elliptic Curve defined by y^2 = x^3 + (z2+3) over Finite Field in z2 of size 5^2, - Elliptic Curve defined by y^2 = x^3 + (4*z2+3) over Finite Field in z2 of size 5^2, - Elliptic Curve defined by y^2 = x^3 + (2*z2+2) over Finite Field in z2 of size 5^2, - Elliptic Curve defined by y^2 = x^3 + (4*z2+1) over Finite Field in z2 of size 5^2] + Elliptic Curve defined by y^2 = x^3 + z2 over Finite Field in z2 of size 5^2, + Elliptic Curve defined by y^2 = x^3 + (z2+3) over Finite Field in z2 of size 5^2, + Elliptic Curve defined by y^2 = x^3 + (4*z2+3) over Finite Field in z2 of size 5^2, + Elliptic Curve defined by y^2 = x^3 + (2*z2+2) over Finite Field in z2 of size 5^2, + Elliptic Curve defined by y^2 = x^3 + (4*z2+1) over Finite Field in z2 of size 5^2] For `K=\GF{q}` where `q\equiv5\mod{6}` there are two curves, quadratic twists of each other by `-3`: `y^2=x^3+1` and @@ -1809,10 +1815,10 @@ def curves_with_j_0(K): sage: from sage.schemes.elliptic_curves.ell_finite_field import curves_with_j_0 sage: curves_with_j_0(GF(5)) [Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 5, - Elliptic Curve defined by y^2 = x^3 + 3 over Finite Field of size 5] + Elliptic Curve defined by y^2 = x^3 + 3 over Finite Field of size 5] sage: curves_with_j_0(GF(11)) [Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 11, - Elliptic Curve defined by y^2 = x^3 + 6 over Finite Field of size 11] + Elliptic Curve defined by y^2 = x^3 + 6 over Finite Field of size 11] """ if not K.is_finite(): raise ValueError("field must be finite") @@ -1843,33 +1849,33 @@ def curves_with_j_1728(K): ``curves_with_j_0_char3``. Otherwise there are either 2 or 4 curves, parametrised by `K^*/(K^*)^4`. - Examples: + EXAMPLES: - For `K=\GF{q}` where `q\equiv1\mod{4} there are four curves, the quartic twists of `y^2=x^3+x`:: + For `K=\GF{q}` where `q\equiv1\mod{4}`, there are four curves, the quartic twists of `y^2=x^3+x`:: sage: from sage.schemes.elliptic_curves.ell_finite_field import curves_with_j_1728 sage: sorted(curves_with_j_1728(GF(5)), key = lambda E: E.a_invariants()) [Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 5, - Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 5, - Elliptic Curve defined by y^2 = x^3 + 3*x over Finite Field of size 5, - Elliptic Curve defined by y^2 = x^3 + 4*x over Finite Field of size 5] + Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 5, + Elliptic Curve defined by y^2 = x^3 + 3*x over Finite Field of size 5, + Elliptic Curve defined by y^2 = x^3 + 4*x over Finite Field of size 5] sage: curves_with_j_1728(GF(49)) [Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 7^2, - Elliptic Curve defined by y^2 = x^3 + z2*x over Finite Field in z2 of size 7^2, - Elliptic Curve defined by y^2 = x^3 + (z2+4)*x over Finite Field in z2 of size 7^2, - Elliptic Curve defined by y^2 = x^3 + (5*z2+4)*x over Finite Field in z2 of size 7^2] + Elliptic Curve defined by y^2 = x^3 + z2*x over Finite Field in z2 of size 7^2, + Elliptic Curve defined by y^2 = x^3 + (z2+4)*x over Finite Field in z2 of size 7^2, + Elliptic Curve defined by y^2 = x^3 + (5*z2+4)*x over Finite Field in z2 of size 7^2] - For `K=\GF{q}` where `q\equiv3\mod{4} there are two curves, + For `K=\GF{q}` where `q\equiv3\mod{4}`, there are two curves, quadratic twists of each other by `-1`: `y^2=x^3+x` and `y^2=x^3-x`:: sage: from sage.schemes.elliptic_curves.ell_finite_field import curves_with_j_1728 sage: curves_with_j_1728(GF(7)) [Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7, - Elliptic Curve defined by y^2 = x^3 + 6*x over Finite Field of size 7] + Elliptic Curve defined by y^2 = x^3 + 6*x over Finite Field of size 7] sage: curves_with_j_1728(GF(11)) [Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 11, - Elliptic Curve defined by y^2 = x^3 + 10*x over Finite Field of size 11] + Elliptic Curve defined by y^2 = x^3 + 10*x over Finite Field of size 11] """ if not K.is_finite(): raise ValueError("field must be finite") @@ -1929,12 +1935,12 @@ def curves_with_j_0_char2(K): 7 sage: [E.ainvs() for E in curves] # random [(0, 0, 1, 0, 0), - (0, 0, 1, 0, z8^5 + z8^4 + z8^3), - (0, 0, 1, z8^6 + z8^5 + z8^2 + 1, 0), - (0, 0, z8^4 + z8^3 + z8^2 + 1, 0, 0), - (0, 0, z8^4 + z8^3 + z8^2 + 1, 0, z8^3 + z8^2 + 1), - (0, 0, z8^6 + z8^3 + z8^2, 0, 0), - (0, 0, z8^6 + z8^3 + z8^2, 0, z8^3 + z8^2)] + (0, 0, 1, 0, z8^5 + z8^4 + z8^3), + (0, 0, 1, z8^6 + z8^5 + z8^2 + 1, 0), + (0, 0, z8^4 + z8^3 + z8^2 + 1, 0, 0), + (0, 0, z8^4 + z8^3 + z8^2 + 1, 0, z8^3 + z8^2 + 1), + (0, 0, z8^6 + z8^3 + z8^2, 0, 0), + (0, 0, z8^6 + z8^3 + z8^2, 0, z8^3 + z8^2)] Check that the twists are mutually non-isomorphic:: @@ -1996,9 +2002,9 @@ def curves_with_j_0_char3(K): 4 sage: [E.ainvs() for E in curves] # random [(0, 0, 0, 1, 0), - (0, 0, 0, 2, 0), - (0, 0, 0, 2, z5^4 + z5^3 + z5^2), - (0, 0, 0, 2, 2*z5^4 + 2*z5^3 + 2*z5^2)] + (0, 0, 0, 2, 0), + (0, 0, 0, 2, z5^4 + z5^3 + z5^2), + (0, 0, 0, 2, 2*z5^4 + 2*z5^3 + 2*z5^2)] Check that the twists are mutually non-isomorphic:: @@ -2019,11 +2025,11 @@ def curves_with_j_0_char3(K): 6 sage: [E.ainvs() for E in curves] # random [(0, 0, 0, 1, 0), - (0, 0, 0, 2, 2*z4^3 + 2*z4^2 + 2*z4 + 2), - (0, 0, 0, 1, 0), - (0, 0, 0, 1, 2*z4^3 + 2*z4^2 + 2*z4 + 2), - (0, 0, 0, z4, 0), - (0, 0, 0, z4^3, 0)] + (0, 0, 0, 2, 2*z4^3 + 2*z4^2 + 2*z4 + 2), + (0, 0, 0, 1, 0), + (0, 0, 0, 1, 2*z4^3 + 2*z4^2 + 2*z4 + 2), + (0, 0, 0, z4, 0), + (0, 0, 0, z4^3, 0)] Check that the twists are mutually non-isomorphic:: @@ -2144,7 +2150,7 @@ def supersingular_j_polynomial(p, use_cache=True): - `p` (integer) -- a prime number. - - `use_cache` (boolean, default ``True``) -- use cached coefficients if they exist + - ``use_cache`` (boolean, default ``True``) -- use cached coefficients if they exist ALGORITHM: diff --git a/src/sage/schemes/elliptic_curves/ell_generic.py b/src/sage/schemes/elliptic_curves/ell_generic.py index e9d42c7e487..4989c94d0d2 100644 --- a/src/sage/schemes/elliptic_curves/ell_generic.py +++ b/src/sage/schemes/elliptic_curves/ell_generic.py @@ -19,12 +19,13 @@ We construct an elliptic curve over an elaborate base ring:: sage: p, a, b = 97, 1, 3 - sage: R. = GF(p)[] - sage: S. = R[] - sage: T = S.fraction_field() - sage: E = EllipticCurve(T, [a, b]); E - Elliptic Curve defined by y^2 = x^3 + x + 3 over Fraction Field of Univariate Polynomial Ring in v over Univariate Polynomial Ring in u over Finite Field of size 97 - sage: latex(E) + sage: R. = GF(p)[] # optional - sage.rings.finite_rings + sage: S. = R[] # optional - sage.rings.finite_rings + sage: T = S.fraction_field() # optional - sage.rings.finite_rings + sage: E = EllipticCurve(T, [a, b]); E # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 = x^3 + x + 3 over Fraction Field of Univariate + Polynomial Ring in v over Univariate Polynomial Ring in u over Finite Field of size 97 + sage: latex(E) # optional - sage.rings.finite_rings y^2 = x^{3} + x + 3 AUTHORS: @@ -136,9 +137,11 @@ def __init__(self, K, ainvs): EXAMPLES:: sage: E = EllipticCurve([1,2,3,4,5]); E - Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field - sage: E = EllipticCurve(GF(7),[1,2,3,4,5]); E - Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Finite Field of size 7 + Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 + over Rational Field + sage: E = EllipticCurve(GF(7), [1,2,3,4,5]); E # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 + over Finite Field of size 7 Constructor from `[a_4,a_6]` sets `a_1=a_2=a_3=0`:: @@ -147,8 +150,9 @@ def __init__(self, K, ainvs): The base ring need not be a field:: - sage: EllipticCurve(IntegerModRing(91),[1,2,3,4,5]) - Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Ring of integers modulo 91 + sage: EllipticCurve(IntegerModRing(91), [1,2,3,4,5]) + Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 + over Ring of integers modulo 91 """ self.__base_ring = K self.__ainvs = tuple(K(a) for a in ainvs) @@ -245,9 +249,10 @@ def _repr_(self): :: sage: R. = QQ['x'] - sage: K. = NumberField(x^3-17) - sage: EllipticCurve([a^2-3, -2/3*a + 3]) - Elliptic Curve defined by y^2 = x^3 + (a^2-3)*x + (-2/3*a+3) over Number Field in a + sage: K. = NumberField(x^3 - 17) # optional - sage.rings.number_field + sage: EllipticCurve([a^2 - 3, -2/3*a + 3]) # optional - sage.rings.number_field + Elliptic Curve defined by y^2 = x^3 + (a^2-3)*x + (-2/3*a+3) + over Number Field in a with defining polynomial x^3 - 17 """ s = "Elliptic Curve defined by " @@ -273,9 +278,9 @@ def _latex_(self): Check that :trac:`12524` is solved:: - sage: K. = NumberField(x^2-x-1) - sage: E = EllipticCurve([0,0,phi,27*phi-43,-80*phi+128]) - sage: E._latex_() + sage: K. = NumberField(x^2 - x - 1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 0, phi, 27*phi - 43, -80*phi + 128]) # optional - sage.rings.number_field + sage: E._latex_() # optional - sage.rings.number_field 'y^2 + \\phi y = x^{3} + \\left(27 \\phi - 43\\right) x - 80 \\phi + 128 ' """ from sage.rings.polynomial.polynomial_ring import polygen @@ -311,20 +316,21 @@ def _magma_init_(self, magma): EXAMPLES:: - sage: E = EllipticCurve(QQ,[1,1]) - sage: E._magma_init_(magma) # optional - magma + sage: E = EllipticCurve(QQ, [1,1]) + sage: E._magma_init_(magma) # optional - magma 'EllipticCurve([_sage_ref...|0/1,0/1,0/1,1/1,1/1])' - sage: E = EllipticCurve(GF(41),[2,5]) # optional - magma - sage: E._magma_init_(magma) # optional - magma + sage: E = EllipticCurve(GF(41), [2,5]) # optional - sage.rings.finite_rings + sage: E._magma_init_(magma) # optional - magma # optional - sage.rings.finite_rings 'EllipticCurve([_sage_ref...|GF(41)!0,GF(41)!0,GF(41)!0,GF(41)!2,GF(41)!5])' - sage: E = EllipticCurve(GF(25,'a'), [0,0,1,4,0]) - sage: magma(E) # optional - magma + sage: E = EllipticCurve(GF(25,'a'), [0,0,1,4,0]) # optional - sage.rings.finite_rings + sage: magma(E) # optional - magma # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 + y = x^3 + 4*x over GF(5^2) - sage: magma(EllipticCurve([1/2,2/3,-4/5,6/7,8/9])) # optional - magma + sage: magma(EllipticCurve([1/2,2/3,-4/5,6/7,8/9])) # optional - magma Elliptic Curve defined by y^2 + 1/2*x*y - 4/5*y = x^3 + 2/3*x^2 + 6/7*x + 8/9 over Rational Field sage: R. = Frac(QQ['x']) - sage: magma(EllipticCurve([x,1+x])) # optional - magma - Elliptic Curve defined by y^2 = x^3 + x*x + (x + 1) over Univariate rational function field over Rational Field + sage: magma(EllipticCurve([x, 1 + x])) # optional - magma + Elliptic Curve defined by y^2 = x^3 + x*x + (x + 1) + over Univariate rational function field over Rational Field """ kmn = magma(self.base_ring())._ref() return 'EllipticCurve([%s|%s])' % (kmn,','.join(x._magma_init_(magma) @@ -340,29 +346,29 @@ def _symbolic_(self, SR): :: sage: E = EllipticCurve('11a') - sage: E._symbolic_(SR) + sage: E._symbolic_(SR) # optional - sage.symbolic y^2 + y == x^3 - x^2 - 10*x - 20 - sage: E.torsion_subgroup().gens() + sage: E.torsion_subgroup().gens() # optional - sage.symbolic ((5 : 5 : 1),) We find the corresponding symbolic equality:: - sage: eqn = symbolic_expression(E); eqn + sage: eqn = symbolic_expression(E); eqn # optional - sage.symbolic y^2 + y == x^3 - x^2 - 10*x - 20 We verify that the given point is on the curve:: - sage: eqn(x=5,y=5) + sage: eqn(x=5, y=5) # optional - sage.symbolic 30 == 30 - sage: bool(eqn(x=5,y=5)) + sage: bool(eqn(x=5, y=5)) # optional - sage.symbolic True We create a single expression:: - sage: F = eqn.lhs() - eqn.rhs(); F + sage: F = eqn.lhs() - eqn.rhs(); F # optional - sage.symbolic -x^3 + x^2 + y^2 + 10*x + y + 20 - sage: y = var('y') - sage: F.solve(y) + sage: y = var('y') # optional - sage.symbolic + sage: F.solve(y) # optional - sage.symbolic [y == -1/2*sqrt(4*x^3 - 4*x^2 - 40*x - 79) - 1/2, y == 1/2*sqrt(4*x^3 - 4*x^2 - 40*x - 79) - 1/2] @@ -370,43 +376,44 @@ def _symbolic_(self, SR): horrendous. Continuing with the above example, we can explicitly find points over random fields by substituting in values for x:: - sage: v = F.solve(y)[0].rhs(); v + sage: v = F.solve(y)[0].rhs(); v # optional - sage.symbolic -1/2*sqrt(4*x^3 - 4*x^2 - 40*x - 79) - 1/2 - sage: v = v.function(x) - sage: v(3) + sage: v = v.function(x) # optional - sage.symbolic + sage: v(3) # optional - sage.symbolic -1/2*sqrt(-127) - 1/2 - sage: v(7) + sage: v(7) # optional - sage.symbolic -1/2*sqrt(817) - 1/2 - sage: v(-7) + sage: v(-7) # optional - sage.symbolic -1/2*sqrt(-1367) - 1/2 - sage: v(sqrt(2)) + sage: v(sqrt(2)) # optional - sage.symbolic -1/2*sqrt(-32*sqrt(2) - 87) - 1/2 We can even do arithmetic with them, as follows:: - sage: E2 = E.change_ring(SR); E2 - Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Symbolic Ring - sage: P = E2.point((3, v(3), 1), check=False) # the check=False option doesn't verify that y^2 = f(x) - sage: P + sage: E2 = E.change_ring(SR); E2 # optional - sage.symbolic + Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) + over Symbolic Ring + sage: P = E2.point((3, v(3), 1), check=False) # the check=False option doesn't verify that y^2 = f(x) # optional - sage.symbolic + sage: P # optional - sage.symbolic (3 : -1/2*sqrt(-127) - 1/2 : 1) - sage: P + P + sage: P + P # optional - sage.symbolic (-756/127 : 41143/32258*sqrt(-127) - 1/2 : 1) We can even throw in a transcendental:: - sage: w = E2.point((pi,v(pi),1), check=False); w + sage: w = E2.point((pi,v(pi),1), check=False); w # optional - sage.symbolic (pi : -1/2*sqrt(-40*pi + 4*pi^3 - 4*pi^2 - 79) - 1/2 : 1) - sage: x, y, z = w; ((y^2 + y) - (x^3 - x^2 - 10*x - 20)).expand() + sage: x, y, z = w; ((y^2 + y) - (x^3 - x^2 - 10*x - 20)).expand() # optional - sage.symbolic 0 - sage: 2*w + sage: 2*w # optional - sage.symbolic (-2*pi - (2*pi - 3*pi^2 + 10)^2/(40*pi - 4*pi^3 + 4*pi^2 + 79) + 1 : (3*pi + (2*pi - 3*pi^2 + 10)^2/(40*pi - 4*pi^3 + 4*pi^2 + 79) - 1)*(2*pi - 3*pi^2 + 10)/sqrt(-40*pi + 4*pi^3 - 4*pi^2 - 79) + 1/2*sqrt(-40*pi + 4*pi^3 - 4*pi^2 - 79) - 1/2 : 1) - sage: x, y, z = 2*w; temp = ((y^2 + y) - (x^3 - x^2 - 10*x - 20)) + sage: x, y, z = 2*w; temp = ((y^2 + y) - (x^3 - x^2 - 10*x - 20)) # optional - sage.symbolic This is a point on the curve:: - sage: bool(temp == 0) + sage: bool(temp == 0) # optional - sage.symbolic True """ a = [SR(x) for x in self.a_invariants()] @@ -426,15 +433,15 @@ def __contains__(self, P): True sage: (1,3) in E False - sage: E = EllipticCurve([GF(7)(0), 1]) - sage: [0,0] in E + sage: E = EllipticCurve([GF(7)(0), 1]) # optional - sage.rings.finite_rings + sage: [0,0] in E # optional - sage.rings.finite_rings False - sage: [0,8] in E + sage: [0,8] in E # optional - sage.rings.finite_rings True - sage: P = E(0,8) - sage: P + sage: P = E(0,8) # optional - sage.rings.finite_rings + sage: P # optional - sage.rings.finite_rings (0 : 1 : 1) - sage: P in E + sage: P in E # optional - sage.rings.finite_rings True """ if not isinstance(P, ell_point.EllipticCurvePoint): @@ -484,28 +491,31 @@ def __call__(self, *args, **kwds): We create points on an elliptic curve over a prime finite field:: - sage: E = EllipticCurve([GF(7)(0), 1]) - sage: E([2,3]) + sage: E = EllipticCurve([GF(7)(0), 1]) # optional - sage.rings.finite_rings + sage: E([2,3]) # optional - sage.rings.finite_rings (2 : 3 : 1) - sage: E([0,0]) + sage: E([0,0]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: Coordinates [0, 0, 1] do not define a point on Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 + TypeError: Coordinates [0, 0, 1] do not define a point + on Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 We create a point on an elliptic curve over a number field:: sage: x = polygen(RationalField()) - sage: K = NumberField(x**3 + x + 1, 'a'); a = K.gen() - sage: E = EllipticCurve([a,a]) - sage: E - Elliptic Curve defined by y^2 = x^3 + a*x + a over Number Field in a with defining polynomial x^3 + x + 1 - sage: E = EllipticCurve([K(1),1]) - sage: E - Elliptic Curve defined by y^2 = x^3 + x + 1 over Number Field in a with defining polynomial x^3 + x + 1 - sage: P = E([a,0,1]) - sage: P + sage: K = NumberField(x**3 + x + 1, 'a'); a = K.gen() # optional - sage.rings.number_field + sage: E = EllipticCurve([a, a]) # optional - sage.rings.number_field + sage: E # optional - sage.rings.number_field + Elliptic Curve defined by y^2 = x^3 + a*x + a + over Number Field in a with defining polynomial x^3 + x + 1 + sage: E = EllipticCurve([K(1), 1]) # optional - sage.rings.number_field + sage: E # optional - sage.rings.number_field + Elliptic Curve defined by y^2 = x^3 + x + 1 + over Number Field in a with defining polynomial x^3 + x + 1 + sage: P = E([a,0,1]) # optional - sage.rings.number_field + sage: P # optional - sage.rings.number_field (a : 0 : 1) - sage: P+P + sage: P + P # optional - sage.rings.number_field (0 : 1 : 0) Another example involving p-adics:: @@ -513,9 +523,11 @@ def __call__(self, *args, **kwds): sage: E = EllipticCurve('37a1') sage: P = E([0,0]); P (0 : 0 : 1) - sage: R = pAdicField(3,20) - sage: Ep = E.base_extend(R); Ep - Elliptic Curve defined by y^2 + (1+O(3^20))*y = x^3 + (2+2*3+2*3^2+2*3^3+2*3^4+2*3^5+2*3^6+2*3^7+2*3^8+2*3^9+2*3^10+2*3^11+2*3^12+2*3^13+2*3^14+2*3^15+2*3^16+2*3^17+2*3^18+2*3^19+O(3^20))*x over 3-adic Field with capped relative precision 20 + sage: R = pAdicField(3, 20) # optional - sage.rings.padics + sage: Ep = E.base_extend(R); Ep # optional - sage.rings.padics + Elliptic Curve defined by + y^2 + (1+O(3^20))*y = x^3 + (2+2*3+2*3^2+2*3^3+2*3^4+2*3^5+2*3^6+2*3^7+2*3^8+2*3^9+2*3^10+2*3^11+2*3^12+2*3^13+2*3^14+2*3^15+2*3^16+2*3^17+2*3^18+2*3^19+O(3^20))*x + over 3-adic Field with capped relative precision 20 sage: Ep(P) (0 : 0 : 1 + O(3^20)) @@ -605,14 +617,14 @@ def _reduce_point(self, R, p): point at infinity on the same curve but reduced modulo 11. The reduce function tells us this:: - sage: E11 = E.change_ring(GF(11)) - sage: S = E11._reduce_point(R, 11) - sage: E11(S) + sage: E11 = E.change_ring(GF(11)) # optional - sage.rings.finite_rings + sage: S = E11._reduce_point(R, 11) # optional - sage.rings.finite_rings + sage: E11(S) # optional - sage.rings.finite_rings (0 : 1 : 0) The 0 point reduces as expected:: - sage: E11._reduce_point(E(0), 11) + sage: E11._reduce_point(E(0), 11) # optional - sage.rings.finite_rings (0 : 1 : 0) Note that one need not explicitly call @@ -673,9 +685,9 @@ def is_x_coord(self, x): :: - sage: F = GF(32,'a') - sage: E = EllipticCurve(F,[1,0,0,0,1]) - sage: set(P[0] for P in E.points() if P!=E(0)) == set(x for x in F if E.is_x_coord(x)) + sage: F = GF(32,'a') # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F,[1,0,0,0,1]) # optional - sage.rings.finite_rings + sage: set(P[0] for P in E.points() if P!=E(0)) == set(x for x in F if E.is_x_coord(x)) # optional - sage.rings.finite_rings True """ K = self.base_ring() @@ -744,17 +756,19 @@ def lift_x(self, x, all=False, extend=False): sage: E.lift_x(3) Traceback (most recent call last): ... - ValueError: No point with x-coordinate 3 on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + ValueError: No point with x-coordinate 3 + on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field We can use the ``extend`` parameter to make the necessary quadratic extension. Note that in such cases the returned point is a point on a new curve object, the result of changing the base ring to the parent of `x`:: - sage: P = E.lift_x(3, extend=True); P + sage: P = E.lift_x(3, extend=True); P # optional - sage.rings.number_field (3 : y : 1) - sage: P.curve() - Elliptic Curve defined by y^2 + y = x^3 + (-1)*x over Number Field in y with defining polynomial y^2 + y - 24 + sage: P.curve() # optional - sage.rings.number_field + Elliptic Curve defined by y^2 + y = x^3 + (-1)*x + over Number Field in y with defining polynomial y^2 + y - 24 Or we can extend scalars. There are two such points in `E(\RR)`:: @@ -776,26 +790,28 @@ def lift_x(self, x, all=False, extend=False): sage: E = EllipticCurve([0,0,0,0,2]); E Elliptic Curve defined by y^2 = x^3 + 2 over Rational Field - sage: P = E.lift_x(0, extend=True); P + sage: P = E.lift_x(0, extend=True); P # optional - sage.rings.number_field (0 : y : 1) - sage: P.curve() - Elliptic Curve defined by y^2 = x^3 + 2 over Number Field in y with defining polynomial y^2 - 2 + sage: P.curve() # optional - sage.rings.number_field + Elliptic Curve defined by y^2 = x^3 + 2 + over Number Field in y with defining polynomial y^2 - 2 We can perform these operations over finite fields too:: - sage: E = EllipticCurve('37a').change_ring(GF(17)); E + sage: E = EllipticCurve('37a').change_ring(GF(17)); E # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 + y = x^3 + 16*x over Finite Field of size 17 - sage: E.lift_x(7) + sage: E.lift_x(7) # optional - sage.rings.finite_rings (7 : 11 : 1) - sage: E.lift_x(3) + sage: E.lift_x(3) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: No point with x-coordinate 3 on Elliptic Curve defined by y^2 + y = x^3 + 16*x over Finite Field of size 17 + ValueError: No point with x-coordinate 3 on + Elliptic Curve defined by y^2 + y = x^3 + 16*x over Finite Field of size 17 Note that there is only one lift with `x`-coordinate 10 in `E(\GF{17})`:: - sage: E.lift_x(10, all=True) + sage: E.lift_x(10, all=True) # optional - sage.rings.finite_rings [(10 : 8 : 1)] We can lift over more exotic rings too. If the supplied x @@ -803,17 +819,19 @@ def lift_x(self, x, all=False, extend=False): returned is on the base-extended curve:: sage: E = EllipticCurve('37a') - sage: P = E.lift_x(pAdicField(17, 5)(6)); P + sage: P = E.lift_x(pAdicField(17, 5)(6)); P # optional - sage.rings.padics (6 + O(17^5) : 2 + 16*17 + 16*17^2 + 16*17^3 + 16*17^4 + O(17^5) : 1 + O(17^5)) - sage: P.curve() - Elliptic Curve defined by y^2 + (1+O(17^5))*y = x^3 + (16+16*17+16*17^2+16*17^3+16*17^4+O(17^5))*x over 17-adic Field with capped relative precision 5 + sage: P.curve() # optional - sage.rings.padics + Elliptic Curve defined by + y^2 + (1+O(17^5))*y = x^3 + (16+16*17+16*17^2+16*17^3+16*17^4+O(17^5))*x + over 17-adic Field with capped relative precision 5 sage: K. = PowerSeriesRing(QQ, 't', 5) - sage: P = E.lift_x(1+t); P + sage: P = E.lift_x(1 + t); P (1 + t : 2*t - t^2 + 5*t^3 - 21*t^4 + O(t^5) : 1) - sage: K. = GF(16) - sage: P = E.change_ring(K).lift_x(a^3); P + sage: K. = GF(16) # optional - sage.rings.finite_rings + sage: P = E.change_ring(K).lift_x(a^3); P # optional - sage.rings.finite_rings (a^3 : a^3 + a : 1) - sage: P.curve() + sage: P.curve() # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 + y = x^3 + x over Finite Field in a of size 2^4 We can extend the base field to include the associated `y` value(s):: @@ -827,7 +845,10 @@ def lift_x(self, x, all=False, extend=False): This point is a generic point on E:: sage: P.curve() - Elliptic Curve defined by y^2 = x^3 + 2 over Univariate Quotient Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Rational Field with modulus y^2 - x^3 - 2 + Elliptic Curve defined by y^2 = x^3 + 2 + over Univariate Quotient Polynomial Ring in y + over Fraction Field of Univariate Polynomial Ring in x over Rational Field + with modulus y^2 - x^3 - 2 sage: -P (x : -y : 1) sage: 2*P @@ -835,9 +856,9 @@ def lift_x(self, x, all=False, extend=False): Check that :trac:`30297` is fixed:: - sage: K = Qp(5) - sage: E = EllipticCurve([K(0), K(1)]) - sage: E.lift_x(1, extend=True) + sage: K = Qp(5) # optional - sage.rings.padics + sage: E = EllipticCurve([K(0), K(1)]) # optional - sage.rings.padics + sage: E.lift_x(1, extend=True) # optional - sage.rings.padics (1 + O(5^20) : y + O(5^20) : 1 + O(5^20)) AUTHORS: @@ -847,10 +868,10 @@ def lift_x(self, x, all=False, extend=False): TESTS:: - sage: E = EllipticCurve('37a').short_weierstrass_model().change_ring(GF(17)) - sage: E.lift_x(3, all=True) + sage: E = EllipticCurve('37a').short_weierstrass_model().change_ring(GF(17)) # optional - sage.rings.finite_rings + sage: E.lift_x(3, all=True) # optional - sage.rings.finite_rings [] - sage: E.lift_x(7, all=True) + sage: E.lift_x(7, all=True) # optional - sage.rings.finite_rings [(7 : 3 : 1), (7 : 14 : 1)] """ K = self.base_ring() @@ -931,8 +952,8 @@ def _point_homset(self, *args, **kwds): EXAMPLES:: - sage: E = EllipticCurve(GF(5),[1,1]) - sage: E._point_homset(Spec(GF(5^10,'a'),GF(5)), E) + sage: E = EllipticCurve(GF(5),[1,1]) # optional - sage.rings.finite_rings + sage: E._point_homset(Spec(GF(5^10,'a'), GF(5)), E) # optional - sage.rings.finite_rings Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 5^10 @@ -977,8 +998,8 @@ def __is_over_RationalField(self): sage: E = EllipticCurve(QQ,[1,1]) sage: E._EllipticCurve_generic__is_over_RationalField() True - sage: E = EllipticCurve(GF(5),[1,1]) - sage: E._EllipticCurve_generic__is_over_RationalField() + sage: E = EllipticCurve(GF(5),[1,1]) # optional - sage.rings.finite_rings + sage: E._EllipticCurve_generic__is_over_RationalField() # optional - sage.rings.finite_rings False """ return isinstance(self.base_ring(), rings.RationalField) @@ -1021,8 +1042,8 @@ def a_invariants(self): sage: E.a_invariants() (0, 0, 0, 0, 1) - sage: E = EllipticCurve([GF(7)(3),5]) - sage: E.a_invariants() + sage: E = EllipticCurve([GF(7)(3),5]) # optional - sage.rings.finite_rings + sage: E.a_invariants() # optional - sage.rings.finite_rings (0, 0, 0, 3, 5) TESTS:: @@ -1267,8 +1288,8 @@ def discriminant(self): sage: E.discriminant() -161051 - sage: E = EllipticCurve([GF(7)(2),1]) - sage: E.discriminant() + sage: E = EllipticCurve([GF(7)(2),1]) # optional - sage.rings.finite_rings + sage: E.discriminant() # optional - sage.rings.finite_rings 1 """ b2, b4, b6, b8 = self.b_invariants() @@ -1295,8 +1316,8 @@ def j_invariant(self): sage: E.j_invariant() 1728 - sage: E = EllipticCurve([GF(7)(2),1]) - sage: E.j_invariant() + sage: E = EllipticCurve([GF(7)(2),1]) # optional - sage.rings.finite_rings + sage: E.j_invariant() # optional - sage.rings.finite_rings 1 """ c4, _ = self.c_invariants() @@ -1319,9 +1340,9 @@ def base_extend(self, R): EXAMPLES:: - sage: E = EllipticCurve(GF(5),[1,1]); E + sage: E = EllipticCurve(GF(5), [1,1]); E # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5 - sage: E1 = E.base_extend(GF(125,'a')); E1 + sage: E1 = E.base_extend(GF(125,'a')); E1 # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 5^3 TESTS: @@ -1329,24 +1350,24 @@ def base_extend(self, R): Check that we are correctly keeping track of known cardinalities when extending the base field:: - sage: E = EllipticCurve(j=GF(7)(5)) - sage: E.cardinality() + sage: E = EllipticCurve(j=GF(7)(5)) # optional - sage.rings.finite_rings + sage: E.cardinality() # optional - sage.rings.finite_rings 10 - sage: EE = E.base_extend(GF(7^2)) - sage: EE._order + sage: EE = E.base_extend(GF(7^2)) # optional - sage.rings.finite_rings + sage: EE._order # optional - sage.rings.finite_rings 60 Changing to a smaller field should not cache orders:: - sage: EE = EllipticCurve(j=GF(7^3)(6)) - sage: hasattr(EE.change_ring(GF(7)), '_order') + sage: EE = EllipticCurve(j=GF(7^3)(6)) # optional - sage.rings.finite_rings + sage: hasattr(EE.change_ring(GF(7)), '_order') # optional - sage.rings.finite_rings False Changing to a field of different characteristic should not cache orders:: - sage: Elift = E.change_ring(QQ) - sage: hasattr(Elift, '_order') + sage: Elift = E.change_ring(QQ) # optional - sage.rings.finite_rings + sage: hasattr(Elift, '_order') # optional - sage.rings.finite_rings False """ E = constructor.EllipticCurve([R(a) for a in self.a_invariants()]) @@ -1367,13 +1388,16 @@ def change_ring(self, R): EXAMPLES:: - sage: F2 = GF(5^2,'a'); a = F2.gen() - sage: F4 = GF(5^4,'b'); b = F4.gen() - sage: h = F2.hom([a.charpoly().roots(ring=F4,multiplicities=False)[0]],F4) - sage: E = EllipticCurve(F2,[1,a]); E - Elliptic Curve defined by y^2 = x^3 + x + a over Finite Field in a of size 5^2 - sage: E.change_ring(h) - Elliptic Curve defined by y^2 = x^3 + x + (4*b^3+4*b^2+4*b+3) over Finite Field in b of size 5^4 + sage: F2 = GF(5^2,'a'); a = F2.gen() # optional - sage.rings.finite_rings + sage: F4 = GF(5^4,'b'); b = F4.gen() # optional - sage.rings.finite_rings + sage: roots = a.charpoly().roots(ring=F4, multiplicities=False) # optional - sage.rings.finite_rings + sage: h = F2.hom([roots[0]], F4) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F2, [1,a]); E # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 = x^3 + x + a + over Finite Field in a of size 5^2 + sage: E.change_ring(h) # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 = x^3 + x + (4*b^3+4*b^2+4*b+3) + over Finite Field in b of size 5^4 """ return self.base_extend(R) @@ -1383,8 +1407,8 @@ def base_ring(self): EXAMPLES:: - sage: E = EllipticCurve(GF(49, 'a'), [3,5]) - sage: E.base_ring() + sage: E = EllipticCurve(GF(49, 'a'), [3,5]) # optional - sage.rings.finite_rings + sage: E.base_ring() # optional - sage.rings.finite_rings Finite Field in a of size 7^2 :: @@ -1412,13 +1436,13 @@ def gens(self): EXAMPLES:: - sage: R.=QQ[] + sage: R. = QQ[] sage: E = EllipticCurve([a1,a2,a3,a4,a6]) sage: E.gens() Traceback (most recent call last): ... NotImplementedError: not implemented. - sage: E = EllipticCurve(QQ,[1,1]) + sage: E = EllipticCurve(QQ, [1,1]) sage: E.gens() [(0 : 1 : 1)] """ @@ -1434,7 +1458,7 @@ def gen(self, i): EXAMPLES:: - sage: R.=QQ[] + sage: R. = QQ[] sage: E = EllipticCurve([a1,a2,a3,a4,a6]) sage: E.gen(0) Traceback (most recent call last): @@ -1453,7 +1477,7 @@ def rst_transform(self, r, s, t): OUTPUT: - The elliptic curve obtained from self by the standard + The elliptic curve obtained from ``self`` by the standard Weierstrass transformation `(u,r,s,t)` with `u=1`. .. NOTE:: @@ -1463,10 +1487,13 @@ def rst_transform(self, r, s, t): EXAMPLES:: - sage: R.=QQ[] + sage: R. = QQ[] sage: E = EllipticCurve([1,2,3,4,5]) - sage: E.rst_transform(r,s,t) - Elliptic Curve defined by y^2 + (2*s+1)*x*y + (r+2*t+3)*y = x^3 + (-s^2+3*r-s+2)*x^2 + (3*r^2-r*s-2*s*t+4*r-3*s-t+4)*x + (r^3+2*r^2-r*t-t^2+4*r-3*t+5) over Multivariate Polynomial Ring in r, s, t over Rational Field + sage: E.rst_transform(r, s, t) + Elliptic Curve defined by y^2 + (2*s+1)*x*y + (r+2*t+3)*y + = x^3 + (-s^2+3*r-s+2)*x^2 + (3*r^2-r*s-2*s*t+4*r-3*s-t+4)*x + + (r^3+2*r^2-r*t-t^2+4*r-3*t+5) + over Multivariate Polynomial Ring in r, s, t over Rational Field """ return self.change_weierstrass_model(1, r, s, t) @@ -1480,7 +1507,7 @@ def scale_curve(self, u): OUTPUT: - The elliptic curve obtained from self by the standard + The elliptic curve obtained from ``self`` by the standard Weierstrass transformation `(u,r,s,t)` with `r=s=t=0`. .. NOTE:: @@ -1490,11 +1517,13 @@ def scale_curve(self, u): EXAMPLES:: - sage: K = Frac(PolynomialRing(QQ,'u')) + sage: K = Frac(PolynomialRing(QQ, 'u')) sage: u = K.gen() sage: E = EllipticCurve([1,2,3,4,5]) sage: E.scale_curve(u) - Elliptic Curve defined by y^2 + u*x*y + 3*u^3*y = x^3 + 2*u^2*x^2 + 4*u^4*x + 5*u^6 over Fraction Field of Univariate Polynomial Ring in u over Rational Field + Elliptic Curve defined by + y^2 + u*x*y + 3*u^3*y = x^3 + 2*u^2*x^2 + 4*u^4*x + 5*u^6 + over Fraction Field of Univariate Polynomial Ring in u over Rational Field """ if isinstance(u, int): u = self.base_ring()(u) # because otherwise 1/u would round! @@ -1611,22 +1640,23 @@ def division_polynomial_0(self, n, x=None): An example to illustrate the relationship with torsion points:: - sage: F = GF(11) - sage: E = EllipticCurve(F, [0, 2]); E + sage: F = GF(11) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [0, 2]); E # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field of size 11 - sage: f = E.division_polynomial_0(5); f + sage: f = E.division_polynomial_0(5); f # optional - sage.rings.finite_rings 5*x^12 + x^9 + 8*x^6 + 4*x^3 + 7 - sage: f.factor() - (5) * (x^2 + 5) * (x^2 + 2*x + 5) * (x^2 + 5*x + 7) * (x^2 + 7*x + 7) * (x^2 + 9*x + 5) * (x^2 + 10*x + 7) + sage: f.factor() # optional - sage.rings.finite_rings + (5) * (x^2 + 5) * (x^2 + 2*x + 5) * (x^2 + 5*x + 7) + * (x^2 + 7*x + 7) * (x^2 + 9*x + 5) * (x^2 + 10*x + 7) This indicates that the `x`-coordinates of all the 5-torsion points of `E` are in `\GF{11^2}`, and therefore the `y`-coordinates are in `\GF{11^4}`:: - sage: K = GF(11^4, 'a') - sage: X = E.change_ring(K) - sage: f = X.division_polynomial_0(5) - sage: x_coords = f.roots(multiplicities=False); x_coords + sage: K = GF(11^4, 'a') # optional - sage.rings.finite_rings + sage: X = E.change_ring(K) # optional - sage.rings.finite_rings + sage: f = X.division_polynomial_0(5) # optional - sage.rings.finite_rings + sage: x_coords = f.roots(multiplicities=False); x_coords # optional - sage.rings.finite_rings [10*a^3 + 4*a^2 + 5*a + 6, 9*a^3 + 8*a^2 + 10*a + 8, 8*a^3 + a^2 + 4*a + 10, @@ -1643,7 +1673,7 @@ def division_polynomial_0(self, n, x=None): Now we check that these are exactly the `x`-coordinates of the 5-torsion points of `E`:: - sage: for x in x_coords: + sage: for x in x_coords: # optional - sage.rings.finite_rings ....: assert X.lift_x(x).order() == 5 The roots of the polynomial are the `x`-coordinates of the points `P` @@ -1733,10 +1763,10 @@ def two_division_polynomial(self, x=None): sage: E = EllipticCurve('5077a1') sage: E.two_division_polynomial() 4*x^3 - 28*x + 25 - sage: E = EllipticCurve(GF(3^2,'a'),[1,1,1,1,1]) - sage: E.two_division_polynomial() + sage: E = EllipticCurve(GF(3^2,'a'), [1,1,1,1,1]) # optional - sage.rings.finite_rings + sage: E.two_division_polynomial() # optional - sage.rings.finite_rings x^3 + 2*x^2 + 2 - sage: E.two_division_polynomial().roots() + sage: E.two_division_polynomial().roots() # optional - sage.rings.finite_rings [(2, 1), (2*a, 1), (a + 2, 1)] """ return self.division_polynomial_0(-1,x) @@ -1825,11 +1855,12 @@ def division_polynomial(self, m, x=None, two_torsion_multiplicity=2, force_evalu :: sage: E = EllipticCurve([0, -1, 1, -10, -20]) - sage: R.=PolynomialRing(QQ) - sage: E.division_polynomial(4,z,0) + sage: R. = PolynomialRing(QQ) + sage: E.division_polynomial(4, z, 0) 2*z^6 - 4*z^5 - 100*z^4 - 790*z^3 - 210*z^2 - 1496*z - 5821 - sage: E.division_polynomial(4,z) - 8*z^9 - 24*z^8 - 464*z^7 - 2758*z^6 + 6636*z^5 + 34356*z^4 + 53510*z^3 + 99714*z^2 + 351024*z + 459859 + sage: E.division_polynomial(4, z) + 8*z^9 - 24*z^8 - 464*z^7 - 2758*z^6 + 6636*z^5 + 34356*z^4 + + 53510*z^3 + 99714*z^2 + 351024*z + 459859 This does not work, since when two_torsion_multiplicity is 1, we compute a bivariate polynomial, and must evaluate at a tuple of @@ -1838,9 +1869,10 @@ def division_polynomial(self, m, x=None, two_torsion_multiplicity=2, force_evalu sage: E.division_polynomial(4,z,1) Traceback (most recent call last): ... - ValueError: x should be a tuple of length 2 (or None) when two_torsion_multiplicity is 1 - sage: R.=PolynomialRing(QQ,2) - sage: E.division_polynomial(4,(z,w),1).factor() + ValueError: x should be a tuple of length 2 (or None) + when two_torsion_multiplicity is 1 + sage: R. = PolynomialRing(QQ, 2) + sage: E.division_polynomial(4, (z,w), 1).factor() (2*w + 1) * (2*z^6 - 4*z^5 - 100*z^4 - 790*z^3 - 210*z^2 - 1496*z - 5821) We can also evaluate this bivariate polynomial at a point:: @@ -2044,11 +2076,11 @@ def _multiple_x_numerator(self, n, x=None): Check for :trac:`33156`:: - sage: E = EllipticCurve(GF(65537), [5,5]) - sage: R. = E.base_field()[] - sage: E._multiple_x_numerator(5, x=R.quotient(x^2).gen()) + sage: E = EllipticCurve(GF(65537), [5,5]) # optional - sage.rings.finite_rings + sage: R. = E.base_field()[] # optional - sage.rings.finite_rings + sage: E._multiple_x_numerator(5, x=R.quotient(x^2).gen()) # optional - sage.rings.finite_rings 10220*xbar + 42539 - sage: E._multiple_x_numerator(5) + sage: E._multiple_x_numerator(5) # optional - sage.rings.finite_rings x^25 + 65037*x^23 + 55137*x^22 + ... + 813*x^2 + 10220*x + 42539 """ n = rings.Integer(n).abs() @@ -2140,11 +2172,11 @@ def _multiple_x_denominator(self, n, x=None): Check for :trac:`33156`:: - sage: E = EllipticCurve(GF(65537), [5,5]) - sage: R. = E.base_field()[] - sage: E._multiple_x_denominator(5, x=R.quotient(x^2).gen()) + sage: E = EllipticCurve(GF(65537), [5,5]) # optional - sage.rings.finite_rings + sage: R. = E.base_field()[] # optional - sage.rings.finite_rings + sage: E._multiple_x_denominator(5, x=R.quotient(x^2).gen()) # optional - sage.rings.finite_rings 52039*xbar + 56726 - sage: E._multiple_x_denominator(5) + sage: E._multiple_x_denominator(5) # optional - sage.rings.finite_rings 25*x^24 + 3100*x^22 + 19000*x^21 + ... + 24111*x^2 + 52039*x + 56726 """ n = rings.Integer(n).abs() @@ -2213,7 +2245,8 @@ def multiplication_by_m(self, m, x_only=False): sage: f = E.multiplication_by_m(2) sage: f - ((x^4 + 2*x^2 - 24*x + 1)/(4*x^3 - 4*x + 12), (8*x^6*y - 40*x^4*y + 480*x^3*y - 40*x^2*y + 96*x*y - 568*y)/(64*x^6 - 128*x^4 + 384*x^3 + 64*x^2 - 384*x + 576)) + ((x^4 + 2*x^2 - 24*x + 1)/(4*x^3 - 4*x + 12), + (8*x^6*y - 40*x^4*y + 480*x^3*y - 40*x^2*y + 96*x*y - 568*y)/(64*x^6 - 128*x^4 + 384*x^3 + 64*x^2 - 384*x + 576)) Grab only the x-coordinate (less work):: @@ -2262,14 +2295,14 @@ def multiplication_by_m(self, m, x_only=False): The following test shows that :trac:`4364` is indeed fixed:: - sage: p = next_prime(2^30-41) - sage: a = GF(p)(1) - sage: b = GF(p)(1) - sage: E = EllipticCurve([a, b]) - sage: P = E.random_point() - sage: my_eval = lambda f,P: [fi(P[0],P[1]) for fi in f] - sage: f = E.multiplication_by_m(2) - sage: assert(E(eval(f,P)) == 2*P) + sage: p = next_prime(2^30-41) # optional - sage.rings.finite_rings + sage: a = GF(p)(1) # optional - sage.rings.finite_rings + sage: b = GF(p)(1) # optional - sage.rings.finite_rings + sage: E = EllipticCurve([a, b]) # optional - sage.rings.finite_rings + sage: P = E.random_point() # optional - sage.rings.finite_rings + sage: my_eval = lambda f,P: [fi(P[0],P[1]) for fi in f] # optional - sage.rings.finite_rings + sage: f = E.multiplication_by_m(2) # optional - sage.rings.finite_rings + sage: assert(E(eval(f,P)) == 2*P) # optional - sage.rings.finite_rings """ # Coerce the input m to be an integer m = rings.Integer(m) @@ -2321,8 +2354,8 @@ def multiplication_by_m_isogeny(self, m): multiplication-by-`m` map on this elliptic curve. The resulting isogeny will - have the associated rational maps (i.e. those returned by - `self.multiplication_by_m()`) already computed. + have the associated rational maps (i.e., those returned by + :meth:`multiplication_by_m`) already computed. NOTE: This function is currently *much* slower than the result of ``self.multiplication_by_m()``, because @@ -2344,21 +2377,25 @@ def multiplication_by_m_isogeny(self, m): sage: E = EllipticCurve('11a1') sage: E.multiplication_by_m_isogeny(7) doctest:warning ... DeprecationWarning: ... - Isogeny of degree 49 from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Isogeny of degree 49 + from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 + over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 + over Rational Field TESTS: Tests for :trac:`32490`:: - sage: E = EllipticCurve(QQbar, [1,0]) - sage: E.multiplication_by_m_isogeny(1).rational_maps() + sage: E = EllipticCurve(QQbar, [1,0]) # optional - sage.rings.number_field + sage: E.multiplication_by_m_isogeny(1).rational_maps() # optional - sage.rings.number_field (x, y) :: - sage: E = EllipticCurve_from_j(GF(31337).random_element()) - sage: P = E.random_point() - sage: [E.multiplication_by_m_isogeny(m)(P) == m*P for m in (1,2,3,5,7,9)] + sage: E = EllipticCurve_from_j(GF(31337).random_element()) # optional - sage.rings.finite_rings + sage: P = E.random_point() # optional - sage.rings.finite_rings + sage: [E.multiplication_by_m_isogeny(m)(P) == m*P for m in (1,2,3,5,7,9)] # optional - sage.rings.finite_rings [True, True, True, True, True, True] :: @@ -2374,11 +2411,17 @@ def multiplication_by_m_isogeny(self, m): sage: E = EllipticCurve([5,5]) sage: E.multiplication_by_m_isogeny(-1) - Isogeny of degree 1 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field + Isogeny of degree 1 + from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field + to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field sage: E.multiplication_by_m_isogeny(-2) - Isogeny of degree 4 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field + Isogeny of degree 4 + from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field + to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field sage: E.multiplication_by_m_isogeny(-3) - Isogeny of degree 9 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field + Isogeny of degree 9 + from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field + to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field sage: mu = E.multiplication_by_m_isogeny sage: all(mu(-m) == -mu(m) for m in (1,2,3,5,7)) True @@ -2411,7 +2454,8 @@ def scalar_multiplication(self, m): sage: E = EllipticCurve('77a1') sage: m = E.scalar_multiplication(-7); m - Scalar-multiplication endomorphism [-7] of Elliptic Curve defined by y^2 + y = x^3 + 2*x over Rational Field + Scalar-multiplication endomorphism [-7] + of Elliptic Curve defined by y^2 + y = x^3 + 2*x over Rational Field sage: m.degree() 49 sage: P = E(2,3) @@ -2437,16 +2481,20 @@ def frobenius_isogeny(self, n=1): EXAMPLES:: - sage: z3, = GF(13^3).gens() - sage: E = EllipticCurve([z3,z3^2]) - sage: E.frobenius_isogeny() + sage: z3, = GF(13^3).gens() # optional - sage.rings.finite_rings + sage: E = EllipticCurve([z3, z3^2]) # optional - sage.rings.finite_rings + sage: E.frobenius_isogeny() # optional - sage.rings.finite_rings Frobenius isogeny of degree 13: - From: Elliptic Curve defined by y^2 = x^3 + z3*x + z3^2 over Finite Field in z3 of size 13^3 - To: Elliptic Curve defined by y^2 = x^3 + (5*z3^2+7*z3+11)*x + (5*z3^2+12*z3+1) over Finite Field in z3 of size 13^3 - sage: E.frobenius_isogeny(3) + From: Elliptic Curve defined by y^2 = x^3 + z3*x + z3^2 + over Finite Field in z3 of size 13^3 + To: Elliptic Curve defined by y^2 = x^3 + (5*z3^2+7*z3+11)*x + (5*z3^2+12*z3+1) + over Finite Field in z3 of size 13^3 + sage: E.frobenius_isogeny(3) # optional - sage.rings.finite_rings Frobenius endomorphism of degree 2197 = 13^3: - From: Elliptic Curve defined by y^2 = x^3 + z3*x + z3^2 over Finite Field in z3 of size 13^3 - To: Elliptic Curve defined by y^2 = x^3 + z3*x + z3^2 over Finite Field in z3 of size 13^3 + From: Elliptic Curve defined by y^2 = x^3 + z3*x + z3^2 + over Finite Field in z3 of size 13^3 + To: Elliptic Curve defined by y^2 = x^3 + z3*x + z3^2 + over Finite Field in z3 of size 13^3 """ p = self.base_ring().characteristic() if not p: @@ -2456,8 +2504,8 @@ def frobenius_isogeny(self, n=1): def isomorphism_to(self, other): """ - Given another weierstrass model ``other`` of self, return an - isomorphism from self to ``other``. + Given another weierstrass model ``other`` of ``self``, return an + isomorphism from ``self`` to ``other``. INPUT: @@ -2465,7 +2513,7 @@ def isomorphism_to(self, other): OUTPUT: - (Weierstrassmorphism) An isomorphism from self to other. + (Weierstrassmorphism) An isomorphism from ``self`` to ``other``. .. NOTE:: @@ -2478,9 +2526,9 @@ def isomorphism_to(self, other): sage: F = E.short_weierstrass_model() sage: w = E.isomorphism_to(F); w Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field - To: Elliptic Curve defined by y^2 = x^3 - 16*x + 16 over Rational Field - Via: (u,r,s,t) = (1/2, 0, 0, -1/2) + From: Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + To: Elliptic Curve defined by y^2 = x^3 - 16*x + 16 over Rational Field + Via: (u,r,s,t) = (1/2, 0, 0, -1/2) sage: P = E(0,-1,1) sage: w(P) (0 : -4 : 1) @@ -2493,18 +2541,19 @@ def isomorphism_to(self, other): We can also handle injections to different base rings:: - sage: K. = NumberField(x^3-7) - sage: E.isomorphism_to(E.change_ring(K)) + sage: K. = NumberField(x^3 - 7) # optional - sage.rings.number_field + sage: E.isomorphism_to(E.change_ring(K)) # optional - sage.rings.number_field Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field - To: Elliptic Curve defined by y^2 + y = x^3 + (-1)*x over Number Field in a with defining polynomial x^3 - 7 + To: Elliptic Curve defined by y^2 + y = x^3 + (-1)*x + over Number Field in a with defining polynomial x^3 - 7 Via: (u,r,s,t) = (1, 0, 0, 0) """ return wm.WeierstrassIsomorphism(self, None, other) def automorphisms(self, field=None): """ - Return the set of isomorphisms from self to itself (as a list). + Return the set of isomorphisms from ``self`` to itself (as a list). The identity and negation morphisms are guaranteed to appear as the first and second entry of the returned list. @@ -2525,31 +2574,40 @@ def automorphisms(self, field=None): sage: E = EllipticCurve_from_j(QQ(0)) # a curve with j=0 over QQ sage: E.automorphisms() - [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Rational Field + [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 + over Rational Field Via: (u,r,s,t) = (1, 0, 0, 0), - Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Rational Field + Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 + over Rational Field Via: (u,r,s,t) = (-1, 0, 0, -1)] We can also find automorphisms defined over extension fields:: - sage: K. = NumberField(x^2+3) # adjoin roots of unity - sage: E.automorphisms(K) - [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 + sage: K. = NumberField(x^2 + 3) # adjoin roots of unity # optional - sage.rings.number_field + sage: E.automorphisms(K) # optional - sage.rings.number_field + [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 + over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (1, 0, 0, 0), - Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 + Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 + over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (-1, 0, 0, -1), - Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 + Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 + over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (-1/2*a - 1/2, 0, 0, 0), - Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 + Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 + over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (1/2*a + 1/2, 0, 0, -1), - Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 + Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 + over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (1/2*a - 1/2, 0, 0, 0), - Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 + Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 + over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (-1/2*a + 1/2, 0, 0, -1)] :: - sage: [len(EllipticCurve_from_j(GF(q,'a')(0)).automorphisms()) for q in [2,4,3,9,5,25,7,49]] + sage: [len(EllipticCurve_from_j(GF(q,'a')(0)).automorphisms()) # optional - sage.rings.finite_rings + ....: for q in [2,4,3,9,5,25,7,49]] [2, 24, 2, 12, 2, 6, 6, 6] TESTS: @@ -2558,19 +2616,19 @@ def automorphisms(self, field=None): sage: p = random_prime(100) sage: k = randrange(1,30) - sage: F. = GF((p,k)) - sage: while True: + sage: F. = GF((p,k)) # optional - sage.rings.finite_rings + sage: while True: # optional - sage.rings.finite_rings ....: try: ....: E = EllipticCurve(list((F^5).random_element())) ....: except ArithmeticError: ....: continue ....: break - sage: Aut = E.automorphisms() - sage: Aut[0] == E.scalar_multiplication(1) + sage: Aut = E.automorphisms() # optional - sage.rings.finite_rings + sage: Aut[0] == E.scalar_multiplication(1) # optional - sage.rings.finite_rings True - sage: Aut[1] == E.scalar_multiplication(-1) + sage: Aut[1] == E.scalar_multiplication(-1) # optional - sage.rings.finite_rings True - sage: sorted(Aut) == Aut + sage: sorted(Aut) == Aut # optional - sage.rings.finite_rings True """ if field is not None: @@ -2579,7 +2637,7 @@ def automorphisms(self, field=None): def isomorphisms(self, other, field=None): """ - Return the set of isomorphisms from self to other (as a list). + Return the set of isomorphisms from ``self`` to ``other`` (as a list). INPUT: @@ -2600,25 +2658,32 @@ def isomorphisms(self, other, field=None): sage: E = EllipticCurve_from_j(QQ(0)) # a curve with j=0 over QQ sage: F = EllipticCurve('27a3') # should be the same one sage: E.isomorphisms(F) - [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Rational Field + [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 + over Rational Field Via: (u,r,s,t) = (1, 0, 0, 0), - Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Rational Field + Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 + over Rational Field Via: (u,r,s,t) = (-1, 0, 0, -1)] We can also find isomorphisms defined over extension fields:: - sage: E = EllipticCurve(GF(7),[0,0,0,1,1]) - sage: F = EllipticCurve(GF(7),[0,0,0,1,-1]) - sage: E.isomorphisms(F) + sage: E = EllipticCurve(GF(7), [0,0,0,1,1]) # optional - sage.rings.finite_rings + sage: F = EllipticCurve(GF(7), [0,0,0,1,-1]) # optional - sage.rings.finite_rings + sage: E.isomorphisms(F) # optional - sage.rings.finite_rings [] - sage: E.isomorphisms(F,GF(49,'a')) + sage: E.isomorphisms(F, GF(49,'a')) # optional - sage.rings.finite_rings [Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 7^2 - To: Elliptic Curve defined by y^2 = x^3 + x + 6 over Finite Field in a of size 7^2 - Via: (u,r,s,t) = (a + 3, 0, 0, 0), Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 7^2 - To: Elliptic Curve defined by y^2 = x^3 + x + 6 over Finite Field in a of size 7^2 - Via: (u,r,s,t) = (6*a + 4, 0, 0, 0)] + From: Elliptic Curve defined by y^2 = x^3 + x + 1 + over Finite Field in a of size 7^2 + To: Elliptic Curve defined by y^2 = x^3 + x + 6 + over Finite Field in a of size 7^2 + Via: (u,r,s,t) = (a + 3, 0, 0, 0), + Elliptic-curve morphism: + From: Elliptic Curve defined by y^2 = x^3 + x + 1 + over Finite Field in a of size 7^2 + To: Elliptic Curve defined by y^2 = x^3 + x + 6 + over Finite Field in a of size 7^2 + Via: (u,r,s,t) = (6*a + 4, 0, 0, 0)] """ if field is not None: self = self.change_ring(field) @@ -2628,7 +2693,7 @@ def isomorphisms(self, other, field=None): def is_isomorphic(self, other, field=None): """ - Return whether or not self is isomorphic to other. + Return whether or not ``self`` is isomorphic to ``other``. INPUT: @@ -2647,7 +2712,8 @@ def is_isomorphic(self, other, field=None): sage: E = EllipticCurve('389a') sage: F = E.change_weierstrass_model([2,3,4,5]); F - Elliptic Curve defined by y^2 + 4*x*y + 11/8*y = x^3 - 3/2*x^2 - 13/16*x over Rational Field + Elliptic Curve defined by y^2 + 4*x*y + 11/8*y = x^3 - 3/2*x^2 - 13/16*x + over Rational Field sage: E.is_isomorphic(F) True sage: E.is_isomorphic(F.change_ring(CC)) @@ -2671,7 +2737,7 @@ def is_isomorphic(self, other, field=None): def change_weierstrass_model(self, *urst): r""" - Return a new Weierstrass model of self under the standard transformation `(u,r,s,t)` + Return a new Weierstrass model of ``self`` under the standard transformation `(u,r,s,t)` .. MATH:: @@ -2681,9 +2747,12 @@ def change_weierstrass_model(self, *urst): sage: E = EllipticCurve('15a') sage: F1 = E.change_weierstrass_model([1/2,0,0,0]); F1 - Elliptic Curve defined by y^2 + 2*x*y + 8*y = x^3 + 4*x^2 - 160*x - 640 over Rational Field + Elliptic Curve defined by y^2 + 2*x*y + 8*y = x^3 + 4*x^2 - 160*x - 640 + over Rational Field sage: F2 = E.change_weierstrass_model([7,2,1/3,5]); F2 - Elliptic Curve defined by y^2 + 5/21*x*y + 13/343*y = x^3 + 59/441*x^2 - 10/7203*x - 58/117649 over Rational Field + Elliptic Curve defined by + y^2 + 5/21*x*y + 13/343*y = x^3 + 59/441*x^2 - 10/7203*x - 58/117649 + over Rational Field sage: F1.is_isomorphic(F2) True """ @@ -2730,25 +2799,28 @@ def short_weierstrass_model(self, complete_cube=True): :: - sage: E = EllipticCurve(GF(3),[1,2,3,4,5]) - sage: E.short_weierstrass_model(complete_cube=False) + sage: E = EllipticCurve(GF(3), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: E.short_weierstrass_model(complete_cube=False) # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 3 This used to be different see :trac:`3973`:: - sage: E.short_weierstrass_model() + sage: E.short_weierstrass_model() # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 3 More tests in characteristic 3:: - sage: E = EllipticCurve(GF(3),[0,2,1,2,1]) - sage: E.short_weierstrass_model() + sage: E = EllipticCurve(GF(3), [0,2,1,2,1]) # optional - sage.rings.finite_rings + sage: E.short_weierstrass_model() # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: short_weierstrass_model(): no short model for Elliptic Curve defined by y^2 + y = x^3 + 2*x^2 + 2*x + 1 over Finite Field of size 3 (characteristic is 3) - sage: E.short_weierstrass_model(complete_cube=False) - Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x + 2 over Finite Field of size 3 - sage: E.short_weierstrass_model(complete_cube=False).is_isomorphic(E) + ValueError: short_weierstrass_model(): no short model for Elliptic Curve + defined by y^2 + y = x^3 + 2*x^2 + 2*x + 1 over Finite Field of size 3 + (characteristic is 3) + sage: E.short_weierstrass_model(complete_cube=False) # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x + 2 + over Finite Field of size 3 + sage: E.short_weierstrass_model(complete_cube=False).is_isomorphic(E) # optional - sage.rings.finite_rings True """ from . import constructor @@ -2821,49 +2893,57 @@ def montgomery_model(self, twisted=False, morphism=False): EXAMPLES:: - sage: E = EllipticCurve(QQbar, '11a1') - sage: E.montgomery_model() - Elliptic Curve defined by y^2 = x^3 + (-1.953522420987248?)*x^2 + x over Algebraic Field + sage: E = EllipticCurve(QQbar, '11a1') # optional - sage.rings.number_field + sage: E.montgomery_model() # optional - sage.rings.number_field + Elliptic Curve defined by y^2 = x^3 + (-1.953522420987248?)*x^2 + x + over Algebraic Field :: - sage: E = EllipticCurve(GF(431^2), [7,7]) - sage: E.montgomery_model() - Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x over Finite Field in z2 of size 431^2 + sage: E = EllipticCurve(GF(431^2), [7,7]) # optional - sage.rings.finite_rings + sage: E.montgomery_model() # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x + over Finite Field in z2 of size 431^2 An isomorphism between the Montgomery and Weierstrass form can be obtained using the ``morphism`` parameter:: - sage: E.montgomery_model(morphism=True) - (Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x over Finite Field in z2 of size 431^2, + sage: E.montgomery_model(morphism=True) # optional - sage.rings.finite_rings + (Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x + over Finite Field in z2 of size 431^2, Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 = x^3 + 7*x + 7 over Finite Field in z2 of size 431^2 - To: Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x over Finite Field in z2 of size 431^2 + From: Elliptic Curve defined by y^2 = x^3 + 7*x + 7 + over Finite Field in z2 of size 431^2 + To: Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x + over Finite Field in z2 of size 431^2 Via: (u,r,s,t) = (64*z2 + 407, 159, 0, 0)) Not all elliptic curves have a Montgomery model over their field of definition:: - sage: E = EllipticCurve(GF(257), [1,1]) - sage: E.montgomery_model() + sage: E = EllipticCurve(GF(257), [1,1]) # optional - sage.rings.finite_rings + sage: E.montgomery_model() # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 257 has no Montgomery model + ValueError: Elliptic Curve defined by y^2 = x^3 + x + 1 + over Finite Field of size 257 has no Montgomery model :: - sage: E = EllipticCurve(GF(257), [10,10]) - sage: E.montgomery_model() + sage: E = EllipticCurve(GF(257), [10,10]) # optional - sage.rings.finite_rings + sage: E.montgomery_model() # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 over Finite Field of size 257 has no untwisted Montgomery model + ValueError: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 + over Finite Field of size 257 has no untwisted Montgomery model However, as hinted by the error message, the latter curve does admit a *twisted* Montgomery model, which can be computed by passing ``twisted=True``:: - sage: E.montgomery_model(twisted=True) - Projective Plane Curve over Finite Field of size 257 defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 + sage: E.montgomery_model(twisted=True) # optional - sage.rings.finite_rings + Projective Plane Curve over Finite Field of size 257 + defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 Since Sage internally represents elliptic curves as (long) Weierstrass curves, which do not feature the Montgomery `B` coefficient, the @@ -2875,51 +2955,56 @@ def montgomery_model(self, twisted=False, morphism=False): but can easily be emulated by mapping back and forth to the corresponding Weierstrass curve:: - sage: C, f = E.montgomery_model(twisted=True, morphism=True) - sage: f + sage: C, f = E.montgomery_model(twisted=True, morphism=True) # optional - sage.rings.finite_rings + sage: f # optional - sage.rings.finite_rings Scheme morphism: - From: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 over Finite Field of size 257 - To: Projective Plane Curve over Finite Field of size 257 defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 + From: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 + over Finite Field of size 257 + To: Projective Plane Curve over Finite Field of size 257 + defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 Defn: Defined on coordinates by sending (x : y : z) to (x + 116*z : -y : -85*z) - sage: g = f.inverse(); g + sage: g = f.inverse(); g # optional - sage.rings.finite_rings Scheme morphism: - From: Projective Plane Curve over Finite Field of size 257 defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 - To: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 over Finite Field of size 257 + From: Projective Plane Curve over Finite Field of size 257 + defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 + To: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 + over Finite Field of size 257 Defn: Defined on coordinates by sending (x : y : z) to (-85*x - 116*z : 85*y : z) - sage: P = C(70, 8) - sage: Q = C(17, 17) - sage: P + Q # this doesn't work... + sage: P = C(70, 8) # optional - sage.rings.finite_rings + sage: Q = C(17, 17) # optional - sage.rings.finite_rings + sage: P + Q # this doesn't work... # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: ... - sage: f(g(P) + g(Q)) # ...but this does + sage: f(g(P) + g(Q)) # ...but this does # optional - sage.rings.finite_rings (107 : 168 : 1) Using the fact that the Weil pairing satisfies `e(\psi(P),\psi(Q)) = e(P,Q)^{\deg\psi}`, even pairings can be emulated in this way (note that isomorphisms have degree `1`):: - sage: F. = GF(257^2) - sage: C_ = C.change_ring(F) - sage: g_ = g.change_ring(F) - sage: g_(P).order() + sage: F. = GF(257^2) # optional - sage.rings.finite_rings + sage: C_ = C.change_ring(F) # optional - sage.rings.finite_rings + sage: g_ = g.change_ring(F) # optional - sage.rings.finite_rings + sage: g_(P).order() # optional - sage.rings.finite_rings 12 - sage: T = C_(-7 * z2 - 57, 31 * z2 - 52, 1) - sage: g_(T).order() + sage: T = C_(-7 * z2 - 57, 31 * z2 - 52, 1) # optional - sage.rings.finite_rings + sage: g_(T).order() # optional - sage.rings.finite_rings 12 - sage: g_(P).weil_pairing(g_(T), 12) + sage: g_(P).weil_pairing(g_(T), 12) # optional - sage.rings.finite_rings 15*z2 + 204 Another alternative is to simply extend the base field enough for the curve to have an untwisted Montgomery model:: - sage: C_ = E.change_ring(F).montgomery_model(); C_ - Elliptic Curve defined by y^2 = x^3 + 249*x^2 + x over Finite Field in z2 of size 257^2 - sage: h = C.defining_polynomial().change_ring(F); h + sage: C_ = E.change_ring(F).montgomery_model(); C_ # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 = x^3 + 249*x^2 + x + over Finite Field in z2 of size 257^2 + sage: h = C.defining_polynomial().change_ring(F); h # optional - sage.rings.finite_rings -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 - sage: C_.is_isomorphic(EllipticCurve_from_cubic(h).codomain()) + sage: C_.is_isomorphic(EllipticCurve_from_cubic(h).codomain()) # optional - sage.rings.finite_rings True .. SEEALSO:: @@ -3029,29 +3114,29 @@ def plot(self, xmin=None, xmax=None, components='both', **args): EXAMPLES:: - sage: E = EllipticCurve([0,-1]) - sage: plot(E, rgbcolor=hue(0.7)) + sage: E = EllipticCurve([0, -1]) + sage: plot(E, rgbcolor=hue(0.7)) # optional - sage.plot Graphics object consisting of 1 graphics primitive sage: E = EllipticCurve('37a') - sage: plot(E) + sage: plot(E) # optional - sage.plot Graphics object consisting of 2 graphics primitives - sage: plot(E, xmin=25,xmax=26) + sage: plot(E, xmin=25, xmax=26) # optional - sage.plot Graphics object consisting of 2 graphics primitives With :trac:`12766` we added the components keyword:: sage: E.real_components() 2 - sage: E.plot(components='bounded') + sage: E.plot(components='bounded') # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: E.plot(components='unbounded') + sage: E.plot(components='unbounded') # optional - sage.plot Graphics object consisting of 1 graphics primitive If there is only one component then specifying components='bounded' raises a ValueError:: sage: E = EllipticCurve('9990be2') - sage: E.plot(components='bounded') + sage: E.plot(components='bounded') # optional - sage.plot Traceback (most recent call last): ... ValueError: no bounded component for this curve @@ -3059,10 +3144,11 @@ def plot(self, xmin=None, xmax=None, components='both', **args): An elliptic curve defined over the Complex Field can not be plotted:: sage: E = EllipticCurve(CC, [0,0,1,-1,0]) - sage: E.plot() + sage: E.plot() # optional - sage.plot Traceback (most recent call last): ... - NotImplementedError: plotting of curves over Complex Field with 53 bits of precision is not implemented yet + NotImplementedError: plotting of curves over Complex Field + with 53 bits of precision is not implemented yet """ RR = rings.RealField() K = self.base_ring() @@ -3202,7 +3288,8 @@ def formal_group(self): sage: E = EllipticCurve("37a") sage: E.formal_group() - Formal Group associated to the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + Formal Group associated to the Elliptic Curve + defined by y^2 + y = x^3 - x over Rational Field """ return formal_group.EllipticCurveFormalGroup(self) @@ -3241,28 +3328,29 @@ def _p_primary_torsion_basis(self, p, m=None): sage: E = EllipticCurve('11a1') sage: E._p_primary_torsion_basis(5) [[(5 : -6 : 1), 1]] - sage: K. = NumberField(x^4 + x^3 + 11*x^2 + 41*x + 101) - sage: EK = E.base_extend(K) - sage: EK._p_primary_torsion_basis(5) # long time (2s on sage.math, 2011) + sage: K. = NumberField(x^4 + x^3 + 11*x^2 + 41*x + 101) # optional - sage.rings.number_field + sage: EK = E.base_extend(K) # optional - sage.rings.number_field + sage: EK._p_primary_torsion_basis(5) # long time (2s on sage.math, 2011) # optional - sage.rings.number_field [[(16 : 60 : 1), 1], [(t : 1/11*t^3 + 6/11*t^2 + 19/11*t + 48/11 : 1), 1]] - sage: EF = E.change_ring(GF(101)) - sage: EF._p_primary_torsion_basis(5) + sage: EF = E.change_ring(GF(101)) # optional - sage.rings.finite_rings + sage: EF._p_primary_torsion_basis(5) # optional - sage.rings.finite_rings [[(0 : 13 : 1), 1], [(5 : 5 : 1), 1]] - sage: F. = CyclotomicField(21) - sage: E = EllipticCurve([2,-z^7,-z^7,0,0]) - sage: E._p_primary_torsion_basis(7,2) # long time (8s on sage.math, 2011) + sage: F. = CyclotomicField(21) # optional - sage.rings.number_field + sage: E = EllipticCurve([2, -z^7, -z^7, 0, 0]) # optional - sage.rings.number_field + sage: E._p_primary_torsion_basis(7,2) # long time (8s on sage.math, 2011) # optional - sage.rings.number_field [[(0 : z^7 : 1), 1], - [(z^7 - z^6 + z^4 - z^3 + z^2 - 1 : z^8 - 2*z^7 + z^6 + 2*z^5 - 3*z^4 + 2*z^3 - 2*z + 2 : 1), 1]] + [(z^7 - z^6 + z^4 - z^3 + z^2 - 1 + : z^8 - 2*z^7 + z^6 + 2*z^5 - 3*z^4 + 2*z^3 - 2*z + 2 : 1), 1]] TESTS: This shows that the bug at :trac:`4937` is fixed:: - sage: a=804515977734860566494239770982282063895480484302363715494873 - sage: b=584772221603632866665682322899297141793188252000674256662071 - sage: E = EllipticCurve(GF(10^60+3201),[0,a,0,b,0]) - sage: [t[1] for t in E._p_primary_torsion_basis(2)] # long time (3s on sage.math, 2011) + sage: a = 804515977734860566494239770982282063895480484302363715494873 + sage: b = 584772221603632866665682322899297141793188252000674256662071 + sage: E = EllipticCurve(GF(10^60+3201), [0,a,0,b,0]) # optional - sage.rings.finite_rings + sage: [t[1] for t in E._p_primary_torsion_basis(2)] # long time (3s on sage.math, 2011) # optional - sage.rings.finite_rings [16, 1] """ p = rings.Integer(p) @@ -3416,50 +3504,57 @@ def pari_curve(self): EXAMPLES:: sage: E = EllipticCurve([RR(0), RR(0), RR(1), RR(-1), RR(0)]) - sage: e = E.pari_curve() - sage: type(e) + sage: e = E.pari_curve() # optional - sage.libs.pari + sage: type(e) # optional - sage.libs.pari <... 'cypari2.gen.Gen'> - sage: e.type() + sage: e.type() # optional - sage.libs.pari 't_VEC' - sage: e.disc() + sage: e.disc() # optional - sage.libs.pari 37.0000000000000 Over a finite field:: - sage: EllipticCurve(GF(41),[2,5]).pari_curve() - [Mod(0, 41), Mod(0, 41), Mod(0, 41), Mod(2, 41), Mod(5, 41), Mod(0, 41), Mod(4, 41), Mod(20, 41), Mod(37, 41), Mod(27, 41), Mod(26, 41), Mod(4, 41), Mod(11, 41), Vecsmall([3]), [41, [9, 31, [6, 0, 0, 0]]], [0, 0, 0, 0]] + sage: EllipticCurve(GF(41), [2,5]).pari_curve() # optional - sage.libs.pari sage.rings.finite_rings + [Mod(0, 41), Mod(0, 41), Mod(0, 41), Mod(2, 41), Mod(5, 41), + Mod(0, 41), Mod(4, 41), Mod(20, 41), Mod(37, 41), Mod(27, 41), + Mod(26, 41), Mod(4, 41), Mod(11, 41), + Vecsmall([3]), + [41, [9, 31, [6, 0, 0, 0]]], [0, 0, 0, 0]] Over a `p`-adic field:: - sage: Qp = pAdicField(5, prec=3) - sage: E = EllipticCurve(Qp,[3, 4]) - sage: E.pari_curve() - [0, 0, 0, 3, 4, 0, 6, 16, -9, -144, -3456, -8640, 1728/5, Vecsmall([2]), [O(5^3)], [0, 0]] - sage: E.j_invariant() + sage: Qp = pAdicField(5, prec=3) # optional - sage.libs.pari sage.rings.padics + sage: E = EllipticCurve(Qp, [3, 4]) # optional - sage.libs.pari sage.rings.padics + sage: E.pari_curve() # optional - sage.libs.pari sage.rings.padics + [0, 0, 0, 3, 4, 0, 6, 16, -9, -144, -3456, -8640, 1728/5, + Vecsmall([2]), [O(5^3)], [0, 0]] + sage: E.j_invariant() # optional - sage.libs.pari sage.rings.padics 3*5^-1 + O(5) Over a number field:: - sage: K. = QuadraticField(2) - sage: E = EllipticCurve([1,a]) - sage: E.pari_curve() + sage: K. = QuadraticField(2) # optional - sage.libs.pari sage.rings.number_field + sage: E = EllipticCurve([1,a]) # optional - sage.libs.pari sage.rings.number_field + sage: E.pari_curve() # optional - sage.libs.pari sage.rings.number_field [0, 0, 0, Mod(1, y^2 - 2), - Mod(y, y^2 - 2), 0, Mod(2, y^2 - 2), Mod(4*y, y^2 - 2), - Mod(-1, y^2 - 2), Mod(-48, y^2 - 2), Mod(-864*y, y^2 - 2), - Mod(-928, y^2 - 2), Mod(3456/29, y^2 - 2), Vecsmall([5]), - [[y^2 - 2, [2, 0], 8, 1, [[1, -1.41421356237310; - 1, 1.41421356237310], [1, -1.41421356237310; 1, 1.41421356237310], - [16, -23; 16, 23], [2, 0; 0, 4], [4, 0; 0, 2], [2, 0; 0, 1], - [2, [0, 2; 1, 0]], [2]], [-1.41421356237310, 1.41421356237310], - [1, y], [1, 0; 0, 1], [1, 0, 0, 2; 0, 1, 1, 0]]], [0, 0, 0, 0, 0]] + Mod(y, y^2 - 2), 0, Mod(2, y^2 - 2), Mod(4*y, y^2 - 2), + Mod(-1, y^2 - 2), Mod(-48, y^2 - 2), Mod(-864*y, y^2 - 2), + Mod(-928, y^2 - 2), Mod(3456/29, y^2 - 2), + Vecsmall([5]), + [[y^2 - 2, [2, 0], 8, 1, [[1, -1.41421356237310; 1, 1.41421356237310], + [1, -1.41421356237310; 1, 1.41421356237310], + [16, -23; 16, 23], [2, 0; 0, 4], [4, 0; 0, 2], [2, 0; 0, 1], + [2, [0, 2; 1, 0]], [2]], [-1.41421356237310, 1.41421356237310], + [1, y], [1, 0; 0, 1], [1, 0, 0, 2; 0, 1, 1, 0]]], [0, 0, 0, 0, 0]] PARI no longer requires that the `j`-invariant has negative `p`-adic valuation:: - sage: E = EllipticCurve(Qp,[1, 1]) - sage: E.j_invariant() # the j-invariant is a p-adic integer + sage: E = EllipticCurve(Qp,[1, 1]) # optional - sage.libs.pari sage.rings.padics + sage: E.j_invariant() # the j-invariant is a p-adic integer # optional - sage.libs.pari sage.rings.padics 2 + 4*5^2 + O(5^3) - sage: E.pari_curve() - [0, 0, 0, 1, 1, 0, 2, 4, -1, -48, -864, -496, 6912/31, Vecsmall([2]), [O(5^3)], [0, 0]] + sage: E.pari_curve() # optional - sage.libs.pari sage.rings.padics + [0, 0, 0, 1, 1, 0, 2, 4, -1, -48, -864, -496, 6912/31, + Vecsmall([2]), [O(5^3)], [0, 0]] """ from sage.categories.number_fields import NumberFields from sage.libs.pari import pari @@ -3478,12 +3573,12 @@ def __pari__(self): EXAMPLES:: sage: E = EllipticCurve('11a1') - sage: pari(E) + sage: pari(E) # optional - sage.libs.pari [0, -1, 1, -10, -20, -4, -20, -79, -21, 496, 20008, -161051, -122023936/161051, Vecsmall([1]), [Vecsmall([64, -1])], [0, 0, 0, 0, 0, 0, 0, 0]] Over a finite field:: - sage: EllipticCurve(GF(2), [0,0,1,1,1]).__pari__() + sage: EllipticCurve(GF(2), [0,0,1,1,1]).__pari__() # optional - sage.libs.pari sage.rings.finite_rings [0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, Vecsmall([4]), [1, [[Vecsmall([0, 1]), Vecsmall([0, 1]), Vecsmall([0, 1])], Vecsmall([0, 1]), [Vecsmall([0, 1]), Vecsmall([0]), Vecsmall([0]), Vecsmall([0])]]], [0, 0, 0, 0]] """ return self.pari_curve() diff --git a/src/sage/schemes/elliptic_curves/ell_local_data.py b/src/sage/schemes/elliptic_curves/ell_local_data.py index ff0847d871e..2845a623d0f 100644 --- a/src/sage/schemes/elliptic_curves/ell_local_data.py +++ b/src/sage/schemes/elliptic_curves/ell_local_data.py @@ -16,8 +16,8 @@ EXAMPLES:: - sage: K. = NumberField(x^2+1) - sage: E = EllipticCurve([(2+i)^2,(2+i)^7]) + sage: K. = NumberField(x^2 + 1) + sage: E = EllipticCurve([(2+i)^2, (2+i)^7]) sage: pp = K.fractional_ideal(2+i) sage: da = E.local_data(pp) sage: da.has_bad_reduction() @@ -29,29 +29,31 @@ sage: da.tamagawa_number() 4 sage: da.minimal_model() - Elliptic Curve defined by y^2 = x^3 + (4*i+3)*x + (-29*i-278) over Number Field in i with defining polynomial x^2 + 1 + Elliptic Curve defined by y^2 = x^3 + (4*i+3)*x + (-29*i-278) + over Number Field in i with defining polynomial x^2 + 1 An example to show how the Neron model can change as one extends the field:: sage: E = EllipticCurve([0,-1]) sage: E.local_data(2) Local data at Principal ideal (2) of Integer Ring: - Reduction type: bad additive - Local minimal model: Elliptic Curve defined by y^2 = x^3 - 1 over Rational Field - Minimal discriminant valuation: 4 - Conductor exponent: 4 - Kodaira Symbol: II - Tamagawa Number: 1 + Reduction type: bad additive + Local minimal model: Elliptic Curve defined by y^2 = x^3 - 1 over Rational Field + Minimal discriminant valuation: 4 + Conductor exponent: 4 + Kodaira Symbol: II + Tamagawa Number: 1 sage: EK = E.base_extend(K) sage: EK.local_data(1+i) Local data at Fractional ideal (i + 1): - Reduction type: bad additive - Local minimal model: Elliptic Curve defined by y^2 = x^3 + (-1) over Number Field in i with defining polynomial x^2 + 1 - Minimal discriminant valuation: 8 - Conductor exponent: 2 - Kodaira Symbol: IV* - Tamagawa Number: 3 + Reduction type: bad additive + Local minimal model: Elliptic Curve defined by y^2 = x^3 + (-1) + over Number Field in i with defining polynomial x^2 + 1 + Minimal discriminant valuation: 8 + Conductor exponent: 2 + Kodaira Symbol: IV* + Tamagawa Number: 3 Or how the minimal equation changes:: @@ -61,7 +63,8 @@ sage: EK = E.base_extend(K) sage: da = EK.local_data(1+i) sage: da.minimal_model() - Elliptic Curve defined by y^2 = x^3 + (-i) over Number Field in i with defining polynomial x^2 + 1 + Elliptic Curve defined by y^2 = x^3 + (-i) + over Number Field in i with defining polynomial x^2 + 1 AUTHORS: @@ -140,12 +143,13 @@ class EllipticCurveLocalData(SageObject): sage: E = EllipticCurve('14a1') sage: EllipticCurveLocalData(E,2) Local data at Principal ideal (2) of Integer Ring: - Reduction type: bad non-split multiplicative - Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field - Minimal discriminant valuation: 6 - Conductor exponent: 1 - Kodaira Symbol: I6 - Tamagawa Number: 2 + Reduction type: bad non-split multiplicative + Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 + over Rational Field + Minimal discriminant valuation: 6 + Conductor exponent: 1 + Kodaira Symbol: I6 + Tamagawa Number: 2 """ def __init__(self, E, P, proof=None, algorithm="pari", globally=False): @@ -184,65 +188,70 @@ def __init__(self, E, P, proof=None, algorithm="pari", globally=False): sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData sage: E = EllipticCurve('14a1') - sage: EllipticCurveLocalData(E,2) + sage: EllipticCurveLocalData(E, 2) Local data at Principal ideal (2) of Integer Ring: - Reduction type: bad non-split multiplicative - Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field - Minimal discriminant valuation: 6 - Conductor exponent: 1 - Kodaira Symbol: I6 - Tamagawa Number: 2 + Reduction type: bad non-split multiplicative + Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 + over Rational Field + Minimal discriminant valuation: 6 + Conductor exponent: 1 + Kodaira Symbol: I6 + Tamagawa Number: 2 :: - sage: EllipticCurveLocalData(E,2,algorithm="generic") + sage: EllipticCurveLocalData(E, 2, algorithm="generic") Local data at Principal ideal (2) of Integer Ring: - Reduction type: bad non-split multiplicative - Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field - Minimal discriminant valuation: 6 - Conductor exponent: 1 - Kodaira Symbol: I6 - Tamagawa Number: 2 + Reduction type: bad non-split multiplicative + Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 + over Rational Field + Minimal discriminant valuation: 6 + Conductor exponent: 1 + Kodaira Symbol: I6 + Tamagawa Number: 2 :: - sage: EllipticCurveLocalData(E,2,algorithm="pari") + sage: EllipticCurveLocalData(E, 2, algorithm="pari") Local data at Principal ideal (2) of Integer Ring: - Reduction type: bad non-split multiplicative - Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field - Minimal discriminant valuation: 6 - Conductor exponent: 1 - Kodaira Symbol: I6 - Tamagawa Number: 2 + Reduction type: bad non-split multiplicative + Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 + over Rational Field + Minimal discriminant valuation: 6 + Conductor exponent: 1 + Kodaira Symbol: I6 + Tamagawa Number: 2 :: - sage: EllipticCurveLocalData(E,2,algorithm="unknown") + sage: EllipticCurveLocalData(E, 2, algorithm="unknown") Traceback (most recent call last): ... ValueError: algorithm must be one of 'pari', 'generic' :: - sage: EllipticCurveLocalData(E,3) + sage: EllipticCurveLocalData(E, 3) Local data at Principal ideal (3) of Integer Ring: - Reduction type: good - Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field - Minimal discriminant valuation: 0 - Conductor exponent: 0 - Kodaira Symbol: I0 - Tamagawa Number: 1 + Reduction type: good + Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 + over Rational Field + Minimal discriminant valuation: 0 + Conductor exponent: 0 + Kodaira Symbol: I0 + Tamagawa Number: 1 :: - sage: EllipticCurveLocalData(E,7) + sage: EllipticCurveLocalData(E, 7) Local data at Principal ideal (7) of Integer Ring: - Reduction type: bad split multiplicative - Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field - Minimal discriminant valuation: 3 - Conductor exponent: 1 - Kodaira Symbol: I3 - Tamagawa Number: 3 + Reduction type: bad split multiplicative + Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 + over Rational Field + Minimal discriminant valuation: 3 + Conductor exponent: 1 + Kodaira Symbol: I3 + Tamagawa Number: 3 """ self._curve = E K = E.base_field() @@ -313,8 +322,8 @@ def minimal_model(self, reduce=True): sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData sage: E = EllipticCurve([0,0,0,0,64]); E - Elliptic Curve defined by y^2 = x^3 + 64 over Rational Field - sage: data = EllipticCurveLocalData(E,2) + Elliptic Curve defined by y^2 = x^3 + 64 over Rational Field + sage: data = EllipticCurveLocalData(E, 2) sage: data.minimal_model() Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field sage: data.minimal_model() == E.local_minimal_model(2) @@ -322,12 +331,14 @@ def minimal_model(self, reduce=True): To demonstrate the behaviour of the parameter ``reduce``:: - sage: K. = NumberField(x^3+x+1) + sage: K. = NumberField(x^3 + x + 1) sage: E = EllipticCurve(K, [0, 0, a, 0, 1]) sage: E.local_data(K.ideal(a-1)).minimal_model() - Elliptic Curve defined by y^2 + a*y = x^3 + 1 over Number Field in a with defining polynomial x^3 + x + 1 + Elliptic Curve defined by y^2 + a*y = x^3 + 1 + over Number Field in a with defining polynomial x^3 + x + 1 sage: E.local_data(K.ideal(a-1)).minimal_model(reduce=False) - Elliptic Curve defined by y^2 + (a+2)*y = x^3 + 3*x^2 + 3*x + (-a+1) over Number Field in a with defining polynomial x^3 + x + 1 + Elliptic Curve defined by y^2 + (a+2)*y = x^3 + 3*x^2 + 3*x + (-a+1) + over Number Field in a with defining polynomial x^3 + x + 1 sage: E = EllipticCurve([2, 1, 0, -2, -1]) sage: E.local_data(ZZ.ideal(2), algorithm="generic").minimal_model(reduce=False) @@ -345,10 +356,15 @@ def minimal_model(self, reduce=True): sage: t = QQ['t'].0 sage: K. = NumberField(t^4 - t^3-3*t^2 - t +1) - sage: E = EllipticCurve([-2*g^3 + 10/3*g^2 + 3*g - 2/3, -11/9*g^3 + 34/9*g^2 - 7/3*g + 4/9, -11/9*g^3 + 34/9*g^2 - 7/3*g + 4/9, 0, 0]) + sage: E = EllipticCurve([-2*g^3 + 10/3*g^2 + 3*g - 2/3, + ....: -11/9*g^3 + 34/9*g^2 - 7/3*g + 4/9, + ....: -11/9*g^3 + 34/9*g^2 - 7/3*g + 4/9, 0, 0]) sage: vv = K.fractional_ideal(g^2 - g - 2) sage: E.local_data(vv).minimal_model() - Elliptic Curve defined by y^2 + (-2*g^3+10/3*g^2+3*g-2/3)*x*y + (-11/9*g^3+34/9*g^2-7/3*g+4/9)*y = x^3 + (-11/9*g^3+34/9*g^2-7/3*g+4/9)*x^2 over Number Field in g with defining polynomial t^4 - t^3 - 3*t^2 - t + 1 + Elliptic Curve defined by + y^2 + (-2*g^3+10/3*g^2+3*g-2/3)*x*y + (-11/9*g^3+34/9*g^2-7/3*g+4/9)*y + = x^3 + (-11/9*g^3+34/9*g^2-7/3*g+4/9)*x^2 + over Number Field in g with defining polynomial t^4 - t^3 - 3*t^2 - t + 1 """ if reduce: try: @@ -455,7 +471,7 @@ def tamagawa_exponent(self): sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData sage: E = EllipticCurve('816a1') - sage: data = EllipticCurveLocalData(E,2) + sage: data = EllipticCurveLocalData(E, 2) sage: data.kodaira_symbol() I2* sage: data.tamagawa_number() @@ -464,7 +480,7 @@ def tamagawa_exponent(self): 2 sage: E = EllipticCurve('200c4') - sage: data = EllipticCurveLocalData(E,5) + sage: data = EllipticCurveLocalData(E, 5) sage: data.kodaira_symbol() I4* sage: data.tamagawa_number() @@ -499,9 +515,9 @@ def bad_reduction_type(self): sage: [(p,E.local_data(p).bad_reduction_type()) for p in prime_range(15)] [(2, -1), (3, None), (5, None), (7, 1), (11, None), (13, None)] - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P17a, P17b = [P for P,e in K.factor(17)] - sage: E = EllipticCurve([0,0,0,0,2*a+1]) + sage: E = EllipticCurve([0, 0, 0, 0, 2*a+1]) sage: [(p,E.local_data(p).bad_reduction_type()) for p in [P17a,P17b]] [(Fractional ideal (4*a^2 - 2*a + 1), None), (Fractional ideal (2*a + 1), 0)] """ @@ -517,12 +533,12 @@ def has_good_reduction(self): sage: [(p,E.local_data(p).has_good_reduction()) for p in prime_range(15)] [(2, False), (3, True), (5, True), (7, False), (11, True), (13, True)] - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P17a, P17b = [P for P,e in K.factor(17)] - sage: E = EllipticCurve([0,0,0,0,2*a+1]) + sage: E = EllipticCurve([0, 0, 0, 0, 2*a+1]) sage: [(p,E.local_data(p).has_good_reduction()) for p in [P17a,P17b]] [(Fractional ideal (4*a^2 - 2*a + 1), True), - (Fractional ideal (2*a + 1), False)] + (Fractional ideal (2*a + 1), False)] """ return self._reduction_type is None @@ -538,12 +554,12 @@ def has_bad_reduction(self): :: - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P17a, P17b = [P for P,e in K.factor(17)] - sage: E = EllipticCurve([0,0,0,0,2*a+1]) + sage: E = EllipticCurve([0, 0, 0, 0, 2*a+1]) sage: [(p,E.local_data(p).has_bad_reduction()) for p in [P17a,P17b]] [(Fractional ideal (4*a^2 - 2*a + 1), False), - (Fractional ideal (2*a + 1), True)] + (Fractional ideal (2*a + 1), True)] """ return self._reduction_type is not None @@ -559,14 +575,14 @@ def has_multiplicative_reduction(self): EXAMPLES:: sage: E = EllipticCurve('14a1') - sage: [(p,E.local_data(p).has_multiplicative_reduction()) for p in prime_range(15)] + sage: [(p, E.local_data(p).has_multiplicative_reduction()) for p in prime_range(15)] [(2, True), (3, False), (5, False), (7, True), (11, False), (13, False)] :: - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P17a, P17b = [P for P,e in K.factor(17)] - sage: E = EllipticCurve([0,0,0,0,2*a+1]) + sage: E = EllipticCurve([0, 0, 0, 0, 2*a+1]) sage: [(p,E.local_data(p).has_multiplicative_reduction()) for p in [P17a,P17b]] [(Fractional ideal (4*a^2 - 2*a + 1), False), (Fractional ideal (2*a + 1), False)] """ @@ -579,17 +595,19 @@ def has_split_multiplicative_reduction(self): EXAMPLES:: sage: E = EllipticCurve('14a1') - sage: [(p,E.local_data(p).has_split_multiplicative_reduction()) for p in prime_range(15)] + sage: [(p, E.local_data(p).has_split_multiplicative_reduction()) + ....: for p in prime_range(15)] [(2, False), (3, False), (5, False), (7, True), (11, False), (13, False)] :: - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P17a, P17b = [P for P,e in K.factor(17)] - sage: E = EllipticCurve([0,0,0,0,2*a+1]) - sage: [(p,E.local_data(p).has_split_multiplicative_reduction()) for p in [P17a,P17b]] + sage: E = EllipticCurve([0, 0, 0, 0, 2*a+1]) + sage: [(p,E .local_data(p).has_split_multiplicative_reduction()) + ....: for p in [P17a,P17b]] [(Fractional ideal (4*a^2 - 2*a + 1), False), - (Fractional ideal (2*a + 1), False)] + (Fractional ideal (2*a + 1), False)] """ return self._reduction_type == +1 @@ -600,15 +618,17 @@ def has_nonsplit_multiplicative_reduction(self): EXAMPLES:: sage: E = EllipticCurve('14a1') - sage: [(p,E.local_data(p).has_nonsplit_multiplicative_reduction()) for p in prime_range(15)] + sage: [(p, E.local_data(p).has_nonsplit_multiplicative_reduction()) + ....: for p in prime_range(15)] [(2, True), (3, False), (5, False), (7, False), (11, False), (13, False)] :: - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P17a, P17b = [P for P,e in K.factor(17)] - sage: E = EllipticCurve([0,0,0,0,2*a+1]) - sage: [(p,E.local_data(p).has_nonsplit_multiplicative_reduction()) for p in [P17a,P17b]] + sage: E = EllipticCurve([0, 0, 0, 0, 2*a+1]) + sage: [(p, E.local_data(p).has_nonsplit_multiplicative_reduction()) + ....: for p in [P17a,P17b]] [(Fractional ideal (4*a^2 - 2*a + 1), False), (Fractional ideal (2*a + 1), False)] """ return self._reduction_type == -1 @@ -620,17 +640,17 @@ def has_additive_reduction(self): EXAMPLES:: sage: E = EllipticCurve('27a1') - sage: [(p,E.local_data(p).has_additive_reduction()) for p in prime_range(15)] + sage: [(p, E.local_data(p).has_additive_reduction()) for p in prime_range(15)] [(2, False), (3, True), (5, False), (7, False), (11, False), (13, False)] :: - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P17a, P17b = [P for P,e in K.factor(17)] - sage: E = EllipticCurve([0,0,0,0,2*a+1]) - sage: [(p,E.local_data(p).has_additive_reduction()) for p in [P17a,P17b]] + sage: E = EllipticCurve([0, 0, 0, 0, 2*a+1]) + sage: [(p, E.local_data(p).has_additive_reduction()) for p in [P17a,P17b]] [(Fractional ideal (4*a^2 - 2*a + 1), False), - (Fractional ideal (2*a + 1), True)] + (Fractional ideal (2*a + 1), True)] """ return self._reduction_type == 0 @@ -1122,11 +1142,14 @@ def check_prime(K, P): sage: check_prime(K, L.ideal(5)) Traceback (most recent call last): ... - TypeError: The ideal Fractional ideal (5) is not a prime ideal of Number Field in a with defining polynomial x^2 - 5 + TypeError: The ideal Fractional ideal (5) is not a prime ideal of + Number Field in a with defining polynomial x^2 - 5 sage: check_prime(K, L.ideal(b)) Traceback (most recent call last): ... - TypeError: No compatible natural embeddings found for Number Field in a with defining polynomial x^2 - 5 and Number Field in b with defining polynomial x^2 + 3 + TypeError: No compatible natural embeddings found for + Number Field in a with defining polynomial x^2 - 5 and + Number Field in b with defining polynomial x^2 + 3 """ if K is QQ: if P in ZZ or isinstance(P, (Integer, int)): diff --git a/src/sage/schemes/elliptic_curves/ell_modular_symbols.py b/src/sage/schemes/elliptic_curves/ell_modular_symbols.py index b31f7dfe46c..e624113bc92 100644 --- a/src/sage/schemes/elliptic_curves/ell_modular_symbols.py +++ b/src/sage/schemes/elliptic_curves/ell_modular_symbols.py @@ -48,9 +48,11 @@ sage: V = E.modular_symbol_space() sage: V - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 2 for Gamma_0(19) of weight 2 with sign 1 over Rational Field + Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 2 + for Gamma_0(19) of weight 2 with sign 1 over Rational Field sage: V.q_eigenform(30) - q - 2*q^3 - 2*q^4 + 3*q^5 - q^7 + q^9 + 3*q^11 + 4*q^12 - 4*q^13 - 6*q^15 + 4*q^16 - 3*q^17 + q^19 - 6*q^20 + 2*q^21 + 4*q^25 + 4*q^27 + 2*q^28 + 6*q^29 + O(q^30) + q - 2*q^3 - 2*q^4 + 3*q^5 - q^7 + q^9 + 3*q^11 + 4*q^12 - 4*q^13 - 6*q^15 + 4*q^16 + - 3*q^17 + q^19 - 6*q^20 + 2*q^21 + 4*q^25 + 4*q^27 + 2*q^28 + 6*q^29 + O(q^30) For more details on modular symbols consult the following @@ -125,11 +127,12 @@ def modular_symbol_space(E, sign, base_ring, bound=None): EXAMPLES:: - sage: import sage.schemes.elliptic_curves.ell_modular_symbols + sage: from sage.schemes.elliptic_curves.ell_modular_symbols import modular_symbol_space sage: E = EllipticCurve('11a1') - sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.modular_symbol_space(E,-1,GF(37)) - sage: M - Modular Symbols space of dimension 1 for Gamma_0(11) of weight 2 with sign -1 over Finite Field of size 37 + sage: M = modular_symbol_space(E, -1, GF(37)) # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings + Modular Symbols space of dimension 1 for Gamma_0(11) of weight 2 with sign -1 + over Finite Field of size 37 """ if sign not in [-1, 0, 1]: raise TypeError('sign must -1, 0 or 1') @@ -209,10 +212,12 @@ def _repr_(self): sage: m = EllipticCurve('11a1').modular_symbol() sage: m - Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Modular symbol with sign 1 over Rational Field attached to + Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: m = EllipticCurve('43a1').modular_symbol(sign=-1, implementation="sage") sage: m - Modular symbol with sign -1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 + x^2 over Rational Field + Modular symbol with sign -1 over Rational Field attached to + Elliptic Curve defined by y^2 + y = x^3 + x^2 over Rational Field """ return "Modular symbol with sign %s over %s attached to %s"%( self._sign, self._base_ring, self._E) @@ -240,22 +245,23 @@ def __init__(self, E, sign, nap=1000): EXAMPLES:: - sage: import sage.schemes.elliptic_curves.ell_modular_symbols + sage: from sage.schemes.elliptic_curves.ell_modular_symbols import ModularSymbolECLIB sage: E = EllipticCurve('11a1') - sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolECLIB(E,+1) + sage: M = ModularSymbolECLIB(E,+1) sage: M - Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Modular symbol with sign 1 over Rational Field attached to + Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: M(0) 1/5 sage: E = EllipticCurve('11a2') - sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolECLIB(E,+1) + sage: M = ModularSymbolECLIB(E,+1) sage: M(0) 1 This is a rank 1 case with vanishing positive twists:: sage: E = EllipticCurve('121b1') - sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolECLIB(E,+1) + sage: M = ModularSymbolECLIB(E,+1) sage: M(0) 0 sage: M(1/7) @@ -273,11 +279,13 @@ def __init__(self, E, sign, nap=1000): sage: E = EllipticCurve('11a1') sage: Mplus = E.modular_symbol(+1); Mplus - Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Modular symbol with sign 1 over Rational Field attached to + Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: [Mplus(1/i) for i in [1..11]] [1/5, -4/5, -3/10, 7/10, 6/5, 6/5, 7/10, -3/10, -4/5, 1/5, 0] sage: Mminus = E.modular_symbol(-1); Mminus - Modular symbol with sign -1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Modular symbol with sign -1 over Rational Field attached to + Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: [Mminus(1/i) for i in [1..11]] [0, 0, 1/2, 1/2, 0, 0, -1/2, -1/2, 0, 0, 0] @@ -393,17 +401,18 @@ def __init__(self, E, sign, normalize="L_ratio"): EXAMPLES:: sage: E = EllipticCurve('11a1') - sage: import sage.schemes.elliptic_curves.ell_modular_symbols - sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,+1) + sage: from sage.schemes.elliptic_curves.ell_modular_symbols import ModularSymbolSage + sage: M = ModularSymbolSage(E, +1) sage: M - Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Modular symbol with sign 1 over Rational Field attached to + Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: M(0) 1/5 sage: E = EllipticCurve('11a2') - sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,+1) + sage: M = ModularSymbolSage(E, +1) sage: M(0) 1 - sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,-1) + sage: M = ModularSymbolSage(E, -1) sage: M(1/3) 1/2 @@ -411,7 +420,7 @@ def __init__(self, E, sign, normalize="L_ratio"): The modular symbol is adjusted by -2:: sage: E = EllipticCurve('121b1') - sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,-1,normalize='L_ratio') + sage: M = ModularSymbolSage(E, -1, normalize='L_ratio') sage: M(1/3) 1 sage: M._scaling @@ -420,16 +429,20 @@ def __init__(self, E, sign, normalize="L_ratio"): sage: M = EllipticCurve('121d1').modular_symbol(implementation="sage") sage: M(0) 2 - sage: M = EllipticCurve('121d1').modular_symbol(implementation="sage", normalize='none') + sage: M = EllipticCurve('121d1').modular_symbol(implementation="sage", + ....: normalize='none') sage: M(0) 1 sage: E = EllipticCurve('15a1') - sage: [C.modular_symbol(implementation="sage", normalize='L_ratio')(0) for C in E.isogeny_class()] + sage: [C.modular_symbol(implementation="sage", normalize='L_ratio')(0) + ....: for C in E.isogeny_class()] [1/4, 1/8, 1/4, 1/2, 1/8, 1/16, 1/2, 1] - sage: [C.modular_symbol(implementation="sage", normalize='period')(0) for C in E.isogeny_class()] + sage: [C.modular_symbol(implementation="sage", normalize='period')(0) + ....: for C in E.isogeny_class()] [1/8, 1/16, 1/8, 1/4, 1/16, 1/32, 1/4, 1/2] - sage: [C.modular_symbol(implementation="sage", normalize='none')(0) for C in E.isogeny_class()] + sage: [C.modular_symbol(implementation="sage", normalize='none')(0) + ....: for C in E.isogeny_class()] [1, 1, 1, 1, 1, 1, 1, 1] """ if sign not in [-1, 1]: diff --git a/src/sage/schemes/elliptic_curves/ell_number_field.py b/src/sage/schemes/elliptic_curves/ell_number_field.py index 6848b4b34ea..998cc0d94b4 100644 --- a/src/sage/schemes/elliptic_curves/ell_number_field.py +++ b/src/sage/schemes/elliptic_curves/ell_number_field.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.rings.number_field r""" Elliptic curves over number fields @@ -19,8 +19,8 @@ EXAMPLES:: - sage: K. = NumberField(x^2+1) - sage: E = EllipticCurve([0,4+i]) + sage: K. = NumberField(x^2 + 1) + sage: E = EllipticCurve([0, 4+i]) sage: E.discriminant() -3456*i - 6480 sage: P= E([i,2]) @@ -29,16 +29,17 @@ :: - sage: E.has_good_reduction(2+i) + sage: E.has_good_reduction(2 + i) True sage: E.local_data(4+i) Local data at Fractional ideal (i + 4): - Reduction type: bad additive - Local minimal model: Elliptic Curve defined by y^2 = x^3 + (i+4) over Number Field in i with defining polynomial x^2 + 1 - Minimal discriminant valuation: 2 - Conductor exponent: 2 - Kodaira Symbol: II - Tamagawa Number: 1 + Reduction type: bad additive + Local minimal model: Elliptic Curve defined by y^2 = x^3 + (i+4) + over Number Field in i with defining polynomial x^2 + 1 + Minimal discriminant valuation: 2 + Conductor exponent: 2 + Kodaira Symbol: II + Tamagawa Number: 1 sage: E.tamagawa_product_bsd() 1 @@ -55,7 +56,11 @@ :: sage: E.isogenies_prime_degree(3) - [Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + (i+4) over Number Field in i with defining polynomial x^2 + 1 to Elliptic Curve defined by y^2 = x^3 + (-27*i-108) over Number Field in i with defining polynomial x^2 + 1] + [Isogeny of degree 3 + from Elliptic Curve defined by y^2 = x^3 + (i+4) + over Number Field in i with defining polynomial x^2 + 1 + to Elliptic Curve defined by y^2 = x^3 + (-27*i-108) + over Number Field in i with defining polynomial x^2 + 1] AUTHORS: @@ -104,24 +109,28 @@ class EllipticCurve_number_field(EllipticCurve_field): EXAMPLES:: - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: EllipticCurve([i, i - 1, i + 1, 24*i + 15, 14*i + 35]) - Elliptic Curve defined by y^2 + i*x*y + (i+1)*y = x^3 + (i-1)*x^2 + (24*i+15)*x + (14*i+35) over Number Field in i with defining polynomial x^2 + 1 + Elliptic Curve defined by + y^2 + i*x*y + (i+1)*y = x^3 + (i-1)*x^2 + (24*i+15)*x + (14*i+35) + over Number Field in i with defining polynomial x^2 + 1 """ def __init__(self, K, ainvs): r""" EXAMPLES: - A curve from the database of curves over `\QQ`, but over a larger field: + A curve from the database of curves over `\QQ`, but over a larger field:: - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: EllipticCurve(K,'389a1') - Elliptic Curve defined by y^2 + y = x^3 + x^2 + (-2)*x over Number Field in i with defining polynomial x^2 + 1 + Elliptic Curve defined by y^2 + y = x^3 + x^2 + (-2)*x + over Number Field in i with defining polynomial x^2 + 1 Making the field of definition explicitly larger:: sage: EllipticCurve(K,[0,-1,1,0,0]) - Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 over Number Field in i with defining polynomial x^2 + 1 + Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + over Number Field in i with defining polynomial x^2 + 1 """ self._known_points = [] EllipticCurve_field.__init__(self, K, ainvs) @@ -137,7 +146,8 @@ def base_extend(self, R): sage: E = EllipticCurve('11a3') sage: K = QuadraticField(-5, 'a') sage: E.base_extend(K) - Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 over Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I + Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 over Number Field in a + with defining polynomial x^2 + 5 with a = 2.236067977499790?*I Check that non-torsion points are remembered when extending the base field (see :trac:`16034`):: @@ -226,7 +236,8 @@ def simon_two_descent(self, verbose=0, lim1=2, lim3=4, limtriv=2, sage: K. = NumberField(x^2 + 7, 'a') sage: E = EllipticCurve(K, [0,0,0,1,a]); E - Elliptic Curve defined by y^2 = x^3 + x + a over Number Field in a with defining polynomial x^2 + 7 + Elliptic Curve defined by y^2 = x^3 + x + a + over Number Field in a with defining polynomial x^2 + 7 sage: v = E.simon_two_descent(verbose=1); v elliptic curve: Y^2 = x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7) @@ -265,7 +276,7 @@ def simon_two_descent(self, verbose=0, lim1=2, lim3=4, limtriv=2, sage: R. = QQ[] sage: L. = NumberField(t^3 - 9*t^2 + 13*t - 4) - sage: E1 = EllipticCurve(L,[1-g*(g-1),-g^2*(g-1),-g^2*(g-1),0,0]) + sage: E1 = EllipticCurve(L, [1-g*(g-1), -g^2*(g-1), -g^2*(g-1), 0, 0]) sage: E1.rank() # long time (about 5 s) 0 @@ -341,7 +352,7 @@ def height_pairing_matrix(self, points=None, precision=None, normalised=True): sage: E = EllipticCurve('389a1') sage: E = EllipticCurve('389a1') - sage: P,Q = E.point([-1,1,1]),E.point([0,-1,1]) + sage: P, Q = E.point([-1,1,1]), E.point([0,-1,1]) sage: E.height_pairing_matrix([P,Q]) [0.686667083305587 0.268478098806726] [0.268478098806726 0.327000773651605] @@ -349,7 +360,7 @@ def height_pairing_matrix(self, points=None, precision=None, normalised=True): Over a number field:: sage: x = polygen(QQ) - sage: K. = NumberField(x^2+47) + sage: K. = NumberField(x^2 + 47) sage: EK = E.base_extend(K) sage: EK.height_pairing_matrix([EK(P),EK(Q)]) [0.686667083305587 0.268478098806726] @@ -359,7 +370,7 @@ def height_pairing_matrix(self, points=None, precision=None, normalised=True): sage: K. = QuadraticField(-1) sage: E = EllipticCurve([0,0,0,i,i]) - sage: P = E(-9+4*i,-18-25*i) + sage: P = E(-9+4*i, -18-25*i) sage: Q = E(i,-i) sage: E.height_pairing_matrix([P,Q]) [ 2.16941934493768 -0.870059380421505] @@ -430,7 +441,7 @@ def regulator_of_points(self, points=[], precision=None, normalised=True): sage: points = [E.lift_x(x) for x in [-2,-7/4,1]] sage: E.regulator_of_points(points) 0.417143558758384 - sage: E.regulator_of_points(points,precision=100) + sage: E.regulator_of_points(points, precision=100) 0.41714355875838396981711954462 :: @@ -438,7 +449,7 @@ def regulator_of_points(self, points=[], precision=None, normalised=True): sage: E = EllipticCurve('389a') sage: E.regulator_of_points() 1.00000000000000 - sage: points = [P,Q] = [E(-1,1),E(0,-1)] + sage: points = [P,Q] = [E(-1,1), E(0,-1)] sage: E.regulator_of_points(points) 0.152460177943144 sage: E.regulator_of_points(points, precision=100) @@ -451,7 +462,7 @@ def regulator_of_points(self, points=[], precision=None, normalised=True): Examples over number fields:: sage: K. = QuadraticField(97) - sage: E = EllipticCurve(K,[1,1]) + sage: E = EllipticCurve(K, [1,1]) sage: P = E(0,1) sage: P.height() 0.476223106404866 @@ -471,9 +482,9 @@ def regulator_of_points(self, points=[], precision=None, normalised=True): sage: E = EllipticCurve('11a1') sage: x = polygen(QQ) - sage: K. = NumberField(x^2+47) + sage: K. = NumberField(x^2 + 47) sage: EK = E.base_extend(K) - sage: T = EK(5,5) + sage: T = EK(5, 5) sage: T.order() 5 sage: P = EK(-2, -1/2*t - 1/2) @@ -490,7 +501,7 @@ def regulator_of_points(self, points=[], precision=None, normalised=True): sage: P,Q = E.gens() sage: E.regulator_of_points([P,Q]) 0.152460177943144 - sage: K. = NumberField(x^2+47) + sage: K. = NumberField(x^2 + 47) sage: EK = E.base_extend(K) sage: EK.regulator_of_points([EK(P),EK(Q)]) 0.152460177943144 @@ -499,8 +510,8 @@ def regulator_of_points(self, points=[], precision=None, normalised=True): sage: K. = QuadraticField(-1) sage: E = EllipticCurve([0,0,0,i,i]) - sage: P = E(-9+4*i,-18-25*i) - sage: Q = E(i,-i) + sage: P = E(-9+4*i, -18-25*i) + sage: Q = E(i, -i) sage: E.height_pairing_matrix([P,Q]) [ 2.16941934493768 -0.870059380421505] [-0.870059380421505 0.424585837470709] @@ -523,13 +534,13 @@ def is_local_integral_model(self, *P): EXAMPLES:: - sage: K. = NumberField(x^2+1) - sage: P1,P2 = K.primes_above(5) + sage: K. = NumberField(x^2 + 1) + sage: P1, P2 = K.primes_above(5) sage: E = EllipticCurve([i/5,i/5,i/5,i/5,i/5]) - sage: E.is_local_integral_model(P1,P2) + sage: E.is_local_integral_model(P1, P2) False - sage: Emin = E.local_integral_model(P1,P2) - sage: Emin.is_local_integral_model(P1,P2) + sage: Emin = E.local_integral_model(P1, P2) + sage: Emin.is_local_integral_model(P1, P2) True """ if len(P) == 1: @@ -540,8 +551,7 @@ def is_local_integral_model(self, *P): def local_integral_model(self,*P): r""" - Return a model of self which is integral at the prime ideal - `P`. + Return a model of self which is integral at the prime ideal `P`. .. NOTE:: @@ -554,11 +564,13 @@ def local_integral_model(self,*P): EXAMPLES:: - sage: K. = NumberField(x^2+1) - sage: P1,P2 = K.primes_above(5) + sage: K. = NumberField(x^2 + 1) + sage: P1, P2 = K.primes_above(5) sage: E = EllipticCurve([i/5,i/5,i/5,i/5,i/5]) sage: E.local_integral_model((P1,P2)) - Elliptic Curve defined by y^2 + (-i)*x*y + (-25*i)*y = x^3 + 5*i*x^2 + 125*i*x + 3125*i over Number Field in i with defining polynomial x^2 + 1 + Elliptic Curve defined by + y^2 + (-i)*x*y + (-25*i)*y = x^3 + 5*i*x^2 + 125*i*x + 3125*i + over Number Field in i with defining polynomial x^2 + 1 """ if len(P) == 1: P = P[0] @@ -579,9 +591,9 @@ def is_global_integral_model(self): EXAMPLES:: - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: E = EllipticCurve([i/5,i/5,i/5,i/5,i/5]) - sage: P1,P2 = K.primes_above(5) + sage: P1, P2 = K.primes_above(5) sage: Emin = E.global_integral_model() sage: Emin.is_global_integral_model() True @@ -594,33 +606,39 @@ def global_integral_model(self): EXAMPLES:: - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: E = EllipticCurve([i/5,i/5,i/5,i/5,i/5]) - sage: P1,P2 = K.primes_above(5) + sage: P1, P2 = K.primes_above(5) sage: E.global_integral_model() - Elliptic Curve defined by y^2 + (-i)*x*y + (-25*i)*y = x^3 + 5*i*x^2 + 125*i*x + 3125*i over Number Field in i with defining polynomial x^2 + 1 + Elliptic Curve defined by + y^2 + (-i)*x*y + (-25*i)*y = x^3 + 5*i*x^2 + 125*i*x + 3125*i + over Number Field in i with defining polynomial x^2 + 1 :trac:`7935`:: - sage: K. = NumberField(x^2-38) + sage: K. = NumberField(x^2 - 38) sage: E = EllipticCurve([a,1/2]) sage: E.global_integral_model() - Elliptic Curve defined by y^2 = x^3 + 1444*a*x + 27436 over Number Field in a with defining polynomial x^2 - 38 + Elliptic Curve defined by y^2 = x^3 + 1444*a*x + 27436 + over Number Field in a with defining polynomial x^2 - 38 :trac:`9266`:: - sage: K. = NumberField(x^2-5) + sage: K. = NumberField(x^2 - 5) sage: w = (1+s)/2 - sage: E = EllipticCurve(K,[2,w]) + sage: E = EllipticCurve(K, [2,w]) sage: E.global_integral_model() - Elliptic Curve defined by y^2 = x^3 + 2*x + (1/2*s+1/2) over Number Field in s with defining polynomial x^2 - 5 + Elliptic Curve defined by y^2 = x^3 + 2*x + (1/2*s+1/2) + over Number Field in s with defining polynomial x^2 - 5 :trac:`12151`:: sage: K. = NumberField(x^2 + 161*x - 150) sage: E = EllipticCurve([25105/216*v - 3839/36, 634768555/7776*v - 98002625/1296, 634768555/7776*v - 98002625/1296, 0, 0]) sage: M = E.global_integral_model(); M # choice varies, not tested - Elliptic Curve defined by y^2 + (2094779518028859*v-1940492905300351)*x*y + (477997268472544193101178234454165304071127500*v-442791377441346852919930773849502871958097500)*y = x^3 + (26519784690047674853185542622500*v-24566525306469707225840460652500)*x^2 over Number Field in v with defining polynomial x^2 + 161*x - 150 + Elliptic Curve defined by + y^2 + (2094779518028859*v-1940492905300351)*x*y + (477997268472544193101178234454165304071127500*v-442791377441346852919930773849502871958097500)*y = x^3 + (26519784690047674853185542622500*v-24566525306469707225840460652500)*x^2 + over Number Field in v with defining polynomial x^2 + 161*x - 150 :trac:`14476`:: @@ -628,7 +646,9 @@ def global_integral_model(self): sage: K. = NumberField(t^4 - t^3 - 3*t^2 - t + 1) sage: E = EllipticCurve([ -43/625*g^3 + 14/625*g^2 - 4/625*g + 706/625, -4862/78125*g^3 - 4074/78125*g^2 - 711/78125*g + 10304/78125, -4862/78125*g^3 - 4074/78125*g^2 - 711/78125*g + 10304/78125, 0,0]) sage: E.global_integral_model() - Elliptic Curve defined by y^2 + (15*g^3-48*g-42)*x*y + (-111510*g^3-162162*g^2-44145*g+37638)*y = x^3 + (-954*g^3-1134*g^2+81*g+576)*x^2 over Number Field in g with defining polynomial t^4 - t^3 - 3*t^2 - t + 1 + Elliptic Curve defined by + y^2 + (15*g^3-48*g-42)*x*y + (-111510*g^3-162162*g^2-44145*g+37638)*y = x^3 + (-954*g^3-1134*g^2+81*g+576)*x^2 + over Number Field in g with defining polynomial t^4 - t^3 - 3*t^2 - t + 1 TESTS: @@ -694,10 +714,10 @@ def _reduce_model(self): 8456608930180227786550494643437985949781*a - 52130038506835491453281450568107193773505) sage: E._reduce_model().ainvs() (a, - a + 1, - a + 1, - 368258520200522046806318444*a - 2270097978636731786720859345, - 8456608930173478039472018047583706316424*a - 52130038506793883217874390501829588391299) + a + 1, + a + 1, + 368258520200522046806318444*a - 2270097978636731786720859345, + 8456608930173478039472018047583706316424*a - 52130038506793883217874390501829588391299) sage: EllipticCurve([101,202,303,404,505])._reduce_model().ainvs() (1, 1, 0, -2509254, 1528863051) sage: EllipticCurve([-101,-202,-303,-404,-505])._reduce_model().ainvs() @@ -855,51 +875,56 @@ def local_data(self, P=None, proof=None, algorithm="pari", globally=False): EXAMPLES:: - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: E = EllipticCurve([1 + i, 0, 1, 0, 0]) sage: E.local_data() [Local data at Fractional ideal (2*i + 1): - Reduction type: bad non-split multiplicative - Local minimal model: Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 over Number Field in i with defining polynomial x^2 + 1 - Minimal discriminant valuation: 1 - Conductor exponent: 1 - Kodaira Symbol: I1 - Tamagawa Number: 1, - Local data at Fractional ideal (-2*i + 3): - Reduction type: bad split multiplicative - Local minimal model: Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 over Number Field in i with defining polynomial x^2 + 1 - Minimal discriminant valuation: 2 - Conductor exponent: 1 - Kodaira Symbol: I2 - Tamagawa Number: 2] + Reduction type: bad non-split multiplicative + Local minimal model: Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 + over Number Field in i with defining polynomial x^2 + 1 + Minimal discriminant valuation: 1 + Conductor exponent: 1 + Kodaira Symbol: I1 + Tamagawa Number: 1, + Local data at Fractional ideal (-2*i + 3): + Reduction type: bad split multiplicative + Local minimal model: Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 + over Number Field in i with defining polynomial x^2 + 1 + Minimal discriminant valuation: 2 + Conductor exponent: 1 + Kodaira Symbol: I2 + Tamagawa Number: 2] sage: E.local_data(K.ideal(3)) Local data at Fractional ideal (3): - Reduction type: good - Local minimal model: Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 over Number Field in i with defining polynomial x^2 + 1 - Minimal discriminant valuation: 0 - Conductor exponent: 0 - Kodaira Symbol: I0 - Tamagawa Number: 1 + Reduction type: good + Local minimal model: Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 + over Number Field in i with defining polynomial x^2 + 1 + Minimal discriminant valuation: 0 + Conductor exponent: 0 + Kodaira Symbol: I0 + Tamagawa Number: 1 sage: E.local_data(2*i + 1) Local data at Fractional ideal (2*i + 1): - Reduction type: bad non-split multiplicative - Local minimal model: Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 over Number Field in i with defining polynomial x^2 + 1 - Minimal discriminant valuation: 1 - Conductor exponent: 1 - Kodaira Symbol: I1 - Tamagawa Number: 1 + Reduction type: bad non-split multiplicative + Local minimal model: Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 + over Number Field in i with defining polynomial x^2 + 1 + Minimal discriminant valuation: 1 + Conductor exponent: 1 + Kodaira Symbol: I1 + Tamagawa Number: 1 An example raised in :trac:`3897`:: sage: E = EllipticCurve([1,1]) sage: E.local_data(3) Local data at Principal ideal (3) of Integer Ring: - Reduction type: good - Local minimal model: Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field - Minimal discriminant valuation: 0 - Conductor exponent: 0 - Kodaira Symbol: I0 - Tamagawa Number: 1 + Reduction type: good + Local minimal model: Elliptic Curve defined by y^2 = x^3 + x + 1 + over Rational Field + Minimal discriminant valuation: 0 + Conductor exponent: 0 + Kodaira Symbol: I0 + Tamagawa Number: 1 """ if proof is None: import sage.structure.proof.proof @@ -947,17 +972,19 @@ def _get_local_data(self, P, proof, algorithm="pari", globally=False): EXAMPLES:: - sage: K. = NumberField(x^2+1) - sage: E = EllipticCurve(K,[0,1,0,-160,308]) - sage: p = K.ideal(i+1) + sage: K. = NumberField(x^2 + 1) + sage: E = EllipticCurve(K, [0,1,0,-160,308]) + sage: p = K.ideal(i + 1) sage: E._get_local_data(p, False) Local data at Fractional ideal (i + 1): - Reduction type: good - Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + (-10)*x + (-10) over Number Field in i with defining polynomial x^2 + 1 - Minimal discriminant valuation: 0 - Conductor exponent: 0 - Kodaira Symbol: I0 - Tamagawa Number: 1 + Reduction type: good + Local minimal model: Elliptic Curve defined by + y^2 + x*y + y = x^3 + x^2 + (-10)*x + (-10) + over Number Field in i with defining polynomial x^2 + 1 + Minimal discriminant valuation: 0 + Conductor exponent: 0 + Kodaira Symbol: I0 + Tamagawa Number: 1 Verify that we cache based on the proof value and the algorithm choice:: @@ -1012,7 +1039,7 @@ def local_minimal_model(self, P, proof=None, algorithm="pari"): EXAMPLES:: - sage: K. = NumberField(x^2-5) + sage: K. = NumberField(x^2 - 5) sage: E = EllipticCurve([20, 225, 750, 1250*a + 6250, 62500*a + 15625]) sage: P = K.ideal(a) sage: E.local_minimal_model(P).ainvs() @@ -1047,15 +1074,15 @@ def has_good_reduction(self, P): EXAMPLES:: sage: E = EllipticCurve('14a1') - sage: [(p,E.has_good_reduction(p)) for p in prime_range(15)] + sage: [(p, E.has_good_reduction(p)) for p in prime_range(15)] [(2, False), (3, True), (5, True), (7, False), (11, True), (13, True)] - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P17a, P17b = [P for P,e in K.factor(17)] sage: E = EllipticCurve([0,0,0,0,2*a+1]) - sage: [(p,E.has_good_reduction(p)) for p in [P17a,P17b]] + sage: [(p, E.has_good_reduction(p)) for p in [P17a,P17b]] [(Fractional ideal (4*a^2 - 2*a + 1), True), - (Fractional ideal (2*a + 1), False)] + (Fractional ideal (2*a + 1), False)] """ return self.local_data(P).has_good_reduction() @@ -1081,15 +1108,15 @@ def has_bad_reduction(self, P): EXAMPLES:: sage: E = EllipticCurve('14a1') - sage: [(p,E.has_bad_reduction(p)) for p in prime_range(15)] + sage: [(p, E.has_bad_reduction(p)) for p in prime_range(15)] [(2, True), (3, False), (5, False), (7, True), (11, False), (13, False)] - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P17a, P17b = [P for P,e in K.factor(17)] sage: E = EllipticCurve([0,0,0,0,2*a+1]) - sage: [(p,E.has_bad_reduction(p)) for p in [P17a,P17b]] + sage: [(p, E.has_bad_reduction(p)) for p in [P17a,P17b]] [(Fractional ideal (4*a^2 - 2*a + 1), False), - (Fractional ideal (2*a + 1), True)] + (Fractional ideal (2*a + 1), True)] """ return self.local_data(P).has_bad_reduction() @@ -1105,7 +1132,7 @@ def has_multiplicative_reduction(self, P): INPUT: - ``P`` -- a prime ideal of the base field of self, or a field - element generating such an ideal. + element generating such an ideal. OUTPUT: @@ -1115,14 +1142,15 @@ def has_multiplicative_reduction(self, P): EXAMPLES:: sage: E = EllipticCurve('14a1') - sage: [(p,E.has_multiplicative_reduction(p)) for p in prime_range(15)] + sage: [(p, E.has_multiplicative_reduction(p)) for p in prime_range(15)] [(2, True), (3, False), (5, False), (7, True), (11, False), (13, False)] - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P17a, P17b = [P for P,e in K.factor(17)] sage: E = EllipticCurve([0,0,0,0,2*a+1]) - sage: [(p,E.has_multiplicative_reduction(p)) for p in [P17a,P17b]] - [(Fractional ideal (4*a^2 - 2*a + 1), False), (Fractional ideal (2*a + 1), False)] + sage: [(p, E.has_multiplicative_reduction(p)) for p in [P17a,P17b]] + [(Fractional ideal (4*a^2 - 2*a + 1), False), + (Fractional ideal (2*a + 1), False)] """ return self.local_data(P).has_multiplicative_reduction() @@ -1143,14 +1171,15 @@ def has_split_multiplicative_reduction(self, P): EXAMPLES:: sage: E = EllipticCurve('14a1') - sage: [(p,E.has_split_multiplicative_reduction(p)) for p in prime_range(15)] + sage: [(p, E.has_split_multiplicative_reduction(p)) for p in prime_range(15)] [(2, False), (3, False), (5, False), (7, True), (11, False), (13, False)] - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P17a, P17b = [P for P,e in K.factor(17)] sage: E = EllipticCurve([0,0,0,0,2*a+1]) - sage: [(p,E.has_split_multiplicative_reduction(p)) for p in [P17a,P17b]] - [(Fractional ideal (4*a^2 - 2*a + 1), False), (Fractional ideal (2*a + 1), False)] + sage: [(p, E.has_split_multiplicative_reduction(p)) for p in [P17a,P17b]] + [(Fractional ideal (4*a^2 - 2*a + 1), False), + (Fractional ideal (2*a + 1), False)] """ return self.local_data(P).has_split_multiplicative_reduction() @@ -1171,14 +1200,15 @@ def has_nonsplit_multiplicative_reduction(self, P): EXAMPLES:: sage: E = EllipticCurve('14a1') - sage: [(p,E.has_nonsplit_multiplicative_reduction(p)) for p in prime_range(15)] + sage: [(p, E.has_nonsplit_multiplicative_reduction(p)) for p in prime_range(15)] [(2, True), (3, False), (5, False), (7, False), (11, False), (13, False)] - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P17a, P17b = [P for P,e in K.factor(17)] sage: E = EllipticCurve([0,0,0,0,2*a+1]) - sage: [(p,E.has_nonsplit_multiplicative_reduction(p)) for p in [P17a,P17b]] - [(Fractional ideal (4*a^2 - 2*a + 1), False), (Fractional ideal (2*a + 1), False)] + sage: [(p, E.has_nonsplit_multiplicative_reduction(p)) for p in [P17a,P17b]] + [(Fractional ideal (4*a^2 - 2*a + 1), False), + (Fractional ideal (2*a + 1), False)] """ return self.local_data(P).has_nonsplit_multiplicative_reduction() @@ -1198,15 +1228,15 @@ def has_additive_reduction(self, P): EXAMPLES:: sage: E = EllipticCurve('27a1') - sage: [(p,E.has_additive_reduction(p)) for p in prime_range(15)] + sage: [(p, E.has_additive_reduction(p)) for p in prime_range(15)] [(2, False), (3, True), (5, False), (7, False), (11, False), (13, False)] - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P17a, P17b = [P for P,e in K.factor(17)] sage: E = EllipticCurve([0,0,0,0,2*a+1]) - sage: [(p,E.has_additive_reduction(p)) for p in [P17a,P17b]] + sage: [(p, E.has_additive_reduction(p)) for p in [P17a,P17b]] [(Fractional ideal (4*a^2 - 2*a + 1), False), - (Fractional ideal (2*a + 1), True)] + (Fractional ideal (2*a + 1), True)] """ return self.local_data(P).has_additive_reduction() @@ -1257,7 +1287,7 @@ def tamagawa_numbers(self): [2, 3, 1] sage: vector(e.tamagawa_numbers()) (2, 3, 1) - sage: K. = NumberField(x^2+3) + sage: K. = NumberField(x^2 + 3) sage: eK = e.base_extend(K) sage: eK.tamagawa_numbers() [4, 6, 1] @@ -1284,7 +1314,7 @@ def tamagawa_exponent(self, P, proof=None): EXAMPLES:: - sage: K. = NumberField(x^2-5) + sage: K. = NumberField(x^2 - 5) sage: E = EllipticCurve([20, 225, 750, 625*a + 6875, 31250*a + 46875]) sage: [E.tamagawa_exponent(P) for P in E.discriminant().support()] [1, 1, 1, 1] @@ -1316,12 +1346,12 @@ def tamagawa_product(self): EXAMPLES:: - sage: K. = NumberField(x^2+1) - sage: E = EllipticCurve([0,2+i]) + sage: K. = NumberField(x^2 + 1) + sage: E = EllipticCurve([0, 2+i]) sage: E.tamagawa_product() 1 - sage: E = EllipticCurve([(2*i+1)^2,i*(2*i+1)^7]) + sage: E = EllipticCurve([(2*i+1)^2, i*(2*i+1)^7]) sage: E.tamagawa_product() 4 @@ -1371,19 +1401,19 @@ def tamagawa_product_bsd(self): EXAMPLES:: - sage: K. = NumberField(x^2+1) - sage: E = EllipticCurve([0,2+i]) + sage: K. = NumberField(x^2 + 1) + sage: E = EllipticCurve([0, 2+i]) sage: E.tamagawa_product_bsd() 1 - sage: E = EllipticCurve([(2*i+1)^2,i*(2*i+1)^7]) + sage: E = EllipticCurve([(2*i+1)^2, i*(2*i+1)^7]) sage: E.tamagawa_product_bsd() 4 An example where the Neron model changes over K:: - sage: K. = NumberField(x^5-10*x^3+5*x^2+10*x+1) - sage: E = EllipticCurve(K,'75a1') + sage: K. = NumberField(x^5 - 10*x^3 + 5*x^2 + 10*x + 1) + sage: E = EllipticCurve(K, '75a1') sage: E.tamagawa_product_bsd() 5 sage: da = E.local_data() @@ -1430,14 +1460,15 @@ def kodaira_symbol(self, P, proof=None): OUTPUT: - The Kodaira Symbol of the curve at P, represented as a string. + The Kodaira Symbol of the curve at ``P``, represented as a string. EXAMPLES:: - sage: K. = NumberField(x^2-5) + sage: K. = NumberField(x^2 - 5) sage: E = EllipticCurve([20, 225, 750, 625*a + 6875, 31250*a + 46875]) sage: bad_primes = E.discriminant().support(); bad_primes - [Fractional ideal (-a), Fractional ideal (7/2*a - 81/2), Fractional ideal (-a - 52), Fractional ideal (2)] + [Fractional ideal (-a), Fractional ideal (7/2*a - 81/2), + Fractional ideal (-a - 52), Fractional ideal (2)] sage: [E.kodaira_symbol(P) for P in bad_primes] [I0, I1, I1, II] sage: K. = QuadraticField(-11) @@ -1463,32 +1494,32 @@ def conductor(self): EXAMPLES:: - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: EllipticCurve([i, i - 1, i + 1, 24*i + 15, 14*i + 35]).conductor() Fractional ideal (21*i - 3) - sage: K. = NumberField(x^2-x+3) - sage: EllipticCurve([1 + a , -1 + a , 1 + a , -11 + a , 5 -9*a ]).conductor() + sage: K. = NumberField(x^2 - x + 3) + sage: EllipticCurve([1 + a, -1 + a, 1 + a, -11 + a, 5 - 9*a]).conductor() Fractional ideal (-6*a) A not so well known curve with everywhere good reduction:: - sage: K. = NumberField(x^2-38) + sage: K. = NumberField(x^2 - 38) sage: E = EllipticCurve([0,0,0, 21796814856932765568243810*a - 134364590724198567128296995, 121774567239345229314269094644186997594*a - 750668847495706904791115375024037711300]) sage: E.conductor() Fractional ideal (1) An example which used to fail (see :trac:`5307`):: - sage: K. = NumberField(x^2+x+6) - sage: E = EllipticCurve([w,-1,0,-w-6,0]) + sage: K. = NumberField(x^2 + x + 6) + sage: E = EllipticCurve([w, -1, 0, -w-6, 0]) sage: E.conductor() Fractional ideal (86304, w + 5898) An example raised in :trac:`11346`:: sage: K. = NumberField(x^2 - x - 1) - sage: E1 = EllipticCurve(K,[0,0,0,-1/48,-161/864]) - sage: [(p.smallest_integer(),e) for p,e in E1.conductor().factor()] + sage: E1 = EllipticCurve(K, [0, 0, 0, -1/48, -161/864]) + sage: [(p.smallest_integer(), e) for p,e in E1.conductor().factor()] [(2, 4), (3, 1), (5, 1)] """ try: @@ -1520,10 +1551,10 @@ def minimal_discriminant_ideal(self): EXAMPLES:: - sage: K. = NumberField(x^2-x-57) + sage: K. = NumberField(x^2 - x - 57) sage: K.class_number() 3 - sage: E = EllipticCurve([a,-a,a,-5692-820*a,-259213-36720*a]) + sage: E = EllipticCurve([a, -a, a, -5692-820*a, -259213-36720*a]) sage: K.ideal(E.discriminant()) Fractional ideal (90118662980*a + 636812084644) sage: K.ideal(E.discriminant()).factor() @@ -1541,8 +1572,8 @@ def minimal_discriminant_ideal(self): If (and only if) the curve has everywhere good reduction the result is the unit ideal:: - sage: K. = NumberField(x^2-26) - sage: E = EllipticCurve([a,a-1,a+1,4*a+10,2*a+6]) + sage: K. = NumberField(x^2 - 26) + sage: E = EllipticCurve([a, a-1, a+1, 4*a+10, 2*a+6]) sage: E.conductor() Fractional ideal (1) sage: E.discriminant() @@ -1576,7 +1607,7 @@ def non_minimal_primes(self): EXAMPLES:: - sage: K. = NumberField(x^2-10) + sage: K. = NumberField(x^2 - 10) sage: E = EllipticCurve([0, 0, 0, -22500, 750000*a]) sage: E.non_minimal_primes() [Fractional ideal (2, a), Fractional ideal (5, a)] @@ -1587,7 +1618,7 @@ def non_minimal_primes(self): Over `\QQ`, the primes returned are integers, not ideals:: - sage: E = EllipticCurve([0,0,0,-3024,46224]) + sage: E = EllipticCurve([0, 0, 0, -3024, 46224]) sage: E.non_minimal_primes() [2, 3] sage: Emin = E.global_minimal_model() @@ -1597,7 +1628,7 @@ def non_minimal_primes(self): If the model is not globally integral, a ``ValueError`` is raised:: - sage: E = EllipticCurve([0,0,0,1/2,1/3]) + sage: E = EllipticCurve([0, 0, 0, 1/2, 1/3]) sage: E.non_minimal_primes() Traceback (most recent call last): ... @@ -1624,14 +1655,14 @@ def is_global_minimal_model(self): EXAMPLES:: - sage: K. = NumberField(x^2-10) + sage: K. = NumberField(x^2 - 10) sage: E = EllipticCurve([0, 0, 0, -22500, 750000*a]) sage: E.is_global_minimal_model() False sage: E.non_minimal_primes() [Fractional ideal (2, a), Fractional ideal (5, a)] - sage: E = EllipticCurve([0,0,0,-3024,46224]) + sage: E = EllipticCurve([0, 0, 0, -3024, 46224]) sage: E.is_global_minimal_model() False sage: E.non_minimal_primes() @@ -1671,7 +1702,7 @@ def global_minimality_class(self): A curve defined over a field of class number 2 with no global minimal model was a nontrivial minimality class:: - sage: K. = NumberField(x^2-10) + sage: K. = NumberField(x^2 - 10) sage: K.class_number() 2 sage: E = EllipticCurve([0, 0, 0, -22500, 750000*a]) @@ -1684,8 +1715,8 @@ def global_minimality_class(self): has trivial class, showing that a global minimal model does exist:: - sage: K. = NumberField(x^2-10) - sage: E = EllipticCurve([0,0,0,4536*a+14148,-163728*a- 474336]) + sage: K. = NumberField(x^2 - 10) + sage: E = EllipticCurve([0, 0, 0, 4536*a+14148, -163728*a-474336]) sage: E.is_global_minimal_model() False sage: E.global_minimality_class() @@ -1694,7 +1725,7 @@ def global_minimality_class(self): Over a field of class number 1 the result is always the trivial class:: - sage: K. = NumberField(x^2-5) + sage: K. = NumberField(x^2 - 5) sage: E = EllipticCurve([0, 0, 0, K(16), K(64)]) sage: E.global_minimality_class() Trivial principal fractional ideal class @@ -1728,8 +1759,8 @@ def has_global_minimal_model(self): EXAMPLES:: - sage: K. = NumberField(x^2-10) - sage: E = EllipticCurve([0,0,0,4536*a+14148,-163728*a-474336]) + sage: K. = NumberField(x^2 - 10) + sage: E = EllipticCurve([0, 0, 0, 4536*a+14148, -163728*a-474336]) sage: E.is_global_minimal_model() False sage: E.has_global_minimal_model() @@ -1768,41 +1799,46 @@ def global_minimal_model(self, proof=None, semi_global=False): EXAMPLES:: - sage: K. = NumberField(x^2-38) + sage: K. = NumberField(x^2 - 38) sage: E = EllipticCurve([0,0,0, 21796814856932765568243810*a - 134364590724198567128296995, 121774567239345229314269094644186997594*a - 750668847495706904791115375024037711300]) sage: E2 = E.global_minimal_model() sage: E2 - Elliptic Curve defined by y^2 + a*x*y + (a+1)*y = x^3 + (a+1)*x^2 + (4*a+15)*x + (4*a+21) over Number Field in a with defining polynomial x^2 - 38 + Elliptic Curve defined by + y^2 + a*x*y + (a+1)*y = x^3 + (a+1)*x^2 + (4*a+15)*x + (4*a+21) + over Number Field in a with defining polynomial x^2 - 38 sage: E2.local_data() [] See :trac:`11347`:: sage: K. = NumberField(x^2 - x - 1) - sage: E = EllipticCurve(K,[0,0,0,-1/48,161/864]).integral_model().global_minimal_model(); E - Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 over Number Field in g with defining polynomial x^2 - x - 1 - sage: [(p.norm(), e) for p, e in E.conductor().factor()] + sage: E = EllipticCurve(K, [0, 0, 0, -1/48, 161/864]) + sage: E2 = E.integral_model().global_minimal_model(); E2 + Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + over Number Field in g with defining polynomial x^2 - x - 1 + sage: [(p.norm(), e) for p, e in E2.conductor().factor()] [(9, 1), (5, 1)] - sage: [(p.norm(), e) for p, e in E.discriminant().factor()] + sage: [(p.norm(), e) for p, e in E2.discriminant().factor()] [(-5, 2), (9, 1)] See :trac:`14472`, this used not to work over a relative extension:: - sage: K1. = NumberField(x^2+x+1) + sage: K1. = NumberField(x^2 + x + 1) sage: m = polygen(K1) - sage: K2. = K1.extension(m^2-w+1) - sage: E = EllipticCurve([0*v,-432]) + sage: K2. = K1.extension(m^2 - w + 1) + sage: E = EllipticCurve([0*v, -432]) sage: E.global_minimal_model() - Elliptic Curve defined by y^2 + y = x^3 over Number Field in v with defining polynomial x^2 - w + 1 over its base field + Elliptic Curve defined by y^2 + y = x^3 + over Number Field in v with defining polynomial x^2 - w + 1 over its base field See :trac:`18662`: for fields of class number greater than 1, even when global minimal models did exist, their computation was not implemented. Now it is:: - sage: K. = NumberField(x^2-10) + sage: K. = NumberField(x^2 - 10) sage: K.class_number() 2 - sage: E = EllipticCurve([0,0,0,-186408*a - 589491, 78055704*a + 246833838]) + sage: E = EllipticCurve([0, 0, 0, -186408*a - 589491, 78055704*a + 246833838]) sage: E.discriminant().norm() 16375845905239507992576 sage: E.discriminant().norm().factor() @@ -1810,7 +1846,9 @@ def global_minimal_model(self, proof=None, semi_global=False): sage: E.has_global_minimal_model() True sage: Emin = E.global_minimal_model(); Emin - Elliptic Curve defined by y^2 + (a+1)*x*y + (a+1)*y = x^3 + (-a)*x^2 + (a-12)*x + (-2*a+2) over Number Field in a with defining polynomial x^2 - 10 + Elliptic Curve defined by + y^2 + (a+1)*x*y + (a+1)*y = x^3 + (-a)*x^2 + (a-12)*x + (-2*a+2) + over Number Field in a with defining polynomial x^2 - 10 sage: Emin.discriminant().norm() 3456 sage: Emin.discriminant().norm().factor() @@ -1819,23 +1857,28 @@ def global_minimal_model(self, proof=None, semi_global=False): If there is no global minimal model, this method will raise an error unless you set the parameter ``semi_global`` to ``True``:: - sage: K. = NumberField(x^2-10) + sage: K. = NumberField(x^2 - 10) sage: K.class_number() 2 - sage: E = EllipticCurve([a,a,0,3*a+8,4*a+3]) + sage: E = EllipticCurve([a, a, 0, 3*a+8, 4*a+3]) sage: E.has_global_minimal_model() False sage: E.global_minimal_model() Traceback (most recent call last): ... - ValueError: Elliptic Curve defined by y^2 + a*x*y = x^3 + a*x^2 + (3*a+8)*x + (4*a+3) over Number Field in a with defining polynomial x^2 - 10 has no global minimal model! For a semi-global minimal model use semi_global=True + ValueError: Elliptic Curve defined by + y^2 + a*x*y = x^3 + a*x^2 + (3*a+8)*x + (4*a+3) over Number Field + in a with defining polynomial x^2 - 10 has no global minimal model! + For a semi-global minimal model use semi_global=True sage: E.global_minimal_model(semi_global=True) - Elliptic Curve defined by y^2 + a*x*y = x^3 + a*x^2 + (3*a+8)*x + (4*a+3) over Number Field in a with defining polynomial x^2 - 10 + Elliptic Curve defined by + y^2 + a*x*y = x^3 + a*x^2 + (3*a+8)*x + (4*a+3) over Number Field in a + with defining polynomial x^2 - 10 An example of a curve with everywhere good reduction but which has no model with unit discriminant:: - sage: K. = NumberField(x^2-x-16) + sage: K. = NumberField(x^2 - x - 16) sage: K.class_number() 2 sage: E = EllipticCurve([0,0,0,-15221331*a - 53748576, -79617688290*a - 281140318368]) @@ -1883,10 +1926,11 @@ def reduction(self,place): EXAMPLES:: sage: K. = QuadraticField(-1) - sage: EK = EllipticCurve([0,0,0,i,i+3]) + sage: EK = EllipticCurve([0, 0, 0, i, i+3]) sage: v = K.fractional_ideal(2*i+3) sage: EK.reduction(v) - Elliptic Curve defined by y^2 = x^3 + 5*x + 8 over Residue field of Fractional ideal (2*i + 3) + Elliptic Curve defined by y^2 = x^3 + 5*x + 8 + over Residue field of Fractional ideal (2*i + 3) sage: EK.reduction(K.ideal(1+i)) Traceback (most recent call last): ... @@ -1895,10 +1939,11 @@ def reduction(self,place): Traceback (most recent call last): ... ValueError: The ideal must be prime. - sage: K=QQ.extension(x^2+x+1,"a") - sage: E = EllipticCurve([1024*K.0,1024*K.0]) + sage: K = QQ.extension(x^2 + x + 1, "a") + sage: E = EllipticCurve([1024*K.0, 1024*K.0]) sage: E.reduction(2*K) - Elliptic Curve defined by y^2 + (abar+1)*y = x^3 over Residue field in abar of Fractional ideal (2) + Elliptic Curve defined by y^2 + (abar+1)*y = x^3 + over Residue field in abar of Fractional ideal (2) """ K = self.base_field() OK = K.ring_of_integers() @@ -1923,10 +1968,7 @@ def torsion_subgroup(self): r""" Return the torsion subgroup of this elliptic curve. - OUTPUT: - - (``EllipticCurveTorsionSubgroup``) The - ``EllipticCurveTorsionSubgroup`` associated to this elliptic + OUTPUT: The :class:`EllipticCurveTorsionSubgroup` associated to this elliptic curve. EXAMPLES:: @@ -1936,7 +1978,9 @@ def torsion_subgroup(self): sage: EK = E.base_extend(K) sage: tor = EK.torsion_subgroup() # long time (2s on sage.math, 2014) sage: tor # long time - Torsion Subgroup isomorphic to Z/5 + Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in t with defining polynomial x^4 + x^3 + 11*x^2 + 41*x + 101 + Torsion Subgroup isomorphic to Z/5 + Z/5 associated to the Elliptic Curve + defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field + in t with defining polynomial x^4 + x^3 + 11*x^2 + 41*x + 101 sage: tor.gens() # long time ((16 : 60 : 1), (t : 1/11*t^3 + 6/11*t^2 + 19/11*t + 48/11 : 1)) @@ -1946,7 +1990,9 @@ def torsion_subgroup(self): sage: K. = NumberField(x^2 + 2*x + 10) sage: EK = E.base_extend(K) sage: EK.torsion_subgroup() - Torsion Subgroup isomorphic to Z/4 + Z/4 associated to the Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + (-10)*x + (-10) over Number Field in t with defining polynomial x^2 + 2*x + 10 + Torsion Subgroup isomorphic to Z/4 + Z/4 associated to the + Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + (-10)*x + (-10) + over Number Field in t with defining polynomial x^2 + 2*x + 10 :: @@ -1954,14 +2000,18 @@ def torsion_subgroup(self): sage: K. = NumberField(x^9-3*x^8-4*x^7+16*x^6-3*x^5-21*x^4+5*x^3+7*x^2-7*x+1) sage: EK = E.base_extend(K) sage: EK.torsion_subgroup() - Torsion Subgroup isomorphic to Z/9 associated to the Elliptic Curve defined by y^2 + y = x^3 + x^2 + (-9)*x + (-15) over Number Field in t with defining polynomial x^9 - 3*x^8 - 4*x^7 + 16*x^6 - 3*x^5 - 21*x^4 + 5*x^3 + 7*x^2 - 7*x + 1 + Torsion Subgroup isomorphic to Z/9 associated to the Elliptic Curve defined + by y^2 + y = x^3 + x^2 + (-9)*x + (-15) over Number Field in t with defining + polynomial x^9 - 3*x^8 - 4*x^7 + 16*x^6 - 3*x^5 - 21*x^4 + 5*x^3 + 7*x^2 - 7*x + 1 :: sage: K. = QuadraticField(-1) - sage: EK = EllipticCurve([0,0,0,i,i+3]) + sage: EK = EllipticCurve([0, 0, 0, i, i+3]) sage: EK.torsion_subgroup () - Torsion Subgroup isomorphic to Trivial group associated to the Elliptic Curve defined by y^2 = x^3 + i*x + (i+3) over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + Torsion Subgroup isomorphic to Trivial group associated to the + Elliptic Curve defined by y^2 = x^3 + i*x + (i+3) + over Number Field in i with defining polynomial x^2 + 1 with i = 1*I .. SEEALSO:: @@ -1999,7 +2049,7 @@ def torsion_order(self): :: sage: E = EllipticCurve('19a1') - sage: K. = NumberField(x^9-3*x^8-4*x^7+16*x^6-3*x^5-21*x^4+5*x^3+7*x^2-7*x+1) + sage: K. = NumberField(x^9 - 3*x^8 - 4*x^7 + 16*x^6 - 3*x^5 - 21*x^4 + 5*x^3 + 7*x^2 - 7*x + 1) sage: EK = E.base_extend(K) sage: EK.torsion_order() 9 @@ -2007,7 +2057,7 @@ def torsion_order(self): :: sage: K. = QuadraticField(-1) - sage: EK = EllipticCurve([0,0,0,i,i+3]) + sage: EK = EllipticCurve([0, 0, 0, i, i + 3]) sage: EK.torsion_order() 1 """ @@ -2081,8 +2131,8 @@ def torsion_points(self): :: sage: K. = QuadraticField(-1) - sage: EK = EllipticCurve(K,[0,0,0,0,-1]) - sage: EK.torsion_points () + sage: EK = EllipticCurve(K, [0,0,0,0,-1]) + sage: EK.torsion_points() [(-2 : -3*i : 1), (-2 : 3*i : 1), (0 : -i : 1), (0 : i : 1), (0 : 1 : 0), (1 : 0 : 1)] """ T = self.torsion_subgroup() # cached @@ -2138,8 +2188,8 @@ def rank_bounds(self, **kwds): Here is a curve with two-torsion, again the bounds coincide:: - sage: Qrt5. = NumberField(x^2-5) - sage: E = EllipticCurve([0,5-rt5,0,rt5,0]) + sage: Qrt5. = NumberField(x^2 - 5) + sage: E = EllipticCurve([0, 5-rt5, 0, rt5, 0]) sage: E.rank_bounds() (1, 1) @@ -2148,9 +2198,9 @@ def rank_bounds(self, **kwds): give bounds:: sage: E = EllipticCurve("15a5") - sage: K. = NumberField(x^2-6) + sage: K. = NumberField(x^2 - 6) sage: EK = E.base_extend(K) - sage: EK.rank_bounds(lim1=1,lim3=1,limtriv=1) + sage: EK.rank_bounds(lim1=1, lim3=1, limtriv=1) (0, 2) IMPLEMENTATION: @@ -2220,7 +2270,7 @@ def rank(self, **kwds): determine the rank:: sage: E = EllipticCurve("15a5") - sage: K. = NumberField(x^2-6) + sage: K. = NumberField(x^2 - 6) sage: EK = E.base_extend(K) sage: EK.rank(lim1=1, lim3=1, limtriv=1) Traceback (most recent call last): @@ -2314,8 +2364,8 @@ def gens(self, **kwds): Here is a curve of rank 2:: - sage: K. = NumberField(x^2-17) - sage: E = EllipticCurve(K,[-4,0]) + sage: K. = NumberField(x^2 - 17) + sage: E = EllipticCurve(K, [-4, 0]) sage: E.gens() [(-1/2*t + 1/2 : -1/2*t + 1/2 : 1), (-t + 3 : -2*t + 10 : 1)] sage: E.rank() @@ -2324,7 +2374,7 @@ def gens(self, **kwds): Test that points of finite order are not included (see :trac:`13593`):: sage: E = EllipticCurve("17a3") - sage: K. = NumberField(x^2+3) + sage: K. = NumberField(x^2 + 3) sage: EK = E.base_extend(K) sage: EK.rank() 0 @@ -2365,7 +2415,7 @@ def period_lattice(self, embedding): First define a field with two real embeddings:: - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: E = EllipticCurve([0,0,0,a,2]) sage: embs = K.embeddings(CC); len(embs) 3 @@ -2373,33 +2423,40 @@ def period_lattice(self, embedding): For each embedding we have a different period lattice:: sage: E.period_lattice(embs[0]) - Period lattice associated to Elliptic Curve defined by y^2 = x^3 + a*x + 2 over Number Field in a with defining polynomial x^3 - 2 with respect to the embedding Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Algebraic Field - Defn: a |--> -0.6299605249474365? - 1.091123635971722?*I + Period lattice associated to Elliptic Curve defined by y^2 = x^3 + a*x + 2 + over Number Field in a with defining polynomial x^3 - 2 + with respect to the embedding Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Algebraic Field + Defn: a |--> -0.6299605249474365? - 1.091123635971722?*I sage: E.period_lattice(embs[1]) - Period lattice associated to Elliptic Curve defined by y^2 = x^3 + a*x + 2 over Number Field in a with defining polynomial x^3 - 2 with respect to the embedding Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Algebraic Field - Defn: a |--> -0.6299605249474365? + 1.091123635971722?*I + Period lattice associated to Elliptic Curve defined by y^2 = x^3 + a*x + 2 + over Number Field in a with defining polynomial x^3 - 2 + with respect to the embedding Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Algebraic Field + Defn: a |--> -0.6299605249474365? + 1.091123635971722?*I sage: E.period_lattice(embs[2]) - Period lattice associated to Elliptic Curve defined by y^2 = x^3 + a*x + 2 over Number Field in a with defining polynomial x^3 - 2 with respect to the embedding Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Algebraic Field - Defn: a |--> 1.259921049894873? + Period lattice associated to Elliptic Curve defined by y^2 = x^3 + a*x + 2 + over Number Field in a with defining polynomial x^3 - 2 + with respect to the embedding Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Algebraic Field + Defn: a |--> 1.259921049894873? Although the original embeddings have only the default precision, we can obtain the basis with higher precision later:: - sage: L=E.period_lattice(embs[0]) + sage: L = E.period_lattice(embs[0]) sage: L.basis() (1.86405007647981 - 0.903761485143226*I, -0.149344633143919 - 2.06619546272945*I) sage: L.basis(prec=100) - (1.8640500764798108425920506200 - 0.90376148514322594749786960975*I, -0.14934463314391922099120107422 - 2.0661954627294548995621225062*I) + (1.8640500764798108425920506200 - 0.90376148514322594749786960975*I, + -0.14934463314391922099120107422 - 2.0661954627294548995621225062*I) """ from sage.schemes.elliptic_curves.period_lattice import PeriodLattice_ell return PeriodLattice_ell(self,embedding) @@ -2466,7 +2523,9 @@ def height_function(self): sage: K. = NumberField(x^2 - 5) sage: E = EllipticCurve(K, '11a3') sage: E.height_function() - EllipticCurveCanonicalHeight object associated to Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 over Number Field in a with defining polynomial x^2 - 5 + EllipticCurveCanonicalHeight object associated to + Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + over Number Field in a with defining polynomial x^2 - 5 """ if not hasattr(self, '_height_function'): from sage.schemes.elliptic_curves.height import EllipticCurveCanonicalHeight @@ -2487,10 +2546,10 @@ def isogeny_class(self, reducible_primes=None, algorithm='Billerey', minimal_mod the isogeny class, only composites isogenies of these degrees will be used. - - ``algorithm`` (string, default 'Billerey') -- the algorithm + - ``algorithm`` (string, default ``'Billerey'``) -- the algorithm to use to compute the reducible primes. Ignored for CM curves or if ``reducible_primes`` is provided. Values are - 'Billerey' (default), 'Larson', and 'heuristic'. + ``'Billerey'`` (default), ``'Larson'``, and ``'heuristic'``. - ``minimal_models`` (bool, default ``True``) -- if ``True``, all curves in the class will be minimal or semi-minimal @@ -2507,7 +2566,7 @@ def isogeny_class(self, reducible_primes=None, algorithm='Billerey', minimal_mod .. NOTE:: - If using the algorithm 'heuristic' for non-CM curves, the + If using the algorithm ``'heuristic'`` for non-CM curves, the result is not guaranteed to be the complete isogeny class, since only reducible primes up to the default bound in :meth:`reducible_primes_naive` (currently 1000) are @@ -2529,7 +2588,8 @@ def isogeny_class(self, reducible_primes=None, algorithm='Billerey', minimal_mod sage: K. = QuadraticField(-1) sage: E = EllipticCurve(K, [0,0,0,0,1]) sage: C = E.isogeny_class(); C - Isogeny class of Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + Isogeny class of Elliptic Curve defined by y^2 = x^3 + 1 + over Number Field in i with defining polynomial x^2 + 1 with i = 1*I The curves in the class (sorted):: @@ -2555,16 +2615,18 @@ class :class:`EllipticCurveIsogeny` allowed composition. In to 3, and `3`-isogenies to go from 0 to 1 and from 2 to 3:: sage: isogs = C.isogenies() - sage: [((i,j),isogs[i][j].degree()) for i in range(4) for j in range(4) if isogs[i][j]!=0] + sage: [((i,j), isogs[i][j].degree()) + ....: for i in range(4) for j in range(4) if isogs[i][j] != 0] [((0, 1), 3), - ((0, 3), 2), - ((1, 0), 3), - ((1, 2), 2), - ((2, 1), 2), - ((2, 3), 3), - ((3, 0), 2), - ((3, 2), 3)] - sage: [((i,j),isogs[i][j].x_rational_map()) for i in range(4) for j in range(4) if isogs[i][j]!=0] + ((0, 3), 2), + ((1, 0), 3), + ((1, 2), 2), + ((2, 1), 2), + ((2, 3), 3), + ((3, 0), 2), + ((3, 2), 3)] + sage: [((i,j), isogs[i][j].x_rational_map()) + ....: for i in range(4) for j in range(4) if isogs[i][j] != 0] [((0, 1), (1/9*x^3 - 12)/x^2), ((0, 3), (-1/2*i*x^2 + i*x - 12*i)/(x - 3)), ((1, 0), (x^3 + 4)/x^2), @@ -2583,7 +2645,9 @@ class :class:`EllipticCurveIsogeny` allowed composition. In sage: K. = QuadraticField(-1) sage: E = EllipticCurve([1+i, -i, i, 1, 0]) sage: C = E.isogeny_class(); C # long time - Isogeny class of Elliptic Curve defined by y^2 + (i+1)*x*y + i*y = x^3 + (-i)*x^2 + x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + Isogeny class of + Elliptic Curve defined by y^2 + (i+1)*x*y + i*y = x^3 + (-i)*x^2 + x + over Number Field in i with defining polynomial x^2 + 1 with i = 1*I sage: len(C) # long time 6 sage: C.matrix() # long time @@ -2595,17 +2659,17 @@ class :class:`EllipticCurveIsogeny` allowed composition. In [ 2 6 18 9 3 1] sage: [E1.ainvs() for E1 in C] # long time [(i + 1, i - 1, i, -i - 1, -i + 1), - (i + 1, i - 1, i, 14*i + 4, 7*i + 14), - (i + 1, i - 1, i, 59*i + 99, 372*i - 410), - (i + 1, -i, i, -240*i - 399, 2869*i + 2627), - (i + 1, -i, i, -5*i - 4, 2*i + 5), - (i + 1, -i, i, 1, 0)] + (i + 1, i - 1, i, 14*i + 4, 7*i + 14), + (i + 1, i - 1, i, 59*i + 99, 372*i - 410), + (i + 1, -i, i, -240*i - 399, 2869*i + 2627), + (i + 1, -i, i, -5*i - 4, 2*i + 5), + (i + 1, -i, i, 1, 0)] An example with CM by `\sqrt{-5}`:: sage: pol = PolynomialRing(QQ,'x')([1,0,3,0,1]) sage: K. = NumberField(pol) - sage: j = 1480640+565760*c^2 + sage: j = 1480640 + 565760*c^2 sage: E = EllipticCurve(j=j) sage: E.has_cm() True @@ -2623,7 +2687,13 @@ class :class:`EllipticCurveIsogeny` allowed composition. In [(0, 0, 0, 83490*c^2 - 147015, -64739840*c^2 - 84465260), (0, 0, 0, -161535*c^2 + 70785, -62264180*c^3 + 6229080*c)] sage: C.isogenies()[0][1] - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + (83490*c^2-147015)*x + (-64739840*c^2-84465260) over Number Field in c with defining polynomial x^4 + 3*x^2 + 1 to Elliptic Curve defined by y^2 = x^3 + (-161535*c^2+70785)*x + (-62264180*c^3+6229080*c) over Number Field in c with defining polynomial x^4 + 3*x^2 + 1 + Isogeny of degree 2 + from Elliptic Curve defined by + y^2 = x^3 + (83490*c^2-147015)*x + (-64739840*c^2-84465260) + over Number Field in c with defining polynomial x^4 + 3*x^2 + 1 + to Elliptic Curve defined by + y^2 = x^3 + (-161535*c^2+70785)*x + (-62264180*c^3+6229080*c) + over Number Field in c with defining polynomial x^4 + 3*x^2 + 1 An example with CM by `\sqrt{-23}` (class number `3`):: @@ -2716,7 +2786,7 @@ class number is only `3` is that the class also contains three different endomorphism rings, then use a 3-dimensional plot which can be rotated:: - sage: for i,j,l in G.edge_iterator(): # long time + sage: for i, j, l in G.edge_iterator(): # long time ....: G.set_edge_label(i, j, l.count(',')) sage: G.show3d(color_by_label=True) # long time @@ -2724,9 +2794,9 @@ class number is only `3` is that the class also contains three defines the same field as ``pol26`` but is simpler:: sage: pol26 = hilbert_class_polynomial(-4*26) - sage: pol = x^6-x^5+2*x^4+x^3-2*x^2-x-1 + sage: pol = x^6 - x^5 + 2*x^4 + x^3 - 2*x^2 - x - 1 sage: K. = NumberField(pol) - sage: L. = K.extension(x^2+26) + sage: L. = K.extension(x^2 + 26) Only `2` of the `j`-invariants with discriminant -104 are in `K`, though all are in `L`:: @@ -2769,7 +2839,7 @@ class number is only `3` is that the class also contains three sage: len(CL) # long time 6 sage: s1 = Set([EE.j_invariant() for EE in CL.curves]) # long time - sage: s2 = Set(pol26.roots(L,multiplicities=False)) # long time + sage: s2 = Set(pol26.roots(L, multiplicities=False)) # long time sage: s1 == s2 # long time True @@ -2823,17 +2893,20 @@ class number is only `3` is that the class also contains three sage: K. = CyclotomicField(53) sage: E = EllipticCurve(K,[0,6,0,2,0]) sage: C = E.isogeny_class(algorithm='heuristic', minimal_models=False); C # long time (10s) - Isogeny class of Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 2*x over Cyclotomic Field of order 53 and degree 52 + Isogeny class of Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 2*x + over Cyclotomic Field of order 53 and degree 52 sage: C.curves # long time - [Elliptic Curve defined by y^2 = x^3 + 6*x^2 + (-8)*x + (-48) over Cyclotomic Field of order 53 and degree 52, - Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 2*x over Cyclotomic Field of order 53 and degree 52] + [Elliptic Curve defined by y^2 = x^3 + 6*x^2 + (-8)*x + (-48) + over Cyclotomic Field of order 53 and degree 52, + Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 2*x + over Cyclotomic Field of order 53 and degree 52] TESTS: An example which failed until fixed at :trac:`19229`:: - sage: K. = NumberField(x^2-x+1) - sage: E = EllipticCurve([a+1,1,1,0,0]) + sage: K. = NumberField(x^2 - x + 1) + sage: E = EllipticCurve([a+1, 1, 1, 0, 0]) sage: C = E.isogeny_class(); len(C) # long time 4 """ @@ -2893,7 +2966,7 @@ def isogenies_prime_degree(self, l=None, algorithm='Billerey', minimal_models=Tr sage: pol = PolynomialRing(QQ,'x')([1,-3,5,-5,5,-3,1]) sage: L. = NumberField(pol) - sage: js = hilbert_class_polynomial(-23).roots(L,multiplicities=False); len(js) + sage: js = hilbert_class_polynomial(-23).roots(L, multiplicities=False); len(js) 3 sage: E = EllipticCurve(j=js[0]) sage: len(E.isogenies_prime_degree()) # long time @@ -2906,11 +2979,19 @@ def isogenies_prime_degree(self, l=None, algorithm='Billerey', minimal_models=Tr sage: proof.number_field(False) sage: K. = CyclotomicField(53) - sage: E = EllipticCurve(K,[0,6,0,2,0]) + sage: E = EllipticCurve(K, [0,6,0,2,0]) sage: E.isogenies_prime_degree(2, minimal_models=False) - [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 2*x over Cyclotomic Field of order 53 and degree 52 to Elliptic Curve defined by y^2 = x^3 + 6*x^2 + (-8)*x + (-48) over Cyclotomic Field of order 53 and degree 52] + [Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 2*x + over Cyclotomic Field of order 53 and degree 52 + to Elliptic Curve defined by y^2 = x^3 + 6*x^2 + (-8)*x + (-48) + over Cyclotomic Field of order 53 and degree 52] sage: E.isogenies_prime_degree(2, minimal_models=True) # not tested (10s) - [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 2*x over Cyclotomic Field of order 53 and degree 52 to Elliptic Curve defined by y^2 = x^3 + (-20)*x + (-16) over Cyclotomic Field of order 53 and degree 52] + [Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 2*x + over Cyclotomic Field of order 53 and degree 52 + to Elliptic Curve defined by y^2 = x^3 + (-20)*x + (-16) + over Cyclotomic Field of order 53 and degree 52] TESTS:: @@ -2978,7 +3059,7 @@ def is_isogenous(self, other, proof=True, maxnorm=100): EXAMPLES:: sage: x = polygen(QQ, 'x') - sage: F = NumberField(x^2 -2, 's'); F + sage: F = NumberField(x^2 - 2, 's'); F Number Field in s with defining polynomial x^2 - 2 sage: E1 = EllipticCurve(F, [7,8]) sage: E2 = EllipticCurve(F, [0,5,0,1,0]) @@ -2997,7 +3078,7 @@ def is_isogenous(self, other, proof=True, maxnorm=100): :: sage: x = polygen(QQ, 'x') - sage: F = NumberField(x^2 -2, 's'); F + sage: F = NumberField(x^2 - 2, 's'); F Number Field in s with defining polynomial x^2 - 2 sage: E = EllipticCurve('14a1') sage: EE = EllipticCurve('14a2') @@ -3009,9 +3090,9 @@ def is_isogenous(self, other, proof=True, maxnorm=100): :: sage: x = polygen(QQ, 'x') - sage: F = NumberField(x^2 -2, 's'); F + sage: F = NumberField(x^2 - 2, 's'); F Number Field in s with defining polynomial x^2 - 2 - sage: k. = NumberField(x^3+7) + sage: k. = NumberField(x^3 + 7) sage: E = EllipticCurve(F, [7,8]) sage: EE = EllipticCurve(k, [2, 2]) sage: E.is_isogenous(EE) @@ -3145,7 +3226,7 @@ def isogeny_degree(self, other): EXAMPLES:: sage: x = QQ['x'].0 - sage: F = NumberField(x^2 -2, 's'); F + sage: F = NumberField(x^2 - 2, 's'); F Number Field in s with defining polynomial x^2 - 2 sage: E = EllipticCurve('14a1') sage: EE = EllipticCurve('14a2') @@ -3305,30 +3386,30 @@ def lll_reduce(self, points, height_matrix=None, precision=None): :: sage: E = EllipticCurve([1,0,1,-120039822036992245303534619191166796374,504224992484910670010801799168082726759443756222911415116]) - sage: xi = [2005024558054813068,\ - -4690836759490453344,\ - 4700156326649806635,\ - 6785546256295273860,\ - 6823803569166584943,\ - 7788809602110240789,\ - 27385442304350994620556,\ - 54284682060285253719/4,\ - -94200235260395075139/25,\ - -3463661055331841724647/576,\ - -6684065934033506970637/676,\ - -956077386192640344198/2209,\ - -27067471797013364392578/2809,\ - -25538866857137199063309/3721,\ - -1026325011760259051894331/108241,\ - 9351361230729481250627334/1366561,\ - 10100878635879432897339615/1423249,\ - 11499655868211022625340735/17522596,\ - 110352253665081002517811734/21353641,\ - 414280096426033094143668538257/285204544,\ - 36101712290699828042930087436/4098432361,\ - 45442463408503524215460183165/5424617104,\ - 983886013344700707678587482584/141566320009,\ - 1124614335716851053281176544216033/152487126016] + sage: xi = [2005024558054813068, + ....: -4690836759490453344, + ....: 4700156326649806635, + ....: 6785546256295273860, + ....: 6823803569166584943, + ....: 7788809602110240789, + ....: 27385442304350994620556, + ....: 54284682060285253719/4, + ....: -94200235260395075139/25, + ....: -3463661055331841724647/576, + ....: -6684065934033506970637/676, + ....: -956077386192640344198/2209, + ....: -27067471797013364392578/2809, + ....: -25538866857137199063309/3721, + ....: -1026325011760259051894331/108241, + ....: 9351361230729481250627334/1366561, + ....: 10100878635879432897339615/1423249, + ....: 11499655868211022625340735/17522596, + ....: 110352253665081002517811734/21353641, + ....: 414280096426033094143668538257/285204544, + ....: 36101712290699828042930087436/4098432361, + ....: 45442463408503524215460183165/5424617104, + ....: 983886013344700707678587482584/141566320009, + ....: 1124614335716851053281176544216033/152487126016] sage: points = [E.lift_x(x) for x in xi] sage: newpoints, U = E.lll_reduce(points) # long time (35s on sage.math, 2011) sage: [P[0] for P in newpoints] # long time @@ -3351,7 +3432,7 @@ def lll_reduce(self, points, height_matrix=None, precision=None): sage: K. = QuadraticField(-23, 'a') sage: E = EllipticCurve(K, [0,0,1,-1,0]) - sage: P = E(-2,-(a+1)/2) + sage: P = E(-2, -(a+1)/2) sage: Q = E(0,-1) sage: E.lll_reduce([P,Q]) ( @@ -3362,8 +3443,9 @@ def lll_reduce(self, points, height_matrix=None, precision=None): :: sage: K. = QuadraticField(-5) - sage: E = EllipticCurve(K,[0,a]) - sage: points = [E.point([-211/841*a - 6044/841,-209584/24389*a + 53634/24389]),E.point([-17/18*a - 1/9, -109/108*a - 277/108]) ] + sage: E = EllipticCurve(K, [0,a]) + sage: points = [E.point([-211/841*a - 6044/841,-209584/24389*a + 53634/24389]), + ....: E.point([-17/18*a - 1/9, -109/108*a - 277/108])] sage: E.lll_reduce(points) ( [(-a + 4 : -3*a + 7 : 1), (-17/18*a - 1/9 : 109/108*a + 277/108 : 1)], @@ -3399,7 +3481,9 @@ def galois_representation(self): sage: E = EllipticCurve('11a1').change_ring(K) sage: rho = E.galois_representation() sage: rho - Compatible family of Galois representations associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in a with defining polynomial x^2 + 1 + Compatible family of Galois representations associated to the + Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) + over Number Field in a with defining polynomial x^2 + 1 sage: rho.is_surjective(3) True sage: rho.is_surjective(5) # long time (4s on sage.math, 2014) @@ -3435,7 +3519,8 @@ def cm_discriminant(self): sage: EllipticCurve(j=1).cm_discriminant() Traceback (most recent call last): ... - ValueError: Elliptic Curve defined by y^2 + x*y = x^3 + 36*x + 3455 over Rational Field does not have CM + ValueError: Elliptic Curve defined by y^2 + x*y = x^3 + 36*x + 3455 + over Rational Field does not have CM sage: EllipticCurve(j=1728).cm_discriminant() -4 sage: EllipticCurve(j=8000).cm_discriminant() @@ -3553,7 +3638,7 @@ def has_rational_cm(self, field=None): False sage: E.cm_discriminant() -20 - sage: E.has_rational_cm(K.extension(x^2+5,'b')) + sage: E.has_rational_cm(K.extension(x^2 + 5, 'b')) True An error is raised if a field is given which is not an extension of the base field:: @@ -3561,7 +3646,10 @@ def has_rational_cm(self, field=None): sage: E.has_rational_cm(QuadraticField(-20)) Traceback (most recent call last): ... - ValueError: Error in has_rational_cm: Number Field in a with defining polynomial x^2 + 20 with a = 4.472135954999579?*I is not an extension field of Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? + ValueError: Error in has_rational_cm: Number Field in a + with defining polynomial x^2 + 20 with a = 4.472135954999579?*I + is not an extension field of Number Field in a + with defining polynomial x^2 - 5 with a = 2.236067977499790? sage: K. = NumberField(x^3 - 2) sage: E = EllipticCurve(j=31710790944000*a^2 + 39953093016000*a + 50337742902000) @@ -3571,7 +3659,7 @@ def has_rational_cm(self, field=None): False sage: D = E.cm_discriminant(); D -108 - sage: E.has_rational_cm(K.extension(x^2+108,'b')) + sage: E.has_rational_cm(K.extension(x^2 + 108,'b')) True """ D = self.cm_discriminant() @@ -3611,20 +3699,20 @@ def is_Q_curve(self, maxp=100, certificate=False, verbose=False): - when the flag is ``True``, so `E` is a `\QQ`-curve: - - either {'CM':`D`} where `D` is a negative discriminant, when - `E` has potential CM with discriminant `D`; - - - otherwise {'CM': `0`, 'core_poly': `f`, 'rho': `\rho`, - 'r': `r`, 'N': `N`}, when `E` is a non-CM `\QQ`-curve, - where the core polynomial `f` is an irreducible monic - polynomial over `QQ` of degree `2^\rho`, all of whose - roots are `j`-invariants of curves isogenous to `E`, the - core level `N` is a square-free integer with `r` prime - factors which is the LCM of the degrees of the isogenies - between these conjugates. For example, if there exists - a curve `E'` isogenous to `E` with `j(E')=j\in\QQ`, then - the certificate is {'CM':0, 'r':0, 'rho':0, 'core_poly': - x-j, 'N':1}. + - either {'CM':`D`} where `D` is a negative discriminant, when + `E` has potential CM with discriminant `D`; + + - otherwise {'CM': `0`, 'core_poly': `f`, 'rho': `\rho`, + 'r': `r`, 'N': `N`}, when `E` is a non-CM `\QQ`-curve, + where the core polynomial `f` is an irreducible monic + polynomial over `QQ` of degree `2^\rho`, all of whose + roots are `j`-invariants of curves isogenous to `E`, the + core level `N` is a square-free integer with `r` prime + factors which is the LCM of the degrees of the isogenies + between these conjugates. For example, if there exists + a curve `E'` isogenous to `E` with `j(E')=j\in\QQ`, then + the certificate is {'CM':0, 'r':0, 'rho':0, 'core_poly': + x-j, 'N':1}. - when the flag is ``False``, so `E` is not a `\QQ`-curve, the certificate is a prime `p` such that the reductions of `E` @@ -3663,7 +3751,7 @@ def is_Q_curve(self, maxp=100, certificate=False, verbose=False): sage: R. = PolynomialRing(QQ) sage: K. = NumberField(R([3, 0, -5, 0, 1])) - sage: E = EllipticCurve([K([-3,-4,1,1]),K([4,-1,-1,0]),K([-2,0,1,0]),K([-621,778,138,-178]),K([9509,2046,-24728,10380])]) + sage: E = EllipticCurve([K([-3,-4,1,1]), K([4,-1,-1,0]), K([-2,0,1,0]), K([-621,778,138,-178]), K([9509,2046,-24728,10380])]) sage: E.is_Q_curve(certificate=True, verbose=True) Checking whether Elliptic Curve defined by y^2 + (a^3+a^2-4*a-3)*x*y + (a^2-2)*y = x^3 + (-a^2-a+4)*x^2 + (-178*a^3+138*a^2+778*a-621)*x + (10380*a^3-24728*a^2+2046*a+9509) over Number Field in a with defining polynomial x^4 - 5*x^2 + 3 is a Q-curve No: inconsistency at the 2 primes dividing 3 @@ -3675,7 +3763,7 @@ def is_Q_curve(self, maxp=100, certificate=False, verbose=False): is not:: sage: K. = NumberField(R([-10, 0, 1])) - sage: E = EllipticCurve([K([0,1]),K([-1,-1]),K([0,0]),K([-236,40]),K([-1840,464])]) + sage: E = EllipticCurve([K([0,1]), K([-1,-1]), K([0,0]), K([-236,40]), K([-1840,464])]) sage: E.is_Q_curve(certificate=True, verbose=True) Checking whether Elliptic Curve defined by y^2 + a*x*y = x^3 + (-a-1)*x^2 + (40*a-236)*x + (464*a-1840) over Number Field in a with defining polynomial x^2 - 10 is a Q-curve Applying local tests at good primes above p<=100 @@ -3689,7 +3777,7 @@ def is_Q_curve(self, maxp=100, certificate=False, verbose=False): sage: R. = PolynomialRing(QQ) sage: K. = NumberField(R([-1, -1, 1])) - sage: E = EllipticCurve([K([1,0]),K([-1,0]),K([0,1]),K([0,-2]),K([0,1])]) + sage: E = EllipticCurve([K([1,0]), K([-1,0]), K([0,1]), K([0,-2]), K([0,1])]) sage: E.is_Q_curve(certificate=True, verbose=True) Checking whether Elliptic Curve defined by y^2 + x*y + a*y = x^3 + (-1)*x^2 + (-2*a)*x + a over Number Field in a with defining polynomial x^2 - x - 1 is a Q-curve Yes: E is CM (discriminant -15) @@ -3701,7 +3789,7 @@ def is_Q_curve(self, maxp=100, certificate=False, verbose=False): `j`, so we have a so-called rational `\QQ`-curve:: sage: K. = NumberField(R([1, 0, -4, 0, 1])) - sage: E = EllipticCurve([K([-2,-4,1,1]),K([0,1,0,0]),K([0,1,0,0]),K([-4780,9170,1265,-2463]),K([163923,-316598,-43876,84852])]) + sage: E = EllipticCurve([K([-2,-4,1,1]), K([0,1,0,0]), K([0,1,0,0]), K([-4780,9170,1265,-2463]), K([163923,-316598,-43876,84852])]) sage: flag, cert = E.is_Q_curve(certificate=True) # long time sage: flag # long time True @@ -3715,17 +3803,17 @@ def is_Q_curve(self, maxp=100, certificate=False, verbose=False): with quadratic conjugate `j`-invariants in `\QQ(\sqrt{3})` (but which are not base-changes from the quadratic subfield):: - sage: E = EllipticCurve([K([0,-3,0,1]),K([1,4,0,-1]),K([0,0,0,0]),K([-2,-16,0,4]),K([-19,-32,4,8])]) + sage: E = EllipticCurve([K([0,-3,0,1]), K([1,4,0,-1]), K([0,0,0,0]), K([-2,-16,0,4]), K([-19,-32,4,8])]) sage: flag, cert = E.is_Q_curve(certificate=True) # long time sage: flag # long time True sage: cert # long time {'CM': 0, - 'N': 2, - 'core_degs': [1, 2], - 'core_poly': x^2 - 840064*x + 1593413632, - 'r': 1, - 'rho': 1} + 'N': 2, + 'core_degs': [1, 2], + 'core_poly': x^2 - 840064*x + 1593413632, + 'r': 1, + 'rho': 1} """ from sage.schemes.elliptic_curves.Qcurves import is_Q_curve as isQ return isQ(self, maxp, certificate, verbose) @@ -3795,13 +3883,13 @@ def saturation(self, points, verbose=False, ([(-1 : 1 : 1)], 12, 0.686667083305587) sage: EK.saturation([2*P, Q], max_prime=2) ([(-1 : 1 : 1), (0 : -1 : 1)], 2, 0.152460177943144) - sage: EK.saturation([P+Q, P-Q], lower_ht_bound=.1, debug=2) + sage: EK.saturation([P + Q, P - Q], lower_ht_bound=.1, debug=2) ([(-1 : 1 : 1), (1 : 0 : 1)], 2, 0.152460177943144) - sage: EK.saturation([P+Q, 17*Q], lower_ht_bound=0.1) # long time + sage: EK.saturation([P + Q, 17*Q], lower_ht_bound=0.1) # long time ([(4 : 8 : 1), (0 : -1 : 1)], 17, 0.152460177943143) sage: R = EK(i-2,-i-3) - sage: EK.saturation([P+R, P+Q, Q+R], lower_ht_bound=0.1) + sage: EK.saturation([P + R, P + Q, Q + R], lower_ht_bound=0.1) ([(841/1369*i - 171/1369 : 41334/50653*i - 74525/50653 : 1), (4 : 8 : 1), (-1/25*i + 18/25 : -69/125*i - 58/125 : 1)], @@ -3813,12 +3901,12 @@ def saturation(self, points, verbose=False, Another number field:: sage: E = EllipticCurve('389a1') - sage: K. = NumberField(x^3-x+1) + sage: K. = NumberField(x^3 - x + 1) sage: EK = E.change_ring(K) sage: P = EK(-1,1); Q = EK(0,-1) - sage: EK.saturation([P+Q, P-Q], lower_ht_bound=0.1) + sage: EK.saturation([P + Q, P - Q], lower_ht_bound=0.1) ([(-1 : 1 : 1), (1 : 0 : 1)], 2, 0.152460177943144) - sage: EK.saturation([3*P, P+5*Q], lower_ht_bound=0.1) + sage: EK.saturation([3*P, P + 5*Q], lower_ht_bound=0.1) ([(-185/2209 : -119510/103823 : 1), (80041/34225 : -26714961/6331625 : 1)], 15, 0.152460177943144) @@ -3828,8 +3916,8 @@ def saturation(self, points, verbose=False, sage: K. = QuadraticField(3) sage: E = EllipticCurve('37a1') sage: EK = E.change_ring(K) - sage: P = EK(0,0); Q = EK(2-a,2*a-4) - sage: EK.saturation([3*P-Q, 3*P+Q], lower_ht_bound=.01) + sage: P = EK(0,0); Q = EK(2-a, 2*a-4) + sage: EK.saturation([3*P - Q, 3*P + Q], lower_ht_bound=.01) ([(0 : 0 : 1), (1/2*a : -1/4*a - 1/4 : 1)], 6, 0.0317814530725985) The points must be linearly independent:: @@ -3862,21 +3950,21 @@ def saturation(self, points, verbose=False, sage: EK.saturation([P+Q, P-Q], lower_ht_bound=.1, debug=2) ([(-1 : 1 : 1), (1 : 0 : 1)], 2, 0.152460177943144) - sage: EK.saturation([5*P+6*Q, 5*P-3*Q], lower_ht_bound=.1) + sage: EK.saturation([5*P + 6*Q, 5*P - 3*Q], lower_ht_bound=.1) ([(-3/4 : -15/8 : 1), (159965/16129 : -67536260/2048383 : 1)], - 45, - 0.152460177943144) - sage: EK.saturation([5*P+6*Q, 5*P-3*Q], lower_ht_bound=.1, debug=2) + 45, + 0.152460177943144) + sage: EK.saturation([5*P + 6*Q, 5*P - 3*Q], lower_ht_bound=.1, debug=2) ([(-3/4 : -15/8 : 1), (159965/16129 : -67536260/2048383 : 1)], - 45, - 0.152460177943144) + 45, + 0.152460177943144) See :trac:`27387`:: - sage: K. = NumberField(x^2-x-26) - sage: E = EllipticCurve([a,1-a,0,93-16*a, 3150-560*a]) + sage: K. = NumberField(x^2 - x - 26) + sage: E = EllipticCurve([a, 1-a, 0, 93-16*a, 3150-560*a]) sage: P = E([65-35*a/3, (959*a-5377)/9]) - sage: E.saturation([P],one_prime=2) + sage: E.saturation([P], one_prime=2) ([(-1/4*a + 3/4 : 59/8*a - 317/8 : 1)], 2, 0.344624259712631) """ full_saturation = (max_prime == 0) and (one_prime == 0) @@ -4053,7 +4141,7 @@ def rational_points(self, **kwds): An example over a number field:: sage: E = EllipticCurve([1,0]) - sage: pts = E.rational_points(bound = 2, F = QuadraticField(-1)) + sage: pts = E.rational_points(bound=2, F=QuadraticField(-1)) sage: pts [(-a : 0 : 1), (0 : 0 : 1), (0 : 1 : 0), (a : 0 : 1)] sage: pts[0] + pts[1] diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index d49bcccd279..368741fbcd7 100644 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -32,42 +32,42 @@ An example over a number field:: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve(K,[1,0,0,0,-1]) - sage: P = E(0,i); P + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [1,0,0,0,-1]) # optional - sage.rings.number_field + sage: P = E(0,i); P # optional - sage.rings.number_field (0 : i : 1) - sage: P.order() + sage: P.order() # optional - sage.rings.number_field +Infinity - sage: 101*P-100*P == P + sage: 101*P - 100*P == P # optional - sage.rings.number_field True An example over a finite field:: - sage: K. = GF((101,3)) - sage: E = EllipticCurve(K,[1,0,0,0,-1]) - sage: P = E(40*a^2 + 69*a + 84 , 58*a^2 + 73*a + 45) - sage: P.order() + sage: K. = GF((101,3)) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(K, [1,0,0,0,-1]) # optional - sage.rings.finite_rings + sage: P = E(40*a^2 + 69*a + 84 , 58*a^2 + 73*a + 45) # optional - sage.rings.finite_rings + sage: P.order() # optional - sage.rings.finite_rings 1032210 - sage: E.cardinality() + sage: E.cardinality() # optional - sage.rings.finite_rings 1032210 Arithmetic with a point over an extension of a finite field:: - sage: k. = GF((5,2)) - sage: E = EllipticCurve(k,[1,0]); E + sage: k. = GF((5,2)) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(k,[1,0]); E # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + x over Finite Field in a of size 5^2 - sage: P = E([a,2*a+4]) - sage: 5*P + sage: P = E([a,2*a+4]) # optional - sage.rings.finite_rings + sage: 5*P # optional - sage.rings.finite_rings (2*a + 3 : 2*a : 1) - sage: P*5 + sage: P*5 # optional - sage.rings.finite_rings (2*a + 3 : 2*a : 1) - sage: P + P + P + P + P + sage: P + P + P + P + P # optional - sage.rings.finite_rings (2*a + 3 : 2*a : 1) :: sage: F = Zmod(3) - sage: E = EllipticCurve(F,[1,0]); + sage: E = EllipticCurve(F, [1,0]); sage: P = E([2,1]) sage: import sys sage: n = sys.maxsize @@ -76,16 +76,17 @@ Arithmetic over `\ZZ/N\ZZ` with composite `N` is supported. When an operation tries to invert a non-invertible element, a -ZeroDivisionError is raised and a factorization of the modulus appears +:class:`ZeroDivisionError` is raised and a factorization of the modulus appears in the error message:: sage: N = 1715761513 - sage: E = EllipticCurve(Integers(N),[3,-13]) + sage: E = EllipticCurve(Integers(N), [3,-13]) sage: P = E(2,1) sage: LCM([2..60])*P Traceback (most recent call last): ... - ZeroDivisionError: Inverse of 26927 does not exist (characteristic = 1715761513 = 26927*63719) + ZeroDivisionError: Inverse of 26927 does not exist + (characteristic = 1715761513 = 26927*63719) AUTHORS: @@ -162,7 +163,7 @@ class EllipticCurvePoint_field(SchemeMorphism_point_abelian_variety_field): (0 : 0 : 1) sage: E(0,0) # brackets are optional (0 : 0 : 1) - sage: E([GF(5)(0), 0]) # entries are coerced + sage: E([GF(5)(0), 0]) # entries are coerced # optional - sage.rings.finite_rings (0 : 0 : 1) sage: E(0.000, 0) @@ -178,23 +179,24 @@ class EllipticCurvePoint_field(SchemeMorphism_point_abelian_variety_field): sage: E = EllipticCurve([0,0,1,-1,0]) sage: S = E(QQ); S - Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field - - sage: K.=NumberField(x^2+1) - sage: E=EllipticCurve(K,[0,1,0,-160,308]) - sage: P=E(26,-120) - sage: Q=E(2+12*i,-36+48*i) - sage: P.order() == Q.order() == 4 # long time (3s) + Abelian group of points on + Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,1,0,-160,308]) # optional - sage.rings.number_field + sage: P = E(26, -120) # optional - sage.rings.number_field + sage: Q = E(2+12*i, -36+48*i) # optional - sage.rings.number_field + sage: P.order() == Q.order() == 4 # long time (3s) # optional - sage.rings.number_field True - sage: 2*P==2*Q + sage: 2*P == 2*Q # optional - sage.rings.number_field False :: - sage: K.=FractionField(PolynomialRing(QQ,'t')) - sage: E=EllipticCurve([0,0,0,0,t^2]) - sage: P=E(0,t) - sage: P,2*P,3*P + sage: K. = FractionField(PolynomialRing(QQ,'t')) + sage: E = EllipticCurve([0,0,0,0,t^2]) + sage: P = E(0,t) + sage: P, 2*P, 3*P ((0 : t : 1), (0 : -t : 1), (0 : 1 : 0)) TESTS:: @@ -218,17 +220,18 @@ class EllipticCurvePoint_field(SchemeMorphism_point_abelian_variety_field): Test that the refactoring from :trac:`14711` did preserve the behaviour of domain and codomain:: - sage: E=EllipticCurve(QQ,[1,1]) - sage: P=E(0,1) + sage: E = EllipticCurve(QQ,[1,1]) + sage: P = E(0,1) sage: P.domain() Spectrum of Rational Field - sage: K.=NumberField(x^2-3,'a') - sage: P=E.base_extend(K)(1,a) - sage: P.domain() + sage: K. = NumberField(x^2 - 3, 'a') # optional - sage.rings.number_field + sage: P = E.base_extend(K)(1,a) # optional - sage.rings.number_field + sage: P.domain() # optional - sage.rings.number_field Spectrum of Number Field in a with defining polynomial x^2 - 3 - sage: P.codomain() - Elliptic Curve defined by y^2 = x^3 + x + 1 over Number Field in a with defining polynomial x^2 - 3 - sage: P.codomain() == P.curve() + sage: P.codomain() # optional - sage.rings.number_field + Elliptic Curve defined by y^2 = x^3 + x + 1 + over Number Field in a with defining polynomial x^2 - 3 + sage: P.codomain() == P.curve() # optional - sage.rings.number_field True """ def __init__(self, curve, v, check=True): @@ -404,18 +407,18 @@ def __pari__(self): Try the same over a finite field:: - sage: E = EllipticCurve(GF(11), [0,0,0,3,0]) - sage: O = E(0) - sage: P = E.point([1,2]) - sage: O.__pari__() + sage: E = EllipticCurve(GF(11), [0,0,0,3,0]) # optional - sage.rings.finite_rings + sage: O = E(0) # optional - sage.rings.finite_rings + sage: P = E.point([1,2]) # optional - sage.rings.finite_rings + sage: O.__pari__() # optional - sage.rings.finite_rings [0] - sage: P.__pari__() + sage: P.__pari__() # optional - sage.rings.finite_rings [Mod(1, 11), Mod(2, 11)] We no longer need to explicitly call ``pari(O)`` and ``pari(P)`` after :trac:`11868`:: - sage: pari(E).elladd(O, P) + sage: pari(E).elladd(O, P) # optional - sage.rings.finite_rings [Mod(1, 11), Mod(2, 11)] """ if self[2]: @@ -431,16 +434,17 @@ def scheme(self): EXAMPLES:: - sage: E=EllipticCurve(QQ,[1,1]) - sage: P=E(0,1) + sage: E = EllipticCurve(QQ,[1,1]) + sage: P = E(0,1) sage: P.scheme() Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field sage: P.scheme() == P.curve() True - sage: K.=NumberField(x^2-3,'a') - sage: P=E.base_extend(K)(1,a) - sage: P.scheme() - Elliptic Curve defined by y^2 = x^3 + x + 1 over Number Field in a with defining polynomial x^2 - 3 + sage: K. = NumberField(x^2 - 3,'a') # optional - sage.rings.number_field + sage: P = E.base_extend(K)(1, a) # optional - sage.rings.number_field + sage: P.scheme() # optional - sage.rings.number_field + Elliptic Curve defined by y^2 = x^3 + x + 1 + over Number Field in a with defining polynomial x^2 - 3 """ # The following text is just not true: it applies to the class # EllipticCurvePoint, which appears to be never used, but does @@ -459,7 +463,7 @@ def order(self): Return the order of this point on the elliptic curve. If the point is zero, returns 1, otherwise raise a - NotImplementedError. + :class:`NotImplementedError`. For curves over number fields and finite fields, see below. @@ -469,13 +473,14 @@ def order(self): EXAMPLES:: - sage: K.=FractionField(PolynomialRing(QQ,'t')) - sage: E=EllipticCurve([0,0,0,-t^2,0]) - sage: P=E(t,0) + sage: K. = FractionField(PolynomialRing(QQ,'t')) + sage: E = EllipticCurve([0, 0, 0, -t^2, 0]) + sage: P = E(t,0) sage: P.order() Traceback (most recent call last): ... - NotImplementedError: Computation of order of a point not implemented over general fields. + NotImplementedError: Computation of order of a point not implemented + over general fields. sage: E(0).additive_order() 1 sage: E(0).order() == 1 @@ -535,16 +540,17 @@ def has_finite_order(self): EXAMPLES:: - sage: K.=FractionField(PolynomialRing(QQ,'t')) - sage: E=EllipticCurve([0,0,0,-t^2,0]) + sage: K. = FractionField(PolynomialRing(QQ,'t')) + sage: E = EllipticCurve([0, 0, 0, -t^2, 0]) sage: P = E(0) sage: P.has_finite_order() True - sage: P=E(t,0) + sage: P = E(t,0) sage: P.has_finite_order() Traceback (most recent call last): ... - NotImplementedError: Computation of order of a point not implemented over general fields. + NotImplementedError: Computation of order of a point not implemented + over general fields. sage: (2*P).is_zero() True """ @@ -564,12 +570,12 @@ def has_infinite_order(self): EXAMPLES:: - sage: K.=FractionField(PolynomialRing(QQ,'t')) - sage: E=EllipticCurve([0,0,0,-t^2,0]) + sage: K. = FractionField(PolynomialRing(QQ,'t')) + sage: E = EllipticCurve([0, 0, 0, -t^2, 0]) sage: P = E(0) sage: P.has_infinite_order() False - sage: P=E(t,0) + sage: P = E(t,0) sage: P.has_infinite_order() Traceback (most recent call last): ... @@ -594,7 +600,7 @@ def plot(self, **args): sage: E = EllipticCurve('389a') sage: P = E([-1,1]) - sage: P.plot(pointsize=30, rgbcolor=(1,0,0)) + sage: P.plot(pointsize=30, rgbcolor=(1,0,0)) # optional - sage.plot Graphics object consisting of 1 graphics primitive """ from sage.plot.point import point @@ -628,7 +634,7 @@ def _add_(self, right): Checks that :trac:`15964` is fixed:: sage: N = 1715761513 - sage: E = EllipticCurve(Integers(N),[3,-13]) + sage: E = EllipticCurve(Integers(N), [3,-13]) sage: P = E(2,1) sage: LCM([2..60])*P Traceback (most recent call last): @@ -637,7 +643,7 @@ def _add_(self, right): (characteristic = 1715761513 = 26927*63719) sage: N = 35 - sage: E = EllipticCurve(Integers(N),[5,1]) + sage: E = EllipticCurve(Integers(N), [5,1]) sage: P = E(0,1) sage: 4*P Traceback (most recent call last): @@ -731,8 +737,8 @@ def __neg__(self): sage: [type(c) for c in -EllipticCurve('37a1').gen(0)] [<... 'sage.rings.rational.Rational'>, - <... 'sage.rings.rational.Rational'>, - <... 'sage.rings.rational.Rational'>] + <... 'sage.rings.rational.Rational'>, + <... 'sage.rings.rational.Rational'>] """ if self.is_zero(): return self @@ -743,7 +749,7 @@ def __neg__(self): def xy(self): """ Return the `x` and `y` coordinates of this point, as a 2-tuple. - If this is the point at infinity a ZeroDivisionError is raised. + If this is the point at infinity, a :class:`ZeroDivisionError` is raised. EXAMPLES:: @@ -795,43 +801,43 @@ def is_divisible_by(self, m): A finite field example:: - sage: E = EllipticCurve(GF(101),[23,34]) - sage: E.cardinality().factor() + sage: E = EllipticCurve(GF(101), [23,34]) # optional - sage.rings.finite_rings + sage: E.cardinality().factor() # optional - sage.rings.finite_rings 2 * 53 - sage: Set([T.order() for T in E.points()]) + sage: Set([T.order() for T in E.points()]) # optional - sage.rings.finite_rings {1, 106, 2, 53} - sage: len([T for T in E.points() if T.is_divisible_by(2)]) + sage: len([T for T in E.points() if T.is_divisible_by(2)]) # optional - sage.rings.finite_rings 53 - sage: len([T for T in E.points() if T.is_divisible_by(3)]) + sage: len([T for T in E.points() if T.is_divisible_by(3)]) # optional - sage.rings.finite_rings 106 TESTS: This shows that the bug reported at :trac:`10076` is fixed:: - sage: K = QuadraticField(8,'a') - sage: E = EllipticCurve([K(0),0,0,-1,0]) - sage: P = E([-1,0]) - sage: P.is_divisible_by(2) + sage: K = QuadraticField(8,'a') # optional - sage.rings.number_field + sage: E = EllipticCurve([K(0),0,0,-1,0]) # optional - sage.rings.number_field + sage: P = E([-1,0]) # optional - sage.rings.number_field + sage: P.is_divisible_by(2) # optional - sage.rings.number_field False - sage: P.division_points(2) + sage: P.division_points(2) # optional - sage.rings.number_field [] Note that it is not sufficient to test that ``self.division_points(m,poly_only=True)`` has roots:: - sage: P.division_points(2, poly_only=True).roots() + sage: P.division_points(2, poly_only=True).roots() # optional - sage.rings.number_field [(1/2*a - 1, 1), (-1/2*a - 1, 1)] - sage: tor = E.torsion_points(); len(tor) + sage: tor = E.torsion_points(); len(tor) # optional - sage.rings.number_field 8 - sage: [T.order() for T in tor] + sage: [T.order() for T in tor] # optional - sage.rings.number_field [2, 4, 4, 2, 1, 2, 4, 4] - sage: all(T.is_divisible_by(3) for T in tor) + sage: all(T.is_divisible_by(3) for T in tor) # optional - sage.rings.number_field True - sage: sorted(T for T in tor if T.is_divisible_by(2)) + sage: sorted(T for T in tor if T.is_divisible_by(2)) # optional - sage.rings.number_field [(0 : 1 : 0), (1 : 0 : 1)] - sage: sorted(Set([2*T for T in tor])) + sage: sorted(Set([2*T for T in tor])) # optional - sage.rings.number_field [(0 : 1 : 0), (1 : 0 : 1)] """ # Coerce the input m to an integer @@ -885,7 +891,7 @@ def is_divisible_by(self, m): def division_points(self, m, poly_only=False): r""" - Return a list of all points `Q` such that `mQ=P` where `P` = self. + Return a list of all points `Q` such that `mQ=P` where `P` = ``self``. Only points on the elliptic curve containing self and defined over the base field are included. @@ -896,7 +902,7 @@ def division_points(self, m, poly_only=False): - ``poly_only`` -- bool (default: False); if True return polynomial whose roots give all possible `x`-coordinates of - `m`-th roots of self. + `m`-th roots of ``self``. OUTPUT: @@ -926,63 +932,64 @@ def division_points(self, m, poly_only=False): We create a curve over a non-prime finite field with group of order `18`:: - sage: k. = GF((5,2)) - sage: E = EllipticCurve(k, [1,2+a,3,4*a,2]) - sage: P = E([3,3*a+4]) - sage: factor(E.order()) + sage: k. = GF((5,2)) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(k, [1,2+a,3,4*a,2]) # optional - sage.rings.finite_rings + sage: P = E([3, 3*a+4]) # optional - sage.rings.finite_rings + sage: factor(E.order()) # optional - sage.rings.finite_rings 2 * 3^2 - sage: P.order() + sage: P.order() # optional - sage.rings.finite_rings 9 We find the `1`-division points as a consistency check -- there is just one, of course:: - sage: P.division_points(1) + sage: P.division_points(1) # optional - sage.rings.finite_rings [(3 : 3*a + 4 : 1)] The point `P` has order coprime to 2 but divisible by 3, so:: - sage: P.division_points(2) + sage: P.division_points(2) # optional - sage.rings.finite_rings [(2*a + 1 : 3*a + 4 : 1), (3*a + 1 : a : 1)] We check that each of the 2-division points works as claimed:: - sage: [2*Q for Q in P.division_points(2)] + sage: [2*Q for Q in P.division_points(2)] # optional - sage.rings.finite_rings [(3 : 3*a + 4 : 1), (3 : 3*a + 4 : 1)] Some other checks:: - sage: P.division_points(3) + sage: P.division_points(3) # optional - sage.rings.finite_rings [] - sage: P.division_points(4) + sage: P.division_points(4) # optional - sage.rings.finite_rings [(0 : 3*a + 2 : 1), (1 : 0 : 1)] - sage: P.division_points(5) + sage: P.division_points(5) # optional - sage.rings.finite_rings [(1 : 1 : 1)] An example over a number field (see :trac:`3383`):: sage: E = EllipticCurve('19a1') - sage: K. = NumberField(x^9-3*x^8-4*x^7+16*x^6-3*x^5-21*x^4+5*x^3+7*x^2-7*x+1) - sage: EK = E.base_extend(K) - sage: E(0).division_points(3) + sage: K. = NumberField(x^9 - 3*x^8 - 4*x^7 + 16*x^6 - 3*x^5 # optional - sage.rings.number_field + ....: - 21*x^4 + 5*x^3 + 7*x^2 - 7*x + 1) + sage: EK = E.base_extend(K) # optional - sage.rings.number_field + sage: E(0).division_points(3) # optional - sage.rings.number_field [(0 : 1 : 0), (5 : -10 : 1), (5 : 9 : 1)] - sage: EK(0).division_points(3) + sage: EK(0).division_points(3) # optional - sage.rings.number_field [(0 : 1 : 0), (5 : 9 : 1), (5 : -10 : 1)] - sage: E(0).division_points(9) + sage: E(0).division_points(9) # optional - sage.rings.number_field [(0 : 1 : 0), (5 : -10 : 1), (5 : 9 : 1)] - sage: EK(0).division_points(9) + sage: EK(0).division_points(9) # optional - sage.rings.number_field [(0 : 1 : 0), (5 : 9 : 1), (5 : -10 : 1), (-150/121*t^8 + 414/121*t^7 + 1481/242*t^6 - 2382/121*t^5 - 103/242*t^4 + 629/22*t^3 - 367/242*t^2 - 1307/121*t + 625/121 : 35/484*t^8 - 133/242*t^7 + 445/242*t^6 - 799/242*t^5 + 373/484*t^4 + 113/22*t^3 - 2355/484*t^2 - 753/242*t + 1165/484 : 1), (-150/121*t^8 + 414/121*t^7 + 1481/242*t^6 - 2382/121*t^5 - 103/242*t^4 + 629/22*t^3 - 367/242*t^2 - 1307/121*t + 625/121 : -35/484*t^8 + 133/242*t^7 - 445/242*t^6 + 799/242*t^5 - 373/484*t^4 - 113/22*t^3 + 2355/484*t^2 + 753/242*t - 1649/484 : 1), (-1383/484*t^8 + 970/121*t^7 + 3159/242*t^6 - 5211/121*t^5 + 37/484*t^4 + 654/11*t^3 - 909/484*t^2 - 4831/242*t + 6791/484 : 927/121*t^8 - 5209/242*t^7 - 8187/242*t^6 + 27975/242*t^5 - 1147/242*t^4 - 1729/11*t^3 + 1566/121*t^2 + 12873/242*t - 10871/242 : 1), (-1383/484*t^8 + 970/121*t^7 + 3159/242*t^6 - 5211/121*t^5 + 37/484*t^4 + 654/11*t^3 - 909/484*t^2 - 4831/242*t + 6791/484 : -927/121*t^8 + 5209/242*t^7 + 8187/242*t^6 - 27975/242*t^5 + 1147/242*t^4 + 1729/11*t^3 - 1566/121*t^2 - 12873/242*t + 10629/242 : 1), (-4793/484*t^8 + 6791/242*t^7 + 10727/242*t^6 - 18301/121*t^5 + 2347/484*t^4 + 2293/11*t^3 - 7311/484*t^2 - 17239/242*t + 26767/484 : 30847/484*t^8 - 21789/121*t^7 - 34605/121*t^6 + 117164/121*t^5 - 10633/484*t^4 - 29437/22*t^3 + 39725/484*t^2 + 55428/121*t - 176909/484 : 1), (-4793/484*t^8 + 6791/242*t^7 + 10727/242*t^6 - 18301/121*t^5 + 2347/484*t^4 + 2293/11*t^3 - 7311/484*t^2 - 17239/242*t + 26767/484 : -30847/484*t^8 + 21789/121*t^7 + 34605/121*t^6 - 117164/121*t^5 + 10633/484*t^4 + 29437/22*t^3 - 39725/484*t^2 - 55428/121*t + 176425/484 : 1)] TESTS: Check that :trac:`24844` is fixed:: - sage: p = next_prime(1000000) - sage: E = EllipticCurve(GF(p), 123, 456) - sage: pts = E(0).division_points(3) - sage: P = pts[1]; P + sage: p = next_prime(1000000) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(GF(p), 123, 456) # optional - sage.rings.finite_rings + sage: pts = E(0).division_points(3) # optional - sage.rings.finite_rings + sage: P = pts[1]; P # optional - sage.rings.finite_rings (389063 : 124244 : 1) - sage: P._order + sage: P._order # optional - sage.rings.finite_rings 3 When we successfully divide a point known to have infinite @@ -993,7 +1000,7 @@ def division_points(self, m, poly_only=False): sage: P = E(-1,0) sage: P.order() +Infinity - sage: pts = P.division_points(3); len(pts) + sage: pts = P.division_points(3); len(pts) 1 sage: [(Q,Q._order) for Q in pts] [((0 : -1 : 1), +Infinity)] @@ -1005,17 +1012,17 @@ def division_points(self, m, poly_only=False): sage: E = EllipticCurve([1, 0, 1, -19, 26]) sage: [(Q,Q._order) for Q in E(0).division_points(12)] [((-5 : 2 : 1), 2), - ((-2 : -7 : 1), 6), - ((-2 : 8 : 1), 6), - ((0 : 1 : 0), 1), - ((1 : -4 : 1), 6), - ((1 : 2 : 1), 6), - ((7/4 : -11/8 : 1), 2), - ((3 : -2 : 1), 2), - ((4 : -7 : 1), 3), - ((4 : 2 : 1), 3), - ((13 : -52 : 1), 6), - ((13 : 38 : 1), 6)] + ((-2 : -7 : 1), 6), + ((-2 : 8 : 1), 6), + ((0 : 1 : 0), 1), + ((1 : -4 : 1), 6), + ((1 : 2 : 1), 6), + ((7/4 : -11/8 : 1), 2), + ((3 : -2 : 1), 2), + ((4 : -7 : 1), 3), + ((4 : 2 : 1), 3), + ((13 : -52 : 1), 6), + ((13 : 38 : 1), 6)] sage: P = E(4,-7) sage: P.order() 3 @@ -1177,7 +1184,7 @@ def _divide_out(self, p): def set_order(self, value, *, check=True): r""" - Set the value of self._order to value. + Set the value of ``self._order`` to ``value``. Use this when you know a priori the order of this point to avoid a potentially expensive order calculation. @@ -1186,9 +1193,7 @@ def set_order(self, value, *, check=True): - ``value`` -- positive integer - OUTPUT: - - ``None`` + OUTPUT: ``None`` EXAMPLES: @@ -1196,10 +1201,10 @@ def set_order(self, value, *, check=True): :: - sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 12 - sage: G = E(5, 0) - sage: G.set_order(2) - sage: 2*G + sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 12 # optional - sage.rings.finite_rings + sage: G = E(5, 0) # optional - sage.rings.finite_rings + sage: G.set_order(2) # optional - sage.rings.finite_rings + sage: 2*G # optional - sage.rings.finite_rings (0 : 1 : 0) We now give a more interesting case, the NIST-P521 curve. Its @@ -1210,27 +1215,27 @@ def set_order(self, value, *, check=True): sage: p = 2^521 - 1 sage: prev_proof_state = proof.arithmetic() - sage: proof.arithmetic(False) # turn off primality checking - sage: F = GF(p) + sage: proof.arithmetic(False) # turn off primality checking + sage: F = GF(p) # optional - sage.rings.finite_rings sage: A = p - 3 sage: B = 1093849038073734274511112390766805569936207598951683748994586394495953116150735016013708737573759623248592132296706313309438452531591012912142327488478985984 sage: q = 6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449 - sage: E = EllipticCurve([F(A), F(B)]) - sage: G = E.random_point() - sage: G.set_order(q) - sage: G.order() * G # This takes practically no time. + sage: E = EllipticCurve([F(A), F(B)]) # optional - sage.rings.finite_rings + sage: G = E.random_point() # optional - sage.rings.finite_rings + sage: G.set_order(q) # optional - sage.rings.finite_rings + sage: G.order() * G # This takes practically no time. # optional - sage.rings.finite_rings (0 : 1 : 0) sage: proof.arithmetic(prev_proof_state) # restore state It is an error to pass a `value` equal to `0`:: - sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 12 - sage: G = E.random_point() - sage: G.set_order(0) + sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 12 # optional - sage.rings.finite_rings + sage: G = E.random_point() # optional - sage.rings.finite_rings + sage: G.set_order(0) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Value 0 illegal for point order - sage: G.set_order(1000) + sage: G.set_order(1000) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Value 1000 illegal: outside max Hasse bound @@ -1239,26 +1244,26 @@ def set_order(self, value, *, check=True): order of this point. How unlikely is determined by the factorization of the actual order, and the actual group structure:: - sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 12 - sage: G = E(5, 0) # G has order 2 - sage: G.set_order(11) + sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 12 # optional - sage.rings.finite_rings + sage: G = E(5, 0) # G has order 2 # optional - sage.rings.finite_rings + sage: G.set_order(11) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Value 11 illegal: 11 * (5 : 0 : 1) is not the identity - However, set_order can be fooled, though it's not likely in "real cases + However, ``set_order`` can be fooled, though it's not likely in "real cases of interest". For instance, the order can be set to a multiple the actual order:: - sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 12 - sage: G = E(5, 0) # G has order 2 - sage: G.set_order(8) - sage: G.order() + sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 12 # optional - sage.rings.finite_rings + sage: G = E(5, 0) # G has order 2 # optional - sage.rings.finite_rings + sage: G.set_order(8) # optional - sage.rings.finite_rings + sage: G.order() # optional - sage.rings.finite_rings 8 AUTHORS: - - Mariah Lenox (2011-02-16) + - Mariah Lenox (2011-02-16) """ value = Integer(value) @@ -1292,27 +1297,27 @@ def _line_(self, R, Q): EXAMPLES:: - sage: F.=GF((2,5)) - sage: E=EllipticCurve(F,[0,0,1,1,1]) - sage: P = E(a^4 + 1, a^3) - sage: Q = E(a^4, a^4 + a^3) - sage: O = E(0) - sage: P._line_(P,-2*P) == 0 + sage: F. = GF((2,5)) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F,[0,0,1,1,1]) # optional - sage.rings.finite_rings + sage: P = E(a^4 + 1, a^3) # optional - sage.rings.finite_rings + sage: Q = E(a^4, a^4 + a^3) # optional - sage.rings.finite_rings + sage: O = E(0) # optional - sage.rings.finite_rings + sage: P._line_(P,-2*P) == 0 # optional - sage.rings.finite_rings True - sage: P._line_(Q,-(P+Q)) == 0 + sage: P._line_(Q,-(P+Q)) == 0 # optional - sage.rings.finite_rings True - sage: O._line_(O,Q) == F(1) + sage: O._line_(O,Q) == F(1) # optional - sage.rings.finite_rings True - sage: P._line_(O,Q) == a^4 - a^4 + 1 + sage: P._line_(O,Q) == a^4 - a^4 + 1 # optional - sage.rings.finite_rings True - sage: P._line_(13*P,Q) == a^4 + sage: P._line_(13*P,Q) == a^4 # optional - sage.rings.finite_rings True - sage: P._line_(P,Q) == a^4 + a^3 + a^2 + 1 + sage: P._line_(P,Q) == a^4 + a^3 + a^2 + 1 # optional - sage.rings.finite_rings True See :trac:`7116`:: - sage: P._line_ (Q,O) + sage: P._line_ (Q,O) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Q must be nonzero. @@ -1365,123 +1370,125 @@ def _miller_(self, Q, n): OUTPUT: - An element in the base field self.curve().base_field() - A ValueError is raised if `Q` is zero. + An element in the base field ``self.curve().base_field()``. + A :class:`ValueError` is raised if `Q` is zero. EXAMPLES:: - sage: F.=GF((2,5)) - sage: E=EllipticCurve(F,[0,0,1,1,1]) - sage: P = E(a^4 + 1, a^3) - sage: Fx.=GF((2,(4*5))) - sage: Ex=EllipticCurve(Fx,[0,0,1,1,1]) - sage: phi=Hom(F,Fx)(F.gen().minpoly().roots(Fx)[0][0]) - sage: Px=Ex(phi(P.xy()[0]),phi(P.xy()[1])) - sage: Qx = Ex(b^19 + b^18 + b^16 + b^12 + b^10 + b^9 + b^8 + b^5 + b^3 + 1, b^18 + b^13 + b^10 + b^8 + b^5 + b^4 + b^3 + b) - sage: Px._miller_(Qx,41) == b^17 + b^13 + b^12 + b^9 + b^8 + b^6 + b^4 + 1 + sage: F. = GF((2,5)) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [0,0,1,1,1]) # optional - sage.rings.finite_rings + sage: P = E(a^4 + 1, a^3) # optional - sage.rings.finite_rings + sage: Fx. = GF((2,(4*5))) # optional - sage.rings.finite_rings + sage: Ex = EllipticCurve(Fx, [0,0,1,1,1]) # optional - sage.rings.finite_rings + sage: phi = Hom(F,Fx)(F.gen().minpoly().roots(Fx)[0][0]) # optional - sage.rings.finite_rings + sage: Px = Ex(phi(P.xy()[0]), phi(P.xy()[1])) # optional - sage.rings.finite_rings + sage: Qx = Ex(b^19 + b^18 + b^16 + b^12 + b^10 + b^9 + b^8 + b^5 + b^3 + 1, # optional - sage.rings.finite_rings + ....: b^18 + b^13 + b^10 + b^8 + b^5 + b^4 + b^3 + b) + sage: Px._miller_(Qx,41) == b^17 + b^13 + b^12 + b^9 + b^8 + b^6 + b^4 + 1 # optional - sage.rings.finite_rings True - sage: Qx._miller_(Px,41) == b^13 + b^10 + b^8 + b^7 + b^6 + b^5 + sage: Qx._miller_(Px,41) == b^13 + b^10 + b^8 + b^7 + b^6 + b^5 # optional - sage.rings.finite_rings True - sage: P._miller_(E(0),41) + sage: P._miller_(E(0),41) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Q must be nonzero. An example of even order:: - sage: F. = GF((19,4)) - sage: E = EllipticCurve(F,[-1,0]) - sage: P = E(15*a^3 + 17*a^2 + 14*a + 13,16*a^3 + 7*a^2 + a + 18) - sage: Q = E(10*a^3 + 16*a^2 + 4*a + 2, 6*a^3 + 4*a^2 + 3*a + 2) - sage: x=P.weil_pairing(Q,360) - sage: x^360 == F(1) + sage: F. = GF((19,4)) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [-1,0]) # optional - sage.rings.finite_rings + sage: P = E(15*a^3 + 17*a^2 + 14*a + 13,16*a^3 + 7*a^2 + a + 18) # optional - sage.rings.finite_rings + sage: Q = E(10*a^3 + 16*a^2 + 4*a + 2, 6*a^3 + 4*a^2 + 3*a + 2) # optional - sage.rings.finite_rings + sage: x = P.weil_pairing(Q, 360) # optional - sage.rings.finite_rings + sage: x^360 == F(1) # optional - sage.rings.finite_rings True You can use the _miller_ function on linearly dependent points, but with the risk of a dividing with zero:: - sage: Px._miller_(2*Px,41) + sage: Px._miller_(2*Px, 41) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: division by zero in finite field A small example of embedding degree 6:: - sage: q = 401; F = GF(q); a = 146; b = 400; k = 6 - sage: E = EllipticCurve([F(a), F(b)]) - sage: R. = F[]; K. = GF(q^k, modulus=x^6 + 4*x^4 + 115*x^3 + 81*x^2 + 51*x + 3) - sage: EK = E.base_extend(K) - sage: P = E([F(338), F(227)]) - sage: Q_x = 333*a^5 + 391*a^4 + 160*a^3 + 335*a^2 + 71*a + 93 - sage: Q_y = 343*a^5 + 273*a^4 + 26*a^3 + 342*a^2 + 340*a + 210 - sage: Q = EK([Q_x, Q_y]) - sage: P._miller_(Q, 127) + sage: q = 401; F = GF(q); a = 146; b = 400; k = 6 # optional - sage.rings.finite_rings + sage: E = EllipticCurve([F(a), F(b)]) # optional - sage.rings.finite_rings + sage: R. = F[] # optional - sage.rings.finite_rings + sage: K. = GF(q^k, modulus=x^6 + 4*x^4 + 115*x^3 + 81*x^2 + 51*x + 3) # optional - sage.rings.finite_rings + sage: EK = E.base_extend(K) # optional - sage.rings.finite_rings + sage: P = E([F(338), F(227)]) # optional - sage.rings.finite_rings + sage: Q_x = 333*a^5 + 391*a^4 + 160*a^3 + 335*a^2 + 71*a + 93 # optional - sage.rings.finite_rings + sage: Q_y = 343*a^5 + 273*a^4 + 26*a^3 + 342*a^2 + 340*a + 210 # optional - sage.rings.finite_rings + sage: Q = EK([Q_x, Q_y]) # optional - sage.rings.finite_rings + sage: P._miller_(Q, 127) # optional - sage.rings.finite_rings 371*a^5 + 39*a^4 + 355*a^3 + 233*a^2 + 20*a + 275 A series of small examples and small torsions. We start with `n=1`, which is trivial: the function is the constant 1:: - sage: E = EllipticCurve([GF(7)(0), 2]) - sage: P = E(5, 1); Q = E(0, 3); I = E(0) - sage: I._miller_(P, 1) + sage: E = EllipticCurve([GF(7)(0), 2]) # optional - sage.rings.finite_rings + sage: P = E(5, 1); Q = E(0, 3); I = E(0) # optional - sage.rings.finite_rings + sage: I._miller_(P, 1) # optional - sage.rings.finite_rings 1 - sage: I._miller_(Q, 1) + sage: I._miller_(Q, 1) # optional - sage.rings.finite_rings 1 A two-torsion example. In this case `f_{n,P}(Q) = x_Q - x_P`:: - sage: E = EllipticCurve([GF(7)(-1), 0]) - sage: P = E(0,0); Q = E(1, 0); - sage: P._miller_(P, 2) + sage: E = EllipticCurve([GF(7)(-1), 0]) # optional - sage.rings.finite_rings + sage: P = E(0,0); Q = E(1, 0); # optional - sage.rings.finite_rings + sage: P._miller_(P, 2) # optional - sage.rings.finite_rings 0 - sage: Q._miller_(Q, 2) + sage: Q._miller_(Q, 2) # optional - sage.rings.finite_rings 0 - sage: P._miller_(Q, 2) + sage: P._miller_(Q, 2) # optional - sage.rings.finite_rings 1 - sage: Q._miller_(P, 2) + sage: Q._miller_(P, 2) # optional - sage.rings.finite_rings 6 A three-torsion example:: - sage: E = EllipticCurve([GF(7)(0), 2]) - sage: P = E(5, 1); Q = E(0, 3); - sage: P._miller_(Q, 3) + sage: E = EllipticCurve([GF(7)(0), 2]) # optional - sage.rings.finite_rings + sage: P = E(5, 1); Q = E(0, 3); # optional - sage.rings.finite_rings + sage: P._miller_(Q, 3) # optional - sage.rings.finite_rings 4 A 4-torsion example:: - sage: E = EllipticCurve([GF(7)(-1), 0]) - sage: P = E(5, 1); Q = E(4, 2) - sage: P._miller_(Q, 4) + sage: E = EllipticCurve([GF(7)(-1), 0]) # optional - sage.rings.finite_rings + sage: P = E(5, 1); Q = E(4, 2) # optional - sage.rings.finite_rings + sage: P._miller_(Q, 4) # optional - sage.rings.finite_rings 3 A 5-torsion example:: - sage: E = EllipticCurve([GF(7)(-1), 4]) - sage: P = E(4, 1); Q = E(6, 5) - sage: P._miller_(Q, 5) + sage: E = EllipticCurve([GF(7)(-1), 4]) # optional - sage.rings.finite_rings + sage: P = E(4, 1); Q = E(6, 5) # optional - sage.rings.finite_rings + sage: P._miller_(Q, 5) # optional - sage.rings.finite_rings 1 A 6-torsion example:: - sage: E = EllipticCurve([GF(7)(3), 1]) - sage: P = E(5, 1); Q = E(3, 3) - sage: P._miller_(Q, 6) + sage: E = EllipticCurve([GF(7)(3), 1]) # optional - sage.rings.finite_rings + sage: P = E(5, 1); Q = E(3, 3) # optional - sage.rings.finite_rings + sage: P._miller_(Q, 6) # optional - sage.rings.finite_rings 5 An example which is part of an ate pairing calculation. The trace of the curve is negative, so it should exercise the `n<0` case in the code:: - sage: p = 2017; A = 1; B = 30; r = 29; t = -70; k = 7; - sage: F = GF(p); R. = F[] - sage: E = EllipticCurve([F(A), F(B)]); P = E(369, 716) - sage: K. = GF(p^k, modulus=x^k+2); EK = E.base_extend(K) - sage: Qx = 1226*a^6 + 1778*a^5 + 660*a^4 + 1791*a^3 + 1750*a^2 + 867*a + 770 - sage: Qy = 1764*a^6 + 198*a^5 + 1206*a^4 + 406*a^3 + 1200*a^2 + 273*a + 1712 - sage: Q = EK(Qx, Qy) - sage: Q._miller_(P, t-1) + sage: p = 2017; A = 1; B = 30; r = 29; t = -70; k = 7 + sage: F = GF(p); R. = F[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve([F(A), F(B)]); P = E(369, 716) # optional - sage.rings.finite_rings + sage: K. = GF(p^k, modulus=x^k+2); EK = E.base_extend(K) # optional - sage.rings.finite_rings + sage: Qx = 1226*a^6 + 1778*a^5 + 660*a^4 + 1791*a^3 + 1750*a^2 + 867*a + 770 # optional - sage.rings.finite_rings + sage: Qy = 1764*a^6 + 198*a^5 + 1206*a^4 + 406*a^3 + 1200*a^2 + 273*a + 1712 # optional - sage.rings.finite_rings + sage: Q = EK(Qx, Qy) # optional - sage.rings.finite_rings + sage: Q._miller_(P, t - 1) # optional - sage.rings.finite_rings 1311*a^6 + 1362*a^5 + 1177*a^4 + 807*a^3 + 1331*a^2 + 1530*a + 1931 ALGORITHM: @@ -1549,64 +1556,66 @@ def weil_pairing(self, Q, n, algorithm=None): EXAMPLES:: - sage: F.=GF((2,5)) - sage: E=EllipticCurve(F,[0,0,1,1,1]) - sage: P = E(a^4 + 1, a^3) - sage: Fx.=GF((2,4*5)) - sage: Ex=EllipticCurve(Fx,[0,0,1,1,1]) - sage: phi=Hom(F,Fx)(F.gen().minpoly().roots(Fx)[0][0]) - sage: Px=Ex(phi(P.xy()[0]),phi(P.xy()[1])) - sage: O = Ex(0) - sage: Qx = Ex(b^19 + b^18 + b^16 + b^12 + b^10 + b^9 + b^8 + b^5 + b^3 + 1, b^18 + b^13 + b^10 + b^8 + b^5 + b^4 + b^3 + b) - sage: Px.weil_pairing(Qx,41) == b^19 + b^15 + b^9 + b^8 + b^6 + b^4 + b^3 + b^2 + 1 + sage: F. = GF((2,5)) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [0,0,1,1,1]) # optional - sage.rings.finite_rings + sage: P = E(a^4 + 1, a^3) # optional - sage.rings.finite_rings + sage: Fx. = GF((2, 4*5)) # optional - sage.rings.finite_rings + sage: Ex = EllipticCurve(Fx, [0,0,1,1,1]) # optional - sage.rings.finite_rings + sage: phi = Hom(F, Fx)(F.gen().minpoly().roots(Fx)[0][0]) # optional - sage.rings.finite_rings + sage: Px = Ex(phi(P.xy()[0]), phi(P.xy()[1])) # optional - sage.rings.finite_rings + sage: O = Ex(0) # optional - sage.rings.finite_rings + sage: Qx = Ex(b^19 + b^18 + b^16 + b^12 + b^10 + b^9 + b^8 + b^5 + b^3 + 1, # optional - sage.rings.finite_rings + ....: b^18 + b^13 + b^10 + b^8 + b^5 + b^4 + b^3 + b) + sage: Px.weil_pairing(Qx, 41) == b^19 + b^15 + b^9 + b^8 + b^6 + b^4 + b^3 + b^2 + 1 # optional - sage.rings.finite_rings True - sage: Px.weil_pairing(17*Px,41) == Fx(1) + sage: Px.weil_pairing(17*Px, 41) == Fx(1) # optional - sage.rings.finite_rings True - sage: Px.weil_pairing(O,41) == Fx(1) + sage: Px.weil_pairing(O, 41) == Fx(1) # optional - sage.rings.finite_rings True An error is raised if either point is not `n`-torsion:: - sage: Px.weil_pairing(O,40) + sage: Px.weil_pairing(O, 40) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: points must both be n-torsion A larger example (see :trac:`4964`):: - sage: P,Q = EllipticCurve(GF((19,4),'a'),[-1,0]).gens() - sage: P.order(), Q.order() + sage: P, Q = EllipticCurve(GF((19,4),'a'), [-1,0]).gens() # optional - sage.rings.finite_rings + sage: P.order(), Q.order() # optional - sage.rings.finite_rings (360, 360) - sage: z = P.weil_pairing(Q,360) - sage: z.multiplicative_order() + sage: z = P.weil_pairing(Q, 360) # optional - sage.rings.finite_rings + sage: z.multiplicative_order() # optional - sage.rings.finite_rings 360 An example over a number field:: - sage: P,Q = EllipticCurve('11a1').change_ring(CyclotomicField(5)).torsion_subgroup().gens() - sage: P,Q = (P.element(), Q.element()) - sage: (P.order(),Q.order()) + sage: E = EllipticCurve('11a1').change_ring(CyclotomicField(5)) # optional - sage.rings.number_field + sage: P, Q = E.torsion_subgroup().gens() # optional - sage.rings.number_field + sage: P, Q = (P.element(), Q.element()) # optional - sage.rings.number_field + sage: (P.order(), Q.order()) # optional - sage.rings.number_field (5, 5) - sage: P.weil_pairing(Q,5) + sage: P.weil_pairing(Q, 5) # optional - sage.rings.number_field zeta5^2 - sage: Q.weil_pairing(P,5) + sage: Q.weil_pairing(P, 5) # optional - sage.rings.number_field zeta5^3 TESTS: Check that the original Sage implementation still works:: - sage: GF(65537^2).inject_variables() + sage: GF(65537^2).inject_variables() # optional - sage.rings.finite_rings Defining z2 - sage: E = EllipticCurve(GF(65537^2), [0,1]) - sage: P = E(22, 28891) - sage: Q = E(-93, 40438*z2 + 31573) - sage: P.weil_pairing(Q, 7282, algorithm='sage') + sage: E = EllipticCurve(GF(65537^2), [0,1]) # optional - sage.rings.finite_rings + sage: P = E(22, 28891) # optional - sage.rings.finite_rings + sage: Q = E(-93, 40438*z2 + 31573) # optional - sage.rings.finite_rings + sage: P.weil_pairing(Q, 7282, algorithm='sage') # optional - sage.rings.finite_rings 19937*z2 + 65384 Passing an unknown ``algorithm=`` argument should fail:: - sage: P.weil_pairing(Q, 7282, algorithm='_invalid_') + sage: P.weil_pairing(Q, 7282, algorithm='_invalid_') # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: unknown algorithm @@ -1618,7 +1627,7 @@ def weil_pairing(self, Q, n, algorithm=None): - For ``algorithm='sage'``: Implemented using Proposition 8 in [Mil2004]_. The value 1 is returned for linearly dependent input points. This condition - is caught via a DivisionByZeroError, since the use of a + is caught via a :class:`ZeroDivisionError`, since the use of a discrete logarithm test for linear dependence is much too slow for large `n`. @@ -1718,87 +1727,89 @@ def tate_pairing(self, Q, n, k, q=None): OUTPUT: - An `n`'th root of unity in the base field self.curve().base_field() + An `n`'th root of unity in the base field ``self.curve().base_field()`` EXAMPLES: A simple example, pairing a point with itself, and pairing a point with another rational point:: - sage: p = 103; A = 1; B = 18; E = EllipticCurve(GF(p), [A, B]) - sage: P = E(33, 91); n = P.order(); n + sage: p = 103; A = 1; B = 18; E = EllipticCurve(GF(p), [A, B]) # optional - sage.rings.finite_rings + sage: P = E(33, 91); n = P.order(); n # optional - sage.rings.finite_rings 19 - sage: k = GF(n)(p).multiplicative_order(); k + sage: k = GF(n)(p).multiplicative_order(); k # optional - sage.rings.finite_rings 6 - sage: P.tate_pairing(P, n, k) + sage: P.tate_pairing(P, n, k) # optional - sage.rings.finite_rings 1 - sage: Q = E(87, 51) - sage: P.tate_pairing(Q, n, k) + sage: Q = E(87, 51) # optional - sage.rings.finite_rings + sage: P.tate_pairing(Q, n, k) # optional - sage.rings.finite_rings 1 sage: set_random_seed(35) - sage: P.tate_pairing(P,n,k) + sage: P.tate_pairing(P, n, k) # optional - sage.rings.finite_rings 1 - We now let Q be a point on the same curve as above, but defined over + We now let `Q` be a point on the same curve as above, but defined over the pairing extension field, and we also demonstrate the bilinearity of the pairing:: - sage: K. = GF((p,k)) - sage: EK = E.base_extend(K); P = EK(P) - sage: Qx = 69*a^5 + 96*a^4 + 22*a^3 + 86*a^2 + 6*a + 35 - sage: Qy = 34*a^5 + 24*a^4 + 16*a^3 + 41*a^2 + 4*a + 40 - sage: Q = EK(Qx, Qy); + sage: K. = GF((p,k)) # optional - sage.rings.finite_rings + sage: EK = E.base_extend(K); P = EK(P) # optional - sage.rings.finite_rings + sage: Qx = 69*a^5 + 96*a^4 + 22*a^3 + 86*a^2 + 6*a + 35 # optional - sage.rings.finite_rings + sage: Qy = 34*a^5 + 24*a^4 + 16*a^3 + 41*a^2 + 4*a + 40 # optional - sage.rings.finite_rings + sage: Q = EK(Qx, Qy); # optional - sage.rings.finite_rings Multiply by cofactor so Q has order n:: - sage: h = 551269674; Q = h*Q - sage: P = EK(P); P.tate_pairing(Q, n, k) + sage: h = 551269674; Q = h*Q # optional - sage.rings.finite_rings + sage: P = EK(P); P.tate_pairing(Q, n, k) # optional - sage.rings.finite_rings 24*a^5 + 34*a^4 + 3*a^3 + 69*a^2 + 86*a + 45 - sage: s = Integer(randrange(1,n)) - sage: ans1 = (s*P).tate_pairing(Q, n, k) - sage: ans2 = P.tate_pairing(s*Q, n, k) - sage: ans3 = P.tate_pairing(Q, n, k)^s - sage: ans1 == ans2 == ans3 + sage: s = Integer(randrange(1,n)) # optional - sage.rings.finite_rings + sage: ans1 = (s*P).tate_pairing(Q, n, k) # optional - sage.rings.finite_rings + sage: ans2 = P.tate_pairing(s*Q, n, k) # optional - sage.rings.finite_rings + sage: ans3 = P.tate_pairing(Q, n, k)^s # optional - sage.rings.finite_rings + sage: ans1 == ans2 == ans3 # optional - sage.rings.finite_rings True - sage: (ans1 != 1) and (ans1^n == 1) + sage: (ans1 != 1) and (ans1^n == 1) # optional - sage.rings.finite_rings True Here is an example of using the Tate pairing to compute the Weil pairing (using the same data as above):: - sage: e = Integer((p^k-1)/n); e + sage: e = Integer((p^k-1)/n); e # optional - sage.rings.finite_rings 62844857712 - sage: P.weil_pairing(Q, n)^e + sage: P.weil_pairing(Q, n)^e # optional - sage.rings.finite_rings 94*a^5 + 99*a^4 + 29*a^3 + 45*a^2 + 57*a + 34 - sage: P.tate_pairing(Q, n, k) == P._miller_(Q, n)^e + sage: P.tate_pairing(Q, n, k) == P._miller_(Q, n)^e # optional - sage.rings.finite_rings True - sage: Q.tate_pairing(P, n, k) == Q._miller_(P, n)^e + sage: Q.tate_pairing(P, n, k) == Q._miller_(P, n)^e # optional - sage.rings.finite_rings True - sage: P.tate_pairing(Q, n, k)/Q.tate_pairing(P, n, k) + sage: P.tate_pairing(Q, n, k)/Q.tate_pairing(P, n, k) # optional - sage.rings.finite_rings 94*a^5 + 99*a^4 + 29*a^3 + 45*a^2 + 57*a + 34 An example where we have to pass the base field size (and we again have agreement with the Weil pairing):: - sage: F.=GF((2,5)) - sage: E=EllipticCurve(F,[0,0,1,1,1]) - sage: P = E(a^4 + 1, a^3) - sage: Fx.=GF((2,4*5)) - sage: Ex=EllipticCurve(Fx,[0,0,1,1,1]) - sage: phi=Hom(F,Fx)(F.gen().minpoly().roots(Fx)[0][0]) - sage: Px=Ex(phi(P.xy()[0]),phi(P.xy()[1])) - sage: Qx = Ex(b^19+b^18+b^16+b^12+b^10+b^9+b^8+b^5+b^3+1, b^18+b^13+b^10+b^8+b^5+b^4+b^3+b) - sage: Px.tate_pairing(Qx, n=41, k=4) + sage: F. = GF((2,5)) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [0,0,1,1,1]) # optional - sage.rings.finite_rings + sage: P = E(a^4 + 1, a^3) # optional - sage.rings.finite_rings + sage: Fx. = GF((2,4*5)) # optional - sage.rings.finite_rings + sage: Ex = EllipticCurve(Fx,[0,0,1,1,1]) # optional - sage.rings.finite_rings + sage: phi = Hom(F, Fx)(F.gen().minpoly().roots(Fx)[0][0]) # optional - sage.rings.finite_rings + sage: Px = Ex(phi(P.xy()[0]), phi(P.xy()[1])) # optional - sage.rings.finite_rings + sage: Qx = Ex(b^19 + b^18 + b^16 + b^12 + b^10 + b^9 + b^8 + b^5 + b^3 + 1, # optional - sage.rings.finite_rings + ....: b^18 + b^13 + b^10 + b^8 + b^5 + b^4 + b^3 + b) + sage: Px.tate_pairing(Qx, n=41, k=4) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: Unexpected field degree: set keyword argument q equal to the size of the base field (big field is GF(q^4)). - sage: num = Px.tate_pairing(Qx, n=41, k=4, q=32); num + ValueError: Unexpected field degree: set keyword argument q equal to + the size of the base field (big field is GF(q^4)). + sage: num = Px.tate_pairing(Qx, n=41, k=4, q=32); num # optional - sage.rings.finite_rings b^19 + b^14 + b^13 + b^12 + b^6 + b^4 + b^3 - sage: den = Qx.tate_pairing(Px, n=41, k=4, q=32); den + sage: den = Qx.tate_pairing(Px, n=41, k=4, q=32); den # optional - sage.rings.finite_rings b^19 + b^17 + b^16 + b^15 + b^14 + b^10 + b^6 + b^2 + 1 - sage: e = Integer((32^4-1)/41); e + sage: e = Integer((32^4-1)/41); e # optional - sage.rings.finite_rings 25575 - sage: Px.weil_pairing(Qx, 41)^e == num/den + sage: Px.weil_pairing(Qx, 41)^e == num/den # optional - sage.rings.finite_rings True .. NOTE:: @@ -1807,7 +1818,7 @@ def tate_pairing(self, Q, n, k, q=None): exponentiation. It does not do anything fancy. In the case that there is an issue with `Q` being on one of the lines generated in the `r*P` calculation, `Q` is offset by a random - point `R` and P.tate_pairing(Q+R,n,k)/P.tate_pairing(R,n,k) + point `R` and ``P.tate_pairing(Q+R,n,k)/P.tate_pairing(R,n,k)`` is returned. AUTHORS: @@ -1848,7 +1859,7 @@ def tate_pairing(self, Q, n, k, q=None): def ate_pairing(self, Q, n, k, t, q=None): r""" - Return ate pairing of `n`-torsion points `P=self` and `Q`. + Return ate pairing of `n`-torsion points `P` (``=self``) and `Q`. Also known as the `n`-th modified ate pairing. `P` is `GF(q)`-rational, and `Q` must be an element of `Ker(\pi-p)`, where `\pi` is the @@ -1856,8 +1867,8 @@ def ate_pairing(self, Q, n, k, t, q=None): INPUT: - - ``P=self`` -- a point of order `n`, in `ker(\pi-1)`, where - `\pi` is the `q`-Frobenius map (e.g., `P` is `q-rational`). + - `P` (``=self``) -- a point of order `n`, in `ker(\pi-1)`, where + `\pi` is the `q`-Frobenius map (e.g., `P` is `q`-rational). - ``Q`` -- a point of order `n` in `ker(\pi-q)` @@ -1880,63 +1891,63 @@ def ate_pairing(self, Q, n, k, t, q=None): An example with embedding degree 6:: sage: p = 7549; A = 0; B = 1; n = 157; k = 6; t = 14 - sage: F = GF(p); E = EllipticCurve(F, [A, B]) - sage: R. = F[]; K. = GF((p,k), modulus=x^k+2) - sage: EK = E.base_extend(K) - sage: P = EK(3050, 5371); Q = EK(6908*a^4, 3231*a^3) - sage: P.ate_pairing(Q, n, k, t) + sage: F = GF(p); E = EllipticCurve(F, [A, B]) # optional - sage.rings.finite_rings + sage: R. = F[]; K. = GF((p,k), modulus=x^k+2) # optional - sage.rings.finite_rings + sage: EK = E.base_extend(K) # optional - sage.rings.finite_rings + sage: P = EK(3050, 5371); Q = EK(6908*a^4, 3231*a^3) # optional - sage.rings.finite_rings + sage: P.ate_pairing(Q, n, k, t) # optional - sage.rings.finite_rings 6708*a^5 + 4230*a^4 + 4350*a^3 + 2064*a^2 + 4022*a + 6733 - sage: s = Integer(randrange(1, n)) - sage: (s*P).ate_pairing(Q, n, k, t) == P.ate_pairing(s*Q, n, k, t) + sage: s = Integer(randrange(1, n)) # optional - sage.rings.finite_rings + sage: (s*P).ate_pairing(Q, n, k, t) == P.ate_pairing(s*Q, n, k, t) # optional - sage.rings.finite_rings True - sage: P.ate_pairing(s*Q, n, k, t) == P.ate_pairing(Q, n, k, t)^s + sage: P.ate_pairing(s*Q, n, k, t) == P.ate_pairing(Q, n, k, t)^s # optional - sage.rings.finite_rings True Another example with embedding degree 7 and positive trace:: sage: p = 2213; A = 1; B = 49; n = 1093; k = 7; t = 28 - sage: F = GF(p); E = EllipticCurve(F, [A, B]) - sage: R. = F[]; K. = GF((p,k), modulus=x^k+2) - sage: EK = E.base_extend(K) - sage: P = EK(1583, 1734) - sage: Qx = 1729*a^6+1767*a^5+245*a^4+980*a^3+1592*a^2+1883*a+722 - sage: Qy = 1299*a^6+1877*a^5+1030*a^4+1513*a^3+1457*a^2+309*a+1636 - sage: Q = EK(Qx, Qy) - sage: P.ate_pairing(Q, n, k, t) + sage: F = GF(p); E = EllipticCurve(F, [A, B]) # optional - sage.rings.finite_rings + sage: R. = F[]; K. = GF((p,k), modulus=x^k+2) # optional - sage.rings.finite_rings + sage: EK = E.base_extend(K) # optional - sage.rings.finite_rings + sage: P = EK(1583, 1734) # optional - sage.rings.finite_rings + sage: Qx = 1729*a^6+1767*a^5+245*a^4+980*a^3+1592*a^2+1883*a+722 # optional - sage.rings.finite_rings + sage: Qy = 1299*a^6+1877*a^5+1030*a^4+1513*a^3+1457*a^2+309*a+1636 # optional - sage.rings.finite_rings + sage: Q = EK(Qx, Qy) # optional - sage.rings.finite_rings + sage: P.ate_pairing(Q, n, k, t) # optional - sage.rings.finite_rings 1665*a^6 + 1538*a^5 + 1979*a^4 + 239*a^3 + 2134*a^2 + 2151*a + 654 - sage: s = Integer(randrange(1, n)) - sage: (s*P).ate_pairing(Q, n, k, t) == P.ate_pairing(s*Q, n, k, t) + sage: s = Integer(randrange(1, n)) # optional - sage.rings.finite_rings + sage: (s*P).ate_pairing(Q, n, k, t) == P.ate_pairing(s*Q, n, k, t) # optional - sage.rings.finite_rings True - sage: P.ate_pairing(s*Q, n, k, t) == P.ate_pairing(Q, n, k, t)^s + sage: P.ate_pairing(s*Q, n, k, t) == P.ate_pairing(Q, n, k, t)^s # optional - sage.rings.finite_rings True Another example with embedding degree 7 and negative trace:: sage: p = 2017; A = 1; B = 30; n = 29; k = 7; t = -70 - sage: F = GF(p); E = EllipticCurve(F, [A, B]) - sage: R. = F[]; K. = GF((p,k), modulus=x^k+2) - sage: EK = E.base_extend(K) - sage: P = EK(369, 716) - sage: Qx = 1226*a^6+1778*a^5+660*a^4+1791*a^3+1750*a^2+867*a+770 - sage: Qy = 1764*a^6+198*a^5+1206*a^4+406*a^3+1200*a^2+273*a+1712 - sage: Q = EK(Qx, Qy) - sage: P.ate_pairing(Q, n, k, t) + sage: F = GF(p); E = EllipticCurve(F, [A, B]) # optional - sage.rings.finite_rings + sage: R. = F[]; K. = GF((p,k), modulus=x^k+2) # optional - sage.rings.finite_rings + sage: EK = E.base_extend(K) # optional - sage.rings.finite_rings + sage: P = EK(369, 716) # optional - sage.rings.finite_rings + sage: Qx = 1226*a^6+1778*a^5+660*a^4+1791*a^3+1750*a^2+867*a+770 # optional - sage.rings.finite_rings + sage: Qy = 1764*a^6+198*a^5+1206*a^4+406*a^3+1200*a^2+273*a+1712 # optional - sage.rings.finite_rings + sage: Q = EK(Qx, Qy) # optional - sage.rings.finite_rings + sage: P.ate_pairing(Q, n, k, t) # optional - sage.rings.finite_rings 1794*a^6 + 1161*a^5 + 576*a^4 + 488*a^3 + 1950*a^2 + 1905*a + 1315 - sage: s = Integer(randrange(1, n)) - sage: (s*P).ate_pairing(Q, n, k, t) == P.ate_pairing(s*Q, n, k, t) + sage: s = Integer(randrange(1, n)) # optional - sage.rings.finite_rings + sage: (s*P).ate_pairing(Q, n, k, t) == P.ate_pairing(s*Q, n, k, t) # optional - sage.rings.finite_rings True - sage: P.ate_pairing(s*Q, n, k, t) == P.ate_pairing(Q, n, k, t)^s + sage: P.ate_pairing(s*Q, n, k, t) == P.ate_pairing(Q, n, k, t)^s # optional - sage.rings.finite_rings True Using the same data, we show that the ate pairing is a power of the Tate pairing (see [HSV2006]_ end of section 3.1):: - sage: c = (k*p^(k-1)).mod(n); T = t - 1 - sage: N = gcd(T^k - 1, p^k - 1) - sage: s = Integer(N/n) - sage: L = Integer((T^k - 1)/N) - sage: M = (L*s*c.inverse_mod(n)).mod(n) - sage: P.ate_pairing(Q, n, k, t) == Q.tate_pairing(P, n, k)^M + sage: c = (k*p^(k-1)).mod(n); T = t - 1 # optional - sage.rings.finite_rings + sage: N = gcd(T^k - 1, p^k - 1) # optional - sage.rings.finite_rings + sage: s = Integer(N/n) # optional - sage.rings.finite_rings + sage: L = Integer((T^k - 1)/N) # optional - sage.rings.finite_rings + sage: M = (L*s*c.inverse_mod(n)).mod(n) # optional - sage.rings.finite_rings + sage: P.ate_pairing(Q, n, k, t) == Q.tate_pairing(P, n, k)^M # optional - sage.rings.finite_rings True An example where we have to pass the base field size (and we again have @@ -1944,44 +1955,47 @@ def ate_pairing(self, Q, n, k, t, q=None): `F`-rational, (it is the homomorphic image of an `F`-rational point) it is nonetheless in `ker(\pi-1)`, and so is a legitimate input:: - sage: q = 2^5; F.=GF(q) - sage: n = 41; k = 4; t = -8 - sage: E=EllipticCurve(F,[0,0,1,1,1]) - sage: P = E(a^4 + 1, a^3) - sage: Fx.=GF(q^k) - sage: Ex=EllipticCurve(Fx,[0,0,1,1,1]) - sage: phi=Hom(F,Fx)(F.gen().minpoly().roots(Fx)[0][0]) - sage: Px=Ex(phi(P.xy()[0]),phi(P.xy()[1])) - sage: Qx = Ex(b^19+b^18+b^16+b^12+b^10+b^9+b^8+b^5+b^3+1, b^18+b^13+b^10+b^8+b^5+b^4+b^3+b) - sage: Qx = Ex(Qx[0]^q, Qx[1]^q) - Qx # ensure Qx is in ker(pi - q) - sage: Px.ate_pairing(Qx, n, k, t) + sage: q = 2^5; F. = GF(q) # optional - sage.rings.finite_rings + sage: n = 41; k = 4; t = -8 # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F,[0,0,1,1,1]) # optional - sage.rings.finite_rings + sage: P = E(a^4 + 1, a^3) # optional - sage.rings.finite_rings + sage: Fx. = GF(q^k) # optional - sage.rings.finite_rings + sage: Ex = EllipticCurve(Fx, [0,0,1,1,1]) # optional - sage.rings.finite_rings + sage: phi = Hom(F, Fx)(F.gen().minpoly().roots(Fx)[0][0]) # optional - sage.rings.finite_rings + sage: Px = Ex(phi(P.xy()[0]), phi(P.xy()[1])) # optional - sage.rings.finite_rings + sage: Qx = Ex(b^19+b^18+b^16+b^12+b^10+b^9+b^8+b^5+b^3+1, # optional - sage.rings.finite_rings + ....: b^18+b^13+b^10+b^8+b^5+b^4+b^3+b) + sage: Qx = Ex(Qx[0]^q, Qx[1]^q) - Qx # ensure Qx is in ker(pi - q) # optional - sage.rings.finite_rings + sage: Px.ate_pairing(Qx, n, k, t) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: Unexpected field degree: set keyword argument q equal to the size of the base field (big field is GF(q^4)). - sage: Px.ate_pairing(Qx, n, k, t, q) - b^19 + b^18 + b^17 + b^16 + b^15 + b^14 + b^13 + b^12 + b^11 + b^9 + b^8 + b^5 + b^4 + b^2 + b + 1 + ValueError: Unexpected field degree: set keyword argument q equal to + the size of the base field (big field is GF(q^4)). + sage: Px.ate_pairing(Qx, n, k, t, q) # optional - sage.rings.finite_rings + b^19 + b^18 + b^17 + b^16 + b^15 + b^14 + b^13 + b^12 + + b^11 + b^9 + b^8 + b^5 + b^4 + b^2 + b + 1 sage: s = Integer(randrange(1, n)) - sage: (s*Px).ate_pairing(Qx, n, k, t, q) == Px.ate_pairing(s*Qx, n, k, t, q) + sage: (s*Px).ate_pairing(Qx, n, k, t, q) == Px.ate_pairing(s*Qx, n, k, t, q) # optional - sage.rings.finite_rings True - sage: Px.ate_pairing(s*Qx, n, k, t, q) == Px.ate_pairing(Qx, n, k, t, q)^s + sage: Px.ate_pairing(s*Qx, n, k, t, q) == Px.ate_pairing(Qx, n, k, t, q)^s # optional - sage.rings.finite_rings True - sage: c = (k*q^(k-1)).mod(n); T = t - 1 - sage: N = gcd(T^k - 1, q^k - 1) - sage: s = Integer(N/n) - sage: L = Integer((T^k - 1)/N) - sage: M = (L*s*c.inverse_mod(n)).mod(n) - sage: Px.ate_pairing(Qx, n, k, t, q) == Qx.tate_pairing(Px, n, k, q)^M + sage: c = (k*q^(k-1)).mod(n); T = t - 1 # optional - sage.rings.finite_rings + sage: N = gcd(T^k - 1, q^k - 1) # optional - sage.rings.finite_rings + sage: s = Integer(N/n) # optional - sage.rings.finite_rings + sage: L = Integer((T^k - 1)/N) # optional - sage.rings.finite_rings + sage: M = (L*s*c.inverse_mod(n)).mod(n) # optional - sage.rings.finite_rings + sage: Px.ate_pairing(Qx, n, k, t, q) == Qx.tate_pairing(Px, n, k, q)^M # optional - sage.rings.finite_rings True It is an error if `Q` is not in the kernel of `\pi - p`, where `\pi` is the Frobenius automorphism:: - sage: p = 29; A = 1; B = 0; n = 5; k = 2; t = 10 - sage: F = GF(p); R. = F[] - sage: E = EllipticCurve(F, [A, B]); - sage: K. = GF((p,k), modulus=x^k+2); EK = E.base_extend(K) - sage: P = EK(13, 8); Q = EK(13, 21) - sage: P.ate_pairing(Q, n, k, t) + sage: p = 29; A = 1; B = 0; n = 5; k = 2; t = 10 # optional - sage.rings.finite_rings + sage: F = GF(p); R. = F[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [A, B]); # optional - sage.rings.finite_rings + sage: K. = GF((p,k), modulus=x^k+2); EK = E.base_extend(K) # optional - sage.rings.finite_rings + sage: P = EK(13, 8); Q = EK(13, 21) # optional - sage.rings.finite_rings + sage: P.ate_pairing(Q, n, k, t) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Point (13 : 21 : 1) not in Ker(pi - q) @@ -1989,11 +2003,11 @@ def ate_pairing(self, Q, n, k, t, q=None): It is also an error if `P` is not in the kernel os `\pi - 1`:: sage: p = 29; A = 1; B = 0; n = 5; k = 2; t = 10 - sage: F = GF(p); R. = F[] - sage: E = EllipticCurve(F, [A, B]); - sage: K. = GF((p,k), modulus=x^k+2); EK = E.base_extend(K) - sage: P = EK(14, 10*a); Q = EK(13, 21) - sage: P.ate_pairing(Q, n, k, t) + sage: F = GF(p); R. = F[] # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [A, B]); # optional - sage.rings.finite_rings + sage: K. = GF((p,k), modulus=x^k+2); EK = E.base_extend(K) # optional - sage.rings.finite_rings + sage: P = EK(14, 10*a); Q = EK(13, 21) # optional - sage.rings.finite_rings + sage: P.ate_pairing(Q, n, k, t) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: This point (14 : 10*a : 1) is not in Ker(pi - 1) @@ -2053,7 +2067,7 @@ class EllipticCurvePoint_number_field(EllipticCurvePoint_field): A point on an elliptic curve over a number field. Most of the functionality is derived from the parent class - ``EllipticCurvePoint_field``. In addition we have support for + :class:`EllipticCurvePoint_field`. In addition we have support for orders, heights, reduction modulo primes, and elliptic logarithms. EXAMPLES:: @@ -2063,7 +2077,7 @@ class EllipticCurvePoint_number_field(EllipticCurvePoint_field): (0 : 0 : 1) sage: E(0,0) # brackets are optional (0 : 0 : 1) - sage: E([GF(5)(0), 0]) # entries are coerced + sage: E([GF(5)(0), 0]) # entries are coerced # optional - sage.rings.finite_rings (0 : 0 : 1) sage: E(0.000, 0) @@ -2079,7 +2093,8 @@ class EllipticCurvePoint_number_field(EllipticCurvePoint_field): sage: E = EllipticCurve([0,0,1,-1,0]) sage: S = E(QQ); S - Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + Abelian group of points on + Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field TESTS:: @@ -2220,7 +2235,7 @@ def has_infinite_order(self): def is_on_identity_component(self, embedding=None): r""" - Returns True iff this point is on the identity component of + Return True iff this point is on the identity component of its curve with respect to a given (real or complex) embedding. INPUT: @@ -2241,26 +2256,27 @@ def is_on_identity_component(self, embedding=None): For `K=\QQ` there is no need to specify an embedding:: - sage: E=EllipticCurve('5077a1') + sage: E = EllipticCurve('5077a1') sage: [E.lift_x(x).is_on_identity_component() for x in srange(-3,5)] [False, False, False, False, False, True, True, True] An example over a field with two real embeddings:: - sage: L. = QuadraticField(2) - sage: E=EllipticCurve(L,[0,1,0,a,a]) - sage: P=E(-1,0) - sage: [P.is_on_identity_component(e) for e in L.embeddings(RR)] + sage: L. = QuadraticField(2) # optional - sage.rings.number_field + sage: E = EllipticCurve(L, [0,1,0,a,a]) # optional - sage.rings.number_field + sage: P = E(-1,0) # optional - sage.rings.number_field + sage: [P.is_on_identity_component(e) for e in L.embeddings(RR)] # optional - sage.rings.number_field [False, True] We can check this as follows:: - sage: [e(E.discriminant())>0 for e in L.embeddings(RR)] + sage: [e(E.discriminant()) > 0 for e in L.embeddings(RR)] # optional - sage.rings.number_field [True, False] - sage: e = L.embeddings(RR)[0] - sage: E1 = EllipticCurve(RR,[e(ai) for ai in E.ainvs()]) - sage: e1,e2,e3 = E1.two_division_polynomial().roots(RR,multiplicities=False) - sage: e1 < e2 < e3 and e(P[0]) < e3 + sage: e = L.embeddings(RR)[0] # optional - sage.rings.number_field + sage: E1 = EllipticCurve(RR, [e(ai) for ai in E.ainvs()]) # optional - sage.rings.number_field + sage: e1, e2, e3 = E1.two_division_polynomial().roots(RR, # optional - sage.rings.number_field + ....: multiplicities=False) + sage: e1 < e2 < e3 and e(P[0]) < e3 # optional - sage.rings.number_field True """ if self.is_zero(): # trivial case @@ -2331,21 +2347,21 @@ def has_good_reduction(self, P=None): :: - sage: K. = NumberField(x^2+1) - sage: E = EllipticCurve(K,[0,1,0,-160,308]) - sage: P = E(26,-120) - sage: E.discriminant().support() + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,1,0,-160,308]) # optional - sage.rings.number_field + sage: P = E(26, -120) # optional - sage.rings.number_field + sage: E.discriminant().support() # optional - sage.rings.number_field [Fractional ideal (i + 1), - Fractional ideal (-i - 2), - Fractional ideal (2*i + 1), - Fractional ideal (3)] - sage: [E.tamagawa_exponent(p) for p in E.discriminant().support()] + Fractional ideal (-i - 2), + Fractional ideal (2*i + 1), + Fractional ideal (3)] + sage: [E.tamagawa_exponent(p) for p in E.discriminant().support()] # optional - sage.rings.number_field [1, 4, 4, 4] - sage: P.has_good_reduction() + sage: P.has_good_reduction() # optional - sage.rings.number_field False - sage: (2*P).has_good_reduction() + sage: (2*P).has_good_reduction() # optional - sage.rings.number_field False - sage: (4*P).has_good_reduction() + sage: (4*P).has_good_reduction() # optional - sage.rings.number_field True TESTS: @@ -2353,14 +2369,14 @@ def has_good_reduction(self, P=None): An example showing that :trac:`8498` is fixed:: sage: E = EllipticCurve('11a1') - sage: K. = NumberField(x^2+47) - sage: EK = E.base_extend(K) - sage: T = EK(5,5) - sage: P = EK(-2, -1/2*t - 1/2) - sage: p = K.ideal(11) - sage: T.has_good_reduction(p) + sage: K. = NumberField(x^2 + 47) # optional - sage.rings.number_field + sage: EK = E.base_extend(K) # optional - sage.rings.number_field + sage: T = EK(5, 5) # optional - sage.rings.number_field + sage: P = EK(-2, -1/2*t - 1/2) # optional - sage.rings.number_field + sage: p = K.ideal(11) # optional - sage.rings.number_field + sage: T.has_good_reduction(p) # optional - sage.rings.number_field False - sage: P.has_good_reduction(p) + sage: P.has_good_reduction(p) # optional - sage.rings.number_field True """ if self.is_zero(): # trivial case @@ -2441,22 +2457,22 @@ def reduction(self, p): :: - sage: F. = NumberField(x^2+5) - sage: E = EllipticCurve(F,[1,2,3,4,0]) - sage: Q = E(98,931) - sage: Q.reduction(a) + sage: F. = NumberField(x^2 + 5) # optional - sage.rings.number_field + sage: E = EllipticCurve(F, [1,2,3,4,0]) # optional - sage.rings.number_field + sage: Q = E(98, 931) # optional - sage.rings.number_field + sage: Q.reduction(a) # optional - sage.rings.number_field (3 : 1 : 1) - sage: Q.reduction(11) + sage: Q.reduction(11) # optional - sage.rings.number_field (10 : 7 : 1) :: - sage: F. = NumberField(x^3+x^2+1) - sage: E = EllipticCurve(F,[a,2]) - sage: P = E(a,1) - sage: P.reduction(F.ideal(5)) + sage: F. = NumberField(x^3 + x^2 + 1) # optional - sage.rings.number_field + sage: E = EllipticCurve(F, [a,2]) # optional - sage.rings.number_field + sage: P = E(a, 1) # optional - sage.rings.number_field + sage: P.reduction(F.ideal(5)) # optional - sage.rings.number_field (abar : 1 : 1) - sage: P.reduction(F.ideal(a^2-4*a-2)) + sage: P.reduction(F.ideal(a^2 - 4*a - 2)) # optional - sage.rings.number_field (abar : 1 : 1) """ P = self @@ -2480,8 +2496,8 @@ def height(self, precision=None, normalised=True, algorithm='pari'): return this normalised height multiplied by the degree of `K`. - - ``algorithm`` -- string: either 'pari' (default) or 'sage'. - If 'pari' and the base field is `\QQ`, use the PARI library + - ``algorithm`` -- string: either ``'pari'`` (default) or ``'sage'``. + If ``'pari'`` and the base field is `\QQ`, use the PARI library function; otherwise use the Sage implementation. OUTPUT: @@ -2542,7 +2558,8 @@ def height(self, precision=None, normalised=True, algorithm='pari'): :: sage: E = EllipticCurve('4602a1'); E - Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 37746035*x - 89296920339 over Rational Field + Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 37746035*x - 89296920339 + over Rational Field sage: x = 77985922458974949246858229195945103471590 sage: y = 19575260230015313702261379022151675961965157108920263594545223 sage: d = 2254020761884782243 @@ -2558,7 +2575,7 @@ def height(self, precision=None, normalised=True, algorithm='pari'): sage: E = EllipticCurve('389a1'); E Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field - sage: [P,Q] = [E(-1,1),E(0,-1)] + sage: P, Q = E(-1,1), E(0,-1) sage: P.height(precision=100) 0.68666708330558658572355210295 sage: (3*Q).height(precision=100)/Q.height(precision=100) @@ -2569,22 +2586,23 @@ def height(self, precision=None, normalised=True, algorithm='pari'): Canonical heights over number fields are implemented as well:: sage: R. = QQ[] - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([a, 4]); E - Elliptic Curve defined by y^2 = x^3 + a*x + 4 over Number Field in a with defining polynomial x^3 - 2 - sage: P = E((0,2)) - sage: P.height() + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([a, 4]); E # optional - sage.rings.number_field + Elliptic Curve defined by y^2 = x^3 + a*x + 4 + over Number Field in a with defining polynomial x^3 - 2 + sage: P = E((0,2)) # optional - sage.rings.number_field + sage: P.height() # optional - sage.rings.number_field 0.810463096585925 - sage: P.height(precision=100) + sage: P.height(precision=100) # optional - sage.rings.number_field 0.81046309658592536863991810577 - sage: P.height(precision=200) + sage: P.height(precision=200) # optional - sage.rings.number_field 0.81046309658592536863991810576865158896130286417155832378086 - sage: (2*P).height() / P.height() + sage: (2*P).height() / P.height() # optional - sage.rings.number_field 4.00000000000000 - sage: (100*P).height() / P.height() + sage: (100*P).height() / P.height() # optional - sage.rings.number_field 10000.0000000000 - Setting normalised=False multiplies the height by the degree of `K`:: + Setting ``normalised=False`` multiplies the height by the degree of `K`:: sage: E = EllipticCurve('37a') sage: P = E([0,0]) @@ -2592,12 +2610,12 @@ def height(self, precision=None, normalised=True, algorithm='pari'): 0.0511114082399688 sage: P.height(normalised=False) 0.0511114082399688 - sage: K. = CyclotomicField(5) - sage: EK = E.change_ring(K) - sage: PK = EK([0,0]) - sage: PK.height() + sage: K. = CyclotomicField(5) # optional - sage.rings.number_field + sage: EK = E.change_ring(K) # optional - sage.rings.number_field + sage: PK = EK([0,0]) # optional - sage.rings.number_field + sage: PK.height() # optional - sage.rings.number_field 0.0511114082399688 - sage: PK.height(normalised=False) + sage: PK.height(normalised=False) # optional - sage.rings.number_field 0.204445632959875 Some consistency checks:: @@ -2607,31 +2625,31 @@ def height(self, precision=None, normalised=True, algorithm='pari'): sage: P.height() 1.36857250535393 - sage: EK = E.change_ring(QuadraticField(-3,'a')) - sage: PK = EK([-2,3,1]) - sage: PK.height() + sage: EK = E.change_ring(QuadraticField(-3,'a')) # optional - sage.rings.number_field + sage: PK = EK([-2,3,1]) # optional - sage.rings.number_field + sage: PK.height() # optional - sage.rings.number_field 1.36857250535393 - sage: K. = NumberField(x^2+1) - sage: E = EllipticCurve(K, [0,0,4,6*i,0]) - sage: Q = E.lift_x(-9/4); Q + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,0,4,6*i,0]) # optional - sage.rings.number_field + sage: Q = E.lift_x(-9/4); Q # optional - sage.rings.number_field (-9/4 : -27/8*i : 1) - sage: Q.height() + sage: Q.height() # optional - sage.rings.number_field 2.69518560017909 - sage: (15*Q).height() / Q.height() + sage: (15*Q).height() / Q.height() # optional - sage.rings.number_field 225.000000000000 sage: E = EllipticCurve('37a') sage: P = E([0,-1]) sage: P.height() 0.0511114082399688 - sage: K. = QuadraticField(-7) - sage: ED = E.quadratic_twist(-7) - sage: Q = E.isomorphism_to(ED.change_ring(K))(P); Q + sage: K. = QuadraticField(-7) # optional - sage.rings.number_field + sage: ED = E.quadratic_twist(-7) # optional - sage.rings.number_field + sage: Q = E.isomorphism_to(ED.change_ring(K))(P); Q # optional - sage.rings.number_field (0 : -7/2*a - 1/2 : 1) - sage: Q.height() + sage: Q.height() # optional - sage.rings.number_field 0.0511114082399688 - sage: Q.height(precision=100) + sage: Q.height(precision=100) # optional - sage.rings.number_field 0.051111408239968840235886099757 An example to show that the bug at :trac:`5252` is fixed:: @@ -2666,17 +2684,17 @@ def height(self, precision=None, normalised=True, algorithm='pari'): An example to show that the bug at :trac:`12509` is fixed (precision issues):: sage: x = polygen(QQ) - sage: K. = NumberField(x^2-x-1) - sage: v = [0, a + 1, 1, 28665*a - 46382, 2797026*a - 4525688] - sage: E = EllipticCurve(v) - sage: P = E([72*a - 509/5, -682/25*a - 434/25]) - sage: P.height() + sage: K. = NumberField(x^2 - x - 1) # optional - sage.rings.number_field + sage: v = [0, a + 1, 1, 28665*a - 46382, 2797026*a - 4525688] # optional - sage.rings.number_field + sage: E = EllipticCurve(v) # optional - sage.rings.number_field + sage: P = E([72*a - 509/5, -682/25*a - 434/25]) # optional - sage.rings.number_field + sage: P.height() # optional - sage.rings.number_field 1.38877711688727 - sage: (2*P).height()/P.height() + sage: (2*P).height()/P.height() # optional - sage.rings.number_field 4.00000000000000 - sage: (2*P).height(precision=100)/P.height(precision=100) + sage: (2*P).height(precision=100)/P.height(precision=100) # optional - sage.rings.number_field 4.0000000000000000000000000000 - sage: (2*P).height(precision=1000)/P.height(precision=1000) + sage: (2*P).height(precision=1000)/P.height(precision=1000) # optional - sage.rings.number_field 4.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 This shows that the bug reported at :trac:`13951` has been fixed:: @@ -2685,9 +2703,9 @@ def height(self, precision=None, normalised=True, algorithm='pari'): sage: P1 = E(2,5) sage: P1.height() 1.06248137652528 - sage: F = E.change_ring(QuadraticField(-3,'a')) - sage: P2 = F([2,5]) - sage: P2.height() + sage: F = E.change_ring(QuadraticField(-3, 'a')) # optional - sage.rings.number_field + sage: P2 = F([2,5]) # optional - sage.rings.number_field + sage: P2.height() # optional - sage.rings.number_field 1.06248137652528 """ if self.has_finite_order(): @@ -2740,7 +2758,7 @@ def archimedean_local_height(self, v=None, prec=None, weighted=False): archimedean contribution to the global height. - ``prec`` -- integer, or None (default). The precision of the - computation. If None, the precision is deduced from v. + computation. If None, the precision is deduced from `v`. - ``weighted`` -- boolean. If False (default), the height is normalised to be invariant under extension of `K`. If True, @@ -2762,24 +2780,26 @@ def archimedean_local_height(self, v=None, prec=None, weighted=False): Examples 1, 2, and 3 from [Sil1988]_:: - sage: K. = QuadraticField(-2) - sage: E = EllipticCurve(K, [0,-1,1,0,0]); E - Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 over Number Field in a with defining polynomial x^2 + 2 with a = 1.414213562373095?*I - sage: P = E.lift_x(2+a); P + sage: K. = QuadraticField(-2) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,-1,1,0,0]); E # optional - sage.rings.number_field + Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 over Number Field + in a with defining polynomial x^2 + 2 with a = 1.414213562373095?*I + sage: P = E.lift_x(2 + a); P # optional - sage.rings.number_field (a + 2 : 2*a + 1 : 1) - sage: P.archimedean_local_height(K.places(prec=170)[0]) / 2 + sage: P.archimedean_local_height(K.places(prec=170)[0]) / 2 # optional - sage.rings.number_field 0.45754773287523276736211210741423654346576029814695 - sage: K. = NumberField(x^2+1) - sage: E = EllipticCurve(K, [0,0,4,6*i,0]); E - Elliptic Curve defined by y^2 + 4*y = x^3 + 6*i*x over Number Field in i with defining polynomial x^2 + 1 - sage: P = E((0,0)) - sage: P.archimedean_local_height(K.places()[0]) / 2 + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,0,4,6*i,0]); E # optional - sage.rings.number_field + Elliptic Curve defined by y^2 + 4*y = x^3 + 6*i*x + over Number Field in i with defining polynomial x^2 + 1 + sage: P = E((0,0)) # optional - sage.rings.number_field + sage: P.archimedean_local_height(K.places()[0]) / 2 # optional - sage.rings.number_field 0.510184995162373 - sage: Q = E.lift_x(-9/4); Q + sage: Q = E.lift_x(-9/4); Q # optional - sage.rings.number_field (-9/4 : -27/8*i : 1) - sage: Q.archimedean_local_height(K.places()[0]) / 2 + sage: Q.archimedean_local_height(K.places()[0]) / 2 # optional - sage.rings.number_field 0.654445619529600 An example over the rational numbers:: @@ -2792,10 +2812,10 @@ def archimedean_local_height(self, v=None, prec=None, weighted=False): Local heights of torsion points can be non-zero (unlike the global height):: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve([0, 0, 0, K(1), 0]) - sage: P = E(i, 0) - sage: P.archimedean_local_height() + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 0, 0, K(1), 0]) # optional - sage.rings.number_field + sage: P = E(i, 0) # optional - sage.rings.number_field + sage: P.archimedean_local_height() # optional - sage.rings.number_field 0.346573590279973 TESTS: @@ -2803,33 +2823,34 @@ def archimedean_local_height(self, v=None, prec=None, weighted=False): See :trac:`12509`:: sage: x = polygen(QQ) - sage: K. = NumberField(x^2-x-1) - sage: v = [0, a + 1, 1, 28665*a - 46382, 2797026*a - 4525688] - sage: E = EllipticCurve(v) - sage: P = E([72*a - 509/5, -682/25*a - 434/25]) - sage: P.archimedean_local_height() + sage: K. = NumberField(x^2 - x - 1) # optional - sage.rings.number_field + sage: v = [0, a + 1, 1, 28665*a - 46382, 2797026*a - 4525688] # optional - sage.rings.number_field + sage: E = EllipticCurve(v) # optional - sage.rings.number_field + sage: P = E([72*a - 509/5, -682/25*a - 434/25]) # optional - sage.rings.number_field + sage: P.archimedean_local_height() # optional - sage.rings.number_field -0.220660795546828 See :trac:`19276`:: - sage: K. = NumberField(x^2-x-104) - sage: E = EllipticCurve([1, a - 1, 1, -816765673272*a - 7931030674178, 1478955604013312315*a + 14361086227143654561]) - sage: P = E(5393511/49*a + 52372721/49 , -33896210324/343*a - 329141996591/343 ) - sage: P.height() + sage: K. = NumberField(x^2 - x - 104) # optional - sage.rings.number_field + sage: E = EllipticCurve([1, a - 1, 1, -816765673272*a - 7931030674178, 1478955604013312315*a + 14361086227143654561]) # optional - sage.rings.number_field + sage: P = E(5393511/49*a + 52372721/49 , -33896210324/343*a - 329141996591/343 ) # optional - sage.rings.number_field + sage: P.height() # optional - sage.rings.number_field 0.974232017827741 See :trac:`29966`:: - sage: K. = NumberField(x^3 - x^2 - 6*x + 2) - sage: E = EllipticCurve([1, -a^2 + 2*a + 4, 0, -6056450500590472699700624*a^2 - 11239394326797569935861742*a + 4241549693833829432516231, 1904879037869682826729875958079326124520*a^2 + 3535022146945771697732350459284777382011*a - 1334055169621036218710397707677347972626]) - sage: P = E([1033399668533*a^2 + 1917754693229*a - 723726883800 , 12536493059202326563*a^2 + 23264879148900575548*a - 8779756111574815918 , 1]) - sage: P.height() + sage: K. = NumberField(x^3 - x^2 - 6*x + 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([1, -a^2 + 2*a + 4, 0, -6056450500590472699700624*a^2 - 11239394326797569935861742*a + 4241549693833829432516231, # optional - sage.rings.number_field + ....: 1904879037869682826729875958079326124520*a^2 + 3535022146945771697732350459284777382011*a - 1334055169621036218710397707677347972626]) + sage: P = E([1033399668533*a^2 + 1917754693229*a - 723726883800 , 12536493059202326563*a^2 + 23264879148900575548*a - 8779756111574815918 , 1]) # optional - sage.rings.number_field + sage: P.height() # optional - sage.rings.number_field 0.297318833424763 - sage: (2*P).height() / P.height() + sage: (2*P).height() / P.height() # optional - sage.rings.number_field 4.00000000000000 - sage: P.height(200) + sage: P.height(200) # optional - sage.rings.number_field 0.29731883342476341806143743594519935578696537745294661858984 - sage: (2*P).height(200) / P.height(200) + sage: (2*P).height(200) / P.height(200) # optional - sage.rings.number_field 4.0000000000000000000000000000000000000000000000000000000000 """ from sage.rings.number_field.number_field import refine_embedding @@ -2987,26 +3008,27 @@ def non_archimedean_local_height(self, v=None, prec=None, Examples 2 and 3 from [Sil1988]_:: - sage: K. = NumberField(x^2+1) - sage: E = EllipticCurve(K, [0,0,4,6*i,0]); E - Elliptic Curve defined by y^2 + 4*y = x^3 + 6*i*x over Number Field in i with defining polynomial x^2 + 1 - sage: P = E((0,0)) - sage: P.non_archimedean_local_height(K.ideal(i+1)) + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,0,4,6*i,0]); E # optional - sage.rings.number_field + Elliptic Curve defined by y^2 + 4*y = x^3 + 6*i*x + over Number Field in i with defining polynomial x^2 + 1 + sage: P = E((0,0)) # optional - sage.rings.number_field + sage: P.non_archimedean_local_height(K.ideal(i+1)) # optional - sage.rings.number_field -1/2*log(2) - sage: P.non_archimedean_local_height(K.ideal(3)) + sage: P.non_archimedean_local_height(K.ideal(3)) # optional - sage.rings.number_field 0 - sage: P.non_archimedean_local_height(K.ideal(1-2*i)) + sage: P.non_archimedean_local_height(K.ideal(1-2*i)) # optional - sage.rings.number_field 0 - sage: Q = E.lift_x(-9/4); Q + sage: Q = E.lift_x(-9/4); Q # optional - sage.rings.number_field (-9/4 : -27/8*i : 1) - sage: Q.non_archimedean_local_height(K.ideal(1+i)) + sage: Q.non_archimedean_local_height(K.ideal(1+i)) # optional - sage.rings.number_field 2*log(2) - sage: Q.non_archimedean_local_height(K.ideal(3)) + sage: Q.non_archimedean_local_height(K.ideal(3)) # optional - sage.rings.number_field 0 - sage: Q.non_archimedean_local_height(K.ideal(1-2*i)) + sage: Q.non_archimedean_local_height(K.ideal(1-2*i)) # optional - sage.rings.number_field 0 - sage: Q.non_archimedean_local_height() + sage: Q.non_archimedean_local_height() # optional - sage.rings.number_field 2*log(2) An example over the rational numbers:: @@ -3019,30 +3041,30 @@ def non_archimedean_local_height(self, v=None, prec=None, Local heights of torsion points can be non-zero (unlike the global height):: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve([0, 0, 0, K(1), 0]) - sage: P = E(i, 0) - sage: P.non_archimedean_local_height() + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 0, 0, K(1), 0]) # optional - sage.rings.number_field + sage: P = E(i, 0) # optional - sage.rings.number_field + sage: P.non_archimedean_local_height() # optional - sage.rings.number_field -1/2*log(2) TESTS:: - sage: Q.non_archimedean_local_height(prec=100) + sage: Q.non_archimedean_local_height(prec=100) # optional - sage.rings.number_field 1.3862943611198906188344642429 - sage: (3*Q).non_archimedean_local_height() + sage: (3*Q).non_archimedean_local_height() # optional - sage.rings.number_field 1/2*log(75923153929839865104) - sage: F. = NumberField(x^4 + 2*x^3 + 19*x^2 + 18*x + 288) - sage: F.ring_of_integers().basis() + sage: F. = NumberField(x^4 + 2*x^3 + 19*x^2 + 18*x + 288) # optional - sage.rings.number_field + sage: F.ring_of_integers().basis() # optional - sage.rings.number_field [1, 5/6*a^3 + 1/6*a, 1/6*a^3 + 1/6*a^2, a^3] - sage: F.class_number() + sage: F.class_number() # optional - sage.rings.number_field 12 - sage: E = EllipticCurve('37a').change_ring(F) - sage: P = E((-a^2/6 - a/6 - 1, a)); P + sage: E = EllipticCurve('37a').change_ring(F) # optional - sage.rings.number_field + sage: P = E((-a^2/6 - a/6 - 1, a)); P # optional - sage.rings.number_field (-1/6*a^2 - 1/6*a - 1 : a : 1) - sage: P[0].is_integral() + sage: P[0].is_integral() # optional - sage.rings.number_field True - sage: P.non_archimedean_local_height() + sage: P.non_archimedean_local_height() # optional - sage.rings.number_field 0 This shows that the bug reported at :trac:`13951` has been fixed:: @@ -3150,8 +3172,8 @@ def elliptic_logarithm(self, embedding=None, precision=100, - ``precision``: a positive integer (default 100) setting the number of bits of precision for the computation - - ``algorithm``: either 'pari' (default for real embeddings) - to use PARI's :pari:`ellpointtoz`, or 'sage' for a native + - ``algorithm``: either ``'pari'`` (default for real embeddings) + to use PARI's :pari:`ellpointtoz`, or ``'sage'`` for a native implementation. Ignored for complex embeddings. ALGORITHM: @@ -3177,7 +3199,7 @@ def elliptic_logarithm(self, embedding=None, precision=100, False sage: P.elliptic_logarithm (precision=96) 0.4793482501902193161295330101 + 0.985868850775824102211203849...*I - sage: Q=E([3,5]) + sage: Q = E([3,5]) sage: Q.is_on_identity_component() True sage: Q.elliptic_logarithm (precision=96) @@ -3202,7 +3224,7 @@ def elliptic_logarithm(self, embedding=None, precision=100, sage: P.elliptic_logarithm() # 100 bits 0.27656204014107061464076203097 - The native algorithm 'sage' used to have trouble with + The native algorithm ``'sage'`` used to have trouble with precision in this example, but no longer:: sage: P.elliptic_logarithm(algorithm='sage') # 100 bits @@ -3229,30 +3251,39 @@ def elliptic_logarithm(self, embedding=None, precision=100, Examples over number fields:: - sage: K. = NumberField(x^3-2) - sage: embs = K.embeddings(CC) - sage: E = EllipticCurve([0,1,0,a,a]) - sage: Ls = [E.period_lattice(e) for e in embs] - sage: [L.real_flag for L in Ls] + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: embs = K.embeddings(CC) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: Ls = [E.period_lattice(e) for e in embs] # optional - sage.rings.number_field + sage: [L.real_flag for L in Ls] # optional - sage.rings.number_field [0, 0, -1] - sage: P = E(-1,0) # order 2 - sage: [L.elliptic_logarithm(P) for L in Ls] - [-1.73964256006716 - 1.07861534489191*I, -0.363756518406398 - 1.50699412135253*I, 1.90726488608927] - - sage: E = EllipticCurve([-a^2 - a - 1, a^2 + a]) - sage: Ls = [E.period_lattice(e) for e in embs] - sage: pts = [E(2*a^2 - a - 1 , -2*a^2 - 2*a + 6 ), E(-2/3*a^2 - 1/3 , -4/3*a - 2/3 ), E(5/4*a^2 - 1/2*a , -a^2 - 1/4*a + 9/4 ), E(2*a^2 + 3*a + 4 , -7*a^2 - 10*a - 12 )] - sage: [[L.elliptic_logarithm(P) for P in pts] for L in Ls] - [[0.250819591818930 - 0.411963479992219*I, -0.290994550611374 - 1.37239400324105*I, -0.693473752205595 - 2.45028458830342*I, -0.151659609775291 - 1.48985406505459*I], [1.33444787667954 - 1.50889756650544*I, 0.792633734249234 - 0.548467043256610*I, 0.390154532655013 + 0.529423541805758*I, 0.931968675085317 - 0.431006981443071*I], [1.14758249500109 + 0.853389664016075*I, 2.59823462472518 + 0.853389664016075*I, 1.75372176444709, 0.303069634723001]] + sage: P = E(-1,0) # order 2 # optional - sage.rings.number_field + sage: [L.elliptic_logarithm(P) for L in Ls] # optional - sage.rings.number_field + [-1.73964256006716 - 1.07861534489191*I, + -0.363756518406398 - 1.50699412135253*I, 1.90726488608927] + + sage: E = EllipticCurve([-a^2 - a - 1, a^2 + a]) # optional - sage.rings.number_field + sage: Ls = [E.period_lattice(e) for e in embs] # optional - sage.rings.number_field + sage: pts = [E(2*a^2 - a - 1 , -2*a^2 - 2*a + 6 ), + ....: E(-2/3*a^2 - 1/3 , -4/3*a - 2/3 ), + ....: E(5/4*a^2 - 1/2*a , -a^2 - 1/4*a + 9/4 ), + ....: E(2*a^2 + 3*a + 4 , -7*a^2 - 10*a - 12 )] + sage: [[L.elliptic_logarithm(P) for P in pts] for L in Ls] # optional - sage.rings.number_field + [[0.250819591818930 - 0.411963479992219*I, -0.290994550611374 - 1.37239400324105*I, + -0.693473752205595 - 2.45028458830342*I, -0.151659609775291 - 1.48985406505459*I], + [1.33444787667954 - 1.50889756650544*I, 0.792633734249234 - 0.548467043256610*I, + 0.390154532655013 + 0.529423541805758*I, 0.931968675085317 - 0.431006981443071*I], + [1.14758249500109 + 0.853389664016075*I, 2.59823462472518 + 0.853389664016075*I, + 1.75372176444709, 0.303069634723001]] :: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve([0,0,0,9*i-10,21-i]) - sage: emb = K.embeddings(CC)[1] - sage: L = E.period_lattice(emb) - sage: P = E(2-i,4+2*i) - sage: L.elliptic_logarithm(P,prec=100) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,0,0,9*i-10,21-i]) # optional - sage.rings.number_field + sage: emb = K.embeddings(CC)[1] # optional - sage.rings.number_field + sage: L = E.period_lattice(emb) # optional - sage.rings.number_field + sage: P = E(2-i, 4+2*i) # optional - sage.rings.number_field + sage: L.elliptic_logarithm(P, prec=100) # optional - sage.rings.number_field 0.70448375537782208460499649302 - 0.79246725643650979858266018068*I """ from sage.rings.number_field.number_field import refine_embedding @@ -3370,31 +3401,32 @@ def padic_elliptic_logarithm(self, p, absprec=20): EXAMPLES:: sage: E = EllipticCurve([0,1,1,-2,0]) - sage: E(0).padic_elliptic_logarithm(3) + sage: E(0).padic_elliptic_logarithm(3) # optional - sage.rings.padics 0 - sage: P = E(0,0) - sage: P.padic_elliptic_logarithm(3) + sage: P = E(0, 0) # optional - sage.rings.padics + sage: P.padic_elliptic_logarithm(3) # optional - sage.rings.padics 2 + 2*3 + 3^3 + 2*3^7 + 3^8 + 3^9 + 3^11 + 3^15 + 2*3^17 + 3^18 + O(3^19) - sage: P.padic_elliptic_logarithm(3).lift() + sage: P.padic_elliptic_logarithm(3).lift() # optional - sage.rings.padics 660257522 - sage: P = E(-11/9,28/27) - sage: [(2*P).padic_elliptic_logarithm(p)/P.padic_elliptic_logarithm(p) for p in prime_range(20)] # long time (3s) + sage: P = E(-11/9, 28/27) # optional - sage.rings.padics + sage: [(2*P).padic_elliptic_logarithm(p)/P.padic_elliptic_logarithm(p) for p in prime_range(20)] # long time (3s) # optional - sage.rings.padics [2 + O(2^19), 2 + O(3^20), 2 + O(5^19), 2 + O(7^19), 2 + O(11^19), 2 + O(13^19), 2 + O(17^19), 2 + O(19^19)] - sage: [(3*P).padic_elliptic_logarithm(p)/P.padic_elliptic_logarithm(p) for p in prime_range(12)] # long time (2s) + sage: [(3*P).padic_elliptic_logarithm(p)/P.padic_elliptic_logarithm(p) for p in prime_range(12)] # long time (2s) # optional - sage.rings.padics [1 + 2 + O(2^19), 3 + 3^20 + O(3^21), 3 + O(5^19), 3 + O(7^19), 3 + O(11^19)] - sage: [(5*P).padic_elliptic_logarithm(p)/P.padic_elliptic_logarithm(p) for p in prime_range(12)] # long time (2s) + sage: [(5*P).padic_elliptic_logarithm(p)/P.padic_elliptic_logarithm(p) for p in prime_range(12)] # long time (2s) # optional - sage.rings.padics [1 + 2^2 + O(2^19), 2 + 3 + O(3^20), 5 + O(5^19), 5 + O(7^19), 5 + O(11^19)] An example which arose during reviewing :trac:`4741`:: sage: E = EllipticCurve('794a1') sage: P = E(-1,2) - sage: P.padic_elliptic_logarithm(2) # default precision=20 + sage: P.padic_elliptic_logarithm(2) # default precision=20 # optional - sage.rings.padics 2^4 + 2^5 + 2^6 + 2^8 + 2^9 + 2^13 + 2^14 + 2^15 + O(2^16) - sage: P.padic_elliptic_logarithm(2, absprec=30) + sage: P.padic_elliptic_logarithm(2, absprec=30) # optional - sage.rings.padics 2^4 + 2^5 + 2^6 + 2^8 + 2^9 + 2^13 + 2^14 + 2^15 + 2^22 + 2^23 + 2^24 + O(2^26) - sage: P.padic_elliptic_logarithm(2, absprec=40) - 2^4 + 2^5 + 2^6 + 2^8 + 2^9 + 2^13 + 2^14 + 2^15 + 2^22 + 2^23 + 2^24 + 2^28 + 2^29 + 2^31 + 2^34 + O(2^35) + sage: P.padic_elliptic_logarithm(2, absprec=40) # optional - sage.rings.padics + 2^4 + 2^5 + 2^6 + 2^8 + 2^9 + 2^13 + 2^14 + 2^15 + 2^22 + 2^23 + 2^24 + + 2^28 + 2^29 + 2^31 + 2^34 + O(2^35) """ if not p.is_prime(): raise ValueError('p must be prime') @@ -3481,9 +3513,9 @@ def _magma_init_(self, magma): EXAMPLES:: - sage: E = EllipticCurve(GF(17), [1,-1]) - sage: P = E([13, 4]) - sage: P._magma_init_(magma) # optional - magma + sage: E = EllipticCurve(GF(17), [1,-1]) # optional - sage.rings.finite_rings + sage: P = E([13, 4]) # optional - sage.rings.finite_rings + sage: P._magma_init_(magma) # optional - magma # optional - sage.rings.finite_rings 'EllipticCurve([_sage_ref...|GF(17)!0,GF(17)!0,GF(17)!0,GF(17)!1,GF(17)!16])![13,4]' """ E = self.curve()._magma_init_(magma) @@ -3497,14 +3529,14 @@ def _acted_upon_(self, other, side): EXAMPLES:: - sage: P = EllipticCurve(GF(65537), [2,2]).lift_x(6) - sage: P.order().factor() + sage: P = EllipticCurve(GF(65537), [2,2]).lift_x(6) # optional - sage.rings.finite_rings + sage: P.order().factor() # optional - sage.rings.finite_rings 2^2 * 3 * 37^2 - sage: getattr(74*P, '_order', None) + sage: getattr(74*P, '_order', None) # optional - sage.rings.finite_rings 222 - sage: getattr(P*4070, '_order', None) + sage: getattr(P*4070, '_order', None) # optional - sage.rings.finite_rings 222 - sage: getattr(506*P*37, '_order', None) + sage: getattr(506*P*37, '_order', None) # optional - sage.rings.finite_rings 222 """ k = ZZ(other) @@ -3587,14 +3619,14 @@ def discrete_log(self, Q, ord=None): EXAMPLES:: - sage: F = GF((3,6),'a') - sage: a = F.gen() - sage: E = EllipticCurve([0,1,1,a,a]) - sage: E.cardinality() + sage: F = GF((3,6),'a') # optional - sage.rings.finite_rings + sage: a = F.gen() # optional - sage.rings.finite_rings + sage: E = EllipticCurve([0,1,1,a,a]) # optional - sage.rings.finite_rings + sage: E.cardinality() # optional - sage.rings.finite_rings 762 - sage: P = E.gens()[0] - sage: Q = 400*P - sage: P.discrete_log(Q) + sage: P = E.gens()[0] # optional - sage.rings.finite_rings + sage: Q = 400*P # optional - sage.rings.finite_rings + sage: P.discrete_log(Q) # optional - sage.rings.finite_rings 400 TESTS: @@ -3604,16 +3636,16 @@ def discrete_log(self, Q, ord=None): sage: sz = randint(8,32) sage: e = randint(1,3) sage: p = random_prime(ceil(2**(sz/e))) - sage: E = EllipticCurve(j=GF((p,e),'a').random_element()) - sage: P = E.random_point() - sage: Q = randrange(2**999) * P - sage: x = P.discrete_log(Q) - sage: x*P == Q + sage: E = EllipticCurve(j=GF((p,e),'a').random_element()) # optional - sage.rings.finite_rings + sage: P = E.random_point() # optional - sage.rings.finite_rings + sage: Q = randrange(2**999) * P # optional - sage.rings.finite_rings + sage: x = P.discrete_log(Q) # optional - sage.rings.finite_rings + sage: x*P == Q # optional - sage.rings.finite_rings True Doctest deprecation:: - sage: P.discrete_log(Q, ord=P.order()) + sage: P.discrete_log(Q, ord=P.order()) # optional - sage.rings.finite_rings doctest:warning ... DeprecationWarning: The "ord" argument to .discrete_log() is obsolete. ... @@ -3652,8 +3684,8 @@ def padic_elliptic_logarithm(self,Q, p): INPUT: - - ``Q`` (point) -- another point on the same curve as ``self``. - - ``p`` (integer) -- a prime equals the order of the curve. + - ``Q`` (point) -- another point on the same curve as ``self``. + - ``p`` (integer) -- a prime equal to the order of the curve. OUTPUT: @@ -3671,11 +3703,11 @@ def padic_elliptic_logarithm(self,Q, p): sage: p=235322474717419 sage: b=8856682 - sage: E = EllipticCurve(GF(p), [0, b]) - sage: P = E(200673830421813, 57025307876612) - sage: Q = E(40345734829479, 211738132651297) - sage: x = P.padic_elliptic_logarithm(Q, p) - sage: x * P == Q + sage: E = EllipticCurve(GF(p), [0, b]) # optional - sage.rings.finite_rings + sage: P = E(200673830421813, 57025307876612) # optional - sage.rings.finite_rings + sage: Q = E(40345734829479, 211738132651297) # optional - sage.rings.finite_rings + sage: x = P.padic_elliptic_logarithm(Q, p) # optional - sage.rings.finite_rings sage.rings.padics + sage: x * P == Q # optional - sage.rings.finite_rings sage.rings.padics True TESTS: @@ -3685,11 +3717,11 @@ def padic_elliptic_logarithm(self,Q, p): sage: a = 49850651047495986645822557378918223 sage: b = 21049438014429831351540675253466229 sage: p = 54283205379427155782089046839411711 - sage: E = EllipticCurve(GF(p),[a, b]) - sage: P = E.random_point() - sage: Q = randrange(0, p-1) * P - sage: x = P.padic_elliptic_logarithm(Q, p) - sage: x*P == Q + sage: E = EllipticCurve(GF(p), [a, b]) # optional - sage.rings.finite_rings + sage: P = E.random_point() # optional - sage.rings.finite_rings + sage: Q = randrange(0, p-1) * P # optional - sage.rings.finite_rings + sage: x = P.padic_elliptic_logarithm(Q, p) # optional - sage.rings.finite_rings sage.rings.padics + sage: x*P == Q # optional - sage.rings.finite_rings sage.rings.padics True """ E = self.curve() @@ -3737,9 +3769,9 @@ def has_finite_order(self): EXAMPLES:: - sage: E = EllipticCurve(GF(7), [1,3]) - sage: P = E.points()[3] - sage: P.has_finite_order() + sage: E = EllipticCurve(GF(7), [1,3]) # optional - sage.rings.finite_rings + sage: P = E.points()[3] # optional - sage.rings.finite_rings + sage: P.has_finite_order() # optional - sage.rings.finite_rings True """ return True @@ -3756,67 +3788,68 @@ def order(self): EXAMPLES:: - sage: k. = GF((5,5)) - sage: E = EllipticCurve(k,[2,4]); E + sage: k. = GF((5,5)) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(k,[2,4]); E # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 2*x + 4 over Finite Field in a of size 5^5 - sage: P = E(3*a^4 + 3*a , 2*a + 1 ) - sage: P.order() + sage: P = E(3*a^4 + 3*a, 2*a + 1) # optional - sage.rings.finite_rings + sage: P.order() # optional - sage.rings.finite_rings 3227 - sage: Q = E(0,2) - sage: Q.order() + sage: Q = E(0,2) # optional - sage.rings.finite_rings + sage: Q.order() # optional - sage.rings.finite_rings 7 - sage: Q.additive_order() + sage: Q.additive_order() # optional - sage.rings.finite_rings 7 :: - sage: p=next_prime(2^150) - sage: E=EllipticCurve(GF(p),[1,1]) - sage: P=E(831623307675610677632782670796608848711856078, 42295786042873366706573292533588638217232964) - sage: P.order() + sage: p = next_prime(2^150) + sage: E = EllipticCurve(GF(p), [1,1]) # optional - sage.rings.finite_rings + sage: P = E(831623307675610677632782670796608848711856078, # optional - sage.rings.finite_rings + ....: 42295786042873366706573292533588638217232964) + sage: P.order() # optional - sage.rings.finite_rings 1427247692705959881058262545272474300628281448 - sage: P.order() == E.cardinality() + sage: P.order() == E.cardinality() # optional - sage.rings.finite_rings True The next example has `j(E)=0`:: sage: p = 33554501 - sage: F. = GF((p,2)) - sage: E = EllipticCurve(F,[0,1]) - sage: E.j_invariant() + sage: F. = GF((p,2)) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [0,1]) # optional - sage.rings.finite_rings + sage: E.j_invariant() # optional - sage.rings.finite_rings 0 - sage: P = E.random_point() - sage: P.order() # random + sage: P = E.random_point() # optional - sage.rings.finite_rings + sage: P.order() # random # optional - sage.rings.finite_rings 16777251 Similarly when `j(E)=1728`:: sage: p = 33554473 - sage: F. = GF((p,2)) - sage: E = EllipticCurve(F,[1,0]) - sage: E.j_invariant() + sage: F. = GF((p,2)) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [1,0]) # optional - sage.rings.finite_rings + sage: E.j_invariant() # optional - sage.rings.finite_rings 1728 - sage: P = E.random_point() - sage: P.order() # random + sage: P = E.random_point() # optional - sage.rings.finite_rings + sage: P.order() # random # optional - sage.rings.finite_rings 46912611635760 TESTS: Check that the order actually gets cached (:trac:`32786`):: - sage: E = EllipticCurve(GF(31337), [42,1]) - sage: P = E.lift_x(1) - sage: hasattr(P, '_order') + sage: E = EllipticCurve(GF(31337), [42,1]) # optional - sage.rings.finite_rings + sage: P = E.lift_x(1) # optional - sage.rings.finite_rings + sage: hasattr(P, '_order') # optional - sage.rings.finite_rings False - sage: P.order() + sage: P.order() # optional - sage.rings.finite_rings 15649 - sage: P._order + sage: P._order # optional - sage.rings.finite_rings 15649 The curve order should also get cached as a side effect of computing a point order:: - sage: E._order + sage: E._order # optional - sage.rings.finite_rings 31298 """ try: diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 418bfd8995f..65499d81718 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -659,7 +659,7 @@ def database_attributes(self): the elliptic curve database. If there is no elliptic curve isomorphic to ``self`` in the - database, a ``LookupError`` is raised. + database, a :class:`LookupError` is raised. EXAMPLES:: @@ -678,7 +678,8 @@ def database_attributes(self): sage: E.database_attributes() Traceback (most recent call last): ... - LookupError: Cremona database does not contain entry for Elliptic Curve defined by y^2 + 8*x*y + 21*y = x^3 + 13*x^2 + 34*x + 55 over Rational Field + LookupError: Cremona database does not contain entry for Elliptic Curve + defined by y^2 + 8*x*y + 21*y = x^3 + 13*x^2 + 34*x + 55 over Rational Field """ from sage.databases.cremona import CremonaDatabase ainvs = self.minimal_model().ainvs() @@ -776,7 +777,7 @@ def mwrank_curve(self, verbose=False): sage: EE.isogeny_class() ([[0, -1, 1, -10, -20], [0, -1, 1, -7820, -263580], [0, -1, 1, 0, 0]], - [[0, 5, 5], [5, 0, 0], [5, 0, 0]]) + [[0, 5, 5], [5, 0, 0], [5, 0, 0]]) """ try: return self.__mwrank_curve @@ -1031,11 +1032,14 @@ def modular_symbol_space(self, sign=1, base_ring=Q, bound=None): sage: f = EllipticCurve('37b') sage: f.modular_symbol_space() - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(37) of weight 2 with sign 1 over Rational Field + Modular Symbols subspace of dimension 1 of Modular Symbols space + of dimension 3 for Gamma_0(37) of weight 2 with sign 1 over Rational Field sage: f.modular_symbol_space(-1) - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 2 for Gamma_0(37) of weight 2 with sign -1 over Rational Field + Modular Symbols subspace of dimension 1 of Modular Symbols space + of dimension 2 for Gamma_0(37) of weight 2 with sign -1 over Rational Field sage: f.modular_symbol_space(0, bound=3) - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Gamma_0(37) of weight 2 with sign 0 over Rational Field + Modular Symbols subspace of dimension 2 of Modular Symbols space + of dimension 5 for Gamma_0(37) of weight 2 with sign 0 over Rational Field .. NOTE:: @@ -1179,7 +1183,8 @@ def modular_symbol(self, sign=+1, normalize=None, implementation='eclib', nap=0) sage: E = EllipticCurve('37a1') sage: M = E.modular_symbol(); M - Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + Modular symbol with sign 1 over Rational Field attached to + Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field sage: M(1/2) 0 sage: M(1/5) @@ -1189,7 +1194,8 @@ def modular_symbol(self, sign=+1, normalize=None, implementation='eclib', nap=0) sage: E = EllipticCurve('121b1') sage: M = E.modular_symbol(implementation="sage") - Warning : Could not normalize the modular symbols, maybe all further results will be multiplied by -1 and a power of 2 + Warning : Could not normalize the modular symbols, maybe all further results + will be multiplied by -1 and a power of 2 sage: M(1/7) -1/2 @@ -1255,11 +1261,13 @@ def modular_symbol(self, sign=+1, normalize=None, implementation='eclib', nap=0) sage: E = EllipticCurve('11a1') sage: Mplus = E.modular_symbol(+1); Mplus - Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Modular symbol with sign 1 over Rational Field attached to + Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: [Mplus(1/i) for i in [1..11]] [1/5, -4/5, -3/10, 7/10, 6/5, 6/5, 7/10, -3/10, -4/5, 1/5, 0] sage: Mminus = E.modular_symbol(-1); Mminus - Modular symbol with sign -1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Modular symbol with sign -1 over Rational Field attached to + Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: [Mminus(1/i) for i in [1..11]] [0, 0, 1/2, 1/2, 0, 0, -1/2, -1/2, 0, 0, 0] @@ -1439,7 +1447,7 @@ def analytic_rank(self, algorithm="pari", leading_coefficient=False): - ``'rubinstein'`` -- use Rubinstein's L-function C++ program lcalc. - ``'magma'`` -- use MAGMA - ``'zero_sum'`` -- Use the rank bounding zero sum method implemented - in self.analytic_rank_upper_bound() + in :meth:`analytic_rank_upper_bound` - ``'all'`` -- compute with PARI, sympow and lcalc, check that the answers agree, and return the common answer. @@ -1666,12 +1674,12 @@ def analytic_rank_upper_bound(self, sage: E = EllipticCurve("11a") sage: E.rank() 0 - sage: E.analytic_rank_upper_bound(max_Delta=1,adaptive=False) + sage: E.analytic_rank_upper_bound(max_Delta=1, adaptive=False) 0 sage: E = EllipticCurve([-39,123]) sage: E.rank() 1 - sage: E.analytic_rank_upper_bound(max_Delta=1,adaptive=True) + sage: E.analytic_rank_upper_bound(max_Delta=1, adaptive=True) 1 This is especially true for elliptic curves with large rank. @@ -1681,7 +1689,8 @@ def analytic_rank_upper_bound(self, sage: for r in range(9): ....: E = elliptic_curves.rank(r)[0] ....: print((r, E.analytic_rank_upper_bound(max_Delta=1, - ....: adaptive=False,root_number="ignore"))) + ....: adaptive=False, + ....: root_number="ignore"))) (0, 0) (1, 1) (2, 2) @@ -1700,9 +1709,9 @@ def analytic_rank_upper_bound(self, sage: E = EllipticCurve("974b1") sage: r = E.rank(); r 0 - sage: E.analytic_rank_upper_bound(max_Delta=1,root_number="ignore") + sage: E.analytic_rank_upper_bound(max_Delta=1, root_number="ignore") 1 - sage: E.analytic_rank_upper_bound(max_Delta=1.3,root_number="ignore") + sage: E.analytic_rank_upper_bound(max_Delta=1.3, root_number="ignore") 0 Knowing the root number of `E` allows us to use smaller Delta values @@ -1710,7 +1719,7 @@ def analytic_rank_upper_bound(self, :: - sage: E.analytic_rank_upper_bound(max_Delta=0.6,root_number="compute") + sage: E.analytic_rank_upper_bound(max_Delta=0.6, root_number="compute") 0 There are a small number of curves which have pathologically low-lying @@ -1723,11 +1732,11 @@ def analytic_rank_upper_bound(self, :: sage: E = EllipticCurve([0, -1, 0, -7460362000712, -7842981500851012704]) - sage: N,r = E.conductor(),E.analytic_rank(); N, r + sage: N, r = E.conductor(), E.analytic_rank(); N, r (256944, 0) - sage: E.analytic_rank_upper_bound(max_Delta=1,adaptive=False) + sage: E.analytic_rank_upper_bound(max_Delta=1, adaptive=False) 2 - sage: E.analytic_rank_upper_bound(max_Delta=2,adaptive=False) + sage: E.analytic_rank_upper_bound(max_Delta=2, adaptive=False) 2 This method is can be called on curves with large conductor. @@ -1748,11 +1757,12 @@ def analytic_rank_upper_bound(self, sage: a4 = -20067762415575526585033208209338542750930230312178956502 sage: a6 = 34481611795030556467032985690390720374855944359319180361266008296291939448732243429 - sage: E = EllipticCurve([1,-1,1,a4,a6]) - sage: bad_primes = [2,3,5,7,11,13,17,19,48463] + sage: E = EllipticCurve([1, -1, 1, a4, a6]) + sage: bad_primes = [2, 3, 5, 7, 11, 13, 17, 19, 48463] sage: N = 3455601108357547341532253864901605231198511505793733138900595189472144724781456635380154149870961231592352897621963802238155192936274322687070 - sage: E.analytic_rank_upper_bound(max_Delta=2.37,adaptive=False, # long time - ....: N=N,root_number=1,bad_primes=bad_primes,ncpus=2) + sage: E.analytic_rank_upper_bound(max_Delta=2.37, adaptive=False, # long time + ....: N=N, root_number=1, + ....: bad_primes=bad_primes, ncpus=2) 32 """ Z = LFunctionZeroSum_EllipticCurve(self, N) @@ -2228,7 +2238,8 @@ def gens(self, proof=None, **kwds): sage: E = EllipticCurve('389a1') sage: E1 = E.change_weierstrass_model([1/20,0,0,0]); E1 - Elliptic Curve defined by y^2 + 8000*y = x^3 + 400*x^2 - 320000*x over Rational Field + Elliptic Curve defined by y^2 + 8000*y = x^3 + 400*x^2 - 320000*x + over Rational Field sage: E1.gens() # random (if database not used) [(-400 : 8000 : 1), (0 : -8000 : 1)] """ @@ -3256,15 +3267,16 @@ def period_lattice(self, embedding=None): OUTPUT: - (period lattice) The PeriodLattice_ell object associated to - this elliptic curve (with respect to the natural embedding of + (period lattice) The :class:`~sage.schemes.elliptic_curves.period_lattice.PeriodLattice_ell` + object associated to this elliptic curve (with respect to the natural embedding of `\QQ` into `\RR`). EXAMPLES:: sage: E = EllipticCurve('37a') sage: E.period_lattice() - Period lattice associated to Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + Period lattice associated to + Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field """ try: return self._period_lattice @@ -3328,13 +3340,13 @@ def elliptic_exponential(self, z, embedding=None): sage: E.division_polynomial(3).roots(CC,multiplicities=False) [-2.88288879135..., - 1.39292799513..., - 0.078313731444316... - 0.492840991709...*I, - 0.078313731444316... + 0.492840991709...*I] + 1.39292799513..., + 0.078313731444316... - 0.492840991709...*I, + 0.078313731444316... + 0.492840991709...*I] sage: [E.elliptic_exponential((a*w1+b*w2)/3)[0] for a,b in [(0,1),(1,0),(1,1),(2,1)]] [-2.8828887913533..., 1.39292799513138, - 0.0783137314443... - 0.492840991709...*I, - 0.0783137314443... + 0.492840991709...*I] + 0.0783137314443... - 0.492840991709...*I, + 0.0783137314443... + 0.492840991709...*I] Observe that this is a group homomorphism (modulo rounding error):: @@ -3396,7 +3408,9 @@ def lseries_gross_zagier(self, A): sage: A = K.class_group().gen(0); A Fractional ideal class (2, 1/2*a) sage: L = E.lseries_gross_zagier(A) ; L - Gross Zagier L-series attached to Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field with ideal class Fractional ideal class (2, 1/2*a) + Gross Zagier L-series attached to + Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + with ideal class Fractional ideal class (2, 1/2*a) sage: L(1) 0.000000000000000 sage: L.taylor_series(1, 5) @@ -3434,7 +3448,7 @@ def Lambda(self, s, prec): EXAMPLES:: sage: E = EllipticCurve('389a') - sage: E.Lambda(1.4+0.5*I, 50) + sage: E.Lambda(1.4 + 0.5*I, 50) -0.354172680517... + 0.874518681720...*I """ from sage.symbolic.constants import pi @@ -3457,7 +3471,7 @@ def is_local_integral_model(self, *p): EXAMPLES:: - sage: E = EllipticCurve([1/2,1/5,1/5,1/5,1/5]) + sage: E = EllipticCurve([1/2, 1/5, 1/5, 1/5, 1/5]) sage: [E.is_local_integral_model(p) for p in (2,3,5)] [False, True, False] sage: E.is_local_integral_model(2,3,5) @@ -3498,7 +3512,7 @@ def is_global_integral_model(self): EXAMPLES:: - sage: E = EllipticCurve([1/2,1/5,1/5,1/5,1/5]) + sage: E = EllipticCurve([1/2, 1/5, 1/5, 1/5, 1/5]) sage: E.is_global_integral_model() False sage: Emin=E.global_integral_model() @@ -3587,8 +3601,8 @@ def _generalized_congmod_numbers(self, M, invariant="both"): EXAMPLES:: sage: E = EllipticCurve('37a') - sage: for M in range(2,8): # long time (22s on 2009 MBP) - ....: print((M, E.modular_degree(M=M),E.congruence_number(M=M))) + sage: for M in range(2, 8): # long time (22s on 2009 MBP) + ....: print((M, E.modular_degree(M=M), E.congruence_number(M=M))) (2, 5, 20) (3, 7, 28) (4, 50, 400) @@ -3775,7 +3789,10 @@ def modular_parametrization(self): sage: E = EllipticCurve('15a') sage: phi = E.modular_parametrization(); phi - Modular parameterization from the upper half plane to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 10*x - 10 over Rational Field + Modular parameterization + from the upper half plane + to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 10*x - 10 + over Rational Field sage: z = 0.1 + 0.2j sage: phi(z) (8.20822465478531 - 13.1562816054682*I : -8.79855099049364 + 69.4006129342200*I : 1.00000000000000) @@ -3789,7 +3806,7 @@ def modular_parametrization(self): We can also get a series expansion of this modular parameterization:: sage: E = EllipticCurve('389a1') - sage: X,Y=E.modular_parametrization().power_series() + sage: X, Y = E.modular_parametrization().power_series() sage: X q^-2 + 2*q^-1 + 4 + 7*q + 13*q^2 + 18*q^3 + 31*q^4 + 49*q^5 + 74*q^6 + 111*q^7 + 173*q^8 + 251*q^9 + 379*q^10 + 560*q^11 + 824*q^12 + 1199*q^13 + 1773*q^14 + 2548*q^15 + 3722*q^16 + 5374*q^17 + O(q^18) sage: Y @@ -3928,7 +3945,8 @@ def cremona_label(self, space=False): sage: E.cremona_label() Traceback (most recent call last): ... - LookupError: Cremona database does not contain entry for Elliptic Curve defined by y^2 + y = x^3 - 79*x + 342 over Rational Field + LookupError: Cremona database does not contain entry for + Elliptic Curve defined by y^2 + y = x^3 - 79*x + 342 over Rational Field """ try: label = self.__cremona_label @@ -3961,22 +3979,22 @@ def reduction(self,p): EXAMPLES:: sage: E = EllipticCurve('389a1') - sage: E.reduction(2) + sage: E.reduction(2) # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 + y = x^3 + x^2 over Finite Field of size 2 - sage: E.reduction(3) + sage: E.reduction(3) # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 3 - sage: E.reduction(5) + sage: E.reduction(5) # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x over Finite Field of size 5 - sage: E.reduction(38) + sage: E.reduction(38) # optional - sage.rings.finite_rings Traceback (most recent call last): ... AttributeError: p must be prime. - sage: E.reduction(389) + sage: E.reduction(389) # optional - sage.rings.finite_rings Traceback (most recent call last): ... AttributeError: The curve must have good reduction at p. - sage: E = EllipticCurve([5^4,5^6]) - sage: E.reduction(5) + sage: E = EllipticCurve([5^4, 5^6]) + sage: E.reduction(5) # optional - sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5 """ p = rings.Integer(p) @@ -4061,14 +4079,16 @@ def torsion_subgroup(self): EXAMPLES:: sage: EllipticCurve('11a').torsion_subgroup() - Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Torsion Subgroup isomorphic to Z/5 associated to the + Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: EllipticCurve('37b').torsion_subgroup() - Torsion Subgroup isomorphic to Z/3 associated to the Elliptic Curve defined by y^2 + y = x^3 + x^2 - 23*x - 50 over Rational Field + Torsion Subgroup isomorphic to Z/3 associated to the + Elliptic Curve defined by y^2 + y = x^3 + x^2 - 23*x - 50 over Rational Field :: - sage: e = EllipticCurve([-1386747,368636886]);e - Elliptic Curve defined by y^2 = x^3 - 1386747*x + 368636886 over Rational Field + sage: e = EllipticCurve([-1386747,368636886]); e + Elliptic Curve defined by y^2 = x^3 - 1386747*x + 368636886 over Rational Field sage: G = e.torsion_subgroup(); G Torsion Subgroup isomorphic to Z/8 + Z/2 associated to the Elliptic Curve defined by y^2 = x^3 - 1386747*x + 368636886 over @@ -4078,7 +4098,10 @@ def torsion_subgroup(self): sage: G.1 (282 : 0 : 1) sage: list(G) - [(0 : 1 : 0), (147 : -12960 : 1), (2307 : -97200 : 1), (-933 : -29160 : 1), (1011 : 0 : 1), (-933 : 29160 : 1), (2307 : 97200 : 1), (147 : 12960 : 1), (-1293 : 0 : 1), (1227 : 22680 : 1), (-285 : 27216 : 1), (8787 : 816480 : 1), (282 : 0 : 1), (8787 : -816480 : 1), (-285 : -27216 : 1), (1227 : -22680 : 1)] + [(0 : 1 : 0), (147 : -12960 : 1), (2307 : -97200 : 1), (-933 : -29160 : 1), + (1011 : 0 : 1), (-933 : 29160 : 1), (2307 : 97200 : 1), (147 : 12960 : 1), + (-1293 : 0 : 1), (1227 : 22680 : 1), (-285 : 27216 : 1), (8787 : 816480 : 1), + (282 : 0 : 1), (8787 : -816480 : 1), (-285 : -27216 : 1), (1227 : -22680 : 1)] """ try: G = self.__torsion_subgroup @@ -4246,7 +4269,7 @@ def cm_discriminant(self): Return the associated quadratic discriminant if this elliptic curve has Complex Multiplication over the algebraic closure. - A ValueError is raised if the curve does not have CM (see the + A :class:`ValueError` is raised if the curve does not have CM (see the function :meth:`has_cm()`). EXAMPLES:: @@ -4261,7 +4284,8 @@ def cm_discriminant(self): sage: E.cm_discriminant() Traceback (most recent call last): ... - ValueError: Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field does not have CM + ValueError: Elliptic Curve defined by y^2 + y = x^3 - x + over Rational Field does not have CM """ try: @@ -4308,7 +4332,7 @@ def has_rational_cm(self, field=None): If we extend scalars to a field in which the discriminant is a square, the CM becomes rational:: - sage: E.has_rational_cm(QuadraticField(-3)) + sage: E.has_rational_cm(QuadraticField(-3)) # optional - sage.rings.number_field True sage: E = EllipticCurve(j=8000) @@ -4322,7 +4346,7 @@ def has_rational_cm(self, field=None): Again, we may extend scalars to a field in which the discriminant is a square, where the CM becomes rational:: - sage: E.has_rational_cm(QuadraticField(-2)) + sage: E.has_rational_cm(QuadraticField(-2)) # optional - sage.rings.number_field True The field need not be a number field provided that it is an @@ -4336,10 +4360,11 @@ def has_rational_cm(self, field=None): An error is raised if a field is given which is not an extension of `\QQ`, i.e., not of characteristic `0`:: - sage: E.has_rational_cm(GF(2)) + sage: E.has_rational_cm(GF(2)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: Error in has_rational_cm: Finite Field of size 2 is not an extension field of QQ + ValueError: Error in has_rational_cm: Finite Field of size 2 + is not an extension field of QQ """ if field is None: return False @@ -4363,8 +4388,8 @@ def quadratic_twist(self, D): EXAMPLES:: sage: E = EllipticCurve('37a1') - sage: E7=E.quadratic_twist(7); E7 - Elliptic Curve defined by y^2 = x^3 - 784*x + 5488 over Rational Field + sage: E7 = E.quadratic_twist(7); E7 + Elliptic Curve defined by y^2 = x^3 - 784*x + 5488 over Rational Field sage: E7.conductor() 29008 sage: E7.quadratic_twist(7) == E @@ -4667,16 +4692,27 @@ def isogenies_prime_degree(self, l=None): [] sage: E = EllipticCurve(j = -262537412640768000) sage: E.isogenies_prime_degree() - [Isogeny of degree 163 from Elliptic Curve defined by y^2 + y = x^3 - 2174420*x + 1234136692 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 57772164980*x - 5344733777551611 over Rational Field] + [Isogeny of degree 163 + from Elliptic Curve defined by y^2 + y = x^3 - 2174420*x + 1234136692 over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - 57772164980*x - 5344733777551611 over Rational Field] sage: E1 = E.quadratic_twist(6584935282) sage: E1.isogenies_prime_degree() - [Isogeny of degree 163 from Elliptic Curve defined by y^2 = x^3 - 94285835957031797981376080*x + 352385311612420041387338054224547830898 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 2505080375542377840567181069520*x - 1526091631109553256978090116318797845018020806 over Rational Field] + [Isogeny of degree 163 + from Elliptic Curve defined by y^2 = x^3 - 94285835957031797981376080*x + 352385311612420041387338054224547830898 over Rational Field + to Elliptic Curve defined by y^2 = x^3 - 2505080375542377840567181069520*x - 1526091631109553256978090116318797845018020806 over Rational Field] sage: E = EllipticCurve('14a1') sage: E.isogenies_prime_degree(2) - [Isogeny of degree 2 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 36*x - 70 over Rational Field] + [Isogeny of degree 2 + from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 - 36*x - 70 over Rational Field] sage: E.isogenies_prime_degree(3) - [Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - x over Rational Field, Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 171*x - 874 over Rational Field] + [Isogeny of degree 3 + from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 - x over Rational Field, + Isogeny of degree 3 + from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 - 171*x - 874 over Rational Field] sage: E.isogenies_prime_degree(5) [] sage: E.isogenies_prime_degree(11) @@ -5034,9 +5070,7 @@ def manin_constant(self): that in each class there is at least one, more precisely the so-called strong Weil curve or `X_0(N)`-optimal curve, that has Manin constant `1`. - OUTPUT: - - an integer + OUTPUT: An integer. This function only works if the curve is in the installed Cremona database. Sage includes by default a small database; @@ -5194,7 +5228,8 @@ def galois_representation(self): sage: rho = EllipticCurve('11a1').galois_representation() sage: rho - Compatible family of Galois representations associated to the Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Compatible family of Galois representations associated to the + Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: rho.is_irreducible(7) True sage: rho.is_irreducible(5) @@ -5447,9 +5482,10 @@ def sha(self): EXAMPLES:: sage: E = EllipticCurve('37a1') - sage: S=E.sha() + sage: S = E.sha() sage: S - Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + Tate-Shafarevich group for the Elliptic Curve + defined by y^2 + y = x^3 - x over Rational Field sage: S.bound_kolyvagin() ([2], 1) """ @@ -5508,7 +5544,8 @@ def mod5family(self): sage: E = EllipticCurve('32a1') sage: E.mod5family() - Elliptic Curve defined by y^2 = x^3 + 4*x over Fraction Field of Univariate Polynomial Ring in t over Rational Field + Elliptic Curve defined by y^2 = x^3 + 4*x + over Fraction Field of Univariate Polynomial Ring in t over Rational Field """ E = self.short_weierstrass_model() a = E.a4() @@ -5536,7 +5573,8 @@ def tate_curve(self, p): sage: e = EllipticCurve('130a1') sage: e.tate_curve(2) - 2-adic Tate curve associated to the Elliptic Curve defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field + 2-adic Tate curve associated to the Elliptic Curve + defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field The input curve must have multiplicative reduction at the prime. @@ -5550,7 +5588,8 @@ def tate_curve(self, p): We compute with `p=5`:: sage: T = e.tate_curve(5); T - 5-adic Tate curve associated to the Elliptic Curve defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field + 5-adic Tate curve associated to the Elliptic Curve + defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field We find the Tate parameter `q`:: @@ -5723,7 +5762,7 @@ def antilogarithm(self, z, max_denominator=None): - point on the curve: the rational point which is the image of `z` under the Weierstrass parametrization, if it exists and can be determined from `z` and the given value - of max_denominator (if any); otherwise a ``ValueError`` exception + of max_denominator (if any); otherwise a :class:`ValueError` exception is raised. EXAMPLES:: @@ -5826,8 +5865,8 @@ def integral_points(self, mw_base='auto', both_signs=False, verbose=False): .. NOTE:: The complexity increases exponentially in the rank of curve - E. The computation time (but not the output!) depends on - the Mordell-Weil basis. If mw_base is given but is not a + `E`. The computation time (but not the output!) depends on + the Mordell-Weil basis. If ``mw_base`` is given but is not a basis for the Mordell-Weil group (modulo torsion), integral points which are not in the subgroup generated by the given points will almost certainly not be listed. @@ -5835,9 +5874,12 @@ def integral_points(self, mw_base='auto', both_signs=False, verbose=False): EXAMPLES: A curve of rank 3 with no torsion points:: sage: E = EllipticCurve([0,0,1,-7,6]) - sage: P1=E.point((2,0)); P2=E.point((-1,3)); P3=E.point((4,6)) - sage: a=E.integral_points([P1,P2,P3]); a - [(-3 : 0 : 1), (-2 : 3 : 1), (-1 : 3 : 1), (0 : 2 : 1), (1 : 0 : 1), (2 : 0 : 1), (3 : 3 : 1), (4 : 6 : 1), (8 : 21 : 1), (11 : 35 : 1), (14 : 51 : 1), (21 : 95 : 1), (37 : 224 : 1), (52 : 374 : 1), (93 : 896 : 1), (342 : 6324 : 1), (406 : 8180 : 1), (816 : 23309 : 1)] + sage: P1 = E.point((2,0)); P2 = E.point((-1,3)); P3 = E.point((4,6)) + sage: a = E.integral_points([P1,P2,P3]); a + [(-3 : 0 : 1), (-2 : 3 : 1), (-1 : 3 : 1), (0 : 2 : 1), (1 : 0 : 1), + (2 : 0 : 1), (3 : 3 : 1), (4 : 6 : 1), (8 : 21 : 1), (11 : 35 : 1), + (14 : 51 : 1), (21 : 95 : 1), (37 : 224 : 1), (52 : 374 : 1), + (93 : 896 : 1), (342 : 6324 : 1), (406 : 8180 : 1), (816 : 23309 : 1)] :: @@ -5854,15 +5896,22 @@ def integral_points(self, mw_base='auto', both_signs=False, verbose=False): [2, 3, 4, 8, 11, 14, 21, 37, 52, 93, 342, 406, 816] Total number of integral points: 18 - It is not necessary to specify mw_base; if it is not provided, + It is not necessary to specify ``mw_base``; if it is not provided, then the Mordell-Weil basis must be computed, which may take much longer. :: sage: E = EllipticCurve([0,0,1,-7,6]) - sage: a=E.integral_points(both_signs=True); a - [(-3 : -1 : 1), (-3 : 0 : 1), (-2 : -4 : 1), (-2 : 3 : 1), (-1 : -4 : 1), (-1 : 3 : 1), (0 : -3 : 1), (0 : 2 : 1), (1 : -1 : 1), (1 : 0 : 1), (2 : -1 : 1), (2 : 0 : 1), (3 : -4 : 1), (3 : 3 : 1), (4 : -7 : 1), (4 : 6 : 1), (8 : -22 : 1), (8 : 21 : 1), (11 : -36 : 1), (11 : 35 : 1), (14 : -52 : 1), (14 : 51 : 1), (21 : -96 : 1), (21 : 95 : 1), (37 : -225 : 1), (37 : 224 : 1), (52 : -375 : 1), (52 : 374 : 1), (93 : -897 : 1), (93 : 896 : 1), (342 : -6325 : 1), (342 : 6324 : 1), (406 : -8181 : 1), (406 : 8180 : 1), (816 : -23310 : 1), (816 : 23309 : 1)] + sage: a = E.integral_points(both_signs=True); a + [(-3 : -1 : 1), (-3 : 0 : 1), (-2 : -4 : 1), (-2 : 3 : 1), (-1 : -4 : 1), + (-1 : 3 : 1), (0 : -3 : 1), (0 : 2 : 1), (1 : -1 : 1), (1 : 0 : 1), + (2 : -1 : 1), (2 : 0 : 1), (3 : -4 : 1), (3 : 3 : 1), (4 : -7 : 1), + (4 : 6 : 1), (8 : -22 : 1), (8 : 21 : 1), (11 : -36 : 1), (11 : 35 : 1), + (14 : -52 : 1), (14 : 51 : 1), (21 : -96 : 1), (21 : 95 : 1), + (37 : -225 : 1), (37 : 224 : 1), (52 : -375 : 1), (52 : 374 : 1), + (93 : -897 : 1), (93 : 896 : 1), (342 : -6325 : 1), (342 : 6324 : 1), + (406 : -8181 : 1), (406 : 8180 : 1), (816 : -23310 : 1), (816 : 23309 : 1)] An example with negative discriminant:: @@ -5872,10 +5921,10 @@ def integral_points(self, mw_base='auto', both_signs=False, verbose=False): Another example with rank 5 and no torsion points:: sage: E = EllipticCurve([-879984,319138704]) - sage: P1=E.point((540,1188)); P2=E.point((576,1836)) - sage: P3=E.point((468,3132)); P4=E.point((612,3132)) - sage: P5=E.point((432,4428)) - sage: a=E.integral_points([P1,P2,P3,P4,P5]); len(a) # long time (18s on sage.math, 2011) + sage: P1 = E.point((540,1188)); P2 = E.point((576,1836)) + sage: P3 = E.point((468,3132)); P4 = E.point((612,3132)) + sage: P5 = E.point((432,4428)) + sage: a = E.integral_points([P1,P2,P3,P4,P5]); len(a) # long time (18s on sage.math, 2011) 54 TESTS: @@ -5898,7 +5947,7 @@ def integral_points(self, mw_base='auto', both_signs=False, verbose=False): See :trac:`22063`:: sage: for n in [67,71,74,91]: - ....: assert 4*n^6+4*n^2 in [P[0] for P in EllipticCurve([0,0,0,2,n^2]).integral_points()] + ....: assert 4*n^6 + 4*n^2 in [P[0] for P in EllipticCurve([0,0,0,2,n^2]).integral_points()] ALGORITHM: @@ -6240,7 +6289,7 @@ def S_integral_points(self, S, mw_base='auto', both_signs=False, verbose=False, sage: P1 = E.point((2,0)) sage: P2 = E.point((-1,3)) sage: P3 = E.point((4,6)) - sage: a = E.S_integral_points(S=[2,3], mw_base=[P1,P2,P3], verbose=True);a + sage: a = E.S_integral_points(S=[2,3], mw_base=[P1,P2,P3], verbose=True); a max_S: 3 len_S: 3 len_tors: 1 lambda 0.485997517468... k1,k2,k3,k4 7.65200453902598e234 1.31952866480763 3.54035317966420e9 2.42767548272846e17 @@ -6266,7 +6315,19 @@ def S_integral_points(self, S, mw_base='auto', both_signs=False, verbose=False, x-coords of points with bounded absolute value [-3, -2, -1, 0, 1, 2] Total number of S-integral points: 43 - [(-3 : 0 : 1), (-26/9 : 28/27 : 1), (-8159/2916 : 233461/157464 : 1), (-2759/1024 : 60819/32768 : 1), (-151/64 : 1333/512 : 1), (-1343/576 : 36575/13824 : 1), (-2 : 3 : 1), (-7/4 : 25/8 : 1), (-1 : 3 : 1), (-47/256 : 9191/4096 : 1), (0 : 2 : 1), (1/4 : 13/8 : 1), (4/9 : 35/27 : 1), (9/16 : 69/64 : 1), (58/81 : 559/729 : 1), (7/9 : 17/27 : 1), (6169/6561 : 109871/531441 : 1), (1 : 0 : 1), (17/16 : -25/64 : 1), (2 : 0 : 1), (33/16 : 17/64 : 1), (172/81 : 350/729 : 1), (9/4 : 7/8 : 1), (25/9 : 64/27 : 1), (3 : 3 : 1), (31/9 : 116/27 : 1), (4 : 6 : 1), (25/4 : 111/8 : 1), (1793/256 : 68991/4096 : 1), (8 : 21 : 1), (625/64 : 14839/512 : 1), (11 : 35 : 1), (14 : 51 : 1), (21 : 95 : 1), (37 : 224 : 1), (52 : 374 : 1), (6142/81 : 480700/729 : 1), (93 : 896 : 1), (4537/36 : 305425/216 : 1), (342 : 6324 : 1), (406 : 8180 : 1), (816 : 23309 : 1), (207331217/4096 : 2985362173625/262144 : 1)] + [(-3 : 0 : 1), (-26/9 : 28/27 : 1), (-8159/2916 : 233461/157464 : 1), + (-2759/1024 : 60819/32768 : 1), (-151/64 : 1333/512 : 1), + (-1343/576 : 36575/13824 : 1), (-2 : 3 : 1), (-7/4 : 25/8 : 1), (-1 : 3 : 1), + (-47/256 : 9191/4096 : 1), (0 : 2 : 1), (1/4 : 13/8 : 1), (4/9 : 35/27 : 1), + (9/16 : 69/64 : 1), (58/81 : 559/729 : 1), (7/9 : 17/27 : 1), + (6169/6561 : 109871/531441 : 1), (1 : 0 : 1), (17/16 : -25/64 : 1), (2 : 0 : 1), + (33/16 : 17/64 : 1), (172/81 : 350/729 : 1), (9/4 : 7/8 : 1), (25/9 : 64/27 : 1), + (3 : 3 : 1), (31/9 : 116/27 : 1), (4 : 6 : 1), (25/4 : 111/8 : 1), + (1793/256 : 68991/4096 : 1), (8 : 21 : 1), (625/64 : 14839/512 : 1), (11 : 35 : 1), + (14 : 51 : 1), (21 : 95 : 1), (37 : 224 : 1), (52 : 374 : 1), + (6142/81 : 480700/729 : 1), (93 : 896 : 1), (4537/36 : 305425/216 : 1), + (342 : 6324 : 1), (406 : 8180 : 1), (816 : 23309 : 1), + (207331217/4096 : 2985362173625/262144 : 1)] It is not necessary to specify mw_base; if it is not provided, then the Mordell-Weil basis must be computed, which may take @@ -6281,7 +6342,9 @@ def S_integral_points(self, S, mw_base='auto', both_signs=False, verbose=False, An example with negative discriminant:: sage: EllipticCurve('900d1').S_integral_points([17], both_signs=True) - [(-11 : -27 : 1), (-11 : 27 : 1), (-4 : -34 : 1), (-4 : 34 : 1), (4 : -18 : 1), (4 : 18 : 1), (2636/289 : -98786/4913 : 1), (2636/289 : 98786/4913 : 1), (16 : -54 : 1), (16 : 54 : 1)] + [(-11 : -27 : 1), (-11 : 27 : 1), (-4 : -34 : 1), (-4 : 34 : 1), (4 : -18 : 1), + (4 : 18 : 1), (2636/289 : -98786/4913 : 1), (2636/289 : 98786/4913 : 1), + (16 : -54 : 1), (16 : 54 : 1)] Output checked with Magma (corrected in 3 cases):: @@ -6298,16 +6361,16 @@ def S_integral_points(self, S, mw_base='auto', both_signs=False, verbose=False, sage: EllipticCurve([1,1,1,-301,-1821]).S_integral_points([13,2]) [(-13 : 16 : 1), - (-9 : 20 : 1), - (-7 : 4 : 1), - (21 : 30 : 1), - (23 : 52 : 1), - (63 : 452 : 1), - (71 : 548 : 1), - (87 : 756 : 1), - (2711 : 139828 : 1), - (7323 : 623052 : 1), - (17687 : 2343476 : 1)] + (-9 : 20 : 1), + (-7 : 4 : 1), + (21 : 30 : 1), + (23 : 52 : 1), + (63 : 452 : 1), + (71 : 548 : 1), + (87 : 756 : 1), + (2711 : 139828 : 1), + (7323 : 623052 : 1), + (17687 : 2343476 : 1)] - Some parts of this implementation are partially based on the function integral_points() @@ -6842,25 +6905,25 @@ def cremona_curves(conductors): sage: [(E.label(), E.rank()) for E in cremona_curves(srange(35,40))] [('35a1', 0), - ('35a2', 0), - ('35a3', 0), - ('36a1', 0), - ('36a2', 0), - ('36a3', 0), - ('36a4', 0), - ('37a1', 1), - ('37b1', 0), - ('37b2', 0), - ('37b3', 0), - ('38a1', 0), - ('38a2', 0), - ('38a3', 0), - ('38b1', 0), - ('38b2', 0), - ('39a1', 0), - ('39a2', 0), - ('39a3', 0), - ('39a4', 0)] + ('35a2', 0), + ('35a3', 0), + ('36a1', 0), + ('36a2', 0), + ('36a3', 0), + ('36a4', 0), + ('37a1', 1), + ('37b1', 0), + ('37b2', 0), + ('37b3', 0), + ('38a1', 0), + ('38a2', 0), + ('38a3', 0), + ('38b1', 0), + ('38b2', 0), + ('39a1', 0), + ('39a2', 0), + ('39a3', 0), + ('39a4', 0)] """ if isinstance(conductors, (rings.RingElement, int)): conductors = [conductors] @@ -6875,17 +6938,18 @@ def cremona_optimal_curves(conductors): sage: [(E.label(), E.rank()) for E in cremona_optimal_curves(srange(35,40))] [('35a1', 0), - ('36a1', 0), - ('37a1', 1), - ('37b1', 0), - ('38a1', 0), - ('38b1', 0), - ('39a1', 0)] + ('36a1', 0), + ('37a1', 1), + ('37b1', 0), + ('38a1', 0), + ('38b1', 0), + ('39a1', 0)] There is one case -- 990h3 -- when the optimal curve isn't labeled with a 1:: sage: [e.cremona_label() for e in cremona_optimal_curves([990])] - ['990a1', '990b1', '990c1', '990d1', '990e1', '990f1', '990g1', '990h3', '990i1', '990j1', '990k1', '990l1'] + ['990a1', '990b1', '990c1', '990d1', '990e1', '990f1', '990g1', + '990h3', '990i1', '990j1', '990k1', '990l1'] """ if isinstance(conductors, (rings.RingElement, int)): conductors = [conductors] @@ -6915,11 +6979,11 @@ def integral_points_with_bounded_mw_coeffs(E, mw_base, N, x_bound): We check that some large integral points in a paper of Zagier are found:: - sage: def t(a,b,x): # indirect doctest - ....: E = EllipticCurve([0,0,0,a,b]) - ....: xs = [P[0] for P in E.integral_points()] - ....: return x in xs - sage: all(t(a,b,x) for a,b,x in [ (-2,5, 1318), (4,-1, 4321), + sage: def t(a, b, x): # indirect doctest + ....: E = EllipticCurve([0,0,0,a,b]) + ....: xs = [P[0] for P in E.integral_points()] + ....: return x in xs + sage: all(t(a,b,x) for a,b,x in [(-2,5, 1318), (4,-1, 4321), ....: (0,17, 5234), (11,4, 16833), (-13,37, 60721), (-12,-10, 80327), ....: (-7,22, 484961), (-9,28, 764396), (-13,4, 1056517), (-19,-51, ....: 2955980), (-24,124, 4435710), (-30,133, 5143326), (-37,60, diff --git a/src/sage/schemes/elliptic_curves/ell_tate_curve.py b/src/sage/schemes/elliptic_curves/ell_tate_curve.py index 4b7cd3e82c5..0b7cd52a146 100644 --- a/src/sage/schemes/elliptic_curves/ell_tate_curve.py +++ b/src/sage/schemes/elliptic_curves/ell_tate_curve.py @@ -68,7 +68,8 @@ class TateCurve(SageObject): sage: e = EllipticCurve('130a1') sage: eq = e.tate_curve(5); eq - 5-adic Tate curve associated to the Elliptic Curve defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field + 5-adic Tate curve associated to the Elliptic Curve + defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field sage: eq == loads(dumps(eq)) True @@ -87,7 +88,8 @@ def __init__(self, E, p): sage: e = EllipticCurve('130a1') sage: eq = e.tate_curve(2); eq - 2-adic Tate curve associated to the Elliptic Curve defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field + 2-adic Tate curve associated to the Elliptic Curve + defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field """ if not p.is_prime(): raise ValueError("p (=%s) must be a prime" % p) @@ -138,7 +140,7 @@ def original_curve(self): sage: eq = EllipticCurve('130a1').tate_curve(5) sage: eq.original_curve() Elliptic Curve defined by y^2 + x*y + y = x^3 - 33*x + 68 - over Rational Field + over Rational Field """ return self._E @@ -151,7 +153,7 @@ def prime(self): sage: eq = EllipticCurve('130a1').tate_curve(5) sage: eq.original_curve() Elliptic Curve defined by y^2 + x*y + y = x^3 - 33*x + 68 - over Rational Field + over Rational Field sage: eq.prime() 5 """ @@ -213,10 +215,9 @@ def curve(self, prec=20): sage: eq = EllipticCurve('130a1').tate_curve(5) sage: eq.curve(prec=5) - Elliptic Curve defined by y^2 + (1+O(5^5))*x*y = x^3 + - (2*5^4+5^5+2*5^6+5^7+3*5^8+O(5^9))*x + - (2*5^3+5^4+2*5^5+5^7+O(5^8)) over 5-adic - Field with capped relative precision 5 + Elliptic Curve defined by y^2 + (1+O(5^5))*x*y = + x^3 + (2*5^4+5^5+2*5^6+5^7+3*5^8+O(5^9))*x + (2*5^3+5^4+2*5^5+5^7+O(5^8)) + over 5-adic Field with capped relative precision 5 """ Eq = getattr(self, "__curve", None) if Eq and Eq.a6().precision_relative() >= prec: @@ -321,9 +322,11 @@ def parametrisation_onto_tate_curve(self, u, prec=None): sage: eq = EllipticCurve('130a1').tate_curve(5) sage: eq.parametrisation_onto_tate_curve(1+5+5^2+O(5^10), prec=10) - (5^-2 + 4*5^-1 + 1 + 2*5 + 3*5^2 + 2*5^5 + 3*5^6 + O(5^7) : 4*5^-3 + 2*5^-1 + 4 + 2*5 + 3*5^4 + 2*5^5 + O(5^6) : 1 + O(5^10)) + (5^-2 + 4*5^-1 + 1 + 2*5 + 3*5^2 + 2*5^5 + 3*5^6 + O(5^7) + : 4*5^-3 + 2*5^-1 + 4 + 2*5 + 3*5^4 + 2*5^5 + O(5^6) : 1 + O(5^10)) sage: eq.parametrisation_onto_tate_curve(1+5+5^2+O(5^10)) - (5^-2 + 4*5^-1 + 1 + 2*5 + 3*5^2 + 2*5^5 + 3*5^6 + O(5^7) : 4*5^-3 + 2*5^-1 + 4 + 2*5 + 3*5^4 + 2*5^5 + O(5^6) : 1 + O(5^10)) + (5^-2 + 4*5^-1 + 1 + 2*5 + 3*5^2 + 2*5^5 + 3*5^6 + O(5^7) + : 4*5^-3 + 2*5^-1 + 4 + 2*5 + 3*5^4 + 2*5^5 + O(5^6) : 1 + O(5^10)) sage: eq.parametrisation_onto_tate_curve(1+5+5^2+O(5^10), prec=20) Traceback (most recent call last): ... @@ -447,7 +450,7 @@ def _inverse_isomorphism(self, prec=20): sage: eq = EllipticCurve('130a1').tate_curve(5) sage: eq._inverse_isomorphism(prec=5) [3 + 2*5 + 3*5^3 + O(5^5), 4 + 2*5 + 4*5^3 + 3*5^4 + O(5^5), - 1 + 5 + 4*5^3 + 2*5^4 + O(5^5), 5 + 2*5^2 + 3*5^4 + O(5^5)] + 1 + 5 + 4*5^3 + 2*5^4 + O(5^5), 5 + 2*5^2 + 3*5^4 + O(5^5)] """ if not self.is_split(): raise RuntimeError("the curve must have split multiplicative " @@ -478,10 +481,12 @@ def lift(self, P, prec=20): Now we map the lift l back and check that it is indeed right.:: sage: eq.parametrisation_onto_original_curve(l) - (4*5^-2 + 2*5^-1 + 4*5 + 3*5^3 + 5^4 + 2*5^5 + 4*5^6 + O(5^7) : 2*5^-3 + 5^-1 + 4 + 4*5 + 5^2 + 3*5^3 + 4*5^4 + O(5^6) : 1 + O(5^10)) + (4*5^-2 + 2*5^-1 + 4*5 + 3*5^3 + 5^4 + 2*5^5 + 4*5^6 + O(5^7) + : 2*5^-3 + 5^-1 + 4 + 4*5 + 5^2 + 3*5^3 + 4*5^4 + O(5^6) : 1 + O(5^10)) sage: e5 = e.change_ring(Qp(5,9)) sage: e5(12*P) - (4*5^-2 + 2*5^-1 + 4*5 + 3*5^3 + 5^4 + 2*5^5 + 4*5^6 + O(5^7) : 2*5^-3 + 5^-1 + 4 + 4*5 + 5^2 + 3*5^3 + 4*5^4 + O(5^6) : 1 + O(5^9)) + (4*5^-2 + 2*5^-1 + 4*5 + 3*5^3 + 5^4 + 2*5^5 + 4*5^6 + O(5^7) + : 2*5^-3 + 5^-1 + 4 + 4*5 + 5^2 + 3*5^3 + 4*5^4 + O(5^6) : 1 + O(5^9)) """ p = self._p R = Qp(self._p, prec) @@ -527,8 +532,8 @@ def parametrisation_onto_original_curve(self, u, prec=None): sage: eq = EllipticCurve('130a1').tate_curve(5) sage: eq.parametrisation_onto_original_curve(1+5+5^2+O(5^10)) (4*5^-2 + 4*5^-1 + 4 + 2*5^3 + 3*5^4 + 2*5^6 + O(5^7) : - 3*5^-3 + 5^-2 + 4*5^-1 + 1 + 4*5 + 5^2 + 3*5^5 + O(5^6) : - 1 + O(5^10)) + 3*5^-3 + 5^-2 + 4*5^-1 + 1 + 4*5 + 5^2 + 3*5^5 + O(5^6) : + 1 + O(5^10)) sage: eq.parametrisation_onto_original_curve(1+5+5^2+O(5^10), prec=20) Traceback (most recent call last): ... diff --git a/src/sage/schemes/elliptic_curves/ell_torsion.py b/src/sage/schemes/elliptic_curves/ell_torsion.py index 7bfda81486a..6a84cb8a5e6 100644 --- a/src/sage/schemes/elliptic_curves/ell_torsion.py +++ b/src/sage/schemes/elliptic_curves/ell_torsion.py @@ -7,7 +7,7 @@ - Nick Alexander: original implementation over `\QQ` - Chris Wuthrich: original implementation over number fields - John Cremona: rewrote p-primary part to use division - polynomials, added some features, unified Number Field and `\QQ` code. + polynomials, added some features, unified Number Field and `\QQ` code. """ # **************************************************************************** @@ -41,9 +41,10 @@ class EllipticCurveTorsionSubgroup(groups.AdditiveAbelianGroupWrapper): Examples over `\QQ`:: sage: E = EllipticCurve([-4, 0]); E - Elliptic Curve defined by y^2 = x^3 - 4*x over Rational Field + Elliptic Curve defined by y^2 = x^3 - 4*x over Rational Field sage: G = E.torsion_subgroup(); G - Torsion Subgroup isomorphic to Z/2 + Z/2 associated to the Elliptic Curve defined by y^2 = x^3 - 4*x over Rational Field + Torsion Subgroup isomorphic to Z/2 + Z/2 associated to the + Elliptic Curve defined by y^2 = x^3 - 4*x over Rational Field sage: G.order() 4 sage: G.gen(0) @@ -58,12 +59,13 @@ class EllipticCurveTorsionSubgroup(groups.AdditiveAbelianGroupWrapper): sage: E = EllipticCurve([17, -120, -60, 0, 0]); E Elliptic Curve defined by y^2 + 17*x*y - 60*y = x^3 - 120*x^2 over Rational Field sage: G = E.torsion_subgroup(); G - Torsion Subgroup isomorphic to Trivial group associated to the Elliptic Curve defined by y^2 + 17*x*y - 60*y = x^3 - 120*x^2 over Rational Field + Torsion Subgroup isomorphic to Trivial group associated to the + Elliptic Curve defined by y^2 + 17*x*y - 60*y = x^3 - 120*x^2 over Rational Field sage: G.gens() () - sage: e = EllipticCurve([0, 33076156654533652066609946884,0,\ - 347897536144342179642120321790729023127716119338758604800,\ - 1141128154369274295519023032806804247788154621049857648870032370285851781352816640000]) + sage: e = EllipticCurve([0, 33076156654533652066609946884, 0, + ....: 347897536144342179642120321790729023127716119338758604800, + ....: 1141128154369274295519023032806804247788154621049857648870032370285851781352816640000]) sage: e.torsion_order() 16 @@ -73,11 +75,11 @@ class EllipticCurveTorsionSubgroup(groups.AdditiveAbelianGroupWrapper): sage: T = E.torsion_subgroup() sage: [E(t) for t in T] [(0 : 1 : 0), - (9 : 23 : 1), - (2 : 2 : 1), - (1 : -1 : 1), - (2 : -5 : 1), - (9 : -33 : 1)] + (9 : 23 : 1), + (2 : 2 : 1), + (1 : -1 : 1), + (2 : -5 : 1), + (9 : -33 : 1)] An example where the torsion subgroup is not cyclic:: @@ -91,21 +93,24 @@ class EllipticCurveTorsionSubgroup(groups.AdditiveAbelianGroupWrapper): sage: E = EllipticCurve('37a1') sage: T = E.torsion_subgroup() sage: T - Torsion Subgroup isomorphic to Trivial group associated to the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + Torsion Subgroup isomorphic to Trivial group associated to the + Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field sage: [E(t) for t in T] [(0 : 1 : 0)] Examples over other Number Fields:: sage: E = EllipticCurve('11a1') - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: EK = E.change_ring(K) sage: from sage.schemes.elliptic_curves.ell_torsion import EllipticCurveTorsionSubgroup sage: EllipticCurveTorsionSubgroup(EK) - Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1 + Torsion Subgroup isomorphic to Z/5 associated to the + Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) + over Number Field in i with defining polynomial x^2 + 1 sage: E = EllipticCurve('11a1') - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: EK = E.change_ring(K) sage: T = EK.torsion_subgroup() sage: T.ngens() @@ -116,7 +121,9 @@ class EllipticCurveTorsionSubgroup(groups.AdditiveAbelianGroupWrapper): Note: this class is normally constructed indirectly as follows:: sage: T = EK.torsion_subgroup(); T - Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1 + Torsion Subgroup isomorphic to Z/5 associated to the + Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) + over Number Field in i with defining polynomial x^2 + 1 sage: type(T) @@ -141,12 +148,16 @@ def __init__(self, E): sage: K. = NumberField(x^2+1) sage: EK = E.change_ring(K) sage: EllipticCurveTorsionSubgroup(EK) - Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1 + Torsion Subgroup isomorphic to Z/5 associated to the + Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) + over Number Field in i with defining polynomial x^2 + 1 Note: this class is normally constructed indirectly as follows:: sage: T = EK.torsion_subgroup(); T - Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1 + Torsion Subgroup isomorphic to Z/5 associated to the + Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) + over Number Field in i with defining polynomial x^2 + 1 sage: type(T) @@ -205,7 +216,7 @@ def _repr_(self): EXAMPLES:: sage: E = EllipticCurve('11a1') - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: EK = E.change_ring(K) sage: T = EK.torsion_subgroup(); T._repr_() 'Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1' @@ -234,7 +245,7 @@ def curve(self): EXAMPLES:: sage: E = EllipticCurve('11a1') - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: EK = E.change_ring(K) sage: T = EK.torsion_subgroup() sage: T.curve() is EK @@ -252,7 +263,7 @@ def points(self): EXAMPLES:: sage: K. = NumberField(x^2 + 1) - sage: E = EllipticCurve(K,[0,0,0,1,0]) + sage: E = EllipticCurve(K, [0,0,0,1,0]) sage: tor = E.torsion_subgroup() sage: tor.points() [(0 : 1 : 0), (0 : 0 : 1), (-i : 0 : 1), (i : 0 : 1)] @@ -269,7 +280,7 @@ def torsion_bound(E, number_of_places=20): - ``E`` -- an elliptic curve over `\QQ` or a number field - ``number_of_places`` (positive integer, default = 20) -- the - number of places that will be used to find the bound + number of places that will be used to find the bound OUTPUT: @@ -301,8 +312,8 @@ def torsion_bound(E, number_of_places=20): sage: R. = QQ[] sage: F. = QuadraticField(5) - sage: K. = F.extension(x^2-3) - sage: E = EllipticCurve(K,[0,0,0,b,1]) + sage: K. = F.extension(x^2 - 3) + sage: E = EllipticCurve(K, [0,0,0,b,1]) sage: E.torsion_subgroup().order() 1 diff --git a/src/sage/schemes/elliptic_curves/ell_wp.py b/src/sage/schemes/elliptic_curves/ell_wp.py index 8ea82fe35e2..820b9050a22 100644 --- a/src/sage/schemes/elliptic_curves/ell_wp.py +++ b/src/sage/schemes/elliptic_curves/ell_wp.py @@ -91,36 +91,42 @@ def weierstrass_p(E, prec=20, algorithm=None): sage: E.weierstrass_p(prec=8, algorithm='quadratic') z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + O(z^8) - sage: k = GF(11) - sage: E = EllipticCurve(k, [1,1]) - sage: E.weierstrass_p(prec=6, algorithm='fast') + sage: k = GF(11) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(k, [1,1]) # optional - sage.rings.finite_rings + sage: E.weierstrass_p(prec=6, algorithm='fast') # optional - sage.rings.finite_rings z^-2 + 2*z^2 + 3*z^4 + O(z^6) - sage: E.weierstrass_p(prec=7, algorithm='fast') + sage: E.weierstrass_p(prec=7, algorithm='fast') # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: for computing the Weierstrass p-function via the fast algorithm, the characteristic (11) of the underlying field must be greater than prec + 4 = 11 - sage: E.weierstrass_p(prec=8) + ValueError: for computing the Weierstrass p-function via the fast algorithm, + the characteristic (11) of the underlying field must be greater than prec + 4 = 11 + sage: E.weierstrass_p(prec=8) # optional - sage.rings.finite_rings z^-2 + 2*z^2 + 3*z^4 + 5*z^6 + O(z^8) - sage: E.weierstrass_p(prec=8, algorithm='quadratic') + sage: E.weierstrass_p(prec=8, algorithm='quadratic') # optional - sage.rings.finite_rings z^-2 + 2*z^2 + 3*z^4 + 5*z^6 + O(z^8) - sage: E.weierstrass_p(prec=8, algorithm='pari') + sage: E.weierstrass_p(prec=8, algorithm='pari') # optional - sage.rings.finite_rings z^-2 + 2*z^2 + 3*z^4 + 5*z^6 + O(z^8) - sage: E.weierstrass_p(prec=9) + sage: E.weierstrass_p(prec=9) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - NotImplementedError: currently no algorithms for computing the Weierstrass p-function for that characteristic / precision pair is implemented. Lower the precision below char(k) - 2 - sage: E.weierstrass_p(prec=9, algorithm="quadratic") + NotImplementedError: currently no algorithms for computing the Weierstrass + p-function for that characteristic / precision pair is implemented. + Lower the precision below char(k) - 2 + sage: E.weierstrass_p(prec=9, algorithm="quadratic") # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: for computing the Weierstrass p-function via the quadratic algorithm, the characteristic (11) of the underlying field must be greater than prec + 2 = 11 - sage: E.weierstrass_p(prec=9, algorithm='pari') + ValueError: for computing the Weierstrass p-function via the quadratic + algorithm, the characteristic (11) of the underlying field must be greater + than prec + 2 = 11 + sage: E.weierstrass_p(prec=9, algorithm='pari') # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: for computing the Weierstrass p-function via pari, the characteristic (11) of the underlying field must be greater than prec + 2 = 11 + ValueError: for computing the Weierstrass p-function via pari, the + characteristic (11) of the underlying field must be greater than prec + 2 = 11 TESTS:: - sage: E.weierstrass_p(prec=4, algorithm='foo') + sage: E.weierstrass_p(prec=4, algorithm='foo') # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: unknown algorithm for computing the Weierstrass p-function @@ -173,7 +179,8 @@ def compute_wp_pari(E,prec): sage: compute_wp_pari(E, prec=20) z^-2 - 1/7*z^4 + 1/637*z^10 - 1/84721*z^16 + O(z^20) sage: compute_wp_pari(E, prec=30) - z^-2 - 1/7*z^4 + 1/637*z^10 - 1/84721*z^16 + 3/38548055*z^22 - 4/8364927935*z^28 + O(z^30) + z^-2 - 1/7*z^4 + 1/637*z^10 - 1/84721*z^16 + + 3/38548055*z^22 - 4/8364927935*z^28 + O(z^30) """ ep = E.__pari__() wpp = ep.ellwp(n=prec) @@ -198,10 +205,10 @@ def compute_wp_quadratic(k, A, B, prec): INPUT: - - ``k`` -- the field of definition of the curve - - ``A`` -- and - - ``B`` -- the coefficients of the elliptic curve - - ``prec`` -- the precision to which we compute the series. + - ``k`` -- the field of definition of the curve + - ``A`` -- and + - ``B`` -- the coefficients of the elliptic curve + - ``prec`` -- the precision to which we compute the series. OUTPUT: @@ -217,12 +224,13 @@ def compute_wp_quadratic(k, A, B, prec): sage: E.weierstrass_p(prec=10, algorithm='quadratic') z^-2 - 7/5*z^2 + 49/75*z^6 + O(z^10) - sage: E = EllipticCurve(GF(103),[1,2]) - sage: E.weierstrass_p(algorithm='quadratic') - z^-2 + 41*z^2 + 88*z^4 + 11*z^6 + 57*z^8 + 55*z^10 + 73*z^12 + 11*z^14 + 17*z^16 + 50*z^18 + O(z^20) + sage: E = EllipticCurve(GF(103), [1,2]) # optional - sage.rings.finite_rings + sage: E.weierstrass_p(algorithm='quadratic') # optional - sage.rings.finite_rings + z^-2 + 41*z^2 + 88*z^4 + 11*z^6 + 57*z^8 + 55*z^10 + 73*z^12 + + 11*z^14 + 17*z^16 + 50*z^18 + O(z^20) sage: from sage.schemes.elliptic_curves.ell_wp import compute_wp_quadratic - sage: compute_wp_quadratic(E.base_ring(), E.a4(), E.a6(), prec=10) + sage: compute_wp_quadratic(E.base_ring(), E.a4(), E.a6(), prec=10) # optional - sage.rings.finite_rings z^-2 + 41*z^2 + 88*z^4 + 11*z^6 + 57*z^8 + O(z^10) """ m = (prec + 1)//2 @@ -247,16 +255,18 @@ def compute_wp_quadratic(k, A, B, prec): def compute_wp_fast(k, A, B, m): r""" - Computes the Weierstrass function of an elliptic curve defined by short Weierstrass model: `y^2 = x^3 + Ax + B`. It does this with as fast as polynomial of degree `m` can be multiplied together in the base ring, i.e. `O(M(n))` in the notation of [BMSS2006]_. + Computes the Weierstrass function of an elliptic curve defined by short Weierstrass model: + `y^2 = x^3 + Ax + B`. It does this with as fast as polynomial of degree `m` can be multiplied + together in the base ring, i.e. `O(M(n))` in the notation of [BMSS2006]_. Let `p` be the characteristic of the underlying field: Then we must have either `p=0`, or `p > m + 3`. INPUT: - - ``k`` -- the base field of the curve - - ``A`` -- and - - ``B`` -- as the coefficients of the short Weierstrass model `y^2 = x^3 +Ax +B`, and - - ``m`` -- the precision to which the function is computed to. + - ``k`` -- the base field of the curve + - ``A`` -- and + - ``B`` -- as the coefficients of the short Weierstrass model `y^2 = x^3 +Ax +B`, and + - ``m`` -- the precision to which the function is computed to. OUTPUT: @@ -273,8 +283,8 @@ def compute_wp_fast(k, A, B, m): sage: compute_wp_fast(QQ, 1, 8, 7) z^-2 - 1/5*z^2 - 8/7*z^4 + 1/75*z^6 + O(z^7) - sage: k = GF(37) - sage: compute_wp_fast(k, k(1), k(8), 5) + sage: k = GF(37) # optional - sage.rings.finite_rings + sage: compute_wp_fast(k, k(1), k(8), 5) # optional - sage.rings.finite_rings z^-2 + 22*z^2 + 20*z^4 + O(z^5) """ R = PowerSeriesRing(k,'z',default_prec=m+5) @@ -320,15 +330,15 @@ def solve_linear_differential_system(a, b, c, alpha): EXAMPLES:: sage: from sage.schemes.elliptic_curves.ell_wp import solve_linear_differential_system - sage: k = GF(17) - sage: R. = PowerSeriesRing(k) - sage: a = 1+x+O(x^7); b = x+O(x^7); c = 1+x^3+O(x^7); alpha = k(3) - sage: f = solve_linear_differential_system(a,b,c,alpha) - sage: f + sage: k = GF(17) # optional - sage.rings.finite_rings + sage: R. = PowerSeriesRing(k) # optional - sage.rings.finite_rings + sage: a = 1 + x + O(x^7); b = x + O(x^7); c = 1 + x^3 + O(x^7); alpha = k(3) # optional - sage.rings.finite_rings + sage: f = solve_linear_differential_system(a, b, c, alpha) # optional - sage.rings.finite_rings + sage: f # optional - sage.rings.finite_rings 3 + x + 15*x^2 + x^3 + 10*x^5 + 3*x^6 + 13*x^7 + O(x^8) - sage: a*f.derivative()+b*f - c + sage: a*f.derivative() + b*f - c # optional - sage.rings.finite_rings O(x^7) - sage: f(0) == alpha + sage: f(0) == alpha # optional - sage.rings.finite_rings True """ a_recip = 1/a diff --git a/src/sage/schemes/elliptic_curves/formal_group.py b/src/sage/schemes/elliptic_curves/formal_group.py index 591ce2d6f29..18fb8b6c9d1 100644 --- a/src/sage/schemes/elliptic_curves/formal_group.py +++ b/src/sage/schemes/elliptic_curves/formal_group.py @@ -29,7 +29,8 @@ def __init__(self, E): sage: E = EllipticCurve('11a') sage: F = E.formal_group(); F - Formal Group associated to the Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Formal Group associated to the Elliptic Curve + defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: F == loads(dumps(F)) True """ @@ -395,7 +396,7 @@ def log(self, prec=20): def inverse(self, prec=20): r""" - Return the formal group inverse law i(t), which satisfies F(t, i(t)) = 0. + Return the formal group inverse law `i(t)`, which satisfies `F(t, i(t)) = 0`. INPUT: @@ -454,8 +455,8 @@ def group_law(self, prec=10): - ``prec`` -- integer (default: 10) - OUTPUT: a power series with given precision in R[['t1','t2']], where - the curve is defined over R. + OUTPUT: a power series with given precision in `R[[t_1,t_2]]`, where + the curve is defined over `R`. Return the formal power series @@ -463,7 +464,7 @@ def group_law(self, prec=10): F(t_1, t_2) = t_1 + t_2 - a_1 t_1 t_2 - \cdots - to precision `O(t1,t2)^{prec}` of page 115 of [Sil2009]_. + to precision `O(t_1,t_2)^{prec}` of page 115 of [Sil2009]_. The result is cached, and a cached version is returned if possible. @@ -486,26 +487,26 @@ def group_law(self, prec=10): sage: ehat.group_law(5) t1 + t2 - t1*t2 - 2*t1^3*t2 - 3*t1^2*t2^2 - 2*t1*t2^3 + O(t1, t2)^5 - sage: e = EllipticCurve(GF(7), [3, 4]) - sage: ehat = e.formal() - sage: ehat.group_law(3) + sage: e = EllipticCurve(GF(7), [3, 4]) # optional - sage.rings.finite_rings + sage: ehat = e.formal() # optional - sage.rings.finite_rings + sage: ehat.group_law(3) # optional - sage.rings.finite_rings t1 + t2 + O(t1, t2)^3 - sage: F = ehat.group_law(7); F + sage: F = ehat.group_law(7); F # optional - sage.rings.finite_rings t1 + t2 + t1^4*t2 + 2*t1^3*t2^2 + 2*t1^2*t2^3 + t1*t2^4 + O(t1, t2)^7 TESTS:: - sage: R. = GF(7)[[]] - sage: F(x, ehat.inverse()(x)) + sage: R. = GF(7)[[]] # optional - sage.rings.finite_rings + sage: F(x, ehat.inverse()(x)) # optional - sage.rings.finite_rings 0 + O(x, y, z)^7 - sage: F(x, y) == F(y, x) + sage: F(x, y) == F(y, x) # optional - sage.rings.finite_rings True - sage: F(x, F(y, z)) == F(F(x, y), z) + sage: F(x, F(y, z)) == F(F(x, y), z) # optional - sage.rings.finite_rings True Let's ensure caching with changed precision is working:: - sage: e.formal_group().group_law(4) + sage: e.formal_group().group_law(4) # optional - sage.rings.finite_rings t1 + t2 + O(t1, t2)^4 Test for :trac:`9646`:: @@ -623,21 +624,21 @@ def mult_by_n(self, n, prec=10): TESTS:: - sage: F = EllipticCurve(GF(17), [1, 1]).formal_group() - sage: F.mult_by_n(10, 50) # long time (13s on sage.math, 2011) + sage: F = EllipticCurve(GF(17), [1, 1]).formal_group() # optional - sage.rings.finite_rings + sage: F.mult_by_n(10, 50) # long time (13s on sage.math, 2011) # optional - sage.rings.finite_rings 10*t + 5*t^5 + 7*t^7 + 13*t^9 + t^11 + 16*t^13 + 13*t^15 + 9*t^17 + 16*t^19 + 15*t^23 + 15*t^25 + 2*t^27 + 10*t^29 + 8*t^31 + 15*t^33 + 6*t^35 + 7*t^37 + 9*t^39 + 10*t^41 + 5*t^43 + 4*t^45 + 6*t^47 + 13*t^49 + O(t^50) - sage: F = EllipticCurve(GF(101), [1, 1]).formal_group() - sage: F.mult_by_n(100, 20) + sage: F = EllipticCurve(GF(101), [1, 1]).formal_group() # optional - sage.rings.finite_rings + sage: F.mult_by_n(100, 20) # optional - sage.rings.finite_rings 100*t + O(t^20) sage: P. = PolynomialRing(ZZ, 5) sage: E = EllipticCurve(list(P.gens())) - sage: E.formal().mult_by_n(2,prec=5) + sage: E.formal().mult_by_n(2, prec=5) 2*t - a1*t^2 - 2*a2*t^3 + (a1*a2 - 7*a3)*t^4 + O(t^5) sage: E = EllipticCurve(QQ, [1,2,3,4,6]) - sage: E.formal().mult_by_n(2,prec=5) + sage: E.formal().mult_by_n(2, prec=5) 2*t - t^2 - 4*t^3 - 19*t^4 + O(t^5) """ if self.curve().base_ring().is_field() and self.curve().base_ring().characteristic() == 0 and n != 0: diff --git a/src/sage/schemes/elliptic_curves/gal_reps.py b/src/sage/schemes/elliptic_curves/gal_reps.py index 056268eb230..8809d8d2990 100644 --- a/src/sage/schemes/elliptic_curves/gal_reps.py +++ b/src/sage/schemes/elliptic_curves/gal_reps.py @@ -262,9 +262,7 @@ def is_reducible(self, p): - ``p`` -- a prime number - OUTPUT: - - - a boolean + OUTPUT: A boolean. The answer is cached. @@ -315,9 +313,7 @@ def is_irreducible(self, p): - ``p`` -- a prime number - OUTPUT: - - - a boolean + OUTPUT: A boolean. EXAMPLES:: @@ -715,9 +711,7 @@ def image_type(self, p): - ``p`` a prime number - OUTPUT: - - - a string. + OUTPUT: A string. EXAMPLES:: @@ -1254,9 +1248,7 @@ def is_unramified(self,p,ell): - ``p`` a prime - ``ell`` another prime - OUTPUT: - - - Boolean + OUTPUT: A boolean. EXAMPLES:: @@ -1289,9 +1281,7 @@ def is_unipotent(self,p,ell): - ``p`` a prime - ``ell`` a different prime - OUTPUT: - - - Boolean + OUTPUT: A boolean. EXAMPLES:: @@ -1328,9 +1318,7 @@ def is_quasi_unipotent(self,p,ell): - ``p`` a prime - ``ell`` a different prime - OUTPUT: - - - Boolean + OUTPUT: A boolean. EXAMPLES:: @@ -1360,9 +1348,7 @@ def is_ordinary(self,p): - ``p`` a prime - OUTPUT: - - - a Boolean + OUTPUT: A boolean. EXAMPLES:: @@ -1390,9 +1376,7 @@ def is_crystalline(self,p): - ``p`` a prime - OUTPUT: - - - a Boolean + OUTPUT: A boolean. EXAMPLES:: @@ -1417,9 +1401,7 @@ def is_potentially_crystalline(self,p): - ``p`` a prime - OUTPUT: - - - a Boolean + OUTPUT: A boolean. EXAMPLES:: @@ -1444,9 +1426,7 @@ def is_semistable(self,p): - ``p`` a prime - OUTPUT: - - - a Boolean + OUTPUT: A boolean. EXAMPLES:: @@ -1472,9 +1452,7 @@ def is_potentially_semistable(self,p): - ``p`` a prime - OUTPUT: - - - a Boolean + OUTPUT: A boolean. EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/gal_reps_number_field.py b/src/sage/schemes/elliptic_curves/gal_reps_number_field.py index 82127860fd3..39ae6a8878e 100644 --- a/src/sage/schemes/elliptic_curves/gal_reps_number_field.py +++ b/src/sage/schemes/elliptic_curves/gal_reps_number_field.py @@ -1154,9 +1154,9 @@ def Billerey_P_l(E, l): sage: from sage.schemes.elliptic_curves.gal_reps_number_field import Billerey_P_l sage: [Billerey_P_l(E,l) for l in primes(10)] [x^2 + 8143*x + 16777216, - x^2 + 451358*x + 282429536481, - x^4 - 664299076*x^3 + 205155493652343750*x^2 - 39595310449600219726562500*x + 3552713678800500929355621337890625, - x^4 - 207302404*x^3 - 377423798538689366394*x^2 - 39715249826471656586987520004*x + 36703368217294125441230211032033660188801] + x^2 + 451358*x + 282429536481, + x^4 - 664299076*x^3 + 205155493652343750*x^2 - 39595310449600219726562500*x + 3552713678800500929355621337890625, + x^4 - 207302404*x^3 - 377423798538689366394*x^2 - 39715249826471656586987520004*x + 36703368217294125441230211032033660188801] """ K = E.base_field() qq = K.primes_above(l) @@ -1190,11 +1190,11 @@ def Billerey_B_l(E,l,B=0): sage: from sage.schemes.elliptic_curves.gal_reps_number_field import Billerey_B_l sage: [Billerey_B_l(E,l) for l in primes(15)] [1123077552537600, - 227279663773903886745600, - 0, - 0, - 269247154818492941287713746693964214802283882086400, - 0] + 227279663773903886745600, + 0, + 0, + 269247154818492941287713746693964214802283882086400, + 0] """ d = E.base_field().absolute_degree() P = Billerey_P_l(E, l) diff --git a/src/sage/schemes/elliptic_curves/heegner.py b/src/sage/schemes/elliptic_curves/heegner.py index e4e19cf154b..6b552bafda9 100644 --- a/src/sage/schemes/elliptic_curves/heegner.py +++ b/src/sage/schemes/elliptic_curves/heegner.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.rings.number_field r""" Heegner points on elliptic curves over the rational numbers @@ -15,7 +15,8 @@ sage: z = P.point_exact(201); z (-4/3 : 1/9*a : 1) sage: parent(z) - Abelian group of points on Elliptic Curve defined by y^2 + x*y = x^3 + 1 over Number Field in a with defining polynomial x^2 - 12*x + 111 + Abelian group of points on Elliptic Curve defined by y^2 + x*y = x^3 + 1 + over Number Field in a with defining polynomial x^2 - 12*x + 111 sage: parent(z[0]).discriminant() -3 sage: E.quadratic_twist(-3).rank() @@ -33,7 +34,9 @@ sage: z[0].charpoly().factor() (x^6 + x^5 - 1/4*x^4 + 19/10*x^3 + 31/20*x^2 - 7/10*x + 49/100)^2 sage: z[1].charpoly().factor() - x^12 - x^11 + 6/5*x^10 - 33/40*x^9 - 89/320*x^8 + 3287/800*x^7 - 5273/1600*x^6 + 993/4000*x^5 + 823/320*x^4 - 2424/625*x^3 + 12059/12500*x^2 + 3329/25000*x + 123251/250000 + x^12 - x^11 + 6/5*x^10 - 33/40*x^9 - 89/320*x^8 + 3287/800*x^7 + - 5273/1600*x^6 + 993/4000*x^5 + 823/320*x^4 - 2424/625*x^3 + + 12059/12500*x^2 + 3329/25000*x + 123251/250000 sage: f = P.x_poly_exact(300); f x^6 + x^5 - 1/4*x^4 + 19/10*x^3 + 31/20*x^2 - 7/10*x + 49/100 sage: f.discriminant().factor() @@ -148,11 +151,11 @@ def heegner_points(N, D=None, c=None): EXAMPLES:: - sage: heegner_points(389,-7) + sage: heegner_points(389, -7) Set of all Heegner points on X_0(389) associated to QQ[sqrt(-7)] - sage: heegner_points(389,-7,1) + sage: heegner_points(389, -7, 1) All Heegner points of conductor 1 on X_0(389) associated to QQ[sqrt(-7)] - sage: heegner_points(389,-7,5) + sage: heegner_points(389, -7, 5) All Heegner points of conductor 5 on X_0(389) associated to QQ[sqrt(-7)] """ if D is None and c is None: @@ -237,16 +240,16 @@ def __init__(self, D, c, check=True): """ INPUT: - - `D` -- discriminant of quadratic imaginary field + - `D` -- discriminant of quadratic imaginary field - - `c` -- conductor (positive integer coprime to `D`) + - `c` -- conductor (positive integer coprime to `D`) - - ``check`` -- bool (default: ``True``); whether to check - validity of input + - ``check`` -- bool (default: ``True``); whether to check + validity of input EXAMPLES:: - sage: sage.schemes.elliptic_curves.heegner.RingClassField(-7,5, False) + sage: sage.schemes.elliptic_curves.heegner.RingClassField(-7, 5, False) Ring class field extension of QQ[sqrt(-7)] of conductor 5 """ if check: @@ -514,7 +517,8 @@ def quadratic_field(self): sage: E = EllipticCurve('389a'); K = E.heegner_point(-7,5).ring_class_field() sage: K.quadratic_field() - Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 with sqrt_minus_7 = 2.645751311064591?*I + Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 + with sqrt_minus_7 = 2.645751311064591?*I """ D = self.__D var = 'sqrt_minus_%s'%(-D) @@ -527,7 +531,7 @@ def galois_group(self, base=QQ): INPUT: - - ``base`` -- (default: `\QQ`) a subfield of ``self`` or `\QQ` + - ``base`` -- (default: `\QQ`) a subfield of ``self`` or `\QQ` EXAMPLES:: @@ -540,13 +544,15 @@ def galois_group(self, base=QQ): sage: A.galois_group() Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 5 sage: A.galois_group(B) - Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 5 over Hilbert class field of QQ[sqrt(-7)] + Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 5 + over Hilbert class field of QQ[sqrt(-7)] sage: A.galois_group().cardinality() 12 sage: A.galois_group(B).cardinality() 6 sage: C.galois_group(A) - Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 15 over Ring class field extension of QQ[sqrt(-7)] of conductor 5 + Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 15 + over Ring class field extension of QQ[sqrt(-7)] of conductor 5 sage: C.galois_group(A).cardinality() 4 """ @@ -602,7 +608,8 @@ class GaloisGroup(SageObject): sage: G.cardinality() 12 sage: G.complex_conjugation() - Complex conjugation automorphism of Ring class field extension of QQ[sqrt(-7)] of conductor 5 + Complex conjugation automorphism of Ring class field extension of QQ[sqrt(-7)] + of conductor 5 TESTS:: @@ -616,18 +623,20 @@ def __init__(self, field, base=QQ): r""" INPUT: - - ``field`` -- a ring class field + - ``field`` -- a ring class field - - ``base`` -- subfield of field (default: `\QQ`) + - ``base`` -- subfield of field (default: `\QQ`) EXAMPLES:: sage: K5 = heegner_points(389,-7,5).ring_class_field() sage: K1 = heegner_points(389,-7,1).ring_class_field() sage: sage.schemes.elliptic_curves.heegner.GaloisGroup(K5,K1) - Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 5 over Hilbert class field of QQ[sqrt(-7)] + Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 5 + over Hilbert class field of QQ[sqrt(-7)] sage: K5.galois_group(K1) - Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 5 over Hilbert class field of QQ[sqrt(-7)] + Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 5 + over Hilbert class field of QQ[sqrt(-7)] """ if not isinstance(field, RingClassField): raise TypeError("field must be of type RingClassField") @@ -690,11 +699,9 @@ def __call__(self, x): INPUT: - - `x` -- automorphism or quadratic field element + - `x` -- automorphism or quadratic field element - OUTPUT: - - - automorphism (or TypeError) + OUTPUT: An automorphism (or ``TypeError``) EXAMPLES:: @@ -773,13 +780,17 @@ def base_field(self): sage: Kc.absolute_degree() 12 sage: G = Kc.galois_group(K); G - Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 5 over Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 with sqrt_minus_7 = 2.645751311064591?*I + Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 5 + over Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 + with sqrt_minus_7 = 2.645751311064591?*I sage: G.cardinality() 6 sage: G.base_field() - Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 with sqrt_minus_7 = 2.645751311064591?*I + Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 + with sqrt_minus_7 = 2.645751311064591?*I sage: G = Kc.galois_group(Kc); G - Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 5 over Ring class field extension of QQ[sqrt(-7)] of conductor 5 + Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 5 + over Ring class field extension of QQ[sqrt(-7)] of conductor 5 sage: G.cardinality() 1 sage: G.base_field() @@ -801,7 +812,7 @@ def kolyvagin_generators(self): OUTPUT: - - list of elements of ``self`` + - list of elements of ``self`` EXAMPLES:: @@ -841,14 +852,15 @@ def lift_of_hilbert_class_field_galois_group(self): OUTPUT: - - tuple of elements of self + - tuple of elements of self EXAMPLES:: sage: K5 = heegner_points(389,-52,5).ring_class_field() sage: G = K5.galois_group(K5.quadratic_field()) sage: G.lift_of_hilbert_class_field_galois_group() - (Class field automorphism defined by x^2 + 325*y^2, Class field automorphism defined by 2*x^2 + 2*x*y + 163*y^2) + (Class field automorphism defined by x^2 + 325*y^2, + Class field automorphism defined by 2*x^2 + 2*x*y + 163*y^2) sage: G.cardinality() 12 sage: K5.quadratic_field().class_number() @@ -877,17 +889,22 @@ def _list(self): Example with order 1 (a special case):: - sage: E = EllipticCurve('389a'); F= E.heegner_point(-7,1).ring_class_field() + sage: E = EllipticCurve('389a'); F = E.heegner_point(-7,1).ring_class_field() sage: G = F.galois_group(F.quadratic_field()) sage: G._list() (Class field automorphism defined by x^2 + x*y + 2*y^2,) Example over quadratic imaginary field:: - sage: E = EllipticCurve('389a'); F= E.heegner_point(-7,5).ring_class_field() + sage: E = EllipticCurve('389a'); F = E.heegner_point(-7,5).ring_class_field() sage: G = F.galois_group(F.quadratic_field()) sage: G._list() - (Class field automorphism defined by x^2 + x*y + 44*y^2, Class field automorphism defined by 2*x^2 - x*y + 22*y^2, Class field automorphism defined by 2*x^2 + x*y + 22*y^2, Class field automorphism defined by 4*x^2 - x*y + 11*y^2, Class field automorphism defined by 4*x^2 + x*y + 11*y^2, Class field automorphism defined by 7*x^2 + 7*x*y + 8*y^2) + (Class field automorphism defined by x^2 + x*y + 44*y^2, + Class field automorphism defined by 2*x^2 - x*y + 22*y^2, + Class field automorphism defined by 2*x^2 + x*y + 22*y^2, + Class field automorphism defined by 4*x^2 - x*y + 11*y^2, + Class field automorphism defined by 4*x^2 + x*y + 11*y^2, + Class field automorphism defined by 7*x^2 + 7*x*y + 8*y^2) Example over `\QQ` (it is not implemented yet):: @@ -899,10 +916,12 @@ def _list(self): Example over Hilbert class field:: - sage: K3 = heegner_points(389,-52,3).ring_class_field(); K1 = heegner_points(389,-52,1).ring_class_field() + sage: K3 = heegner_points(389,-52,3).ring_class_field() + sage: K1 = heegner_points(389,-52,1).ring_class_field() sage: G = K3.galois_group(K1) sage: G._list() - (Class field automorphism defined by x^2 + 117*y^2, Class field automorphism defined by 9*x^2 - 6*x*y + 14*y^2, Class field automorphism defined by 9*x^2 + 13*y^2, Class field automorphism defined by 9*x^2 + 6*x*y + 14*y^2) + (Class field automorphism defined by x^2 + 117*y^2, Class field automorphism defined by 9*x^2 - 6*x*y + 14*y^2, + Class field automorphism defined by 9*x^2 + 13*y^2, Class field automorphism defined by 9*x^2 + 6*x*y + 14*y^2) """ if self._base_is_QQ(): raise NotImplementedError("Galois group over QQ not yet implemented") @@ -941,12 +960,11 @@ def _quadratic_form_to_alpha(self, f): """ INPUT: - - `f` -- a binary quadratic form with discriminant `c^2 D` + - `f` -- a binary quadratic form with discriminant `c^2 D` OUTPUT: - - an element of the ring of integers of the quadratic - imaginary field + - an element of the ring of integers of the quadratic imaginary field EXAMPLES:: @@ -980,7 +998,7 @@ def _alpha_to_automorphism(self, alpha): INPUT: - - `\alpha` -- element of quadratic imaginary field coprime to conductor + - `\alpha` -- element of quadratic imaginary field coprime to conductor EXAMPLES:: @@ -1012,12 +1030,11 @@ def _alpha_to_p1_element(self, alpha): INPUT: - - `\alpha` -- element of the ring of integers of the - quadratic imaginary field + - `\alpha` -- element of the ring of integers of the quadratic imaginary field OUTPUT: - - 2-tuple of integers + - 2-tuple of integers EXAMPLES:: @@ -1058,11 +1075,11 @@ def _p1_element_to_alpha(self, uv): INPUT: - - ``uv`` -- pair of integers + - ``uv`` -- pair of integers OUTPUT: - - element of maximal order of quadratic field + - element of maximal order of quadratic field EXAMPLES:: @@ -1221,7 +1238,8 @@ def complex_conjugation(self): sage: E = EllipticCurve('389a') sage: G = E.heegner_point(-7,5).ring_class_field().galois_group() sage: G.complex_conjugation() - Complex conjugation automorphism of Ring class field extension of QQ[sqrt(-7)] of conductor 5 + Complex conjugation automorphism of Ring class field extension + of QQ[sqrt(-7)] of conductor 5 """ if self.base_field() != QQ: raise ValueError("the base field must be fixed by complex conjugation") @@ -1248,7 +1266,7 @@ def __init__(self, parent): """ INPUT: - - ``parent`` -- a group of automorphisms of a ring class field + - ``parent`` -- a group of automorphisms of a ring class field EXAMPLES:: @@ -1267,7 +1285,8 @@ def parent(self): EXAMPLES:: sage: E = EllipticCurve('389a') - sage: s = E.heegner_point(-7,5).ring_class_field().galois_group().complex_conjugation() + sage: G = E.heegner_point(-7,5).ring_class_field().galois_group() + sage: s = G.complex_conjugation() sage: s.parent() Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 5 """ @@ -1280,7 +1299,8 @@ def domain(self): EXAMPLES:: sage: E = EllipticCurve('389a') - sage: s = E.heegner_point(-7,5).ring_class_field().galois_group().complex_conjugation() + sage: G = E.heegner_point(-7,5).ring_class_field().galois_group() + sage: s = G.complex_conjugation() sage: s.domain() Ring class field extension of QQ[sqrt(-7)] of conductor 5 """ @@ -1293,9 +1313,11 @@ class GaloisAutomorphismComplexConjugation(GaloisAutomorphism): EXAMPLES:: - sage: conj = heegner_point(37,-7,5).ring_class_field().galois_group().complex_conjugation() + sage: G = heegner_point(37,-7,5).ring_class_field().galois_group() + sage: conj = G.complex_conjugation() sage: conj - Complex conjugation automorphism of Ring class field extension of QQ[sqrt(-7)] of conductor 5 + Complex conjugation automorphism of Ring class field extension + of QQ[sqrt(-7)] of conductor 5 sage: conj.domain() Ring class field extension of QQ[sqrt(-7)] of conductor 5 @@ -1316,7 +1338,8 @@ def __init__(self, parent): sage: G = heegner_point(37,-7,5).ring_class_field().galois_group() sage: sage.schemes.elliptic_curves.heegner.GaloisAutomorphismComplexConjugation(G) - Complex conjugation automorphism of Ring class field extension of QQ[sqrt(-7)] of conductor 5 + Complex conjugation automorphism of Ring class field extension + of QQ[sqrt(-7)] of conductor 5 """ GaloisAutomorphism.__init__(self, parent) @@ -1401,7 +1424,8 @@ def order(self): """ EXAMPLES:: - sage: conj = heegner_point(37,-7,5).ring_class_field().galois_group().complex_conjugation() + sage: G = heegner_point(37,-7,5).ring_class_field().galois_group() + sage: conj = G.complex_conjugation() sage: conj.order() 2 """ @@ -1427,19 +1451,19 @@ def __init__(self, parent, quadratic_form, alpha=None): r""" INPUT: - - ``parent`` -- a group of automorphisms of a ring class field + - ``parent`` -- a group of automorphisms of a ring class field - - ``quadratic_form`` -- a binary quadratic form that - defines an element of the Galois group of `K_c` over `K`. + - ``quadratic_form`` -- a binary quadratic form that + defines an element of the Galois group of `K_c` over `K`. - - ``\alpha`` -- (default: ``None``) optional data that specified - element corresponding element of `(\mathcal{O}_K / - c\mathcal{O}_K)^* / (\ZZ/c\ZZ)^*`, via class field - theory. + - ``\alpha`` -- (default: ``None``) optional data that specified + element corresponding element of `(\mathcal{O}_K / + c\mathcal{O}_K)^* / (\ZZ/c\ZZ)^*`, via class field theory. EXAMPLES:: - sage: H = heegner_points(389,-20,3); G = H.ring_class_field().galois_group(H.quadratic_field()) + sage: H = heegner_points(389,-20,3) + sage: G = H.ring_class_field().galois_group(H.quadratic_field()) sage: f = BinaryQF_reduced_representatives(-20*9)[0] sage: sage.schemes.elliptic_curves.heegner.GaloisAutomorphismQuadraticForm(G, f) Class field automorphism defined by x^2 + 45*y^2 @@ -1503,9 +1527,11 @@ def alpha(self): sage: K1 = heegner_points(389,-52,1).ring_class_field() sage: G = K5.galois_group(K1) sage: orb = sorted([g.alpha() for g in G]); orb # random (the sign depends on the database being installed or not) - [1, -1/2*sqrt_minus_52, 1/2*sqrt_minus_52 + 1, 1/2*sqrt_minus_52 - 1, 1/2*sqrt_minus_52 - 2, -1/2*sqrt_minus_52 - 2] + [1, -1/2*sqrt_minus_52, 1/2*sqrt_minus_52 + 1, 1/2*sqrt_minus_52 - 1, + 1/2*sqrt_minus_52 - 2, -1/2*sqrt_minus_52 - 2] sage: sorted([x^2 for x in orb]) # just for testing - [-13, -sqrt_minus_52 - 12, sqrt_minus_52 - 12, -2*sqrt_minus_52 - 9, 2*sqrt_minus_52 - 9, 1] + [-13, -sqrt_minus_52 - 12, sqrt_minus_52 - 12, + -2*sqrt_minus_52 - 9, 2*sqrt_minus_52 - 9, 1] """ if self.__alpha is None: raise ValueError("alpha data not defined") @@ -1606,7 +1632,8 @@ def __mul__(self, right): sage: s * s Class field automorphism defined by x^2 + 45*y^2 sage: G = s.parent(); list(G) - [Class field automorphism defined by x^2 + 45*y^2, Class field automorphism defined by 2*x^2 + 2*x*y + 23*y^2, Class field automorphism defined by 5*x^2 + 9*y^2, Class field automorphism defined by 7*x^2 + 4*x*y + 7*y^2] + [Class field automorphism defined by x^2 + 45*y^2, Class field automorphism defined by 2*x^2 + 2*x*y + 23*y^2, + Class field automorphism defined by 5*x^2 + 9*y^2, Class field automorphism defined by 7*x^2 + 4*x*y + 7*y^2] sage: G[0]*G[0] Class field automorphism defined by x^2 + 45*y^2 sage: G[1]*G[2] == G[3] @@ -1652,7 +1679,8 @@ def ideal(self): sage: G[1].ideal() Fractional ideal (2, 1/2*sqrt_minus_20 + 1) sage: [s.ideal().gens() for s in G] - [(1, 3/2*sqrt_minus_20), (2, 3/2*sqrt_minus_20 - 1), (5, 3/2*sqrt_minus_20), (7, 3/2*sqrt_minus_20 - 2)] + [(1, 3/2*sqrt_minus_20), (2, 3/2*sqrt_minus_20 - 1), + (5, 3/2*sqrt_minus_20), (7, 3/2*sqrt_minus_20 - 2)] """ M = self.parent().field() K = M.quadratic_field() @@ -1820,7 +1848,8 @@ def conductor(self): sage: heegner_point(389,-7,5).conductor() 5 sage: E = EllipticCurve('37a1'); P = E.kolyvagin_point(-67,7); P - Kolyvagin point of discriminant -67 and conductor 7 on elliptic curve of conductor 37 + Kolyvagin point of discriminant -67 and conductor 7 + on elliptic curve of conductor 37 sage: P.conductor() 7 sage: E = EllipticCurve('389a'); P = E.heegner_point(-7, 5); P.conductor() @@ -1838,7 +1867,8 @@ def discriminant(self): sage: heegner_point(389,-7,5).discriminant() -7 sage: E = EllipticCurve('37a1'); P = E.kolyvagin_point(-67,7); P - Kolyvagin point of discriminant -67 and conductor 7 on elliptic curve of conductor 37 + Kolyvagin point of discriminant -67 and conductor 7 + on elliptic curve of conductor 37 sage: P.discriminant() -67 sage: E = EllipticCurve('389a'); P = E.heegner_point(-7, 5); P.discriminant() @@ -1855,11 +1885,13 @@ def quadratic_field(self): sage: x = heegner_point(37,-7,5) sage: x.quadratic_field() - Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 with sqrt_minus_7 = 2.645751311064591?*I + Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 + with sqrt_minus_7 = 2.645751311064591?*I sage: E = EllipticCurve('37a'); P = E.heegner_point(-40) sage: P.quadratic_field() - Number Field in sqrt_minus_40 with defining polynomial x^2 + 40 with sqrt_minus_40 = 6.324555320336759?*I + Number Field in sqrt_minus_40 with defining polynomial x^2 + 40 + with sqrt_minus_40 = 6.324555320336759?*I sage: P.quadratic_field() is P.quadratic_field() True sage: type(P.quadratic_field()) @@ -1876,13 +1908,15 @@ def quadratic_order(self): EXAMPLES:: sage: heegner_point(389,-7,5).quadratic_order() - Order in Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 with sqrt_minus_7 = 2.645751311064591?*I + Order in Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 + with sqrt_minus_7 = 2.645751311064591?*I sage: heegner_point(389,-7,5).quadratic_order().basis() [1, 5*sqrt_minus_7] sage: E = EllipticCurve('37a'); P = E.heegner_point(-40,11) sage: P.quadratic_order() - Order in Number Field in sqrt_minus_40 with defining polynomial x^2 + 40 with sqrt_minus_40 = 6.324555320336759?*I + Order in Number Field in sqrt_minus_40 with defining polynomial x^2 + 40 + with sqrt_minus_40 = 6.324555320336759?*I sage: P.quadratic_order().basis() [1, 11*sqrt_minus_40] """ @@ -1943,7 +1977,7 @@ def __init__(self, N): """ INPUT: - - `N` -- level, a positive integer + - `N` -- level, a positive integer EXAMPLES:: @@ -2031,7 +2065,7 @@ def reduce_mod(self, ell): INPUT: - - `\ell` -- prime + - `\ell` -- prime EXAMPLES:: @@ -2047,11 +2081,11 @@ def discriminants(self, n=10, weak=False): INPUT: - - `n` -- nonnegative integer + - `n` -- nonnegative integer - - ``weak`` -- bool (default: ``False``); if ``True`` only require - weak Heegner hypothesis, which is the same as usual but - without the condition that `\gcd(D,N)=1`. + - ``weak`` -- bool (default: ``False``); if ``True`` only require + weak Heegner hypothesis, which is the same as usual but + without the condition that `\gcd(D,N)=1`. EXAMPLES:: @@ -2069,7 +2103,7 @@ def discriminants(self, n=10, weak=False): The discriminant -111 satisfies only the weak Heegner hypothesis, since it is divisible by 37:: - sage: X.discriminants(15,weak=True) + sage: X.discriminants(15, weak=True) [-7, -11, -40, -47, -67, -71, -83, -84, -95, -104, -107, -111, -115, -120, -123] """ N = self.level() @@ -2101,7 +2135,8 @@ class HeegnerPoints_level_disc(HeegnerPoints): sage: H.discriminant() -7 sage: H.quadratic_field() - Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 with sqrt_minus_7 = 2.645751311064591?*I + Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 + with sqrt_minus_7 = 2.645751311064591?*I sage: H.kolyvagin_conductors() [1, 3, 5, 13, 15, 17, 19, 31, 39, 41] @@ -2112,9 +2147,9 @@ def __init__(self, N, D): """ INPUT: - - `N` -- positive integer + - `N` -- positive integer - - `D` -- negative fundamental discriminant + - `D` -- negative fundamental discriminant EXAMPLES:: @@ -2190,7 +2225,8 @@ def quadratic_field(self): sage: E = EllipticCurve('389a'); K = E.heegner_point(-7,5).ring_class_field() sage: K.quadratic_field() - Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 with sqrt_minus_7 = 2.645751311064591?*I + Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 + with sqrt_minus_7 = 2.645751311064591?*I """ D = self.__D var = 'sqrt_minus_%s'%(-D) @@ -2211,17 +2247,17 @@ def kolyvagin_conductors(self, r=None, n=10, E=None, m=None): INPUT: - - `r` -- (default: ``None``) nonnegative integer or ``None`` + - `r` -- (default: ``None``) nonnegative integer or ``None`` - - `n` -- positive integer + - `n` -- positive integer - - `E` -- an elliptic curve + - `E` -- an elliptic curve - - `m` -- a positive integer + - `m` -- a positive integer EXAMPLES:: - sage: H = heegner_points(389,-7) + sage: H = heegner_points(389, -7) sage: H.kolyvagin_conductors(0) [1] sage: H.kolyvagin_conductors(1) @@ -2230,9 +2266,9 @@ def kolyvagin_conductors(self, r=None, n=10, E=None, m=None): [3, 5, 13, 17, 19, 31, 41, 47, 59, 61, 73, 83, 89, 97, 101] sage: H.kolyvagin_conductors(1,5) [3, 5, 13, 17, 19] - sage: H.kolyvagin_conductors(1,5,EllipticCurve('389a'),3) + sage: H.kolyvagin_conductors(1, 5, EllipticCurve('389a'), 3) [5, 17, 41, 59, 83] - sage: H.kolyvagin_conductors(2,5,EllipticCurve('389a'),3) + sage: H.kolyvagin_conductors(2, 5, EllipticCurve('389a'), 3) [85, 205, 295, 415, 697] """ D = self.__D @@ -2273,30 +2309,30 @@ def is_kolyvagin_conductor(N, E, D, r, n, c): INPUT: - - `N` -- level (positive integer) + - `N` -- level (positive integer) - - `E` -- elliptic curve or ``None`` + - `E` -- elliptic curve or ``None`` - - `D` -- negative fundamental discriminant + - `D` -- negative fundamental discriminant - - `r` -- number of prime factors (nonnegative integer) or ``None`` + - `r` -- number of prime factors (nonnegative integer) or ``None`` - - `n` -- torsion order (i.e., do we get class in `(E(K_c)/n E(K_c))^{Gal(K_c/K)}`?) + - `n` -- torsion order (i.e., do we get class in `(E(K_c)/n E(K_c))^{Gal(K_c/K)}`?) - - `c` -- conductor (positive integer) + - `c` -- conductor (positive integer) EXAMPLES:: sage: from sage.schemes.elliptic_curves.heegner import is_kolyvagin_conductor - sage: is_kolyvagin_conductor(389,None,-7,1,None,5) + sage: is_kolyvagin_conductor(389, None, -7, 1, None, 5) True - sage: is_kolyvagin_conductor(389,None,-7,1,None,7) + sage: is_kolyvagin_conductor(389, None, -7, 1, None, 7) False - sage: is_kolyvagin_conductor(389,None,-7,1,None,11) + sage: is_kolyvagin_conductor(389, None, -7, 1, None, 11) False - sage: is_kolyvagin_conductor(389,EllipticCurve('389a'),-7,1,3,5) + sage: is_kolyvagin_conductor(389, EllipticCurve('389a'), -7, 1, 3, 5) True - sage: is_kolyvagin_conductor(389,EllipticCurve('389a'),-7,1,11,5) + sage: is_kolyvagin_conductor(389, EllipticCurve('389a'), -7, 1, 11, 5) False """ ND = N*D @@ -2341,7 +2377,8 @@ class HeegnerPoints_level_disc_cond(HeegnerPoints_level, HeegnerPoints_level_dis (147, 631) sage: H.quadratic_field() - Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 with sqrt_minus_7 = 2.645751311064591?*I + Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 + with sqrt_minus_7 = 2.645751311064591?*I sage: H.ring_class_field() Ring class field extension of QQ[sqrt(-7)] of conductor 5 @@ -2360,11 +2397,11 @@ def __init__(self, N, D, c=ZZ(1)): INPUT: - - `N` -- positive integer (the level) + - `N` -- positive integer (the level) - - `D` -- negative fundamental discriminant + - `D` -- negative fundamental discriminant - - `c` -- conductor (default: 1) + - `c` -- conductor (default: 1) EXAMPLES:: @@ -2476,9 +2513,11 @@ def __getitem__(self, i): sage: len(H) 12 sage: H[0] - Heegner point 5/778*sqrt(-7) - 147/778 of discriminant -7 and conductor 5 on X_0(389) + Heegner point 5/778*sqrt(-7) - 147/778 of discriminant -7 and conductor 5 + on X_0(389) sage: H[-1] - Heegner point 5/5446*sqrt(-7) - 757/778 of discriminant -7 and conductor 5 on X_0(389) + Heegner point 5/5446*sqrt(-7) - 757/778 of discriminant -7 and conductor 5 + on X_0(389) """ return self.points()[i] @@ -2543,17 +2582,25 @@ def points(self, beta=None): EXAMPLES:: - sage: H = heegner_points(389,-7,5); H + sage: H = heegner_points(389, -7, 5); H All Heegner points of conductor 5 on X_0(389) associated to QQ[sqrt(-7)] sage: H.points() - (Heegner point 5/778*sqrt(-7) - 147/778 of discriminant -7 and conductor 5 on X_0(389), ..., Heegner point 5/5446*sqrt(-7) - 757/778 of discriminant -7 and conductor 5 on X_0(389)) + (Heegner point 5/778*sqrt(-7) - 147/778 of discriminant -7 and conductor 5 + on X_0(389), + ..., + Heegner point 5/5446*sqrt(-7) - 757/778 of discriminant -7 and conductor 5 + on X_0(389)) sage: H.betas() (147, 631) sage: [x.tau() for x in H.points(147)] - [5/778*sqrt_minus_7 - 147/778, 5/1556*sqrt_minus_7 - 147/1556, 5/1556*sqrt_minus_7 - 925/1556, 5/3112*sqrt_minus_7 - 1703/3112, 5/3112*sqrt_minus_7 - 2481/3112, 5/5446*sqrt_minus_7 - 21/778] + [5/778*sqrt_minus_7 - 147/778, 5/1556*sqrt_minus_7 - 147/1556, + 5/1556*sqrt_minus_7 - 925/1556, 5/3112*sqrt_minus_7 - 1703/3112, + 5/3112*sqrt_minus_7 - 2481/3112, 5/5446*sqrt_minus_7 - 21/778] sage: [x.tau() for x in H.points(631)] - [5/778*sqrt_minus_7 - 631/778, 5/1556*sqrt_minus_7 - 631/1556, 5/1556*sqrt_minus_7 - 1409/1556, 5/3112*sqrt_minus_7 - 631/3112, 5/3112*sqrt_minus_7 - 1409/3112, 5/5446*sqrt_minus_7 - 757/778] + [5/778*sqrt_minus_7 - 631/778, 5/1556*sqrt_minus_7 - 631/1556, + 5/1556*sqrt_minus_7 - 1409/1556, 5/3112*sqrt_minus_7 - 631/3112, + 5/3112*sqrt_minus_7 - 1409/3112, 5/5446*sqrt_minus_7 - 757/778] The result is cached and is a tuple (since it is immutable):: @@ -2606,9 +2653,9 @@ def plot(self, *args, **kwds): EXAMPLES:: - sage: heegner_points(389,-7,5).plot(pointsize=50, rgbcolor='red') + sage: heegner_points(389,-7,5).plot(pointsize=50, rgbcolor='red') # optional - sage.plot Graphics object consisting of 12 graphics primitives - sage: heegner_points(53,-7,15).plot(pointsize=50, rgbcolor='purple') + sage: heegner_points(53,-7,15).plot(pointsize=50, rgbcolor='purple') # optional - sage.plot Graphics object consisting of 48 graphics primitives """ return sum(z.plot(*args, **kwds) for z in self) @@ -2621,7 +2668,7 @@ class HeegnerPointOnX0N(HeegnerPoint): EXAMPLES:: - sage: x = heegner_point(37,-7,5); x + sage: x = heegner_point(37, -7, 5); x Heegner point 5/74*sqrt(-7) - 11/74 of discriminant -7 and conductor 5 on X_0(37) sage: type(x) @@ -2632,11 +2679,13 @@ class HeegnerPointOnX0N(HeegnerPoint): sage: x.discriminant() -7 sage: x.quadratic_field() - Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 with sqrt_minus_7 = 2.645751311064591?*I + Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 + with sqrt_minus_7 = 2.645751311064591?*I sage: x.quadratic_form() 37*x^2 + 11*x*y + 2*y^2 sage: x.quadratic_order() - Order in Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 with sqrt_minus_7 = 2.645751311064591?*I + Order in Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 + with sqrt_minus_7 = 2.645751311064591?*I sage: x.tau() 5/74*sqrt_minus_7 - 11/74 sage: loads(dumps(x)) == x @@ -2646,27 +2695,30 @@ def __init__(self, N, D, c=ZZ(1), f=None, check=True): r""" INPUT: - - `N` -- positive integer + - `N` -- positive integer - - `D` -- fundamental discriminant, a negative integer + - `D` -- fundamental discriminant, a negative integer - - `c` -- conductor, a positive integer coprime to `N` + - `c` -- conductor, a positive integer coprime to `N` - - `f` -- binary quadratic form, 3-tuple `(A,B,C)` of coefficients - of `AX^2 + BXY + CY^2`, or element of quadratic imaginary - field `\QQ(\sqrt{D})` in the upper half plan. + - `f` -- binary quadratic form, 3-tuple `(A,B,C)` of coefficients + of `AX^2 + BXY + CY^2`, or element of quadratic imaginary + field `\QQ(\sqrt{D})` in the upper half plan. - - ``check`` -- bool, default: ``True``. should not be used - except internally. + - ``check`` -- bool, default: ``True``. should not be used + except internally. EXAMPLES:: + sage: from sage.schemes.elliptic_curves.heegner import HeegnerPointOnX0N sage: x = heegner_point(389, -7, 5); x - Heegner point 5/778*sqrt(-7) - 147/778 of discriminant -7 and conductor 5 on X_0(389) + Heegner point 5/778*sqrt(-7) - 147/778 of discriminant -7 and conductor 5 + on X_0(389) sage: type(x) - sage: sage.schemes.elliptic_curves.heegner.HeegnerPointOnX0N(389, -7, 5, None, check=False) - Heegner point 5/778*sqrt(-7) - 147/778 of discriminant -7 and conductor 5 on X_0(389) + sage: HeegnerPointOnX0N(389, -7, 5, None, check=False) + Heegner point 5/778*sqrt(-7) - 147/778 of discriminant -7 and conductor 5 + on X_0(389) """ if check: N = ZZ(N) @@ -2713,7 +2765,7 @@ def __hash__(self): EXAMPLES:: - sage: x = heegner_point(37,-7,5) + sage: x = heegner_point(37, -7, 5) sage: from sage.schemes.elliptic_curves.heegner import HeegnerPoint sage: hash(x) == hash( (HeegnerPoint.__hash__(x), x.reduced_quadratic_form()) ) True @@ -2727,7 +2779,7 @@ def __richcmp__(self, x, op): EXAMPLES:: sage: x1 = EllipticCurve('389a').heegner_point(-7).heegner_point_on_X0N() - sage: x5 = EllipticCurve('389a').heegner_point(-7,5).heegner_point_on_X0N() + sage: x5 = EllipticCurve('389a').heegner_point(-7, 5).heegner_point_on_X0N() sage: x1 == x1 True sage: x1 < x5 @@ -2748,7 +2800,7 @@ def _repr_(self): EXAMPLES:: - sage: x = heegner_point(37,-7,5); x._repr_() + sage: x = heegner_point(37, -7, 5); x._repr_() 'Heegner point 5/74*sqrt(-7) - 11/74 of discriminant -7 and conductor 5 on X_0(37)' """ c = self.conductor() @@ -2760,20 +2812,21 @@ def _repr_(self): def atkin_lehner_act(self, Q=None): r""" - Given an integer Q dividing the level N such that `\gcd(Q, N/Q) = 1`, returns the + Given an integer Q dividing the level N such that `\gcd(Q, N/Q) = 1`, return the image of this Heegner point under the Atkin-Lehner operator `W_Q`. INPUT: - - `Q` -- positive divisor of `N`; if not given, default to `N` + - `Q` -- positive divisor of `N`; if not given, default to `N` EXAMPLES:: - sage: x = heegner_point(389,-7,5) + sage: x = heegner_point(389, -7, 5) sage: x.atkin_lehner_act() - Heegner point 5/199168*sqrt(-7) - 631/199168 of discriminant -7 and conductor 5 on X_0(389) + Heegner point 5/199168*sqrt(-7) - 631/199168 of discriminant -7 + and conductor 5 on X_0(389) - sage: x = heegner_point(45,D=-11,c=1); x + sage: x = heegner_point(45, D=-11, c=1); x Heegner point 1/90*sqrt(-11) - 13/90 of discriminant -11 on X_0(45) sage: x.atkin_lehner_act(5) Heegner point 1/90*sqrt(-11) + 23/90 of discriminant -11 on X_0(45) @@ -2805,7 +2858,7 @@ def quadratic_form(self): EXAMPLES:: - sage: heegner_point(389,-7,5).quadratic_form() + sage: heegner_point(389, -7, 5).quadratic_form() 389*x^2 + 147*x*y + 14*y^2 """ # It is good/important that this return a copy, since @@ -2820,7 +2873,7 @@ def reduced_quadratic_form(self): EXAMPLES:: - sage: x = heegner_point(389,-7,5) + sage: x = heegner_point(389, -7, 5) sage: x.quadratic_form() 389*x^2 + 147*x*y + 14*y^2 sage: x.reduced_quadratic_form() @@ -2839,7 +2892,7 @@ def tau(self): EXAMPLES:: - sage: x = heegner_point(37,-7,5); tau = x.tau(); tau + sage: x = heegner_point(37, -7, 5); tau = x.tau(); tau 5/74*sqrt_minus_7 - 11/74 sage: 37 * tau.minpoly() 37*x^2 + 11*x + 2 @@ -2859,14 +2912,17 @@ def map_to_curve(self, E): EXAMPLES:: - sage: x = heegner_point(389,-7,5); x - Heegner point 5/778*sqrt(-7) - 147/778 of discriminant -7 and conductor 5 on X_0(389) + sage: x = heegner_point(389, -7, 5); x + Heegner point 5/778*sqrt(-7) - 147/778 of discriminant -7 + and conductor 5 on X_0(389) sage: y = x.map_to_curve(EllipticCurve('389a')); y - Heegner point of discriminant -7 and conductor 5 on elliptic curve of conductor 389 + Heegner point of discriminant -7 and conductor 5 + on elliptic curve of conductor 389 sage: y.curve().cremona_label() '389a1' sage: y.heegner_point_on_X0N() - Heegner point 5/778*sqrt(-7) - 147/778 of discriminant -7 and conductor 5 on X_0(389) + Heegner point 5/778*sqrt(-7) - 147/778 of discriminant -7 + and conductor 5 on X_0(389) You can also directly apply the modular parametrization of the elliptic curve:: @@ -2885,10 +2941,14 @@ def galois_orbit_over_K(self): EXAMPLES:: - sage: x = heegner_point(389,-7,3); x - Heegner point 3/778*sqrt(-7) - 223/778 of discriminant -7 and conductor 3 on X_0(389) + sage: x = heegner_point(389, -7, 3); x + Heegner point 3/778*sqrt(-7) - 223/778 of discriminant -7 + and conductor 3 on X_0(389) sage: x.galois_orbit_over_K() - [Heegner point 3/778*sqrt(-7) - 223/778 of discriminant -7 and conductor 3 on X_0(389), Heegner point 3/1556*sqrt(-7) - 223/1556 of discriminant -7 and conductor 3 on X_0(389), Heegner point 3/1556*sqrt(-7) - 1001/1556 of discriminant -7 and conductor 3 on X_0(389), Heegner point 3/3112*sqrt(-7) - 223/3112 of discriminant -7 and conductor 3 on X_0(389)] + [Heegner point 3/778*sqrt(-7) - 223/778 of discriminant -7 and conductor 3 on X_0(389), + Heegner point 3/1556*sqrt(-7) - 223/1556 of discriminant -7 and conductor 3 on X_0(389), + Heegner point 3/1556*sqrt(-7) - 1001/1556 of discriminant -7 and conductor 3 on X_0(389), + Heegner point 3/3112*sqrt(-7) - 223/3112 of discriminant -7 and conductor 3 on X_0(389)] """ c = self.conductor() N = self.level() @@ -2957,15 +3017,15 @@ def __init__(self, E, x, check=True): - `x` -- Heegner point on `X_0(N)` - ``check`` -- bool (default: ``True``); if ``True``, ensure that `D`, - `c` are of type Integer and define a Heegner point - on `E` + `c` are of type Integer and define a Heegner point on `E` EXAMPLES:: sage: x = heegner_point(389,-7,5) sage: E = EllipticCurve('389a') sage: sage.schemes.elliptic_curves.heegner.HeegnerPointOnEllipticCurve(E, x) - Heegner point of discriminant -7 and conductor 5 on elliptic curve of conductor 389 + Heegner point of discriminant -7 and conductor 5 on elliptic curve + of conductor 389 """ if check: if E.conductor() != x.level(): @@ -2985,15 +3045,15 @@ def satisfies_kolyvagin_hypothesis(self, n=None): INPUT: - `n` -- positive integer + - `n` -- positive integer EXAMPLES:: sage: EllipticCurve('389a').heegner_point(-7).satisfies_kolyvagin_hypothesis() True - sage: EllipticCurve('389a').heegner_point(-7,5).satisfies_kolyvagin_hypothesis() + sage: EllipticCurve('389a').heegner_point(-7, 5).satisfies_kolyvagin_hypothesis() True - sage: EllipticCurve('389a').heegner_point(-7,11).satisfies_kolyvagin_hypothesis() + sage: EllipticCurve('389a').heegner_point(-7, 11).satisfies_kolyvagin_hypothesis() False """ if n is not None: @@ -3010,7 +3070,7 @@ def __hash__(self): EXAMPLES:: - sage: x = EllipticCurve('389a').heegner_point(-7,5) + sage: x = EllipticCurve('389a').heegner_point(-7, 5) sage: hash(x) == hash( (x.curve(), x.heegner_point_on_X0N()) ) True """ @@ -3021,7 +3081,7 @@ def __eq__(self, right): EXAMPLES:: sage: y1 = EllipticCurve('389a').heegner_point(-7) - sage: y5 = EllipticCurve('389a').heegner_point(-7,5) + sage: y5 = EllipticCurve('389a').heegner_point(-7, 5) sage: y1 == y1 True sage: y5 == y5 @@ -3039,7 +3099,7 @@ def __ne__(self, other): EXAMPLES:: sage: y1 = EllipticCurve('389a').heegner_point(-7) - sage: y5 = EllipticCurve('389a').heegner_point(-7,5) + sage: y5 = EllipticCurve('389a').heegner_point(-7, 5) sage: y1 != y1 False sage: y5 != y5 @@ -3072,9 +3132,11 @@ def heegner_point_on_X0N(self): EXAMPLES:: sage: E = EllipticCurve('37a'); P = E.heegner_point(-7,5); P - Heegner point of discriminant -7 and conductor 5 on elliptic curve of conductor 37 + Heegner point of discriminant -7 and conductor 5 on elliptic curve + of conductor 37 sage: P.heegner_point_on_X0N() - Heegner point 5/74*sqrt(-7) - 11/74 of discriminant -7 and conductor 5 on X_0(37) + Heegner point 5/74*sqrt(-7) - 11/74 of discriminant -7 and conductor 5 + on X_0(37) """ return self.__x @@ -3156,7 +3218,8 @@ def kolyvagin_point(self): sage: P = y.kolyvagin_point(); P Kolyvagin point of discriminant -7 on elliptic curve of conductor 37 sage: P.numerical_approx() # abs tol 1e-15 - (-3.36910401903861e-16 - 2.22076195576076e-16*I : 3.33066907387547e-16 + 2.22076195576075e-16*I : 1.00000000000000) + (-3.36910401903861e-16 - 2.22076195576076e-16*I + : 3.33066907387547e-16 + 2.22076195576075e-16*I : 1.00000000000000) """ return KolyvaginPoint(self) @@ -3172,12 +3235,13 @@ def _trace_index(self, *args, **kwds): OUTPUT: - - ``Integer`` -- returns an integer + - ``Integer`` -- returns an integer EXAMPLES:: sage: E = EllipticCurve('77a1') - sage: P = E.heegner_point(-19); y = P._trace_numerical_conductor_1(); [c.real() for c in y] + sage: P = E.heegner_point(-19); y = P._trace_numerical_conductor_1() + sage: [c.real() for c in y] [-1.2...e-16, -1.00000000000000, 1.00000000000000] sage: -2*E.gens()[0] (0 : -1 : 1) @@ -3187,7 +3251,8 @@ def _trace_index(self, *args, **kwds): sage: P = E.heegner_point(-68); P Heegner point of discriminant -68 on elliptic curve of conductor 77 sage: N(P) - (0.219223593595584 - 1.87443160153148*I : -1.34232921921325 - 1.52356748877889*I : 1.00000000000000) + (0.219223593595584 - 1.87443160153148*I + : -1.34232921921325 - 1.52356748877889*I : 1.00000000000000) sage: P._trace_index() 0 """ @@ -3227,7 +3292,8 @@ def quadratic_form(self): 389*x^2 + 147*x*y + 14*y^2 sage: P = EllipticCurve('389a').heegner_point(-7, 5, (778,925,275)); P - Heegner point of discriminant -7 and conductor 5 on elliptic curve of conductor 389 + Heegner point of discriminant -7 and conductor 5 on elliptic curve + of conductor 389 sage: P.quadratic_form() 778*x^2 + 925*x*y + 275*y^2 """ @@ -3247,14 +3313,15 @@ def numerical_approx(self, prec=53, algorithm=None): INPUT: - - prec -- (default: ``None``) the working precision + - prec -- (default: ``None``) the working precision EXAMPLES:: sage: E = EllipticCurve('37a'); P = E.heegner_point(-7); P Heegner point of discriminant -7 on elliptic curve of conductor 37 sage: P.numerical_approx() # abs tol 1e-15 - (-3.36910401903861e-16 - 2.22076195576076e-16*I : 3.33066907387547e-16 + 2.22076195576075e-16*I : 1.00000000000000) + (-3.36910401903861e-16 - 2.22076195576076e-16*I + : 3.33066907387547e-16 + 2.22076195576075e-16*I : 1.00000000000000) sage: P.numerical_approx(10) # expect random digits (0.0030 - 0.0028*I : -0.0030 + 0.0028*I : 1.0) sage: P.numerical_approx(100)[0] # expect random digits @@ -3262,7 +3329,8 @@ def numerical_approx(self, prec=53, algorithm=None): sage: E = EllipticCurve('37a'); P = E.heegner_point(-40); P Heegner point of discriminant -40 on elliptic curve of conductor 37 sage: P.numerical_approx() # abs tol 1e-14 - (-3.15940603400359e-16 + 1.41421356237309*I : 1.00000000000000 - 1.41421356237309*I : 1.00000000000000) + (-3.15940603400359e-16 + 1.41421356237309*I + : 1.00000000000000 - 1.41421356237309*I : 1.00000000000000) A rank 2 curve, where all Heegner points of conductor 1 are 0:: @@ -3276,15 +3344,20 @@ def numerical_approx(self, prec=53, algorithm=None): However, Heegner points of bigger conductor are often nonzero:: sage: E = EllipticCurve('389a'); P = E.heegner_point(-7, 5); P - Heegner point of discriminant -7 and conductor 5 on elliptic curve of conductor 389 + Heegner point of discriminant -7 and conductor 5 on elliptic curve + of conductor 389 sage: numerical_approx(P) - (0.675507556926807 + 0.344749649302635*I : -0.377142931401887 + 0.843366227137146*I : 1.00000000000000) + (0.675507556926807 + 0.344749649302635*I + : -0.377142931401887 + 0.843366227137146*I : 1.00000000000000) sage: P.numerical_approx() - (0.6755075569268... + 0.3447496493026...*I : -0.3771429314018... + 0.8433662271371...*I : 1.00000000000000) + (0.6755075569268... + 0.3447496493026...*I + : -0.3771429314018... + 0.8433662271371...*I : 1.00000000000000) sage: E.heegner_point(-7, 11).numerical_approx() - (0.1795583794118... + 0.02035501750912...*I : -0.5573941377055... + 0.2738940831635...*I : 1.00000000000000) + (0.1795583794118... + 0.02035501750912...*I + : -0.5573941377055... + 0.2738940831635...*I : 1.00000000000000) sage: E.heegner_point(-7, 13).numerical_approx() - (1.034302915374... - 3.302744319777...*I : 1.323937875767... + 6.908264226850...*I : 1.00000000000000) + (1.034302915374... - 3.302744319777...*I + : 1.323937875767... + 6.908264226850...*I : 1.00000000000000) We find (probably) the defining polynomial of the `x`-coordinate of `P`, which defines a class field. The shape of @@ -3329,15 +3402,15 @@ def x_poly_exact(self, prec=53, algorithm='lll'): INPUT: - - ``prec`` -- integer (default: 53) + - ``prec`` -- integer (default: 53) - - ``algorithm`` -- 'conjugates' or 'lll' (default); if - 'conjugates', compute numerically all the - conjugates ``y[i]`` of the Heegner point and construct - the characteristic polynomial as the product - `f(X)=(X-y[i])`. If 'lll', compute only one of the - conjugates ``y[0]``, then uses the LLL algorithm to - guess `f(X)`. + - ``algorithm`` -- 'conjugates' or 'lll' (default); if + 'conjugates', compute numerically all the + conjugates ``y[i]`` of the Heegner point and construct + the characteristic polynomial as the product + `f(X)=(X-y[i])`. If 'lll', compute only one of the + conjugates ``y[0]``, then uses the LLL algorithm to + guess `f(X)`. EXAMPLES: @@ -3347,26 +3420,37 @@ def x_poly_exact(self, prec=53, algorithm='lll'): sage: E = EllipticCurve('37a') sage: v = E.heegner_discriminants_list(10) sage: [E.heegner_point(D).x_poly_exact() for D in v] - [x, x, x^2 + 2, x^5 - x^4 + x^3 + x^2 - 2*x + 1, x - 6, x^7 - 2*x^6 + 9*x^5 - 10*x^4 - x^3 + 8*x^2 - 5*x + 1, x^3 + 5*x^2 + 10*x + 4, x^4 - 10*x^3 + 10*x^2 + 12*x - 12, x^8 - 5*x^7 + 7*x^6 + 13*x^5 - 10*x^4 - 4*x^3 + x^2 - 5*x + 7, x^6 - 2*x^5 + 11*x^4 - 24*x^3 + 30*x^2 - 16*x + 4] + [x, x, x^2 + 2, x^5 - x^4 + x^3 + x^2 - 2*x + 1, x - 6, + x^7 - 2*x^6 + 9*x^5 - 10*x^4 - x^3 + 8*x^2 - 5*x + 1, + x^3 + 5*x^2 + 10*x + 4, x^4 - 10*x^3 + 10*x^2 + 12*x - 12, + x^8 - 5*x^7 + 7*x^6 + 13*x^5 - 10*x^4 - 4*x^3 + x^2 - 5*x + 7, + x^6 - 2*x^5 + 11*x^4 - 24*x^3 + 30*x^2 - 16*x + 4] We compute `x`-coordinate polynomials for some Heegner points of conductor bigger than 1 on a rank 2 curve:: sage: E = EllipticCurve('389a'); P = E.heegner_point(-7, 5); P - Heegner point of discriminant -7 and conductor 5 on elliptic curve of conductor 389 + Heegner point of discriminant -7 and conductor 5 + on elliptic curve of conductor 389 sage: P.x_poly_exact() Traceback (most recent call last): ... - ValueError: insufficient precision to determine Heegner point (fails discriminant test) + ValueError: insufficient precision to determine Heegner point + (fails discriminant test) sage: P.x_poly_exact(120) x^6 + 10/7*x^5 - 867/49*x^4 - 76/245*x^3 + 3148/35*x^2 - 25944/245*x + 48771/1225 - sage: E.heegner_point(-7,11).x_poly_exact(500) - x^10 + 282527/52441*x^9 + 27049007420/2750058481*x^8 - 22058564794/2750058481*x^7 - 140054237301/2750058481*x^6 + 696429998952/30250643291*x^5 + 2791387923058/30250643291*x^4 - 3148473886134/30250643291*x^3 + 1359454055022/30250643291*x^2 - 250620385365/30250643291*x + 181599685425/332757076201 + sage: E.heegner_point(-7, 11).x_poly_exact(500) + x^10 + 282527/52441*x^9 + 27049007420/2750058481*x^8 - 22058564794/2750058481*x^7 + - 140054237301/2750058481*x^6 + 696429998952/30250643291*x^5 + + 2791387923058/30250643291*x^4 - 3148473886134/30250643291*x^3 + + 1359454055022/30250643291*x^2 - 250620385365/30250643291*x + + 181599685425/332757076201 Here we compute a Heegner point of conductor 5 on a rank 3 curve:: sage: E = EllipticCurve('5077a'); P = E.heegner_point(-7,5); P - Heegner point of discriminant -7 and conductor 5 on elliptic curve of conductor 5077 + Heegner point of discriminant -7 and conductor 5 + on elliptic curve of conductor 5077 sage: P.x_poly_exact(500) x^6 + 1108754853727159228/72351048803252547*x^5 + 88875505551184048168/1953478317687818769*x^4 - 2216200271166098662132/3255797196146364615*x^3 + 14941627504168839449851/9767391588439093845*x^2 - 3456417460183342963918/3255797196146364615*x + 1306572835857500500459/5426328660243941025 @@ -3403,12 +3487,13 @@ def _check_poly_discriminant(self, f): INPUT: - - `f` -- a polynomial + - `f` -- a polynomial EXAMPLES:: sage: E = EllipticCurve('389a'); P = E.heegner_point(-7, 5); P - Heegner point of discriminant -7 and conductor 5 on elliptic curve of conductor 389 + Heegner point of discriminant -7 and conductor 5 + on elliptic curve of conductor 389 sage: R. = QQ[] sage: P._check_poly_discriminant(x^2 - 5) True @@ -3450,22 +3535,23 @@ def point_exact(self, prec=53, algorithm='lll', var='a', optimize=False): INPUT: - - ``prec`` -- integer (default: 53) + - ``prec`` -- integer (default: 53) - - ``algorithm`` -- see the description of the algorithm - parameter for the ``x_poly_exact`` method. + - ``algorithm`` -- see the description of the algorithm + parameter for the ``x_poly_exact`` method. - - ``var`` -- string (default: 'a') + - ``var`` -- string (default: 'a') - - ``optimize`` -- bool (default; False) if ``True``, try to - optimize defining polynomial for the number field that - the point is defined over. Off by default, since this - can be very expensive. + - ``optimize`` -- bool (default; False) if ``True``, try to + optimize defining polynomial for the number field that + the point is defined over. Off by default, since this + can be very expensive. EXAMPLES:: sage: E = EllipticCurve('389a'); P = E.heegner_point(-7, 5); P - Heegner point of discriminant -7 and conductor 5 on elliptic curve of conductor 389 + Heegner point of discriminant -7 and conductor 5 + on elliptic curve of conductor 389 sage: z = P.point_exact(200, optimize=True) sage: z[1].charpoly() x^12 + 6*x^11 + 90089/1715*x^10 + 71224/343*x^9 + 52563964/588245*x^8 - 483814934/588245*x^7 - 156744579/16807*x^6 - 2041518032/84035*x^5 + 1259355443184/14706125*x^4 + 3094420220918/14706125*x^3 + 123060442043827/367653125*x^2 + 82963044474852/367653125*x + 211679465261391/1838265625 @@ -3543,9 +3629,14 @@ def conjugates_over_K(self): sage: E = EllipticCurve('77a') sage: y = E.heegner_point(-52,5); y - Heegner point of discriminant -52 and conductor 5 on elliptic curve of conductor 77 + Heegner point of discriminant -52 and conductor 5 + on elliptic curve of conductor 77 sage: print([z.quadratic_form() for z in y.conjugates_over_K()]) - [77*x^2 + 52*x*y + 13*y^2, 154*x^2 + 206*x*y + 71*y^2, 539*x^2 + 822*x*y + 314*y^2, 847*x^2 + 1284*x*y + 487*y^2, 1001*x^2 + 52*x*y + y^2, 1078*x^2 + 822*x*y + 157*y^2, 1309*x^2 + 360*x*y + 25*y^2, 1309*x^2 + 2054*x*y + 806*y^2, 1463*x^2 + 976*x*y + 163*y^2, 2233*x^2 + 2824*x*y + 893*y^2, 2387*x^2 + 2054*x*y + 442*y^2, 3619*x^2 + 3286*x*y + 746*y^2] + [77*x^2 + 52*x*y + 13*y^2, 154*x^2 + 206*x*y + 71*y^2, 539*x^2 + 822*x*y + 314*y^2, + 847*x^2 + 1284*x*y + 487*y^2, 1001*x^2 + 52*x*y + y^2, 1078*x^2 + 822*x*y + 157*y^2, + 1309*x^2 + 360*x*y + 25*y^2, 1309*x^2 + 2054*x*y + 806*y^2, + 1463*x^2 + 976*x*y + 163*y^2, 2233*x^2 + 2824*x*y + 893*y^2, + 2387*x^2 + 2054*x*y + 442*y^2, 3619*x^2 + 3286*x*y + 746*y^2] sage: y.quadratic_form() 77*x^2 + 52*x*y + 13*y^2 """ @@ -3562,7 +3653,7 @@ def _numerical_approx_conjugates_over_QQ(self, prec=53): INPUT: - - ``prec`` -- positive integer (default: 53) + - ``prec`` -- positive integer (default: 53) EXAMPLES:: @@ -3593,11 +3684,11 @@ def _numerical_approx_xy_poly(self, prec=53): INPUT: - - ``prec`` -- positive integer (default: 53) + - ``prec`` -- positive integer (default: 53) OUTPUT: - - 2-tuple of polynomials with floating point coefficients + - 2-tuple of polynomials with floating point coefficients EXAMPLES:: @@ -3605,7 +3696,8 @@ def _numerical_approx_xy_poly(self, prec=53): sage: y = E.heegner_point(-7,3); y Heegner point of discriminant -7 and conductor 3 on elliptic curve of conductor 37 sage: y._numerical_approx_xy_poly() # rel tol 1e-14 - (X^8 + 6.00000000000000*X^7 + 8.99999999999998*X^6 - 12.0000000000000*X^5 - 42.0000000000000*X^4 - 17.9999999999999*X^3 + 36.0000000000001*X^2 + 35.9999999999999*X + 8.99999999999995, X^8 + 12.0000000000000*X^7 + 72.0000000000000*X^6 + 270.000000000000*X^5 + 678.000000000001*X^4 + 1152.00000000000*X^3 + 1269.00000000000*X^2 + 810.000000000002*X + 225.000000000001) + (X^8 + 6.00000000000000*X^7 + 8.99999999999998*X^6 - 12.0000000000000*X^5 - 42.0000000000000*X^4 - 17.9999999999999*X^3 + 36.0000000000001*X^2 + 35.9999999999999*X + 8.99999999999995, + X^8 + 12.0000000000000*X^7 + 72.0000000000000*X^6 + 270.000000000000*X^5 + 678.000000000001*X^4 + 1152.00000000000*X^3 + 1269.00000000000*X^2 + 810.000000000002*X + 225.000000000001) """ v = self._numerical_approx_conjugates_over_QQ(prec) R = ComplexField(prec)['X'] @@ -3625,13 +3717,13 @@ def _xy_poly_nearby(self, prec=53, max_error=10**(-10)): INPUT: - - ``prec`` -- positive integer (default: 53) + - ``prec`` -- positive integer (default: 53) - - ``max_error`` -- very small floating point number + - ``max_error`` -- very small floating point number OUTPUT: - - 2-tuple of polynomials with rational coefficients + - 2-tuple of polynomials with rational coefficients EXAMPLES:: @@ -3640,7 +3732,7 @@ def _xy_poly_nearby(self, prec=53, max_error=10**(-10)): Heegner point of discriminant -7 and conductor 3 on elliptic curve of conductor 37 sage: y._xy_poly_nearby() [X^8 + 6*X^7 + 9*X^6 - 12*X^5 - 42*X^4 - 18*X^3 + 36*X^2 + 36*X + 9, - X^8 + 12*X^7 + 72*X^6 + 270*X^5 + 678*X^4 + 1152*X^3 + 1269*X^2 + 810*X + 225] + X^8 + 12*X^7 + 72*X^6 + 270*X^5 + 678*X^4 + 1152*X^3 + 1269*X^2 + 810*X + 225] """ v = self._numerical_approx_xy_poly(prec) return [nearby_rational_poly(g, max_error=max_error) for g in v] @@ -3653,9 +3745,9 @@ def _xy_poly_simplest(self, prec=53, prec2=None): INPUT: - - ``prec`` -- positive integer (default: 53) + - ``prec`` -- positive integer (default: 53) - - ``prec2`` -- passed into simplest_rational_poly function + - ``prec2`` -- passed into simplest_rational_poly function EXAMPLES:: @@ -3697,7 +3789,7 @@ def _trace_numerical_conductor_1(self, prec=53): INPUT: - - `prec` -- bits precision (default: 53) + - `prec` -- bits precision (default: 53) EXAMPLES:: @@ -3811,7 +3903,7 @@ def _qf_to_tau(self, f): INPUT: - - `f` -- binary quadratic form + - `f` -- binary quadratic form EXAMPLES:: @@ -3834,7 +3926,7 @@ def _qf_from_tau(self, tau): INPUT: - - `\tau` -- quadratic element of the upper half plane + - `\tau` -- quadratic element of the upper half plane EXAMPLES:: @@ -3865,13 +3957,13 @@ def _qf_atkin_lehner_act(self, Q, f): INPUT: - - `Q` -- integer that divides the level `N` + - `Q` -- integer that divides the level `N` - - `f` -- quadratic form + - `f` -- quadratic form OUTPUT: - - quadratic form + - quadratic form EXAMPLES:: @@ -3919,9 +4011,9 @@ def kolyvagin_cohomology_class(self, n=None): INPUT: - - `n` -- positive integer that divides the gcd of `a_p` - and `p+1` for all `p` dividing the conductor. If `n` is - ``None``, choose the largest valid `n`. + - `n` -- positive integer that divides the gcd of `a_p` + and `p+1` for all `p` dividing the conductor. If `n` is + ``None``, choose the largest valid `n`. EXAMPLES:: @@ -3949,7 +4041,8 @@ class KolyvaginPoint(HeegnerPoint): sage: EllipticCurve('37a1').kolyvagin_point(-67) Kolyvagin point of discriminant -67 on elliptic curve of conductor 37 sage: EllipticCurve('389a1').kolyvagin_point(-7, 5) - Kolyvagin point of discriminant -7 and conductor 5 on elliptic curve of conductor 389 + Kolyvagin point of discriminant -7 and conductor 5 + on elliptic curve of conductor 389 One can also associated a Kolyvagin point to a Heegner point:: @@ -4079,7 +4172,7 @@ def numerical_approx(self, prec=53): INPUT: - - ``prec`` -- precision in bits (default: 53) + - ``prec`` -- precision in bits (default: 53) EXAMPLES:: @@ -4091,7 +4184,8 @@ def numerical_approx(self, prec=53): True sage: P = EllipticCurve('389a1').kolyvagin_point(-7, 5); P - Kolyvagin point of discriminant -7 and conductor 5 on elliptic curve of conductor 389 + Kolyvagin point of discriminant -7 and conductor 5 + on elliptic curve of conductor 389 Numerical approximation is only implemented for points of conductor 1:: @@ -4108,7 +4202,7 @@ def point_exact(self, prec=53): """ INPUT: - - ``prec`` -- precision in bits (default: 53) + - ``prec`` -- precision in bits (default: 53) EXAMPLES: @@ -4194,7 +4288,7 @@ def plot(self, prec=53, *args, **kwds): EXAMPLES:: sage: E = EllipticCurve('37a'); P = E.heegner_point(-11).kolyvagin_point() - sage: P.plot(prec=30, pointsize=50, rgbcolor='red') + E.plot() + sage: P.plot(prec=30, pointsize=50, rgbcolor='red') + E.plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives """ if self.conductor() != 1: @@ -4278,9 +4372,9 @@ def _recognize_point_over_QQ(self, P, n): INPUT: - - `P` -- numerical approximation for a point on `E` + - `P` -- numerical approximation for a point on `E` - - `n` -- upper bound on divisibility index of `P` in group `E(\QQ)` + - `n` -- upper bound on divisibility index of `P` in group `E(\QQ)` EXAMPLES:: @@ -4397,18 +4491,18 @@ def kolyvagin_cohomology_class(self, n=None): """ INPUT: - - `n` -- positive integer that divides the gcd of `a_p` - and `p+1` for all `p` dividing the conductor. If `n` is - ``None``, choose the largest valid `n`. + - `n` -- positive integer that divides the gcd of `a_p` + and `p+1` for all `p` dividing the conductor. If `n` is + ``None``, choose the largest valid `n`. EXAMPLES:: - sage: y = EllipticCurve('389a').heegner_point(-7,5) + sage: y = EllipticCurve('389a').heegner_point(-7, 5) sage: P = y.kolyvagin_point() sage: P.kolyvagin_cohomology_class(3) Kolyvagin cohomology class c(5) in H^1(K,E[3]) - sage: y = EllipticCurve('37a').heegner_point(-7,5).kolyvagin_point() + sage: y = EllipticCurve('37a').heegner_point(-7, 5).kolyvagin_point() sage: y.kolyvagin_cohomology_class() Kolyvagin cohomology class c(5) in H^1(K,E[2]) """ @@ -4437,7 +4531,7 @@ def __init__(self, kolyvagin_point, n): EXAMPLES:: - sage: y = EllipticCurve('389a').heegner_point(-7,5) + sage: y = EllipticCurve('389a').heegner_point(-7, 5) sage: y.kolyvagin_cohomology_class(3) Kolyvagin cohomology class c(5) in H^1(K,E[3]) """ @@ -4506,7 +4600,7 @@ def conductor(self): EXAMPLES:: - sage: y = EllipticCurve('37a').heegner_point(-7,5) + sage: y = EllipticCurve('37a').heegner_point(-7, 5) sage: t = y.kolyvagin_cohomology_class() sage: t.conductor() 5 @@ -4520,10 +4614,11 @@ class is associated. EXAMPLES:: - sage: y = EllipticCurve('37a').heegner_point(-7,5) + sage: y = EllipticCurve('37a').heegner_point(-7, 5) sage: t = y.kolyvagin_cohomology_class() sage: t.kolyvagin_point() - Kolyvagin point of discriminant -7 and conductor 5 on elliptic curve of conductor 37 + Kolyvagin point of discriminant -7 and conductor 5 + on elliptic curve of conductor 37 """ return self.__kolyvagin_point @@ -4534,10 +4629,11 @@ def heegner_point(self): EXAMPLES:: - sage: y = EllipticCurve('37a').heegner_point(-7,5) + sage: y = EllipticCurve('37a').heegner_point(-7, 5) sage: t = y.kolyvagin_cohomology_class() sage: t.heegner_point() - Heegner point of discriminant -7 and conductor 5 on elliptic curve of conductor 37 + Heegner point of discriminant -7 and conductor 5 + on elliptic curve of conductor 37 """ return self.__kolyvagin_point.heegner_point() @@ -4552,7 +4648,7 @@ def _repr_(self): EXAMPLES:: - sage: y = EllipticCurve('37a').heegner_point(-7,5) + sage: y = EllipticCurve('37a').heegner_point(-7, 5) sage: t = y.kolyvagin_cohomology_class() sage: t._repr_() 'Kolyvagin cohomology class c(5) in H^1(K,E[2])' @@ -4589,9 +4685,9 @@ def __init__(self, level, ell): r""" INPUT: - - ``level`` -- the level (a positive integer) + - ``level`` -- the level (a positive integer) - - `\ell` -- the characteristic, a prime coprime to the level + - `\ell` -- the characteristic, a prime coprime to the level EXAMPLES:: @@ -4679,13 +4775,11 @@ def satisfies_heegner_hypothesis(self, D, c=ZZ(1)): INPUT: - - `D` -- negative integer + - `D` -- negative integer - - `c` -- positive integer (default: 1) + - `c` -- positive integer (default: 1) - OUTPUT: - - - bool + OUTPUT: A boolean. EXAMPLES:: @@ -4718,11 +4812,9 @@ def heegner_discriminants(self, n=5): INPUT: - - `n` -- positive integer (default: 5) - - OUTPUT: + - `n` -- positive integer (default: 5) - - list + OUTPUT: A list. EXAMPLES:: @@ -4749,14 +4841,11 @@ def heegner_conductors(self, D, n=5): INPUT: - - `D` -- negative integer; a fundamental Heegner - discriminant - - - `n` -- positive integer (default: 5) + - `D` -- negative integer; a fundamental Heegner discriminant - OUTPUT: + - `n` -- positive integer (default: 5) - - list + OUTPUT: A list. EXAMPLES:: @@ -4860,8 +4949,10 @@ def left_orders(self): EXAMPLES:: sage: heegner_points(11).reduce_mod(3).left_orders() - [Order of Quaternion Algebra (-1, -3) with base ring Rational Field with basis (1/2 + 1/2*j + 7*k, 1/2*i + 13/2*k, j + 3*k, 11*k), - Order of Quaternion Algebra (-1, -3) with base ring Rational Field with basis (1/2 + 1/2*j + 7*k, 1/4*i + 1/2*j + 63/4*k, j + 14*k, 22*k)] + [Order of Quaternion Algebra (-1, -3) with base ring Rational Field + with basis (1/2 + 1/2*j + 7*k, 1/2*i + 13/2*k, j + 3*k, 11*k), + Order of Quaternion Algebra (-1, -3) with base ring Rational Field + with basis (1/2 + 1/2*j + 7*k, 1/4*i + 1/2*j + 63/4*k, j + 14*k, 22*k)] """ return [I.left_order() for I in self.right_ideals()] @@ -4879,13 +4970,11 @@ def heegner_divisor(self, D, c=ZZ(1)): INPUT: - - `D` -- discriminant (negative integer) + - `D` -- discriminant (negative integer) - - `c` -- conductor (positive integer) - - OUTPUT: + - `c` -- conductor (positive integer) - - Brandt module element + OUTPUT: A Brandt module element. EXAMPLES:: @@ -4945,11 +5034,9 @@ def modp_splitting_data(self, p): INPUT: - - `p` -- unramified odd prime + - `p` -- unramified odd prime - OUTPUT: - - - 2-tuple of matrices over finite field + OUTPUT: A 2-tuple of matrices over finite field. EXAMPLES:: @@ -5032,7 +5119,7 @@ def modp_splitting_map(self, p): INPUT: - - `p` -- prime number + - `p` -- prime number EXAMPLES:: @@ -5040,8 +5127,8 @@ def modp_splitting_map(self, p): sage: f = H.modp_splitting_map(13) sage: B = H.quaternion_algebra(); B Quaternion Algebra (-1, -7) with base ring Rational Field - sage: i,j,k = H.quaternion_algebra().gens() - sage: a = 2+i-j+3*k; b = 7+2*i-4*j+k + sage: i, j, k = H.quaternion_algebra().gens() + sage: a = 2 + i - j + 3*k; b = 7 + 2*i - 4*j + k sage: f(a*b) [12 3] [10 5] @@ -5065,11 +5152,10 @@ def cyclic_subideal_p1(self, I, c): INPUT: - - `I` -- right ideal of Eichler order or in quaternion algebra + - `I` -- right ideal of Eichler order or in quaternion algebra - - `c` -- square free integer (currently must be odd prime - and coprime to level, discriminant, characteristic, - etc. + - `c` -- square free integer (currently must be odd prime + and coprime to level, discriminant, characteristic, etc. OUTPUT: @@ -5079,7 +5165,7 @@ def cyclic_subideal_p1(self, I, c): sage: H = heegner_points(11).reduce_mod(7) sage: I = H.brandt_module().right_ideals()[0] - sage: sorted(H.cyclic_subideal_p1(I,3).items()) + sage: sorted(H.cyclic_subideal_p1(I, 3).items()) [((0, 1), Fractional ideal (2 + 2*j + 32*k, 2*i + 8*j + 82*k, 12*j + 60*k, 132*k)), ((1, 0), @@ -5088,7 +5174,7 @@ def cyclic_subideal_p1(self, I, c): Fractional ideal (2 + 2*j + 76*k, 2*i + 4*j + 106*k, 12*j + 60*k, 132*k)), ((1, 2), Fractional ideal (2 + 10*j + 116*k, 2*i + 8*j + 38*k, 12*j + 60*k, 132*k))] - sage: len(H.cyclic_subideal_p1(I,17)) + sage: len(H.cyclic_subideal_p1(I, 17)) 18 """ c = ZZ(c) @@ -5122,16 +5208,17 @@ def galois_group_over_hilbert_class_field(self, D, c): INPUT: - - `D` -- fundamental discriminant + - `D` -- fundamental discriminant - - `c` -- conductor (square-free integer) + - `c` -- conductor (square-free integer) EXAMPLES:: sage: N = 37; D = -7; ell = 17; c = 41; p = 3 sage: H = heegner_points(N).reduce_mod(ell) sage: H.galois_group_over_hilbert_class_field(D, c) - Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 41 over Hilbert class field of QQ[sqrt(-7)] + Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 41 + over Hilbert class field of QQ[sqrt(-7)] """ Kc = heegner_points(self.level(), D, c).ring_class_field() K1 = heegner_points(self.level(), D, 1).ring_class_field() @@ -5145,16 +5232,18 @@ def galois_group_over_quadratic_field(self, D, c): INPUT: - - `D` -- fundamental discriminant + - `D` -- fundamental discriminant - - `c` -- conductor (square-free integer) + - `c` -- conductor (square-free integer) EXAMPLES:: sage: N = 37; D = -7; ell = 17; c = 41; p = 3 sage: H = heegner_points(N).reduce_mod(ell) sage: H.galois_group_over_quadratic_field(D, c) - Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 41 over Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 with sqrt_minus_7 = 2.645751311064591?*I + Galois group of Ring class field extension of QQ[sqrt(-7)] of conductor 41 + over Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 + with sqrt_minus_7 = 2.645751311064591?*I """ Kc = heegner_points(self.level(), D, c).ring_class_field() return Kc.galois_group(Kc.quadratic_field()) @@ -5167,17 +5256,16 @@ def quadratic_field(self, D): INPUT: - - `D` -- fundamental discriminant - - OUTPUT: + - `D` -- fundamental discriminant - - a quadratic number field + OUTPUT: A quadratic number field. EXAMPLES:: sage: H = heegner_points(389).reduce_mod(5) sage: H.quadratic_field(-7) - Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 with sqrt_minus_7 = 2.645751311064591?*I + Number Field in sqrt_minus_7 with defining polynomial x^2 + 7 + with sqrt_minus_7 = 2.645751311064591?*I """ Kc = heegner_points(self.level(), D, 1).ring_class_field() return Kc.quadratic_field() @@ -5191,21 +5279,18 @@ def kolyvagin_cyclic_subideals(self, I, p, alpha_quaternion): INPUT: - - `I` -- right ideal of the quaternion algebra + - `I` -- right ideal of the quaternion algebra - - `p` -- prime number + - `p` -- prime number - - ``alpha_quaternion`` -- image in the quaternion algebra - of generator `\alpha` for - `(\mathcal{O}_K / c\mathcal{O}_K)^* / (\ZZ/c\ZZ)^*`. - - OUTPUT: + - ``alpha_quaternion`` -- image in the quaternion algebra + of generator `\alpha` for `(\mathcal{O}_K / c\mathcal{O}_K)^* / (\ZZ/c\ZZ)^*`. - - list of 2-tuples + OUTPUT: A list of 2-tuples. EXAMPLES:: - sage: N = 37; D = -7; ell = 17; c=5 + sage: N = 37; D = -7; ell = 17; c = 5 sage: H = heegner_points(N).reduce_mod(ell) sage: I = H.brandt_module().right_ideals()[49] sage: f = H.optimal_embeddings(D, 1, I.left_order())[1] @@ -5213,12 +5298,24 @@ def kolyvagin_cyclic_subideals(self, I, p, alpha_quaternion): sage: alpha_quaternion = f(g[0]); alpha_quaternion 1 - 77/192*i - 5/128*j - 137/384*k sage: H.kolyvagin_cyclic_subideals(I, 5, alpha_quaternion) - [(Fractional ideal (2 + 2/3*i + 364*j + 231928/3*k, 4/3*i + 946*j + 69338/3*k, 1280*j + 49920*k, 94720*k), 0), - (Fractional ideal (2 + 2/3*i + 108*j + 31480/3*k, 4/3*i + 434*j + 123098/3*k, 1280*j + 49920*k, 94720*k), 1), - (Fractional ideal (2 + 2/3*i + 876*j + 7672/3*k, 4/3*i + 434*j + 236762/3*k, 1280*j + 49920*k, 94720*k), 2), - (Fractional ideal (2 + 2/3*i + 364*j + 61432/3*k, 4/3*i + 178*j + 206810/3*k, 1280*j + 49920*k, 94720*k), 3), - (Fractional ideal (2 + 2/3*i + 876*j + 178168/3*k, 4/3*i + 1202*j + 99290/3*k, 1280*j + 49920*k, 94720*k), 4), - (Fractional ideal (2 + 2/3*i + 1132*j + 208120/3*k, 4/3*i + 946*j + 183002/3*k, 1280*j + 49920*k, 94720*k), 5)] + [(Fractional ideal (2 + 2/3*i + 364*j + 231928/3*k, + 4/3*i + 946*j + 69338/3*k, + 1280*j + 49920*k, 94720*k), 0), + (Fractional ideal (2 + 2/3*i + 108*j + 31480/3*k, + 4/3*i + 434*j + 123098/3*k, + 1280*j + 49920*k, 94720*k), 1), + (Fractional ideal (2 + 2/3*i + 876*j + 7672/3*k, + 4/3*i + 434*j + 236762/3*k, + 1280*j + 49920*k, 94720*k), 2), + (Fractional ideal (2 + 2/3*i + 364*j + 61432/3*k, + 4/3*i + 178*j + 206810/3*k, + 1280*j + 49920*k, 94720*k), 3), + (Fractional ideal (2 + 2/3*i + 876*j + 178168/3*k, + 4/3*i + 1202*j + 99290/3*k, + 1280*j + 49920*k, 94720*k), 4), + (Fractional ideal (2 + 2/3*i + 1132*j + 208120/3*k, + 4/3*i + 946*j + 183002/3*k, + 1280*j + 49920*k, 94720*k), 5)] """ X = I.cyclic_right_subideals(p, alpha_quaternion) return [(J, i) for i, J in enumerate(X)] @@ -5235,20 +5332,20 @@ def kolyvagin_generator(self, K, p): INPUT: - - `K` -- quadratic imaginary field + - `K` -- quadratic imaginary field - - `p` -- inert prime + - `p` -- inert prime EXAMPLES:: - sage: N = 37; D = -7; ell = 17; p=5 + sage: N = 37; D = -7; ell = 17; p = 5 sage: H = heegner_points(N).reduce_mod(ell) sage: I = H.brandt_module().right_ideals()[49] sage: f = H.optimal_embeddings(D, 1, I.left_order())[0] sage: H.kolyvagin_generator(f.domain().number_field(), 5) a + 1 - This function requires that p be prime, but kolyvagin_generators works in general:: + This function requires that `p` be prime, but ``kolyvagin_generators`` works in general:: sage: H.kolyvagin_generator(f.domain().number_field(), 5*17) Traceback (most recent call last): @@ -5286,13 +5383,13 @@ def kolyvagin_generators(self, K, c): INPUT: - - `K` -- quadratic imaginary field + - `K` -- quadratic imaginary field - - `c` -- square free product of inert prime + - `c` -- square free product of inert prime EXAMPLES:: - sage: N = 37; D = -7; ell = 17; p=5 + sage: N = 37; D = -7; ell = 17; p = 5 sage: H = heegner_points(N).reduce_mod(ell) sage: I = H.brandt_module().right_ideals()[49] sage: f = H.optimal_embeddings(D, 1, I.left_order())[0] @@ -5327,15 +5424,15 @@ def kolyvagin_sigma_operator(self, D, c, r, bound=None): INPUT: - - `D` -- fundamental discriminant + - `D` -- fundamental discriminant - - `c` -- conductor (square-free integer, need not be prime) + - `c` -- conductor (square-free integer, need not be prime) - - `r` -- nonnegative integer + - `r` -- nonnegative integer - - ``bound`` -- (default: ``None``), if given, controls - precision of computation of theta series, which could - impact performance, but does not impact correctness + - ``bound`` -- (default: ``None``), if given, controls + precision of computation of theta series, which could + impact performance, but does not impact correctness EXAMPLES: @@ -5348,9 +5445,11 @@ def kolyvagin_sigma_operator(self, D, c, r, bound=None): sage: V = H.modp_dual_elliptic_curve_factor(E, q, 5) # long time (4s on sage.math, 2012) sage: k118 = H.kolyvagin_sigma_operator(D, c, 118) sage: k104 = H.kolyvagin_sigma_operator(D, c, 104) - sage: [b.dot_product(k104.element().change_ring(GF(3))) for b in V.basis()] # long time + sage: [b.dot_product(k104.element().change_ring(GF(3))) # long time + ....: for b in V.basis()] [0, 0] - sage: [b.dot_product(k118.element().change_ring(GF(3))) for b in V.basis()] # long time + sage: [b.dot_product(k118.element().change_ring(GF(3))) # long time + ....: for b in V.basis()] [0, 0] Next we try again with `c=41` and this does work, in that we @@ -5359,9 +5458,11 @@ def kolyvagin_sigma_operator(self, D, c, r, bound=None): sage: c = 41 sage: k118 = H.kolyvagin_sigma_operator(D, c, 118) sage: k104 = H.kolyvagin_sigma_operator(D, c, 104) - sage: [b.dot_product(k118.element().change_ring(GF(3))) for b in V.basis()] # long time + sage: [b.dot_product(k118.element().change_ring(GF(3))) # long time + ....: for b in V.basis()] [2, 0] - sage: [b.dot_product(k104.element().change_ring(GF(3))) for b in V.basis()] # long time + sage: [b.dot_product(k104.element().change_ring(GF(3))) # long time + ....: for b in V.basis()] [1, 0] By the way, the above is the first ever provable verification @@ -5449,11 +5550,11 @@ def modp_dual_elliptic_curve_factor(self, E, p, bound=10): INPUT: - - `E` -- elliptic curve of conductor equal to the level of self + - `E` -- elliptic curve of conductor equal to the level of ``self`` - - `p` -- prime number + - `p` -- prime number - - `bound` -- positive integer (default: 10) + - ``bound`` -- positive integer (default: 10) EXAMPLES:: @@ -5461,8 +5562,7 @@ def modp_dual_elliptic_curve_factor(self, E, p, bound=10): sage: H = heegner_points(N).reduce_mod(ell) sage: V = H.modp_dual_elliptic_curve_factor(EllipticCurve('37a'), q, 5); V Vector space of degree 52 and dimension 2 over Ring of integers modulo 3 - Basis matrix: - 2 x 52 dense matrix over Ring of integers modulo 3 + Basis matrix: 2 x 52 dense matrix over Ring of integers modulo 3 """ if E.conductor() != self.level(): raise ValueError("conductor of E must equal level of self") @@ -5497,13 +5597,11 @@ def rational_kolyvagin_divisor(self, D, c): INPUT: - - `D` -- discriminant (negative integer) + - `D` -- discriminant (negative integer) - - `c` -- conductor (positive integer) - - OUTPUT: + - `c` -- conductor (positive integer) - - Brandt module element (or tuple of them) + OUTPUT: Brandt module element (or tuple of them). EXAMPLES:: @@ -5542,16 +5640,16 @@ def kolyvagin_point_on_curve(self, D, c, E, p, bound=10): INPUT: - - `D` -- fundamental negative discriminant + - `D` -- fundamental negative discriminant - - `c` -- conductor + - `c` -- conductor - - `E` -- elliptic curve of conductor the level of self + - `E` -- elliptic curve of conductor the level of self - - `p` -- odd prime number such that we consider image in - `E(\GF{\ell^2}) / p E(\GF{\ell^2})` + - `p` -- odd prime number such that we consider image in + `E(\GF{\ell^2}) / p E(\GF{\ell^2})` - - ``bound`` -- integer (default: 10) + - ``bound`` -- integer (default: 10) EXAMPLES:: @@ -5573,51 +5671,51 @@ def kolyvagin_reduction_data(E, q, first_only=True): INPUT: - - `E` -- elliptic curve over `\QQ` of rank 1 or 2 + - `E` -- elliptic curve over `\QQ` of rank 1 or 2 - - `q` -- an odd prime that does not divide the order of the - rational torsion subgroup of `E` + - `q` -- an odd prime that does not divide the order of the + rational torsion subgroup of `E` - - ``first_only`` -- bool (default: ``True``) whether two only return - the first prime that one can work modulo to get data about - the Euler system + - ``first_only`` -- bool (default: ``True``) whether two only return + the first prime that one can work modulo to get data about + the Euler system OUTPUT in the rank 1 case or when the default flag ``first_only=True``: - - `\ell` -- first good odd prime satisfying the Kolyvagin - condition that `q` divides \gcd(a_{\ell},\ell+1)` and the - reduction map is surjective to `E(\GF{\ell}) / q - E(\GF{\ell})` + - `\ell` -- first good odd prime satisfying the Kolyvagin + condition that `q` divides \gcd(a_{\ell},\ell+1)` and the + reduction map is surjective to `E(\GF{\ell}) / q + E(\GF{\ell})` - - `D` -- discriminant of the first quadratic imaginary field - `K` that satisfies the Heegner hypothesis for `E` such that - both `\ell` is inert in `K`, and the twist `E^D` has analytic - rank `\leq 1` + - `D` -- discriminant of the first quadratic imaginary field + `K` that satisfies the Heegner hypothesis for `E` such that + both `\ell` is inert in `K`, and the twist `E^D` has analytic + rank `\leq 1` - - `h_D` -- the class number of `K` + - `h_D` -- the class number of `K` - - the dimension of the Brandt module `B(\ell,N)`, where `N` is - the conductor of `E` + - the dimension of the Brandt module `B(\ell,N)`, where `N` is + the conductor of `E` OUTPUT in the rank 2 case: - - `\ell_1` -- first prime (as above in the rank 1 case) where - reduction map is surjective + - `\ell_1` -- first prime (as above in the rank 1 case) where + reduction map is surjective - - `\ell_2` -- second prime (as above) where reduction map is - surjective + - `\ell_2` -- second prime (as above) where reduction map is + surjective - - `D` -- discriminant of the first quadratic imaginary field - `K` that satisfies the Heegner hypothesis for `E` such that - both `\ell_1` and `\ell_2` are simultaneously inert in `K`, - and the twist `E^D` has analytic rank `\leq 1` + - `D` -- discriminant of the first quadratic imaginary field + `K` that satisfies the Heegner hypothesis for `E` such that + both `\ell_1` and `\ell_2` are simultaneously inert in `K`, + and the twist `E^D` has analytic rank `\leq 1` - - `h_D` -- the class number of `K` + - `h_D` -- the class number of `K` - - the dimension of the Brandt module `B(\ell_1,N)`, where `N` is - the conductor of `E` + - the dimension of the Brandt module `B(\ell_1,N)`, where `N` is + the conductor of `E` - - the dimension of the Brandt module `B(\ell_2,N)` + - the dimension of the Brandt module `B(\ell_2,N)` EXAMPLES: @@ -5627,15 +5725,16 @@ def kolyvagin_reduction_data(E, q, first_only=True): A rank 1 example:: - sage: kolyvagin_reduction_data(EllipticCurve('37a1'),3) + sage: kolyvagin_reduction_data(EllipticCurve('37a1'), 3) (17, -7, 1, 52) A rank 3 example:: - sage: kolyvagin_reduction_data(EllipticCurve('5077a1'),3) + sage: kolyvagin_reduction_data(EllipticCurve('5077a1'), 3) (11, -47, 5, 4234) sage: H = heegner_points(5077, -47) - sage: [c for c in H.kolyvagin_conductors(2,10,EllipticCurve('5077a1'),3) if c%11] + sage: [c for c in H.kolyvagin_conductors(2, 10, EllipticCurve('5077a1'), 3) + ....: if c % 11] [667, 943, 1189, 2461] sage: factor(667) 23 * 29 @@ -5654,19 +5753,19 @@ def kolyvagin_reduction_data(E, q, first_only=True): The first rank 2 example:: - sage: kolyvagin_reduction_data(EllipticCurve('389a'),3) + sage: kolyvagin_reduction_data(EllipticCurve('389a'), 3) (5, -7, 1, 130) - sage: kolyvagin_reduction_data(EllipticCurve('389a'),3, first_only=False) + sage: kolyvagin_reduction_data(EllipticCurve('389a'), 3, first_only=False) (5, 17, -7, 1, 130, 520) A large `q = 7`:: - sage: kolyvagin_reduction_data(EllipticCurve('1143c1'),7, first_only=False) + sage: kolyvagin_reduction_data(EllipticCurve('1143c1'), 7, first_only=False) (13, 83, -59, 3, 1536, 10496) Additive reduction:: - sage: kolyvagin_reduction_data(EllipticCurve('2350g1'),5, first_only=False) + sage: kolyvagin_reduction_data(EllipticCurve('2350g1'), 5, first_only=False) (19, 239, -311, 19, 6480, 85680) """ from .ell_generic import is_EllipticCurve @@ -5791,14 +5890,14 @@ def __init__(self, D, c, R, beta): r""" INPUT: - - `D` -- negative fundamental discriminant + - `D` -- negative fundamental discriminant - - `c` -- positive integer coprime to `D` + - `c` -- positive integer coprime to `D` - - `R` -- Eichler order in a rational quaternion algebra + - `R` -- Eichler order in a rational quaternion algebra - - `\beta` -- element of `R` such that the homomorphism - sends `c\sqrt{D}` to `\beta` + - `\beta` -- element of `R` such that the homomorphism + sends `c\sqrt{D}` to `\beta` EXAMPLES:: @@ -5908,7 +6007,8 @@ def domain(self): sage: H = heegner_points(11).reduce_mod(3); R = H.left_orders()[0] sage: H.optimal_embeddings(-7, 2, R)[0].domain() - Order in Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I + Order in Number Field in a with defining polynomial x^2 + 7 + with a = 2.645751311064591?*I """ R, a = quadratic_order(self.__D, self.__c) @@ -5972,7 +6072,8 @@ def codomain(self): sage: H = heegner_points(11).reduce_mod(3); R = H.left_orders()[0] sage: H.optimal_embeddings(-7, 2, R)[0].codomain() - Order of Quaternion Algebra (-1, -3) with base ring Rational Field with basis (1/2 + 1/2*j + 7*k, 1/2*i + 13/2*k, j + 3*k, 11*k) + Order of Quaternion Algebra (-1, -3) with base ring Rational Field + with basis (1/2 + 1/2*j + 7*k, 1/2*i + 13/2*k, j + 3*k, 11*k) """ return self.__R @@ -6020,27 +6121,29 @@ def quadratic_order(D, c, names='a'): INPUT: - - `D` -- fundamental discriminant + - `D` -- fundamental discriminant - - `c` -- conductor + - `c` -- conductor - - ``names`` -- string (default: 'a') + - ``names`` -- string (default: 'a') OUTPUT: - - order `R` of conductor `c` in an imaginary quadratic field + - order `R` of conductor `c` in an imaginary quadratic field - - the element `c\sqrt{D}` as an element of `R` + - the element `c\sqrt{D}` as an element of `R` The generator for the field is named 'a' by default. EXAMPLES:: sage: sage.schemes.elliptic_curves.heegner.quadratic_order(-7,3) - (Order in Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I, + (Order in Number Field in a with defining polynomial x^2 + 7 + with a = 2.645751311064591?*I, 3*a) sage: sage.schemes.elliptic_curves.heegner.quadratic_order(-7,3,'alpha') - (Order in Number Field in alpha with defining polynomial x^2 + 7 with alpha = 2.645751311064591?*I, + (Order in Number Field in alpha with defining polynomial x^2 + 7 + with alpha = 2.645751311064591?*I, 3*alpha) """ K = QuadraticField(D, names) @@ -6056,7 +6159,7 @@ def class_number(D): INPUT: - - `D` -- integer + - `D` -- integer EXAMPLES:: @@ -6067,7 +6170,7 @@ def class_number(D): sage: sage.schemes.elliptic_curves.heegner.class_number(-163) 1 - A ValueError is raised when `D` is not a fundamental + A :class:`ValueError` is raised when `D` is not a fundamental discriminant:: sage: sage.schemes.elliptic_curves.heegner.class_number(-5) @@ -6085,9 +6188,9 @@ def is_inert(D, p): INPUT: - - `D` -- fundamental discriminant + - `D` -- fundamental discriminant - - `p` -- prime integer + - `p` -- prime integer EXAMPLES:: @@ -6108,9 +6211,9 @@ def is_split(D, p): INPUT: - - `D` -- fundamental discriminant + - `D` -- fundamental discriminant - - `p` -- prime integer + - `p` -- prime integer EXAMPLES:: @@ -6131,9 +6234,9 @@ def is_ramified(D, p): INPUT: - - `D` -- fundamental discriminant + - `D` -- fundamental discriminant - - `p` -- prime integer + - `p` -- prime integer EXAMPLES:: @@ -6153,16 +6256,17 @@ def nearby_rational_poly(f, **kwds): INPUT: - - `f` -- polynomial with real floating point entries + - `f` -- polynomial with real floating point entries - - ``**kwds`` -- passed on to ``nearby_rational`` method + - ``**kwds`` -- passed on to ``nearby_rational`` method EXAMPLES:: + sage: from sage.schemes.elliptic_curves.heegner import nearby_rational_poly sage: R. = RR[] - sage: sage.schemes.elliptic_curves.heegner.nearby_rational_poly(2.1*x^2 + 3.5*x - 1.2, max_error=10e-16) + sage: nearby_rational_poly(2.1*x^2 + 3.5*x - 1.2, max_error=10e-16) 21/10*X^2 + 7/2*X - 6/5 - sage: sage.schemes.elliptic_curves.heegner.nearby_rational_poly(2.1*x^2 + 3.5*x - 1.2, max_error=10e-17) + sage: nearby_rational_poly(2.1*x^2 + 3.5*x - 1.2, max_error=10e-17) 4728779608739021/2251799813685248*X^2 + 7/2*X - 5404319552844595/4503599627370496 sage: RR(4728779608739021/2251799813685248 - 21/10) 8.88178419700125e-17 @@ -6177,14 +6281,15 @@ def simplest_rational_poly(f, prec): INPUT: - - `f` -- polynomial with real floating point entries + - `f` -- polynomial with real floating point entries - - ``prec`` -- positive integer + - ``prec`` -- positive integer EXAMPLES:: + sage: from sage.schemes.elliptic_curves.heegner import simplest_rational_poly sage: R. = RR[] - sage: sage.schemes.elliptic_curves.heegner.simplest_rational_poly(2.1*x^2 + 3.5*x - 1.2, 53) + sage: simplest_rational_poly(2.1*x^2 + 3.5*x - 1.2, 53) 21/10*X^2 + 7/2*X - 6/5 """ R = QQ['X'] @@ -6203,9 +6308,9 @@ def satisfies_weak_heegner_hypothesis(N, D): INPUT: - - `N` -- positive integer + - `N` -- positive integer - - `D` -- negative integer + - `D` -- negative integer EXAMPLES:: @@ -6246,11 +6351,9 @@ def make_monic(f): INPUT: - - f -- polynomial over the rational numbers + - `f` -- polynomial over the rational numbers - OUTPUT: - - a monic integral polynomial and an integer + OUTPUT: A monic integral polynomial and an integer. EXAMPLES:: @@ -6322,9 +6425,7 @@ def ell_heegner_point(self, D, c=ZZ(1), f=None, check=True): - ``check`` -- bool (default: ``True``) - OUTPUT: - - The Heegner point `y_c`. + OUTPUT: The Heegner point `y_c`. EXAMPLES:: @@ -6362,7 +6463,8 @@ def ell_heegner_point(self, D, c=ZZ(1), f=None, check=True): We can specify the quadratic form:: sage: P = EllipticCurve('389a').heegner_point(-7, 5, (778,925,275)); P - Heegner point of discriminant -7 and conductor 5 on elliptic curve of conductor 389 + Heegner point of discriminant -7 and conductor 5 + on elliptic curve of conductor 389 sage: P.quadratic_form() 778*x^2 + 925*x*y + 275*y^2 """ @@ -6376,15 +6478,13 @@ def kolyvagin_point(self, D, c=ZZ(1), check=True): INPUT: - - `D` -- a Heegner discriminant - - - `c` -- (default: 1) conductor, must be coprime to `DN` + - `D` -- a Heegner discriminant - - ``check`` -- bool (default: ``True``) + - `c` -- (default: 1) conductor, must be coprime to `DN` - OUTPUT: + - ``check`` -- bool (default: ``True``) - The Kolyvagin point `P` of conductor `c`. + OUTPUT: The Kolyvagin point `P` of conductor `c`. EXAMPLES:: @@ -6488,7 +6588,7 @@ def heegner_point_height(self, D, prec=2, check_rank=True): sage: E = EllipticCurve('5077a') sage: E.heegner_point_height(-7) 0 - sage: E.heegner_point_height(-7,check_rank=False) + sage: E.heegner_point_height(-7, check_rank=False) 0.0000? """ @@ -6740,7 +6840,7 @@ def _adjust_heegner_index(self, a): EXAMPLES:: sage: E = EllipticCurve('11a1') - sage: a = RIF(sqrt(2))-RIF(1.4142135623730951) + sage: a = RIF(sqrt(2)) - RIF(1.4142135623730951) sage: E._adjust_heegner_index(a) 1.?e-8 """ @@ -6892,9 +6992,7 @@ def _heegner_index_in_EK(self, D): - `D` -- negative integer; the Heegner discriminant - OUTPUT: - - a power of 2 -- the given index + OUTPUT: A power of 2 -- the given index. EXAMPLES: diff --git a/src/sage/schemes/elliptic_curves/height.py b/src/sage/schemes/elliptic_curves/height.py index 929eb056b35..e9eb837d30e 100644 --- a/src/sage/schemes/elliptic_curves/height.py +++ b/src/sage/schemes/elliptic_curves/height.py @@ -60,7 +60,7 @@ class UnionOfIntervals: EXAMPLES:: sage: from sage.schemes.elliptic_curves.height import UnionOfIntervals - sage: R = UnionOfIntervals([1,2,3,infinity]); R + sage: R = UnionOfIntervals([1, 2, 3, infinity]); R ([1, 2] U [3, +Infinity]) sage: R + 5 ([6, 7] U [8, +Infinity]) @@ -83,9 +83,9 @@ def __init__(self, endpoints): EXAMPLES:: sage: from sage.schemes.elliptic_curves.height import UnionOfIntervals - sage: UnionOfIntervals([0,1]) + sage: UnionOfIntervals([0, 1]) ([0, 1]) - sage: UnionOfIntervals([-infinity, pi, 17, infinity]) + sage: UnionOfIntervals([-infinity, pi, 17, infinity]) # optional - sage.symbolic ([-Infinity, pi] U [17, +Infinity]) sage: UnionOfIntervals([]) () @@ -94,7 +94,7 @@ def __init__(self, endpoints): Traceback (most recent call last): ... ValueError: an even number of endpoints must be given (got 1) - sage: UnionOfIntervals([3,2,1,0]) + sage: UnionOfIntervals([3, 2, 1, 0]) Traceback (most recent call last): ... ValueError: endpoints must be given in order @@ -112,7 +112,7 @@ def finite_endpoints(self): EXAMPLES:: sage: from sage.schemes.elliptic_curves.height import UnionOfIntervals - sage: UnionOfIntervals([0,1]).finite_endpoints() + sage: UnionOfIntervals([0, 1]).finite_endpoints() [0, 1] sage: UnionOfIntervals([-infinity, 0, 1, infinity]).finite_endpoints() [0, 1] @@ -140,14 +140,14 @@ def is_empty(self): EXAMPLES:: sage: from sage.schemes.elliptic_curves.height import UnionOfIntervals - sage: UnionOfIntervals([3,4]).is_empty() + sage: UnionOfIntervals([3, 4]).is_empty() False sage: all = UnionOfIntervals([-infinity, infinity]) sage: all.is_empty() False sage: (~all).is_empty() True - sage: A = UnionOfIntervals([0,1]) & UnionOfIntervals([2,3]) + sage: A = UnionOfIntervals([0, 1]) & UnionOfIntervals([2, 3]) sage: A.is_empty() True """ @@ -286,13 +286,13 @@ def join(L, condition): sage: from sage.schemes.elliptic_curves.height import UnionOfIntervals sage: A = UnionOfIntervals([1,3,5,7]); A ([1, 3] U [5, 7]) - sage: B = A+1; B + sage: B = A + 1; B ([2, 4] U [6, 8]) - sage: A.join([A,B],any) # union + sage: A.join([A,B], any) # union ([1, 4] U [5, 8]) - sage: A.join([A,B],all) # intersection + sage: A.join([A,B], all) # intersection ([2, 3] U [6, 7]) - sage: A.join([A,B],sum) # symmetric difference + sage: A.join([A,B], sum) # symmetric difference ([1, 2] U [3, 4] U [5, 6] U [7, 8]) """ all = [] @@ -333,7 +333,7 @@ def union(cls, L): sage: from sage.schemes.elliptic_curves.height import UnionOfIntervals sage: A = UnionOfIntervals([1,3,5,7]); A ([1, 3] U [5, 7]) - sage: B = A+1; B + sage: B = A + 1; B ([2, 4] U [6, 8]) sage: A.union([A,B]) ([1, 4] U [5, 8]) @@ -363,7 +363,7 @@ def intersection(cls, L): sage: from sage.schemes.elliptic_curves.height import UnionOfIntervals sage: A = UnionOfIntervals([1,3,5,7]); A ([1, 3] U [5, 7]) - sage: B = A+1; B + sage: B = A + 1; B ([2, 4] U [6, 8]) sage: A.intersection([A,B]) ([2, 3] U [6, 7]) @@ -390,7 +390,7 @@ def __or__(left, right): sage: from sage.schemes.elliptic_curves.height import UnionOfIntervals sage: A = UnionOfIntervals([1,3,5,7]); A ([1, 3] U [5, 7]) - sage: B = A+1; B + sage: B = A + 1; B ([2, 4] U [6, 8]) sage: A | B ([1, 4] U [5, 8]) @@ -414,7 +414,7 @@ def __and__(left, right): sage: from sage.schemes.elliptic_curves.height import UnionOfIntervals sage: A = UnionOfIntervals([1,3,5,7]); A ([1, 3] U [5, 7]) - sage: B = A+1; B + sage: B = A + 1; B ([2, 4] U [6, 8]) sage: A & B ([2, 3] U [6, 7]) @@ -489,13 +489,13 @@ def nonneg_region(f): sage: from sage.schemes.elliptic_curves.height import nonneg_region sage: x = polygen(RR) - sage: nonneg_region(x^2-1) + sage: nonneg_region(x^2 - 1) ([-Infinity, -1.00000000000000] U [1.00000000000000, +Infinity]) - sage: nonneg_region(1-x^2) + sage: nonneg_region(1 - x^2) ([-1.00000000000000, 1.00000000000000]) - sage: nonneg_region(1-x^3) + sage: nonneg_region(1 - x^3) ([-Infinity, 1.00000000000000]) - sage: nonneg_region(x^3-1) + sage: nonneg_region(x^3 - 1) ([1.00000000000000, +Infinity]) sage: nonneg_region((x-1)*(x-2)) ([-Infinity, 1.00000000000000] U [2.00000000000000, +Infinity]) @@ -505,9 +505,9 @@ def nonneg_region(f): ([1.00000000000000, 2.00000000000000] U [3.00000000000000, +Infinity]) sage: nonneg_region(-(x-1)*(x-2)*(x-3)) ([-Infinity, 1.00000000000000] U [2.00000000000000, 3.00000000000000]) - sage: nonneg_region(x^4+1) + sage: nonneg_region(x^4 + 1) ([-Infinity, +Infinity]) - sage: nonneg_region(-x^4-1) + sage: nonneg_region(-x^4 - 1) () """ roots = sorted(f.roots()) @@ -526,7 +526,7 @@ def inf_max_abs(f, g, D): - ``f``, ``g`` (polynomials) -- real univariate polynomials - - ``D`` (UnionOfIntervals) -- a subset of `\RR` + - ``D`` (:class:`UnionOfIntervals`) -- a subset of `\RR` OUTPUT: @@ -542,14 +542,14 @@ def inf_max_abs(f, g, D): sage: from sage.schemes.elliptic_curves.height import inf_max_abs, UnionOfIntervals sage: x = polygen(RR) - sage: f = (x-10)^4+1 - sage: g = 2*x^3+100 - sage: inf_max_abs(f,g,UnionOfIntervals([1,2,3,4,5,6])) + sage: f = (x-10)^4 + 1 + sage: g = 2*x^3 + 100 + sage: inf_max_abs(f, g, UnionOfIntervals([1,2,3,4,5,6])) 425.638201706391 - sage: r0 = (f-g).roots()[0][0] + sage: r0 = (f - g).roots()[0][0] sage: r0 5.46053402234697 - sage: max(abs(f(r0)),abs(g(r0))) + sage: max(abs(f(r0)), abs(g(r0))) 425.638201706391 """ xs = f.roots() + f.derivative().roots() @@ -583,7 +583,7 @@ def min_on_disk(f, tol, max_iter=10000): EXAMPLES:: sage: from sage.schemes.elliptic_curves.height import min_on_disk - sage: f = lambda x: (x^2+100).abs() + sage: f = lambda x: (x^2 + 100).abs() sage: s, t = min_on_disk(f, 0.0001) sage: s, f(s), t (0.01? + 1.00?*I, 99.01?, 99.0000000000000) @@ -757,12 +757,14 @@ class EllipticCurveCanonicalHeight: sage: from sage.schemes.elliptic_curves.height import EllipticCurveCanonicalHeight sage: E = EllipticCurve([0,0,0,0,1]) sage: EllipticCurveCanonicalHeight(E) - EllipticCurveCanonicalHeight object associated to Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field + EllipticCurveCanonicalHeight object associated to + Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field Normally this object would be created like this:: sage: E.height_function() - EllipticCurveCanonicalHeight object associated to Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field + EllipticCurveCanonicalHeight object associated to + Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field """ def __init__(self, E): @@ -778,25 +780,29 @@ def __init__(self, E): sage: from sage.schemes.elliptic_curves.height import EllipticCurveCanonicalHeight sage: E = EllipticCurve([0,0,0,0,1]) sage: EllipticCurveCanonicalHeight(E) - EllipticCurveCanonicalHeight object associated to Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field + EllipticCurveCanonicalHeight object associated to + Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field An example over a number field:: - sage: K.=QuadraticField(-1) - sage: E = EllipticCurve([0,i,0,i,i]) - sage: EllipticCurveCanonicalHeight(E) - EllipticCurveCanonicalHeight object associated to Elliptic Curve defined by y^2 = x^3 + i*x^2 + i*x + i over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,i,0,i,i]) # optional - sage.rings.number_field + sage: EllipticCurveCanonicalHeight(E) # optional - sage.rings.number_field + EllipticCurveCanonicalHeight object associated to + Elliptic Curve defined by y^2 = x^3 + i*x^2 + i*x + i + over Number Field in i with defining polynomial x^2 + 1 with i = 1*I TESTS: The base field must be a number field (or `\QQ`):: sage: from sage.schemes.elliptic_curves.height import EllipticCurveCanonicalHeight - sage: E = EllipticCurve(GF(7),[0,0,0,0,1]) - sage: EllipticCurveCanonicalHeight(E) + sage: E = EllipticCurve(GF(7), [0,0,0,0,1]) # optional - sage.rings.finite_rings + sage: EllipticCurveCanonicalHeight(E) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: EllipticCurveCanonicalHeight class can only be created from an elliptic curve defined over a number field + ValueError: EllipticCurveCanonicalHeight class can only be created + from an elliptic curve defined over a number field """ from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve if is_EllipticCurve(E): @@ -818,7 +824,8 @@ def __repr__(self): sage: E = EllipticCurve([0,0,0,0,1]) sage: E.height_function() - EllipticCurveCanonicalHeight object associated to Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field + EllipticCurveCanonicalHeight object associated to + Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field """ return "EllipticCurveCanonicalHeight object associated to %s" % self.E @@ -876,12 +883,12 @@ def __call__(self, P): Over a number field other than `\QQ`:: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve(K, [0,0,0,1,-27]) - sage: H = E.height_function() - sage: H.base_field() + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,0,0,1,-27]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.base_field() # optional - sage.rings.number_field Number Field in i with defining polynomial x^2 + 1 with i = 1*I - sage: H((1,5*i)) + sage: H((1, 5*i)) # optional - sage.rings.number_field 1.22257115164148 """ return self.E(P).height() @@ -905,16 +912,16 @@ def alpha(self, v, tol=0.01): Example 1 from [CPS2006]_:: - sage: K.=QuadraticField(-1) - sage: E = EllipticCurve([0,0,0,1+5*i,3+i]) - sage: H = E.height_function() - sage: alpha = H.alpha(K.places()[0]) - sage: alpha + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 0, 0, 1 + 5*i, 3 + i]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: alpha = H.alpha(K.places()[0]) # optional - sage.rings.number_field + sage: alpha # optional - sage.rings.number_field 1.12272013439355 Compare with `\log(\epsilon_v)=0.344562...` in [CPS2006]_:: - sage: 3*alpha.log() + sage: 3*alpha.log() # optional - sage.rings.number_field 0.347263296676126 """ from sage.rings.polynomial.polynomial_ring import polygen @@ -976,29 +983,29 @@ def e_p(self, p): EXAMPLES:: - sage: K.=QuadraticField(-1) - sage: E = EllipticCurve([0,0,0,1+5*i,3+i]) - sage: H = E.height_function() - sage: H.e_p(K.prime_above(2)) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 0, 0, 1 + 5*i, 3 + i]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.e_p(K.prime_above(2)) # optional - sage.rings.number_field 2 - sage: H.e_p(K.prime_above(3)) + sage: H.e_p(K.prime_above(3)) # optional - sage.rings.number_field 10 - sage: H.e_p(K.prime_above(5)) + sage: H.e_p(K.prime_above(5)) # optional - sage.rings.number_field 9 - sage: E.conductor().norm().factor() + sage: E.conductor().norm().factor() # optional - sage.rings.number_field 2^10 * 20921 - sage: p1, p2 = K.primes_above(20921) - sage: E.local_data(p1) + sage: p1, p2 = K.primes_above(20921) # optional - sage.rings.number_field + sage: E.local_data(p1) # optional - sage.rings.number_field Local data at Fractional ideal (-40*i + 139): Reduction type: bad split multiplicative ... - sage: H.e_p(p1) + sage: H.e_p(p1) # optional - sage.rings.number_field 20920 - sage: E.local_data(p2) + sage: E.local_data(p2) # optional - sage.rings.number_field Local data at Fractional ideal (40*i + 139): Reduction type: good ... - sage: H.e_p(p2) + sage: H.e_p(p2) # optional - sage.rings.number_field 20815 """ kp = self.K.residue_field(p) @@ -1028,10 +1035,10 @@ def DE(self, n): EXAMPLES:: - sage: K.=QuadraticField(-1) - sage: E = EllipticCurve([0,0,0,1+5*i,3+i]) - sage: H = E.height_function() - sage: [H.DE(n) for n in srange(1,6)] + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 0, 0, 1+5*i, 3+i]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: [H.DE(n) for n in srange(1,6)] # optional - sage.rings.number_field [0, 2*log(5) + 2*log(2), 0, 2*log(13) + 2*log(5) + 4*log(2), 0] """ s = 0 @@ -1056,10 +1063,10 @@ def ME(self): EXAMPLES:: - sage: K.=QuadraticField(-1) - sage: E = EllipticCurve([0,0,0,1+5*i,3+i]) - sage: H = E.height_function() - sage: H.ME() + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 0, 0, 1+5*i, 3+i]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.ME() # optional - sage.rings.number_field 1 sage: E = EllipticCurve([0,0,0,0,1]) sage: E.height_function().ME() @@ -1095,13 +1102,13 @@ def B(self, n, mu): Example 10.2 from [Tho2010]_:: - sage: K.=QuadraticField(-1) - sage: E = EllipticCurve([0,1-i,i,-i,0]) - sage: H = E.height_function() + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 1-i, i, -i, 0]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field In [Tho2010]_ the value is given as 0.772:: - sage: RealField(12)( H.B(5, 0.01) ) + sage: RealField(12)( H.B(5, 0.01) ) # optional - sage.rings.number_field 0.777 """ K = self.K @@ -1149,25 +1156,25 @@ def psi(self, xi, v): sage: L(P) / L.real_period() 0.615014189772115 sage: H = E.height_function() - sage: H.psi(10/9,v) + sage: H.psi(10/9, v) 0.615014189772115 An example over a number field:: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,0,0,0,a]) - sage: P = E.lift_x(1/3*a^2 + a + 5/3) - sage: v = K.real_places()[0] - sage: L = E.period_lattice(v) - sage: L(P) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,0,0,0,a]) # optional - sage.rings.number_field + sage: P = E.lift_x(1/3*a^2 + a + 5/3) # optional - sage.rings.number_field + sage: v = K.real_places()[0] # optional - sage.rings.number_field + sage: L = E.period_lattice(v) # optional - sage.rings.number_field + sage: L(P) # optional - sage.rings.number_field 3.51086196882538 - sage: L(P) / L.real_period() + sage: L(P) / L.real_period() # optional - sage.rings.number_field 0.867385122699931 - sage: xP = v(P.xy()[0]) - sage: H = E.height_function() - sage: H.psi(xP,v) + sage: xP = v(P.xy()[0]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.psi(xP, v) # optional - sage.rings.number_field 0.867385122699931 - sage: H.psi(1.23,v) + sage: H.psi(1.23, v) # optional - sage.rings.number_field 0.785854718241495 """ if xi > 1e9: @@ -1204,16 +1211,16 @@ def S(self, xi1, xi2, v): sage: E = EllipticCurve('389a') sage: v = QQ.places()[0] sage: H = E.height_function() - sage: H.S(2,3,v) + sage: H.S(2, 3, v) ([0.224512677391895, 0.274544821597130] U [0.725455178402870, 0.775487322608105]) An example over a number field:: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,0,0,0,a]) - sage: v = K.real_places()[0] - sage: H = E.height_function() - sage: H.S(9,10,v) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,0,0,0,a]) # optional - sage.rings.number_field + sage: v = K.real_places()[0] # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.S(9, 10, v) # optional - sage.rings.number_field ([0.0781194447253472, 0.0823423732016403] U [0.917657626798360, 0.921880555274653]) """ L = self.E.period_lattice(v) @@ -1252,22 +1259,22 @@ def Sn(self, xi1, xi2, n, v): sage: E = EllipticCurve('389a') sage: v = QQ.places()[0] sage: H = E.height_function() - sage: H.S(2,3,v) , H.Sn(2,3,1,v) + sage: H.S(2, 3, v), H.Sn(2, 3, 1, v) (([0.224512677391895, 0.274544821597130] U [0.725455178402870, 0.775487322608105]), ([0.224512677391895, 0.274544821597130] U [0.725455178402870, 0.775487322608105])) - sage: H.Sn(2,3,6,v) + sage: H.Sn(2, 3, 6, v) ([0.0374187795653158, 0.0457574702661884] U [0.120909196400478, 0.129247887101351] U [0.204085446231982, 0.212424136932855] U [0.287575863067145, 0.295914553768017] U [0.370752112898649, 0.379090803599522] U [0.454242529733812, 0.462581220434684] U [0.537418779565316, 0.545757470266188] U [0.620909196400478, 0.629247887101351] U [0.704085446231982, 0.712424136932855] U [0.787575863067145, 0.795914553768017] U [0.870752112898649, 0.879090803599522] U [0.954242529733812, 0.962581220434684]) An example over a number field:: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,0,0,0,a]) - sage: v = K.real_places()[0] - sage: H = E.height_function() - sage: H.S(2,3,v) , H.Sn(2,3,1,v) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,0,0,0,a]) # optional - sage.rings.number_field + sage: v = K.real_places()[0] # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.S(2, 3, v), H.Sn(2, 3, 1, v) # optional - sage.rings.number_field (([0.142172065860075, 0.172845716928584] U [0.827154283071416, 0.857827934139925]), - ([0.142172065860075, 0.172845716928584] U [0.827154283071416, 0.857827934139925])) - sage: H.Sn(2,3,6,v) + ([0.142172065860075, 0.172845716928584] U [0.827154283071416, 0.857827934139925])) + sage: H.Sn(2, 3, 6, v) # optional - sage.rings.number_field ([0.0236953443100124, 0.0288076194880974] U [0.137859047178569, 0.142971322356654] U [0.190362010976679, 0.195474286154764] U [0.304525713845236, 0.309637989023321] U [0.357028677643346, 0.362140952821431] U [0.471192380511903, 0.476304655689988] U [0.523695344310012, 0.528807619488097] U [0.637859047178569, 0.642971322356654] U [0.690362010976679, 0.695474286154764] U [0.804525713845236, 0.809637989023321] U [0.857028677643346, 0.862140952821431] U [0.971192380511903, 0.976304655689988]) """ SS = 1/ZZ(n) * self.S(xi1, xi2, v) @@ -1306,26 +1313,26 @@ def real_intersection_is_empty(self, Bk, v): height strictly greater than 0.2, but fail to prove the same for 0.3:: - sage: H.real_intersection_is_empty([H.B(n,0.2) for n in srange(1,10)],v) + sage: H.real_intersection_is_empty([H.B(n,0.2) for n in srange(1,10)], v) True - sage: H.real_intersection_is_empty([H.B(n,0.3) for n in srange(1,10)],v) + sage: H.real_intersection_is_empty([H.B(n,0.3) for n in srange(1,10)], v) False An example over a number field:: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,0,0,0,a]) - sage: v = K.real_places()[0] - sage: H = E.height_function() + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,0,0,0,a]) # optional - sage.rings.number_field + sage: v = K.real_places()[0] # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field The following two lines prove that the heights of non-torsion points on `E` with everywhere good reduction have canonical height strictly greater than 0.07, but fail to prove the same for 0.08:: - sage: H.real_intersection_is_empty([H.B(n,0.07) for n in srange(1,5)],v) # long time (3.3s) + sage: H.real_intersection_is_empty([H.B(n,0.07) for n in srange(1,5)], v) # long time (3.3s) # optional - sage.rings.number_field True - sage: H.real_intersection_is_empty([H.B(n,0.08) for n in srange(1,5)],v) + sage: H.real_intersection_is_empty([H.B(n,0.08) for n in srange(1,5)], v) # optional - sage.rings.number_field False """ return UnionOfIntervals.intersection([self.Sn(-B, B, k+1, v) for k,B in enumerate(Bk)]).is_empty() @@ -1384,10 +1391,10 @@ def wp_c(self, v): sage: H.wp_c(QQ.places()[0]) 2.68744508779950 - sage: K.=QuadraticField(-1) - sage: E = EllipticCurve([0,0,0,1+5*i,3+i]) - sage: H = E.height_function() - sage: H.wp_c(K.places()[0]) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 0, 0, 1 + 5*i, 3 + i]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.wp_c(K.places()[0]) # optional - sage.rings.number_field 2.66213425640096 """ # Note that we normalise w1, w2 differently from [Tho2010]_! @@ -1663,10 +1670,10 @@ def complex_intersection_is_empty(self, Bk, v, verbose=False, use_half=True): EXAMPLES:: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,0,0,0,a]) - sage: v = K.complex_embeddings()[0] - sage: H = E.height_function() + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,0,0,0,a]) # optional - sage.rings.number_field + sage: v = K.complex_embeddings()[0] # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field The following two lines prove that the heights of non-torsion points on `E` with everywhere good reduction have canonical @@ -1674,18 +1681,18 @@ def complex_intersection_is_empty(self, Bk, v, verbose=False, use_half=True): for 0.03. For the first proof, using only `n=1,2,3` is not sufficient:: - sage: H.complex_intersection_is_empty([H.B(n,0.02) for n in [1,2,3]],v) # long time (~6s) + sage: H.complex_intersection_is_empty([H.B(n,0.02) for n in [1,2,3]], v) # long time (~6s) # optional - sage.rings.number_field False - sage: H.complex_intersection_is_empty([H.B(n,0.02) for n in [1,2,3,4]],v) + sage: H.complex_intersection_is_empty([H.B(n,0.02) for n in [1,2,3,4]], v) # optional - sage.rings.number_field True - sage: H.complex_intersection_is_empty([H.B(n,0.03) for n in [1,2,3,4]],v) # long time (4s) + sage: H.complex_intersection_is_empty([H.B(n,0.03) for n in [1,2,3,4]], v) # long time (4s) # optional - sage.rings.number_field False Using `n\le6` enables us to prove the lower bound 0.03. Note that it takes longer when the result is ``False`` than when it is ``True``:: - sage: H.complex_intersection_is_empty([H.B(n,0.03) for n in [1..6]],v) + sage: H.complex_intersection_is_empty([H.B(n,0.03) for n in [1..6]], v) # optional - sage.rings.number_field True """ from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion @@ -1781,28 +1788,28 @@ def test_mu(self, mu, N, verbose=True): EXAMPLES:: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,0,0,0,a]) - sage: H = E.height_function() + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,0,0,0,a]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field This curve does have a point of good reduction whose canonical point is approximately 1.68:: - sage: P = E.gens(lim3=5)[0]; P + sage: P = E.gens(lim3=5)[0]; P # optional - sage.rings.number_field (1/3*a^2 + a + 5/3 : -2*a^2 - 4/3*a - 5/3 : 1) - sage: P.height() + sage: P.height() # optional - sage.rings.number_field 1.68038085233673 - sage: P.has_good_reduction() + sage: P.has_good_reduction() # optional - sage.rings.number_field True Using `N=5` we can prove that 0.1 is a lower bound (in fact we only need `N=2`), but not that 0.2 is:: - sage: H.test_mu(0.1, 5) + sage: H.test_mu(0.1, 5) # optional - sage.rings.number_field B_1(0.100000000000000) = 1.51580969677387 B_2(0.100000000000000) = 0.932072561526720 True - sage: H.test_mu(0.2, 5) + sage: H.test_mu(0.2, 5) # optional - sage.rings.number_field B_1(0.200000000000000) = 2.04612906979932 B_2(0.200000000000000) = 3.09458988474327 B_3(0.200000000000000) = 27.6251108409484 @@ -1814,11 +1821,11 @@ def test_mu(self, mu, N, verbose=True): either primitive or divisible by either 2 or 3. In fact it is primitive:: - sage: (P.height()/0.1).sqrt() + sage: (P.height()/0.1).sqrt() # optional - sage.rings.number_field 4.09924487233530 - sage: P.division_points(2) + sage: P.division_points(2) # optional - sage.rings.number_field [] - sage: P.division_points(3) + sage: P.division_points(3) # optional - sage.rings.number_field [] """ # Compute the list of values `B_n(\mu)` for n in 1..N. If any @@ -1889,46 +1896,46 @@ def min_gr(self, tol, n_max, verbose=False): Example 10.1 from [Tho2010]_ (where a lower bound of 0.18 was given):: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve([0,0,0,91-26*i,-144-323*i]) - sage: H = E.height_function() - sage: H.min_gr(0.1,4) # long time (8.1s) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 0, 0, 91 - 26*i, -144 - 323*i]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.min_gr(0.1, 4) # long time (8.1s) # optional - sage.rings.number_field 0.1621049443313762 Example 10.2 from [Tho2010]_:: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve([0,1-i,i,-i,0]) - sage: H = E.height_function() - sage: H.min_gr(0.01, 5) # long time + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 1 - i, i, -i, 0]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.min_gr(0.01, 5) # long time # optional - sage.rings.number_field 0.020153685521979152 In this example the point `P=(0,0)` has height 0.023 so our lower bound is quite good:: - sage: P = E((0,0)) - sage: P.has_good_reduction() + sage: P = E((0,0)) # optional - sage.rings.number_field + sage: P.has_good_reduction() # optional - sage.rings.number_field True - sage: P.height() + sage: P.height() # optional - sage.rings.number_field 0.0230242154471211 Example 10.3 from [Tho2010]_ (where the same bound of 0.25 is given):: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,0,0,-3*a-a^2,a^2]) - sage: H = E.height_function() - sage: H.min_gr(0.1,5) # long time (7.2s) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 0, 0, -3*a - a^2, a^2]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.min_gr(0.1, 5) # long time (7.2s) # optional - sage.rings.number_field 0.25 TESTS: This example from the LMFDB gave problems before the fix in :trac:`8829`:: - sage: K. = NumberField(x^2-x-1) - sage: E = EllipticCurve([phi + 1, -phi + 1, 1, 20*phi - 39, 196*phi + 237]) - sage: H = E.height_function() - sage: H.min_gr(.1, 5, verbose=True) # long time (~22s) + sage: K. = NumberField(x^2 - x - 1) # optional - sage.rings.number_field + sage: E = EllipticCurve([phi + 1, -phi + 1, 1, 20*phi - 39, 196*phi + 237]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.min_gr(.1, 5, verbose=True) # long time (~22s) # optional - sage.rings.number_field B_1(1) = 1540.199246369678 ... halving mu to 0.25 and increasing n_max to 6 @@ -2010,34 +2017,34 @@ def min(self, tol, n_max, verbose=False): Example 10.1 from [Tho2010]_ (where a lower bound of 0.18 was given):: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve([0,0,0,91-26*i,-144-323*i]) - sage: H = E.height_function() - sage: H.min(0.1,4) # long time (8.1s) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 0, 0, 91 - 26*i, -144 - 323*i]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.min(0.1, 4) # long time (8.1s) # optional - sage.rings.number_field 0.1621049443313762 Example 10.2 from [Tho2010]_:: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve([0,1-i,i,-i,0]) - sage: H = E.height_function() - sage: H.min(0.01,5) # long time (4s) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 1 - i, i, -i, 0]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.min(0.01, 5) # long time (4s) # optional - sage.rings.number_field 0.020153685521979152 In this example the point `P=(0,0)` has height 0.023 so our lower bound is quite good:: - sage: P = E((0,0)) - sage: P.height() + sage: P = E((0,0)) # optional - sage.rings.number_field + sage: P.height() # optional - sage.rings.number_field 0.0230242154471211 Example 10.3 from [Tho2010]_ (where the same bound of 0.0625 is given):: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,0,0,-3*a-a^2,a^2]) - sage: H = E.height_function() - sage: H.min(0.1,5) # long time (7s) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, 0, 0, -3*a - a^2, a^2]) # optional - sage.rings.number_field + sage: H = E.height_function() # optional - sage.rings.number_field + sage: H.min(0.1, 5) # long time (7s) # optional - sage.rings.number_field 0.0625 More examples over `\QQ`:: @@ -2051,8 +2058,8 @@ def min(self, tol, n_max, verbose=False): After base change the lower bound can decrease:: - sage: K. = QuadraticField(-5) - sage: E.change_ring(K).height_function().min(0.5, 10) # long time (8s) + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: E.change_ring(K).height_function().min(0.5, 10) # long time (8s) # optional - sage.rings.number_field 0.04419417382415922 sage: E = EllipticCurve('389a') diff --git a/src/sage/schemes/elliptic_curves/hom_composite.py b/src/sage/schemes/elliptic_curves/hom_composite.py index 576107582db..a117e2e87d0 100644 --- a/src/sage/schemes/elliptic_curves/hom_composite.py +++ b/src/sage/schemes/elliptic_curves/hom_composite.py @@ -15,61 +15,64 @@ sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite sage: p = 3 * 2^143 - 1 - sage: GF(p^2).inject_variables() + sage: GF(p^2).inject_variables() # optional - sage.rings.finite_rings Defining z2 - sage: E = EllipticCurve(GF(p^2), [1,0]) - sage: P = E.lift_x(31415926535897932384626433832795028841971 - z2) - sage: P.order().factor() + sage: E = EllipticCurve(GF(p^2), [1,0]) # optional - sage.rings.finite_rings + sage: P = E.lift_x(31415926535897932384626433832795028841971 - z2) # optional - sage.rings.finite_rings + sage: P.order().factor() # optional - sage.rings.finite_rings 2^143 - sage: EllipticCurveHom_composite(E, P) + sage: EllipticCurveHom_composite(E, P) # optional - sage.rings.finite_rings Composite morphism of degree 11150372599265311570767859136324180752990208 = 2^143: - From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 33451117797795934712303577408972542258970623^2 + From: Elliptic Curve defined by y^2 = x^3 + x + over Finite Field in z2 of size 33451117797795934712303577408972542258970623^2 To: Elliptic Curve defined by y^2 = x^3 + (18676616716352953484576727486205473216172067*z2+32690199585974925193292786311814241821808308)*x - + (3369702436351367403910078877591946300201903*z2+15227558615699041241851978605002704626689722) - over Finite Field in z2 of size 33451117797795934712303577408972542258970623^2 + + (3369702436351367403910078877591946300201903*z2+15227558615699041241851978605002704626689722) + over Finite Field in z2 of size 33451117797795934712303577408972542258970623^2 Yet, the interface provided by :class:`EllipticCurveHom_composite` is identical to :class:`EllipticCurveIsogeny` and other instantiations of :class:`EllipticCurveHom`:: - sage: E = EllipticCurve(GF(419), [0,1]) - sage: P = E.lift_x(33); P.order() + sage: E = EllipticCurve(GF(419), [0,1]) # optional - sage.rings.finite_rings + sage: P = E.lift_x(33); P.order() # optional - sage.rings.finite_rings 35 - sage: psi = EllipticCurveHom_composite(E, P); psi + sage: psi = EllipticCurveHom_composite(E, P); psi # optional - sage.rings.finite_rings Composite morphism of degree 35 = 5*7: From: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 419 To: Elliptic Curve defined by y^2 = x^3 + 101*x + 285 over Finite Field of size 419 - sage: psi(E.lift_x(11)) + sage: psi(E.lift_x(11)) # optional - sage.rings.finite_rings (352 : 73 : 1) - sage: psi.rational_maps() - ((x^35 + 162*x^34 + 186*x^33 + 92*x^32 - ... + 44*x^3 + 190*x^2 + 80*x - - 72)/(x^34 + 162*x^33 - 129*x^32 + 41*x^31 + ... + 66*x^3 - 191*x^2 + 119*x - + 21), (x^51*y - 176*x^50*y + 115*x^49*y - 120*x^48*y + ... + 72*x^3*y + - 129*x^2*y + 163*x*y + 178*y)/(x^51 - 176*x^50 + 11*x^49 + 26*x^48 - ... - - 77*x^3 + 185*x^2 + 169*x - 128)) - sage: psi.kernel_polynomial() + sage: psi.rational_maps() # optional - sage.rings.finite_rings + ((x^35 + 162*x^34 + 186*x^33 + 92*x^32 - ... + 44*x^3 + 190*x^2 + 80*x + - 72)/(x^34 + 162*x^33 - 129*x^32 + 41*x^31 + ... + 66*x^3 - 191*x^2 + 119*x + 21), + (x^51*y - 176*x^50*y + 115*x^49*y - 120*x^48*y + ... + 72*x^3*y + 129*x^2*y + 163*x*y + + 178*y)/(x^51 - 176*x^50 + 11*x^49 + 26*x^48 - ... - 77*x^3 + 185*x^2 + 169*x - 128)) + sage: psi.kernel_polynomial() # optional - sage.rings.finite_rings x^17 + 81*x^16 + 7*x^15 + 82*x^14 + 49*x^13 + 68*x^12 + 109*x^11 + 326*x^10 - + 117*x^9 + 136*x^8 + 111*x^7 + 292*x^6 + 55*x^5 + 389*x^4 + 175*x^3 + - 43*x^2 + 149*x + 373 - sage: psi.dual() + + 117*x^9 + 136*x^8 + 111*x^7 + 292*x^6 + 55*x^5 + 389*x^4 + 175*x^3 + 43*x^2 + 149*x + 373 + sage: psi.dual() # optional - sage.rings.finite_rings Composite morphism of degree 35 = 7*5: From: Elliptic Curve defined by y^2 = x^3 + 101*x + 285 over Finite Field of size 419 To: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 419 - sage: psi.formal() + sage: psi.formal() # optional - sage.rings.finite_rings t + 211*t^5 + 417*t^7 + 159*t^9 + 360*t^11 + 259*t^13 + 224*t^15 + 296*t^17 + 139*t^19 + 222*t^21 + O(t^23) Equality is decided correctly (and, in some cases, much faster than comparing :meth:`EllipticCurveHom.rational_maps`) even when distinct factorizations of the same isogeny are compared:: - sage: psi == EllipticCurveIsogeny(E, P) + sage: psi == EllipticCurveIsogeny(E, P) # optional - sage.rings.finite_rings True We can easily obtain the individual factors of the composite map:: - sage: psi.factors() - (Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 419 to Elliptic Curve defined by y^2 = x^3 + 140*x + 214 over Finite Field of size 419, - Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 140*x + 214 over Finite Field of size 419 to Elliptic Curve defined by y^2 = x^3 + 101*x + 285 over Finite Field of size 419) + sage: psi.factors() # optional - sage.rings.finite_rings + (Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 419 + to Elliptic Curve defined by y^2 = x^3 + 140*x + 214 over Finite Field of size 419, + Isogeny of degree 7 + from Elliptic Curve defined by y^2 = x^3 + 140*x + 214 over Finite Field of size 419 + to Elliptic Curve defined by y^2 = x^3 + 101*x + 285 over Finite Field of size 419) AUTHORS: @@ -100,16 +103,16 @@ def _eval_factored_isogeny(phis, P): EXAMPLES:: sage: from sage.schemes.elliptic_curves import hom_composite - sage: E = EllipticCurve(GF(419), [1,0]) - sage: Q = E(21,8) - sage: phis = [] - sage: while len(phis) < 10: + sage: E = EllipticCurve(GF(419), [1,0]) # optional - sage.rings.finite_rings + sage: Q = E(21, 8) # optional - sage.rings.finite_rings + sage: phis = [] # optional - sage.rings.finite_rings + sage: while len(phis) < 10: # optional - sage.rings.finite_rings ....: P = list(sorted(E(0).division_points(7)))[1] ....: phis.append(E.isogeny(P)) ....: E = phis[-1].codomain() - sage: R = hom_composite._eval_factored_isogeny(phis, Q); R + sage: R = hom_composite._eval_factored_isogeny(phis, Q); R # optional - sage.rings.finite_rings (290 : 183 : 1) - sage: R in E + sage: R in E # optional - sage.rings.finite_rings True """ for phi in phis: @@ -126,13 +129,13 @@ def _compute_factored_isogeny_prime_power(P, l, e): EXAMPLES:: sage: from sage.schemes.elliptic_curves import hom_composite - sage: E = EllipticCurve(GF(8191), [1,0]) - sage: P = E.random_point() - sage: (l,e), = P.order().factor() - sage: phis = hom_composite._compute_factored_isogeny_prime_power(P,l,e) - sage: hom_composite._eval_factored_isogeny(phis, P) + sage: E = EllipticCurve(GF(8191), [1,0]) # optional - sage.rings.finite_rings + sage: P = E.random_point() # optional - sage.rings.finite_rings + sage: (l,e), = P.order().factor() # optional - sage.rings.finite_rings + sage: phis = hom_composite._compute_factored_isogeny_prime_power(P, l, e) # optional - sage.rings.finite_rings + sage: hom_composite._eval_factored_isogeny(phis, P) # optional - sage.rings.finite_rings (0 : 1 : 0) - sage: [phi.degree() for phi in phis] == [l]*e + sage: [phi.degree() for phi in phis] == [l]*e # optional - sage.rings.finite_rings True """ E = P.curve() @@ -155,12 +158,12 @@ def _compute_factored_isogeny_single_generator(P): EXAMPLES:: sage: from sage.schemes.elliptic_curves import hom_composite - sage: E = EllipticCurve(GF(419), [1,0]) - sage: P = E(42,321) - sage: phis = hom_composite._compute_factored_isogeny_single_generator(P) - sage: list(sorted(phi.degree() for phi in phis)) + sage: E = EllipticCurve(GF(419), [1,0]) # optional - sage.rings.finite_rings + sage: P = E(42, 321) # optional - sage.rings.finite_rings + sage: phis = hom_composite._compute_factored_isogeny_single_generator(P) # optional - sage.rings.finite_rings + sage: list(sorted(phi.degree() for phi in phis)) # optional - sage.rings.finite_rings [2, 2, 3, 5, 7] - sage: hom_composite._eval_factored_isogeny(phis, P) + sage: hom_composite._eval_factored_isogeny(phis, P) # optional - sage.rings.finite_rings (0 : 1 : 0) """ phis = [] @@ -182,12 +185,12 @@ def _compute_factored_isogeny(kernel): EXAMPLES:: sage: from sage.schemes.elliptic_curves import hom_composite - sage: E = EllipticCurve(GF(419), [-1,0]) - sage: Ps = [E(41,99), E(41,-99), E(51,14), E(21,21), E(33,17)] - sage: phis = hom_composite._compute_factored_isogeny(Ps) - sage: [phi.degree() for phi in phis] + sage: E = EllipticCurve(GF(419), [-1,0]) # optional - sage.rings.finite_rings + sage: Ps = [E(41,99), E(41,-99), E(51,14), E(21,21), E(33,17)] # optional - sage.rings.finite_rings + sage: phis = hom_composite._compute_factored_isogeny(Ps) # optional - sage.rings.finite_rings + sage: [phi.degree() for phi in phis] # optional - sage.rings.finite_rings [2, 3, 5, 7, 2] - sage: {hom_composite._eval_factored_isogeny(phis, P) for P in Ps} + sage: {hom_composite._eval_factored_isogeny(phis, P) for P in Ps} # optional - sage.rings.finite_rings {(0 : 1 : 0)} """ phis = [] @@ -217,46 +220,53 @@ def __init__(self, E, kernel, codomain=None, model=None): EXAMPLES:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve(GF(419), [1,0]) - sage: EllipticCurveHom_composite(E, E.lift_x(23)) + sage: E = EllipticCurve(GF(419), [1,0]) # optional - sage.rings.finite_rings + sage: EllipticCurveHom_composite(E, E.lift_x(23)) # optional - sage.rings.finite_rings Composite morphism of degree 105 = 3*5*7: - From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419 - To: Elliptic Curve defined by y^2 = x^3 + 373*x + 126 over Finite Field of size 419 + From: Elliptic Curve defined by y^2 = x^3 + x + over Finite Field of size 419 + To: Elliptic Curve defined by y^2 = x^3 + 373*x + 126 + over Finite Field of size 419 The given kernel generators need not be independent:: - sage: K. = NumberField(x^2 - x - 5) - sage: E = EllipticCurve('210.b6').change_ring(K) - sage: E.torsion_subgroup() - Torsion Subgroup isomorphic to Z/12 + Z/2 associated to the Elliptic Curve defined by y^2 + x*y + y = x^3 + (-578)*x + 2756 over Number Field in a with defining polynomial x^2 - x - 5 - sage: EllipticCurveHom_composite(E, E.torsion_points()) + sage: K. = NumberField(x^2 - x - 5) # optional - sage.rings.number_field + sage: E = EllipticCurve('210.b6').change_ring(K) # optional - sage.rings.number_field + sage: E.torsion_subgroup() # optional - sage.rings.number_field + Torsion Subgroup isomorphic to Z/12 + Z/2 associated to the Elliptic Curve + defined by y^2 + x*y + y = x^3 + (-578)*x + 2756 + over Number Field in a with defining polynomial x^2 - x - 5 + sage: EllipticCurveHom_composite(E, E.torsion_points()) # optional - sage.rings.number_field Composite morphism of degree 24 = 2^3*3: - From: Elliptic Curve defined by y^2 + x*y + y = x^3 + (-578)*x + 2756 over Number Field in a with defining polynomial x^2 - x - 5 - To: Elliptic Curve defined by y^2 + x*y + y = x^3 + (-89915533/16)*x + (-328200928141/64) over Number Field in a with defining polynomial x^2 - x - 5 + From: Elliptic Curve defined by y^2 + x*y + y = x^3 + (-578)*x + 2756 + over Number Field in a with defining polynomial x^2 - x - 5 + To: Elliptic Curve defined by + y^2 + x*y + y = x^3 + (-89915533/16)*x + (-328200928141/64) + over Number Field in a with defining polynomial x^2 - x - 5 TESTS:: - sage: E = EllipticCurve(GF(19), [1,0]) - sage: P = E.random_point() - sage: psi = EllipticCurveHom_composite(E, P) - sage: psi # random + sage: E = EllipticCurve(GF(19), [1,0]) # optional - sage.rings.finite_rings + sage: P = E.random_point() # optional - sage.rings.finite_rings + sage: psi = EllipticCurveHom_composite(E, P) # optional - sage.rings.finite_rings + sage: psi # random # optional - sage.rings.finite_rings Composite morphism of degree 10 = 2*5: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 19 To: Elliptic Curve defined by y^2 = x^3 + 14*x over Finite Field of size 19 :: - sage: EllipticCurveHom_composite(E, E.lift_x(3), codomain=E) + sage: EllipticCurveHom_composite(E, E.lift_x(3), codomain=E) # optional - sage.rings.finite_rings Composite morphism of degree 20 = 2^2*5: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 19 To: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 19 :: - sage: E = EllipticCurve(GF((2^127-1)^2), [1,0]) - sage: K = 2^30 * E.random_point() - sage: psi = EllipticCurveHom_composite(E, K, model='montgomery') - sage: psi.codomain().a_invariants() + sage: E = EllipticCurve(GF((2^127-1)^2), [1,0]) # optional - sage.rings.finite_rings + sage: K = 2^30 * E.random_point() # optional - sage.rings.finite_rings + sage: psi = EllipticCurveHom_composite(E, K, model='montgomery') # optional - sage.rings.finite_rings + sage: psi.codomain().a_invariants() # optional - sage.rings.finite_rings (0, ..., 0, 1, 0) """ if not isinstance(E, EllipticCurve_generic): @@ -340,11 +350,11 @@ def from_factors(cls, maps, E=None, strict=True): EXAMPLES:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve(GF(43), [1,0]) - sage: P, = E.gens() - sage: phi = EllipticCurveHom_composite(E, P) - sage: psi = EllipticCurveHom_composite.from_factors(phi.factors()) - sage: psi == phi + sage: E = EllipticCurve(GF(43), [1,0]) # optional - sage.rings.finite_rings + sage: P, = E.gens() # optional - sage.rings.finite_rings + sage: phi = EllipticCurveHom_composite(E, P) # optional - sage.rings.finite_rings + sage: psi = EllipticCurveHom_composite.from_factors(phi.factors()) # optional - sage.rings.finite_rings + sage: psi == phi # optional - sage.rings.finite_rings True TESTS:: @@ -355,10 +365,10 @@ def from_factors(cls, maps, E=None, strict=True): :: - sage: E = EllipticCurve(GF(419), [1,0]) - sage: P, = E.gens() - sage: phi = EllipticCurveHom_composite(E, P) - sage: EllipticCurveHom_composite.from_factors(phi.factors()) == phi + sage: E = EllipticCurve(GF(419), [1,0]) # optional - sage.rings.finite_rings + sage: P, = E.gens() # optional - sage.rings.finite_rings + sage: phi = EllipticCurveHom_composite(E, P) # optional - sage.rings.finite_rings + sage: EllipticCurveHom_composite.from_factors(phi.factors()) == phi # optional - sage.rings.finite_rings True """ maps = tuple(maps) @@ -392,21 +402,21 @@ def _call_(self, P): TESTS:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: K. = NumberField(x^2 - x - 5) - sage: E = EllipticCurve('210.b6').change_ring(K) - sage: psi = EllipticCurveHom_composite(E, E.torsion_points()) - sage: R = E.lift_x(15/4 * (a+3)) - sage: psi(R) # indirect doctest + sage: K. = NumberField(x^2 - x - 5) # optional - sage.rings.number_field + sage: E = EllipticCurve('210.b6').change_ring(K) # optional - sage.rings.number_field + sage: psi = EllipticCurveHom_composite(E, E.torsion_points()) # optional - sage.rings.number_field + sage: R = E.lift_x(15/4 * (a+3)) # optional - sage.rings.number_field + sage: psi(R) # indirect doctest # optional - sage.rings.number_field (1033648757/303450 : 58397496786187/1083316500*a - 62088706165177/2166633000 : 1) Check that copying the order over works:: - sage: E = EllipticCurve(GF(431), [1,0]) - sage: P, = E.gens() - sage: Q = 2^99*P; Q.order() + sage: E = EllipticCurve(GF(431), [1,0]) # optional - sage.rings.finite_rings + sage: P, = E.gens() # optional - sage.rings.finite_rings + sage: Q = 2^99*P; Q.order() # optional - sage.rings.finite_rings 27 - sage: phi = E.isogeny(3^99*P, algorithm='factored') - sage: phi(Q)._order + sage: phi = E.isogeny(3^99*P, algorithm='factored') # optional - sage.rings.finite_rings + sage: phi(Q)._order # optional - sage.rings.finite_rings 27 """ return _eval_factored_isogeny(self._phis, P) @@ -428,8 +438,8 @@ def _eval(self, P): sage: E = EllipticCurve(j=Mod(1728,419)) sage: K, = E.gens() sage: psi = EllipticCurveHom_composite(E, 4*K) - sage: Ps = E.change_ring(GF(419**2))(0).division_points(5) - sage: {psi._eval(P).curve() for P in Ps} + sage: Ps = E.change_ring(GF(419**2))(0).division_points(5) # optional - sage.rings.finite_rings + sage: {psi._eval(P).curve() for P in Ps} # optional - sage.rings.finite_rings {Elliptic Curve defined by y^2 = x^3 + 373*x + 126 over Finite Field in z2 of size 419^2} """ if self._domain.defining_polynomial()(*P): @@ -449,14 +459,14 @@ def _repr_(self): TESTS:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve(GF(43), [1,0]) - sage: P, = E.gens() - sage: phi = EllipticCurveHom_composite(E, P) - sage: phi # indirect doctest + sage: E = EllipticCurve(GF(43), [1,0]) # optional - sage.rings.finite_rings + sage: P, = E.gens() # optional - sage.rings.finite_rings + sage: phi = EllipticCurveHom_composite(E, P) # optional - sage.rings.finite_rings + sage: phi # indirect doctest # optional - sage.rings.finite_rings Composite morphism of degree 44 = 2^2*11: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 43 To: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 43 - sage: phi * phi * phi * phi * phi * phi * phi # indirect doctest + sage: phi * phi * phi * phi * phi * phi * phi # indirect doctest # optional - sage.rings.finite_rings Composite morphism of degree 319277809664 = 2^2*11*2^2*11*2^2*11*2^2*11*2^2*11*2^2*11*2^2*11: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 43 To: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 43 @@ -480,13 +490,19 @@ def factors(self): EXAMPLES:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve(GF(43), [1,0]) - sage: P, = E.gens() - sage: phi = EllipticCurveHom_composite(E, P) - sage: phi.factors() - (Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 43 to Elliptic Curve defined by y^2 = x^3 + 39*x over Finite Field of size 43, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 39*x over Finite Field of size 43 to Elliptic Curve defined by y^2 = x^3 + 42*x + 26 over Finite Field of size 43, - Isogeny of degree 11 from Elliptic Curve defined by y^2 = x^3 + 42*x + 26 over Finite Field of size 43 to Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 43) + sage: E = EllipticCurve(GF(43), [1,0]) # optional - sage.rings.finite_rings + sage: P, = E.gens() # optional - sage.rings.finite_rings + sage: phi = EllipticCurveHom_composite(E, P) # optional - sage.rings.finite_rings + sage: phi.factors() # optional - sage.rings.finite_rings + (Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 43 + to Elliptic Curve defined by y^2 = x^3 + 39*x over Finite Field of size 43, + Isogeny of degree 2 + from Elliptic Curve defined by y^2 = x^3 + 39*x over Finite Field of size 43 + to Elliptic Curve defined by y^2 = x^3 + 42*x + 26 over Finite Field of size 43, + Isogeny of degree 11 + from Elliptic Curve defined by y^2 = x^3 + 42*x + 26 over Finite Field of size 43 + to Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 43) """ return self._phis @@ -502,29 +518,37 @@ def _composition_impl(left, right): TESTS:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve([i+1, i, 0, -4, -6*i]) - sage: P,Q = E.lift_x(i-5), E.lift_x(-4*i) - sage: phi = EllipticCurveHom_composite(E, P) - sage: psi = phi.codomain().isogeny(phi(Q)) + sage: E = EllipticCurve([i + 1, i, 0, -4, -6*i]) # optional - sage.rings.number_field + sage: P,Q = E.lift_x(i - 5), E.lift_x(-4*i) # optional - sage.rings.number_field + sage: phi = EllipticCurveHom_composite(E, P) # optional - sage.rings.number_field + sage: psi = phi.codomain().isogeny(phi(Q)) # optional - sage.rings.number_field sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: iso1 = WeierstrassIsomorphism(E, (-1, 0, -i-1, 0)) - sage: iso2 = psi.codomain().isomorphism_to(E) - sage: psi * phi # indirect doctest + sage: iso1 = WeierstrassIsomorphism(E, (-1, 0, -i - 1, 0)) # optional - sage.rings.number_field + sage: iso2 = psi.codomain().isomorphism_to(E) # optional - sage.rings.number_field + sage: psi * phi # indirect doctest # optional - sage.rings.number_field Composite morphism of degree 16 = 2^2*4: - From: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-4)*x + (-6*I) over Number Field in I with defining polynomial x^2 + 1 with I = 1*I - To: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-3331/4)*x + (-142593/8*I) over Number Field in I with defining polynomial x^2 + 1 with I = 1*I - sage: iso2 * EllipticCurveHom_composite.from_factors([phi, psi]) # indirect doctest + From: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-4)*x + (-6*I) + over Number Field in I with defining polynomial x^2 + 1 with I = 1*I + To: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-3331/4)*x + (-142593/8*I) + over Number Field in I with defining polynomial x^2 + 1 with I = 1*I + sage: iso2 * EllipticCurveHom_composite.from_factors([phi, psi]) # indirect doctest # optional - sage.rings.number_field Composite morphism of degree 16 = 4^2: - From: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-4)*x + (-6*I) over Number Field in I with defining polynomial x^2 + 1 with I = 1*I - To: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-4)*x + (-6*I) over Number Field in I with defining polynomial x^2 + 1 with I = 1*I - sage: phi * iso1 # indirect doctest + From: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-4)*x + (-6*I) + over Number Field in I with defining polynomial x^2 + 1 with I = 1*I + To: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-4)*x + (-6*I) + over Number Field in I with defining polynomial x^2 + 1 with I = 1*I + sage: phi * iso1 # indirect doctest # optional - sage.rings.number_field Composite morphism of degree 4 = 2^2: - From: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-4)*x + (-6*I) over Number Field in I with defining polynomial x^2 + 1 with I = 1*I - To: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (480*I-694)*x + (-7778*I+5556) over Number Field in I with defining polynomial x^2 + 1 with I = 1*I - sage: iso2 * psi * phi * iso1 # indirect doctest + From: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-4)*x + (-6*I) + over Number Field in I with defining polynomial x^2 + 1 with I = 1*I + To: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (480*I-694)*x + (-7778*I+5556) + over Number Field in I with defining polynomial x^2 + 1 with I = 1*I + sage: iso2 * psi * phi * iso1 # indirect doctest # optional - sage.rings.number_field Composite morphism of degree 16 = 2^2*4: - From: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-4)*x + (-6*I) over Number Field in I with defining polynomial x^2 + 1 with I = 1*I - To: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-4)*x + (-6*I) over Number Field in I with defining polynomial x^2 + 1 with I = 1*I + From: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-4)*x + (-6*I) + over Number Field in I with defining polynomial x^2 + 1 with I = 1*I + To: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-4)*x + (-6*I) + over Number Field in I with defining polynomial x^2 + 1 with I = 1*I """ if isinstance(left, EllipticCurveHom_composite): if isinstance(right, WeierstrassIsomorphism) and hasattr(left.factors()[0], '_set_pre_isomorphism'): # XXX bit of a hack @@ -557,25 +581,25 @@ def _comparison_impl(left, right, op): TESTS:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve(QuadraticField(-3), [0,16]) - sage: P,Q = E.lift_x(0), E.lift_x(-4) - sage: phi = EllipticCurveHom_composite(E, P) - sage: psi = phi.codomain().isogeny(phi(Q)) - sage: psi = psi.codomain().isomorphism_to(E) * psi - sage: comp = psi * phi - sage: mu = E.scalar_multiplication(phi.degree()) - sage: sum(a*comp == mu for a in E.automorphisms()) + sage: E = EllipticCurve(QuadraticField(-3), [0,16]) # optional - sage.rings.number_field + sage: P,Q = E.lift_x(0), E.lift_x(-4) # optional - sage.rings.number_field + sage: phi = EllipticCurveHom_composite(E, P) # optional - sage.rings.number_field + sage: psi = phi.codomain().isogeny(phi(Q)) # optional - sage.rings.number_field + sage: psi = psi.codomain().isomorphism_to(E) * psi # optional - sage.rings.number_field + sage: comp = psi * phi # optional - sage.rings.number_field + sage: mu = E.scalar_multiplication(phi.degree()) # optional - sage.rings.number_field + sage: sum(a*comp == mu for a in E.automorphisms()) # optional - sage.rings.number_field 1 :: - sage: E = EllipticCurve(GF(431**2), [1,0]) - sage: P,Q = E.gens() - sage: phi1 = EllipticCurveHom_composite(E, P) - sage: phi2 = EllipticCurveHom_composite(phi1.codomain(), phi1(Q)) - sage: psi1 = EllipticCurveHom_composite(E, Q) - sage: psi2 = EllipticCurveHom_composite(psi1.codomain(), psi1(P)) - sage: phi2 * phi1 == psi2 * psi1 + sage: E = EllipticCurve(GF(431**2), [1,0]) # optional - sage.rings.finite_rings + sage: P,Q = E.gens() # optional - sage.rings.finite_rings + sage: phi1 = EllipticCurveHom_composite(E, P) # optional - sage.rings.finite_rings + sage: phi2 = EllipticCurveHom_composite(phi1.codomain(), phi1(Q)) # optional - sage.rings.finite_rings + sage: psi1 = EllipticCurveHom_composite(E, Q) # optional - sage.rings.finite_rings + sage: psi2 = EllipticCurveHom_composite(psi1.codomain(), psi1(P)) # optional - sage.rings.finite_rings + sage: phi2 * phi1 == psi2 * psi1 # optional - sage.rings.finite_rings True """ if op != op_EQ: @@ -593,26 +617,35 @@ def rational_maps(self): EXAMPLES:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) - sage: P = E.lift_x(7321) - sage: phi = EllipticCurveHom_composite(E, P) - sage: phi.rational_maps() - ((x^9 + 27463*x^8 + 21204*x^7 - 5750*x^6 + 1610*x^5 + 14440*x^4 + 26605*x^3 - 15569*x^2 - 3341*x + 1267)/(x^8 + 27463*x^7 + 26871*x^6 + 5999*x^5 - 20194*x^4 - 6310*x^3 + 24366*x^2 - 20905*x - 13867), - (x^12*y + 8426*x^11*y + 5667*x^11 + 27612*x^10*y + 26124*x^10 + 9688*x^9*y - 22715*x^9 + 19864*x^8*y + 498*x^8 + 22466*x^7*y - 14036*x^7 + 8070*x^6*y + 19955*x^6 - 20765*x^5*y - 12481*x^5 + 12672*x^4*y + 24142*x^4 - 23695*x^3*y + 26667*x^3 + 23780*x^2*y + 17864*x^2 + 15053*x*y - 30118*x + 17539*y - 23609)/(x^12 + 8426*x^11 + 21945*x^10 - 22587*x^9 + 22094*x^8 + 14603*x^7 - 26255*x^6 + 11171*x^5 - 16508*x^4 - 14435*x^3 - 2170*x^2 + 29081*x - 19009)) + sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: P = E.lift_x(7321) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveHom_composite(E, P) # optional - sage.rings.finite_rings + sage: phi.rational_maps() # optional - sage.rings.finite_rings + ((x^9 + 27463*x^8 + 21204*x^7 - 5750*x^6 + 1610*x^5 + 14440*x^4 + + 26605*x^3 - 15569*x^2 - 3341*x + 1267)/(x^8 + 27463*x^7 + 26871*x^6 + + 5999*x^5 - 20194*x^4 - 6310*x^3 + 24366*x^2 - 20905*x - 13867), + (x^12*y + 8426*x^11*y + 5667*x^11 + 27612*x^10*y + 26124*x^10 + 9688*x^9*y + - 22715*x^9 + 19864*x^8*y + 498*x^8 + 22466*x^7*y - 14036*x^7 + 8070*x^6*y + + 19955*x^6 - 20765*x^5*y - 12481*x^5 + 12672*x^4*y + 24142*x^4 - 23695*x^3*y + + 26667*x^3 + 23780*x^2*y + 17864*x^2 + 15053*x*y - 30118*x + 17539*y + - 23609)/(x^12 + 8426*x^11 + 21945*x^10 - 22587*x^9 + 22094*x^8 + 14603*x^7 + - 26255*x^6 + 11171*x^5 - 16508*x^4 - 14435*x^3 - 2170*x^2 + 29081*x - 19009)) TESTS:: - sage: f = phi.codomain().defining_polynomial() - sage: g = E.defining_polynomial().subs({2:1}) - sage: f(*phi.rational_maps(), 1) % g + sage: f = phi.codomain().defining_polynomial() # optional - sage.rings.finite_rings + sage: g = E.defining_polynomial().subs({2:1}) # optional - sage.rings.finite_rings + sage: f(*phi.rational_maps(), 1) % g # optional - sage.rings.finite_rings 0 :: - sage: phi.rational_maps()[0].parent() - Fraction Field of Multivariate Polynomial Ring in x, y over Finite Field of size 65537 - sage: phi.rational_maps()[1].parent() - Fraction Field of Multivariate Polynomial Ring in x, y over Finite Field of size 65537 + sage: phi.rational_maps()[0].parent() # optional - sage.rings.finite_rings + Fraction Field of + Multivariate Polynomial Ring in x, y over Finite Field of size 65537 + sage: phi.rational_maps()[1].parent() # optional - sage.rings.finite_rings + Fraction Field of + Multivariate Polynomial Ring in x, y over Finite Field of size 65537 """ fx, fy = self._phis[-1].rational_maps() for phi in self._phis[:-1][::-1]: @@ -627,16 +660,17 @@ def x_rational_map(self): EXAMPLES:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) - sage: P = E.lift_x(7321) - sage: phi = EllipticCurveHom_composite(E, P) - sage: phi.x_rational_map() == phi.rational_maps()[0] + sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: P = E.lift_x(7321) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveHom_composite(E, P) # optional - sage.rings.finite_rings + sage: phi.x_rational_map() == phi.rational_maps()[0] # optional - sage.rings.finite_rings True TESTS:: - sage: phi.x_rational_map().parent() - Fraction Field of Univariate Polynomial Ring in x over Finite Field of size 65537 + sage: phi.x_rational_map().parent() # optional - sage.rings.finite_rings + Fraction Field of Univariate Polynomial Ring in x + over Finite Field of size 65537 """ fx = self._phis[-1].x_rational_map() for phi in self._phis[:-1][::-1]: @@ -650,13 +684,15 @@ def kernel_polynomial(self): EXAMPLES:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) - sage: P = E.lift_x(7321) - sage: phi = EllipticCurveHom_composite(E, P); phi + sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: P = E.lift_x(7321) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveHom_composite(E, P); phi # optional - sage.rings.finite_rings Composite morphism of degree 9 = 3^2: - From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Finite Field of size 65537 - To: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 28339*x + 59518 over Finite Field of size 65537 - sage: phi.kernel_polynomial() + From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 + over Finite Field of size 65537 + To: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 28339*x + 59518 + over Finite Field of size 65537 + sage: phi.kernel_polynomial() # optional - sage.rings.finite_rings x^4 + 46500*x^3 + 19556*x^2 + 7643*x + 15952 """ # shouldn't there be a better algorithm for this? @@ -670,19 +706,23 @@ def dual(self): EXAMPLES:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) - sage: P = E.lift_x(7321) - sage: phi = EllipticCurveHom_composite(E, P); phi + sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: P = E.lift_x(7321) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveHom_composite(E, P); phi # optional - sage.rings.finite_rings Composite morphism of degree 9 = 3^2: - From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Finite Field of size 65537 - To: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 28339*x + 59518 over Finite Field of size 65537 - sage: psi = phi.dual(); psi + From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 + over Finite Field of size 65537 + To: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 28339*x + 59518 + over Finite Field of size 65537 + sage: psi = phi.dual(); psi # optional - sage.rings.finite_rings Composite morphism of degree 9 = 3^2: - From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 28339*x + 59518 over Finite Field of size 65537 - To: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Finite Field of size 65537 - sage: psi * phi == phi.domain().scalar_multiplication(phi.degree()) + From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 28339*x + 59518 + over Finite Field of size 65537 + To: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 + over Finite Field of size 65537 + sage: psi * phi == phi.domain().scalar_multiplication(phi.degree()) # optional - sage.rings.finite_rings True - sage: phi * psi == psi.domain().scalar_multiplication(psi.degree()) + sage: phi * psi == psi.domain().scalar_multiplication(psi.degree()) # optional - sage.rings.finite_rings True """ phis = (phi.dual() for phi in self._phis[::-1]) @@ -698,13 +738,15 @@ def is_separable(self): EXAMPLES:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve(GF(7^2), [3,2]) - sage: P = E.lift_x(1) - sage: phi = EllipticCurveHom_composite(E, P); phi + sage: E = EllipticCurve(GF(7^2), [3,2]) # optional - sage.rings.finite_rings + sage: P = E.lift_x(1) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveHom_composite(E, P); phi # optional - sage.rings.finite_rings Composite morphism of degree 7 = 7: - From: Elliptic Curve defined by y^2 = x^3 + 3*x + 2 over Finite Field in z2 of size 7^2 - To: Elliptic Curve defined by y^2 = x^3 + 3*x + 2 over Finite Field in z2 of size 7^2 - sage: phi.is_separable() + From: Elliptic Curve defined by y^2 = x^3 + 3*x + 2 + over Finite Field in z2 of size 7^2 + To: Elliptic Curve defined by y^2 = x^3 + 3*x + 2 + over Finite Field in z2 of size 7^2 + sage: phi.is_separable() # optional - sage.rings.finite_rings True """ return all(phi.is_separable() for phi in self._phis) @@ -718,13 +760,17 @@ def formal(self, prec=20): EXAMPLES:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) - sage: P = E.lift_x(7321) - sage: phi = EllipticCurveHom_composite(E, P) - sage: phi.formal() - t + 54203*t^5 + 48536*t^6 + 40698*t^7 + 37808*t^8 + 21111*t^9 + 42381*t^10 + 46688*t^11 + 657*t^12 + 38916*t^13 + 62261*t^14 + 59707*t^15 + 30767*t^16 + 7248*t^17 + 60287*t^18 + 50451*t^19 + 38305*t^20 + 12312*t^21 + 31329*t^22 + O(t^23) - sage: (phi.dual() * phi).formal(prec=5) - 9*t + 65501*t^2 + 65141*t^3 + 59183*t^4 + 21491*t^5 + 8957*t^6 + 999*t^7 + O(t^8) + sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: P = E.lift_x(7321) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveHom_composite(E, P) # optional - sage.rings.finite_rings + sage: phi.formal() # optional - sage.rings.finite_rings + t + 54203*t^5 + 48536*t^6 + 40698*t^7 + 37808*t^8 + 21111*t^9 + 42381*t^10 + + 46688*t^11 + 657*t^12 + 38916*t^13 + 62261*t^14 + 59707*t^15 + + 30767*t^16 + 7248*t^17 + 60287*t^18 + 50451*t^19 + 38305*t^20 + + 12312*t^21 + 31329*t^22 + O(t^23) + sage: (phi.dual() * phi).formal(prec=5) # optional - sage.rings.finite_rings + 9*t + 65501*t^2 + 65141*t^3 + 59183*t^4 + 21491*t^5 + 8957*t^6 + + 999*t^7 + O(t^8) """ res = self._phis[-1].formal(prec=prec) for phi in self._phis[:-1][::-1]: @@ -746,13 +792,16 @@ def scaling_factor(self): sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) - sage: P = E.lift_x(7321) - sage: phi = EllipticCurveHom_composite(E, P) - sage: phi = WeierstrassIsomorphism(phi.codomain(), [7,8,9,10]) * phi - sage: phi.formal() - 7*t + 65474*t^2 + 511*t^3 + 61316*t^4 + 20548*t^5 + 45511*t^6 + 37285*t^7 + 48414*t^8 + 9022*t^9 + 24025*t^10 + 35986*t^11 + 55397*t^12 + 25199*t^13 + 18744*t^14 + 46142*t^15 + 9078*t^16 + 18030*t^17 + 47599*t^18 + 12158*t^19 + 50630*t^20 + 56449*t^21 + 43320*t^22 + O(t^23) - sage: phi.scaling_factor() + sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: P = E.lift_x(7321) # optional - sage.rings.finite_rings + sage: phi = EllipticCurveHom_composite(E, P) # optional - sage.rings.finite_rings + sage: phi = WeierstrassIsomorphism(phi.codomain(), [7,8,9,10]) * phi # optional - sage.rings.finite_rings + sage: phi.formal() # optional - sage.rings.finite_rings + 7*t + 65474*t^2 + 511*t^3 + 61316*t^4 + 20548*t^5 + 45511*t^6 + 37285*t^7 + + 48414*t^8 + 9022*t^9 + 24025*t^10 + 35986*t^11 + 55397*t^12 + 25199*t^13 + + 18744*t^14 + 46142*t^15 + 9078*t^16 + 18030*t^17 + 47599*t^18 + + 12158*t^19 + 50630*t^20 + 56449*t^21 + 43320*t^22 + O(t^23) + sage: phi.scaling_factor() # optional - sage.rings.finite_rings 7 ALGORITHM: The scaling factor is multiplicative under @@ -775,13 +824,15 @@ def is_injective(self): sage: phi = EllipticCurveHom_composite(E, E(0,0)) sage: phi.is_injective() False - sage: E = EllipticCurve_from_j(GF(3).algebraic_closure()(0)) - sage: nu = EllipticCurveHom_composite.from_factors(E.automorphisms()) - sage: nu + sage: E = EllipticCurve_from_j(GF(3).algebraic_closure()(0)) # optional - sage.rings.finite_rings + sage: nu = EllipticCurveHom_composite.from_factors(E.automorphisms()) # optional - sage.rings.finite_rings + sage: nu # optional - sage.rings.finite_rings Composite morphism of degree 1 = 1^12: - From: Elliptic Curve defined by y^2 = x^3 + x over Algebraic closure of Finite Field of size 3 - To: Elliptic Curve defined by y^2 = x^3 + x over Algebraic closure of Finite Field of size 3 - sage: nu.is_injective() + From: Elliptic Curve defined by y^2 = x^3 + x + over Algebraic closure of Finite Field of size 3 + To: Elliptic Curve defined by y^2 = x^3 + x + over Algebraic closure of Finite Field of size 3 + sage: nu.is_injective() # optional - sage.rings.finite_rings True """ return all(phi.is_injective() for phi in self._phis) diff --git a/src/sage/schemes/elliptic_curves/hom_frobenius.py b/src/sage/schemes/elliptic_curves/hom_frobenius.py index 430f8a3f417..38f22f1fcdf 100644 --- a/src/sage/schemes/elliptic_curves/hom_frobenius.py +++ b/src/sage/schemes/elliptic_curves/hom_frobenius.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" Frobenius isogenies of elliptic curves @@ -17,18 +18,22 @@ sage: E = EllipticCurve([z5,1]) sage: pi = EllipticCurveHom_frobenius(E); pi Frobenius isogeny of degree 17: - From: Elliptic Curve defined by y^2 = x^3 + z5*x + 1 over Finite Field in z5 of size 17^5 - To: Elliptic Curve defined by y^2 = x^3 + (9*z5^4+7*z5^3+10*z5^2+z5+14)*x + 1 over Finite Field in z5 of size 17^5 + From: Elliptic Curve defined by y^2 = x^3 + z5*x + 1 + over Finite Field in z5 of size 17^5 + To: Elliptic Curve defined by y^2 = x^3 + (9*z5^4+7*z5^3+10*z5^2+z5+14)*x + 1 + over Finite Field in z5 of size 17^5 By passing `n`, we can also construct higher-power Frobenius maps, such as the Frobenius *endo*\morphism:: sage: z5, = GF(7^5).gens() sage: E = EllipticCurve([z5,1]) - sage: pi = EllipticCurveHom_frobenius(E,5); pi + sage: pi = EllipticCurveHom_frobenius(E, 5); pi Frobenius endomorphism of degree 16807 = 7^5: - From: Elliptic Curve defined by y^2 = x^3 + z5*x + 1 over Finite Field in z5 of size 7^5 - To: Elliptic Curve defined by y^2 = x^3 + z5*x + 1 over Finite Field in z5 of size 7^5 + From: Elliptic Curve defined by y^2 = x^3 + z5*x + 1 + over Finite Field in z5 of size 7^5 + To: Elliptic Curve defined by y^2 = x^3 + z5*x + 1 + over Finite Field in z5 of size 7^5 The usual :class:`EllipticCurveHom` methods are supported:: @@ -55,7 +60,11 @@ sage: E = EllipticCurve([GF(17^6).gen(), 0]) sage: pi = EllipticCurveHom_frobenius(E) sage: pihat = pi.dual(); pihat - Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + (15*z6^5+5*z6^4+8*z6^3+12*z6^2+11*z6+7)*x over Finite Field in z6 of size 17^6 to Elliptic Curve defined by y^2 = x^3 + z6*x over Finite Field in z6 of size 17^6 + Isogeny of degree 17 + from Elliptic Curve defined by y^2 = x^3 + (15*z6^5+5*z6^4+8*z6^3+12*z6^2+11*z6+7)*x + over Finite Field in z6 of size 17^6 + to Elliptic Curve defined by y^2 = x^3 + z6*x + over Finite Field in z6 of size 17^6 sage: pihat.is_separable() True sage: pihat * pi == EllipticCurveHom_scalar(E,17) # known bug -- #6413 @@ -69,18 +78,25 @@ sage: pi1 = EllipticCurveHom_frobenius(E) sage: pi1hat = pi1.dual(); pi1hat Composite morphism of degree 17 = 17*1: - From: Elliptic Curve defined by y^2 = x^3 + (15*z6^5+5*z6^4+8*z6^3+12*z6^2+11*z6+7) over Finite Field in z6 of size 17^6 - To: Elliptic Curve defined by y^2 = x^3 + z6 over Finite Field in z6 of size 17^6 + From: Elliptic Curve defined by y^2 = x^3 + (15*z6^5+5*z6^4+8*z6^3+12*z6^2+11*z6+7) + over Finite Field in z6 of size 17^6 + To: Elliptic Curve defined by y^2 = x^3 + z6 + over Finite Field in z6 of size 17^6 sage: pi6 = EllipticCurveHom_frobenius(E,6) sage: pi6hat = pi6.dual(); pi6hat Composite morphism of degree 24137569 = 24137569*1: - From: Elliptic Curve defined by y^2 = x^3 + z6 over Finite Field in z6 of size 17^6 - To: Elliptic Curve defined by y^2 = x^3 + z6 over Finite Field in z6 of size 17^6 + From: Elliptic Curve defined by y^2 = x^3 + z6 + over Finite Field in z6 of size 17^6 + To: Elliptic Curve defined by y^2 = x^3 + z6 + over Finite Field in z6 of size 17^6 sage: pi6hat.factors() (Frobenius endomorphism of degree 24137569 = 17^6: - From: Elliptic Curve defined by y^2 = x^3 + z6 over Finite Field in z6 of size 17^6 - To: Elliptic Curve defined by y^2 = x^3 + z6 over Finite Field in z6 of size 17^6, - Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + z6 over Finite Field in z6 of size 17^6 + From: Elliptic Curve defined by y^2 = x^3 + z6 + over Finite Field in z6 of size 17^6 + To: Elliptic Curve defined by y^2 = x^3 + z6 + over Finite Field in z6 of size 17^6, + Elliptic-curve endomorphism of + Elliptic Curve defined by y^2 = x^3 + z6 over Finite Field in z6 of size 17^6 Via: (u,r,s,t) = (2*z6^5 + 10*z6^3 + z6^2 + 8, 0, 0, 0)) diff --git a/src/sage/schemes/elliptic_curves/isogeny_class.py b/src/sage/schemes/elliptic_curves/isogeny_class.py index 0d50a9863ef..43495d65293 100644 --- a/src/sage/schemes/elliptic_curves/isogeny_class.py +++ b/src/sage/schemes/elliptic_curves/isogeny_class.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.rings.number_field r""" Isogeny class of elliptic curves over number fields @@ -322,7 +322,7 @@ class (CM case only). sage: pol = PolynomialRing(QQ,'x')([1,0,3,0,1]) sage: K. = NumberField(pol) - sage: j = 1480640+565760*c^2 + sage: j = 1480640 + 565760*c^2 sage: E = EllipticCurve(j=j) sage: C = E.isogeny_class() sage: C.qf_matrix() @@ -362,7 +362,9 @@ def isogenies(self, fill=False): sage: isocls = EllipticCurve('15a3').isogeny_class() sage: f = isocls.isogenies()[0][1]; f - Isogeny of degree 2 from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 5*x + 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 80*x + 242 over Rational Field + Isogeny of degree 2 + from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 5*x + 2 over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 80*x + 242 over Rational Field sage: f.domain() == isocls.curves[0] and f.codomain() == isocls.curves[1] True """ @@ -398,7 +400,9 @@ def graph(self): sage: isocls = EllipticCurve('15a3').isogeny_class() sage: G = isocls.graph() sage: sorted(G._pos.items()) - [(1, [-0.8660254, 0.5]), (2, [-0.8660254, 1.5]), (3, [-1.7320508, 0]), (4, [0, 0]), (5, [0, -1]), (6, [0.8660254, 0.5]), (7, [0.8660254, 1.5]), (8, [1.7320508, 0])] + [(1, [-0.8660254, 0.5]), (2, [-0.8660254, 1.5]), (3, [-1.7320508, 0]), + (4, [0, 0]), (5, [0, -1]), (6, [0.8660254, 0.5]), + (7, [0.8660254, 1.5]), (8, [1.7320508, 0])] """ from sage.graphs.graph import Graph @@ -591,10 +595,10 @@ def __init__(self, E, reducible_primes=None, algorithm='Billerey', minimal_model the isogeny class, only composites isogenies of these degrees will be used. - - ``algorithm`` (string, default 'Billerey') -- the algorithm + - ``algorithm`` (string, default ``'Billerey'``) -- the algorithm to use to compute the reducible primes. Ignored for CM curves or if ``reducible_primes`` is provided. Values are - 'Billerey' (default), 'Larson', and 'heuristic'. + ``'Billerey'`` (default), ``'Larson'``, and ``'heuristic'``. - ``minimal_models`` (bool, default ``True``) -- if ``True``, all curves in the class will be minimal or semi-minimal @@ -606,15 +610,16 @@ def __init__(self, E, reducible_primes=None, algorithm='Billerey', minimal_model sage: K. = QuadraticField(-1) sage: E = EllipticCurve(K, [0,0,0,0,1]) sage: C = E.isogeny_class(); C - Isogeny class of Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + Isogeny class of Elliptic Curve defined by y^2 = x^3 + 1 + over Number Field in i with defining polynomial x^2 + 1 with i = 1*I The curves in the class (sorted):: sage: [E1.ainvs() for E1 in C] [(0, 0, 0, 0, -27), - (0, 0, 0, 0, 1), - (i + 1, i, i + 1, -i + 3, 4*i), - (i + 1, i, i + 1, -i + 33, -58*i)] + (0, 0, 0, 0, 1), + (i + 1, i, i + 1, -i + 3, 4*i), + (i + 1, i, i + 1, -i + 33, -58*i)] The matrix of degrees of cyclic isogenies between curves:: @@ -632,16 +637,18 @@ class :class:`EllipticCurveIsogeny` allowed composition. In to 3, and `3`-isogenies to go from 0 to 1 and from 2 to 3:: sage: isogs = C.isogenies() - sage: [((i,j),isogs[i][j].degree()) for i in range(4) for j in range(4) if isogs[i][j]!=0] + sage: [((i,j), isogs[i][j].degree()) + ....: for i in range(4) for j in range(4) if isogs[i][j] != 0] [((0, 1), 3), - ((0, 3), 2), - ((1, 0), 3), - ((1, 2), 2), - ((2, 1), 2), - ((2, 3), 3), - ((3, 0), 2), - ((3, 2), 3)] - sage: [((i,j),isogs[i][j].x_rational_map()) for i in range(4) for j in range(4) if isogs[i][j]!=0] + ((0, 3), 2), + ((1, 0), 3), + ((1, 2), 2), + ((2, 1), 2), + ((2, 3), 3), + ((3, 0), 2), + ((3, 2), 3)] + sage: [((i,j), isogs[i][j].x_rational_map()) + ....: for i in range(4) for j in range(4) if isogs[i][j] != 0] [((0, 1), (1/9*x^3 - 12)/x^2), ((0, 3), (-1/2*i*x^2 + i*x - 12*i)/(x - 3)), ((1, 0), (x^3 + 4)/x^2), @@ -654,7 +661,9 @@ class :class:`EllipticCurveIsogeny` allowed composition. In sage: K. = QuadraticField(-1) sage: E = EllipticCurve([1+i, -i, i, 1, 0]) sage: C = E.isogeny_class(); C - Isogeny class of Elliptic Curve defined by y^2 + (i+1)*x*y + i*y = x^3 + (-i)*x^2 + x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + Isogeny class of Elliptic Curve defined + by y^2 + (i+1)*x*y + i*y = x^3 + (-i)*x^2 + x + over Number Field in i with defining polynomial x^2 + 1 with i = 1*I sage: len(C) 6 sage: C.matrix() @@ -676,7 +685,7 @@ class :class:`EllipticCurveIsogeny` allowed composition. In sage: pol = PolynomialRing(QQ,'x')([1,0,3,0,1]) sage: K. = NumberField(pol) - sage: j = 1480640+565760*c^2 + sage: j = 1480640 + 565760*c^2 sage: E = EllipticCurve(j=j) sage: E.has_cm() True @@ -692,9 +701,15 @@ class :class:`EllipticCurveIsogeny` allowed composition. In [2 1] sage: [E.ainvs() for E in C] [(0, 0, 0, 83490*c^2 - 147015, -64739840*c^2 - 84465260), - (0, 0, 0, -161535*c^2 + 70785, -62264180*c^3 + 6229080*c)] + (0, 0, 0, -161535*c^2 + 70785, -62264180*c^3 + 6229080*c)] sage: C.isogenies()[0][1] - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + (83490*c^2-147015)*x + (-64739840*c^2-84465260) over Number Field in c with defining polynomial x^4 + 3*x^2 + 1 to Elliptic Curve defined by y^2 = x^3 + (-161535*c^2+70785)*x + (-62264180*c^3+6229080*c) over Number Field in c with defining polynomial x^4 + 3*x^2 + 1 + Isogeny of degree 2 + from Elliptic Curve defined by + y^2 = x^3 + (83490*c^2-147015)*x + (-64739840*c^2-84465260) + over Number Field in c with defining polynomial x^4 + 3*x^2 + 1 + to Elliptic Curve defined by + y^2 = x^3 + (-161535*c^2+70785)*x + (-62264180*c^3+6229080*c) + over Number Field in c with defining polynomial x^4 + 3*x^2 + 1 TESTS:: @@ -761,7 +776,7 @@ def _compute(self, verbose=False): Check that :trac:`19030` is fixed (codomains of reverse isogenies were wrong):: - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: E = EllipticCurve([1, i + 1, 1, -72*i + 8, 95*i + 146]) sage: C = E.isogeny_class() sage: curves = C.curves @@ -986,13 +1001,13 @@ def __init__(self, E, algorithm="sage", label=None, empty=False): - ``E`` -- an elliptic curve over `\QQ`. - - ``algorithm`` -- a string (default "sage"). One of the + - ``algorithm`` -- a string (default ``"sage"``). One of the following: - - "sage" -- Use sage's implementation to compute the curves, + - ``"sage"`` -- Use sage's implementation to compute the curves, matrix and isogenies - - "database" -- Use the Cremona database (only works if the + - ``"database"`` -- Use the Cremona database (only works if the curve is in the database) - ``label`` -- a string, the label of this isogeny class @@ -1008,7 +1023,8 @@ def __init__(self, E, algorithm="sage", label=None, empty=False): sage: E.isogeny_class(order='database') Traceback (most recent call last): ... - LookupError: Cremona database does not contain entry for Elliptic Curve defined by y^2 = x^3 + 1001 over Rational Field + LookupError: Cremona database does not contain entry for + Elliptic Curve defined by y^2 = x^3 + 1001 over Rational Field sage: TestSuite(isocls).run() """ self._algorithm = algorithm @@ -1161,7 +1177,7 @@ def isogeny_degrees_cm(E, verbose=False): sage: pol = PolynomialRing(QQ,'x')([1,-3,5,-5,5,-3,1]) sage: L. = NumberField(pol) - sage: j = hilbert_class_polynomial(-23).roots(L,multiplicities=False)[0] + sage: j = hilbert_class_polynomial(-23).roots(L, multiplicities=False)[0] sage: E = EllipticCurve(j=j) sage: from sage.schemes.elliptic_curves.isogeny_class import isogeny_degrees_cm sage: isogeny_degrees_cm(E, verbose=True) @@ -1299,18 +1315,18 @@ def possible_isogeny_degrees(E, algorithm='Billerey', max_l=None, - ``E`` -- An elliptic curve defined over a number field. - - ``algorithm`` (string, default 'Billerey') -- Algorithm to be - used for non-CM curves: either 'Billerey', 'Larson', or - 'heuristic'. Only relevant for non-CM curves and base fields + - ``algorithm`` (string, default ``'Billerey'``) -- Algorithm to be + used for non-CM curves: either ``'Billerey'``, ``'Larson'``, or + ``'heuristic'``. Only relevant for non-CM curves and base fields other than `\QQ`. - ``max_l`` (int or ``None``) -- only relevant for non-CM curves - and algorithms 'Billerey' and 'heuristic. Controls the maximum + and algorithms ``'Billerey'`` and ``'heuristic'``. Controls the maximum prime used in either algorithm. If ``None``, use the default for that algorithm. - ``num_l`` (int or ``None``) -- only relevant for non-CM curves - and algorithm 'Billerey'. Controls the maximum number of primes + and algorithm ``'Billerey'``. Controls the maximum number of primes used in the algorithm. If ``None``, use the default for that algorithm. @@ -1373,7 +1389,9 @@ def possible_isogeny_degrees(E, algorithm='Billerey', max_l=None, A higher degree example (LMFDB curve 5.5.170701.1-4.1-b1):: sage: K. = NumberField(x^5 - x^4 - 6*x^3 + 4*x + 1) - sage: E = EllipticCurve(K, [a^3 - a^2 - 5*a + 1, a^4 - a^3 - 5*a^2 - a + 1, -a^4 + 2*a^3 + 5*a^2 - 5*a - 3, a^4 - a^3 - 5*a^2 - a, -3*a^4 + 4*a^3 + 17*a^2 - 6*a - 12]) + sage: E = EllipticCurve(K, [a^3 - a^2 - 5*a + 1, a^4 - a^3 - 5*a^2 - a + 1, + ....: -a^4 + 2*a^3 + 5*a^2 - 5*a - 3, a^4 - a^3 - 5*a^2 - a, + ....: -3*a^4 + 4*a^3 + 17*a^2 - 6*a - 12]) sage: possible_isogeny_degrees(E, algorithm='heuristic') [2] sage: possible_isogeny_degrees(E, algorithm='Billerey') @@ -1405,7 +1423,7 @@ def possible_isogeny_degrees(E, algorithm='Billerey', max_l=None, sage: pol = PolynomialRing(QQ,'x')([1,-3,5,-5,5,-3,1]) sage: L. = NumberField(pol) - sage: j = hilbert_class_polynomial(-23).roots(L,multiplicities=False)[0] + sage: j = hilbert_class_polynomial(-23).roots(L, multiplicities=False)[0] sage: E = EllipticCurve(j=j) sage: from sage.schemes.elliptic_curves.isogeny_class import possible_isogeny_degrees sage: possible_isogeny_degrees(E, verbose=True) diff --git a/src/sage/schemes/elliptic_curves/isogeny_small_degree.py b/src/sage/schemes/elliptic_curves/isogeny_small_degree.py index 8f740751da4..8c4fd1e3455 100644 --- a/src/sage/schemes/elliptic_curves/isogeny_small_degree.py +++ b/src/sage/schemes/elliptic_curves/isogeny_small_degree.py @@ -79,7 +79,9 @@ def Fricke_polynomial(l): sage: Fricke_polynomial(7) t^8 + 28*t^7 + 322*t^6 + 1904*t^5 + 5915*t^4 + 8624*t^3 + 4018*t^2 + 748*t + 49 sage: Fricke_polynomial(13) - t^14 + 26*t^13 + 325*t^12 + 2548*t^11 + 13832*t^10 + 54340*t^9 + 157118*t^8 + 333580*t^7 + 509366*t^6 + 534820*t^5 + 354536*t^4 + 124852*t^3 + 15145*t^2 + 746*t + 13 + t^14 + 26*t^13 + 325*t^12 + 2548*t^11 + 13832*t^10 + 54340*t^9 + 157118*t^8 + + 333580*t^7 + 509366*t^6 + 534820*t^5 + 354536*t^4 + 124852*t^3 + + 15145*t^2 + 746*t + 13 """ t = PolynomialRing(ZZ, 't').gen() if l == 2: @@ -129,7 +131,9 @@ def Fricke_module(l): sage: Fricke_module(7) (t^8 + 28*t^7 + 322*t^6 + 1904*t^5 + 5915*t^4 + 8624*t^3 + 4018*t^2 + 748*t + 49)/t sage: Fricke_module(13) - (t^14 + 26*t^13 + 325*t^12 + 2548*t^11 + 13832*t^10 + 54340*t^9 + 157118*t^8 + 333580*t^7 + 509366*t^6 + 534820*t^5 + 354536*t^4 + 124852*t^3 + 15145*t^2 + 746*t + 13)/t + (t^14 + 26*t^13 + 325*t^12 + 2548*t^11 + 13832*t^10 + + 54340*t^9 + 157118*t^8 + 333580*t^7 + 509366*t^6 + + 534820*t^5 + 354536*t^4 + 124852*t^3 + 15145*t^2 + 746*t + 13)/t """ t = PolynomialRing(QQ, 't').gen() return Fricke_polynomial(l) / t @@ -268,12 +272,20 @@ def isogenies_prime_degree_genus_0(E, l=None, minimal_models=True): sage: E = EllipticCurve('1450c1') sage: isogenies_prime_degree_genus_0(E) - [Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 300*x - 1000 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 5950*x - 182250 over Rational Field] + [Isogeny of degree 3 + from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 300*x - 1000 + over Rational Field + to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 5950*x - 182250 + over Rational Field] sage: E = EllipticCurve('50a1') sage: isogenies_prime_degree_genus_0(E) - [Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 over Rational Field, - Isogeny of degree 5 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 over Rational Field] + [Isogeny of degree 3 + from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 over Rational Field, + Isogeny of degree 5 + from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 over Rational Field] """ if l not in [2, 3, 5, 7, 13, None]: raise ValueError("%s is not a genus 0 prime."%l) @@ -588,19 +600,35 @@ def isogenies_sporadic_Q(E, l=None, minimal_models=True): sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_sporadic_Q sage: E = EllipticCurve('121a1') sage: isogenies_sporadic_Q(E, 11) - [Isogeny of degree 11 from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888 over Rational Field] + [Isogeny of degree 11 + from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76 + over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888 + over Rational Field] sage: isogenies_sporadic_Q(E, 13) [] sage: isogenies_sporadic_Q(E, 17) [] sage: isogenies_sporadic_Q(E) - [Isogeny of degree 11 from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888 over Rational Field] + [Isogeny of degree 11 + from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76 + over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888 + over Rational Field] sage: E = EllipticCurve([1, 1, 0, -660, -7600]) sage: isogenies_sporadic_Q(E, 17) - [Isogeny of degree 17 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750 over Rational Field] + [Isogeny of degree 17 + from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600 + over Rational Field + to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750 + over Rational Field] sage: isogenies_sporadic_Q(E) - [Isogeny of degree 17 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750 over Rational Field] + [Isogeny of degree 17 + from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600 + over Rational Field + to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750 + over Rational Field] sage: isogenies_sporadic_Q(E, 11) [] @@ -608,39 +636,67 @@ def isogenies_sporadic_Q(E, l=None, minimal_models=True): sage: isogenies_sporadic_Q(E, 11) [] sage: isogenies_sporadic_Q(E, 19) - [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 over Rational Field] + [Isogeny of degree 19 + from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 + over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 + over Rational Field] sage: isogenies_sporadic_Q(E) - [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 over Rational Field] + [Isogeny of degree 19 + from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 + over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 + over Rational Field] sage: E = EllipticCurve([0, -1, 0, -6288, 211072]) sage: E.conductor() 19600 sage: isogenies_sporadic_Q(E,37) - [Isogeny of degree 37 from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072 over Rational Field to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728 over Rational Field] + [Isogeny of degree 37 + from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072 + over Rational Field + to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728 + over Rational Field] sage: E = EllipticCurve([1, 1, 0, -25178045, 48616918750]) sage: E.conductor() 148225 sage: isogenies_sporadic_Q(E,37) - [Isogeny of degree 37 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 25178045*x + 48616918750 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 970*x - 13075 over Rational Field] + [Isogeny of degree 37 + from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 25178045*x + 48616918750 + over Rational Field + to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 970*x - 13075 + over Rational Field] sage: E = EllipticCurve([-3440, 77658]) sage: E.conductor() 118336 sage: isogenies_sporadic_Q(E,43) - [Isogeny of degree 43 from Elliptic Curve defined by y^2 = x^3 - 3440*x + 77658 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 6360560*x - 6174354606 over Rational Field] + [Isogeny of degree 43 + from Elliptic Curve defined by y^2 = x^3 - 3440*x + 77658 + over Rational Field + to Elliptic Curve defined by y^2 = x^3 - 6360560*x - 6174354606 + over Rational Field] sage: E = EllipticCurve([-29480, -1948226]) sage: E.conductor() 287296 sage: isogenies_sporadic_Q(E,67) - [Isogeny of degree 67 from Elliptic Curve defined by y^2 = x^3 - 29480*x - 1948226 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 132335720*x + 585954296438 over Rational Field] + [Isogeny of degree 67 + from Elliptic Curve defined by y^2 = x^3 - 29480*x - 1948226 + over Rational Field + to Elliptic Curve defined by y^2 = x^3 - 132335720*x + 585954296438 + over Rational Field] sage: E = EllipticCurve([-34790720, -78984748304]) sage: E.conductor() 425104 sage: isogenies_sporadic_Q(E,163) - [Isogeny of degree 163 from Elliptic Curve defined by y^2 = x^3 - 34790720*x - 78984748304 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 924354639680*x + 342062961763303088 over Rational Field] + [Isogeny of degree 163 + from Elliptic Curve defined by y^2 = x^3 - 34790720*x - 78984748304 + over Rational Field + to Elliptic Curve defined by y^2 = x^3 - 924354639680*x + 342062961763303088 + over Rational Field] """ j = E.j_invariant() j = QQ(j) @@ -695,9 +751,9 @@ def isogenies_2(E, minimal_models=True): Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field sage: [phi.codomain().ainvs() for phi in isogenies_2(E)] [] - sage: E = EllipticCurve(QQbar, [9,8]); E + sage: E = EllipticCurve(QQbar, [9,8]); E # optional - sage.rings.number_field Elliptic Curve defined by y^2 = x^3 + 9*x + 8 over Algebraic Field - sage: isogenies_2(E) # not implemented + sage: isogenies_2(E) # not implemented # optional - sage.rings.number_field """ f2 = E.division_polynomial(2) x2 = sorted(f2.roots(multiplicities=False)) @@ -731,12 +787,12 @@ def isogenies_3(E, minimal_models=True): EXAMPLES:: sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_3 - sage: E = EllipticCurve(GF(17), [1,1]) - sage: [phi.codomain().ainvs() for phi in isogenies_3(E)] + sage: E = EllipticCurve(GF(17), [1,1]) # optional - sage.rings.finite_rings + sage: [phi.codomain().ainvs() for phi in isogenies_3(E)] # optional - sage.rings.finite_rings [(0, 0, 0, 9, 7), (0, 0, 0, 0, 1)] - sage: E = EllipticCurve(GF(17^2,'a'), [1,1]) - sage: [phi.codomain().ainvs() for phi in isogenies_3(E)] + sage: E = EllipticCurve(GF(17^2,'a'), [1,1]) # optional - sage.rings.finite_rings + sage: [phi.codomain().ainvs() for phi in isogenies_3(E)] # optional - sage.rings.finite_rings [(0, 0, 0, 9, 7), (0, 0, 0, 0, 1), (0, 0, 0, 5*a + 1, a + 13), (0, 0, 0, 12*a + 6, 16*a + 14)] sage: E = EllipticCurve('19a1') @@ -794,15 +850,50 @@ def isogenies_5_0(E, minimal_models=True): sage: isogenies_5_0(E) [] - sage: E = EllipticCurve(GF(13^2,'a'),[0,-3]) - sage: isogenies_5_0(E) - [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (4*a+6)*x + (2*a+10) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (12*a+5)*x + (2*a+10) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (10*a+2)*x + (2*a+10) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (3*a+12)*x + (11*a+12) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (a+4)*x + (11*a+12) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (9*a+10)*x + (11*a+12) over Finite Field in a of size 13^2] - - sage: K. = NumberField(x**6-320*x**3-320) - sage: E = EllipticCurve(K,[0,0,1,0,0]) - sage: isogenies_5_0(E) - [Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^6 - 320*x^3 - 320 to Elliptic Curve defined by y^2 + y = x^3 + (241565/32*a^5-362149/48*a^4+180281/24*a^3-9693307/4*a^2+14524871/6*a-7254985/3)*x + (1660391123/192*a^5-829315373/96*a^4+77680504/9*a^3-66622345345/24*a^2+33276655441/12*a-24931615912/9) over Number Field in a with defining polynomial x^6 - 320*x^3 - 320, - Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^6 - 320*x^3 - 320 to Elliptic Curve defined by y^2 + y = x^3 + (47519/32*a^5-72103/48*a^4+32939/24*a^3-1909753/4*a^2+2861549/6*a-1429675/3)*x + (-131678717/192*a^5+65520419/96*a^4-12594215/18*a^3+5280985135/24*a^2-2637787519/12*a+1976130088/9) over Number Field in a with defining polynomial x^6 - 320*x^3 - 320] + sage: E = EllipticCurve(GF(13^2,'a'), [0,-3]) # optional - sage.rings.finite_rings + sage: isogenies_5_0(E) # optional - sage.rings.finite_rings + [Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 + to Elliptic Curve defined by y^2 = x^3 + (4*a+6)*x + (2*a+10) + over Finite Field in a of size 13^2, + Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 + to Elliptic Curve defined by y^2 = x^3 + (12*a+5)*x + (2*a+10) + over Finite Field in a of size 13^2, + Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 + to Elliptic Curve defined by y^2 = x^3 + (10*a+2)*x + (2*a+10) + over Finite Field in a of size 13^2, + Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 + to Elliptic Curve defined by y^2 = x^3 + (3*a+12)*x + (11*a+12) + over Finite Field in a of size 13^2, + Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 + to Elliptic Curve defined by y^2 = x^3 + (a+4)*x + (11*a+12) + over Finite Field in a of size 13^2, + Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 + to Elliptic Curve defined by y^2 = x^3 + (9*a+10)*x + (11*a+12) + over Finite Field in a of size 13^2] + + sage: K. = NumberField(x**6 - 320*x**3 - 320) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,0,1,0,0]) # optional - sage.rings.number_field + sage: isogenies_5_0(E) # optional - sage.rings.number_field + [Isogeny of degree 5 + from Elliptic Curve defined by y^2 + y = x^3 + over Number Field in a with defining polynomial x^6 - 320*x^3 - 320 + to Elliptic Curve defined by + y^2 + y = x^3 + (241565/32*a^5-362149/48*a^4+180281/24*a^3-9693307/4*a^2+14524871/6*a-7254985/3)*x + + (1660391123/192*a^5-829315373/96*a^4+77680504/9*a^3-66622345345/24*a^2+33276655441/12*a-24931615912/9) + over Number Field in a with defining polynomial x^6 - 320*x^3 - 320, + Isogeny of degree 5 + from Elliptic Curve defined by y^2 + y = x^3 + over Number Field in a with defining polynomial x^6 - 320*x^3 - 320 + to Elliptic Curve defined by + y^2 + y = x^3 + (47519/32*a^5-72103/48*a^4+32939/24*a^3-1909753/4*a^2+2861549/6*a-1429675/3)*x + + (-131678717/192*a^5+65520419/96*a^4-12594215/18*a^3+5280985135/24*a^2-2637787519/12*a+1976130088/9) + over Number Field in a with defining polynomial x^6 - 320*x^3 - 320] """ F = E.base_field() if E.j_invariant() != 0: @@ -863,40 +954,66 @@ def isogenies_5_1728(E, minimal_models=True): sage: isogenies_5_1728(E) [] - sage: E = EllipticCurve(GF(13),[11,0]) - sage: isogenies_5_1728(E) - [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13 to Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13, - Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13 to Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13] + sage: E = EllipticCurve(GF(13), [11,0]) # optional - sage.rings.finite_rings + sage: isogenies_5_1728(E) # optional - sage.rings.finite_rings + [Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13 + to Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13, + Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13 + to Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13] An example of endomorphisms of degree 5:: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve(K,[0,0,0,1,0]) - sage: isogenies_5_1728(E) - [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I to Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I, - Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I to Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I] - sage: _[0].rational_maps() - (((4/25*i + 3/25)*x^5 + (4/5*i - 2/5)*x^3 - x)/(x^4 + (-4/5*i + 2/5)*x^2 + (-4/25*i - 3/25)), - ((11/125*i + 2/125)*x^6*y + (-23/125*i + 64/125)*x^4*y + (141/125*i + 162/125)*x^2*y + (3/25*i - 4/25)*y)/(x^6 + (-6/5*i + 3/5)*x^4 + (-12/25*i - 9/25)*x^2 + (2/125*i - 11/125))) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,0,0,1,0]) # optional - sage.rings.number_field + sage: isogenies_5_1728(E) # optional - sage.rings.number_field + [Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + x over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + to Elliptic Curve defined by y^2 = x^3 + x over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I, + Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + x over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + to Elliptic Curve defined by y^2 = x^3 + x over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I] + sage: _[0].rational_maps() # optional - sage.rings.number_field + (((4/25*i + 3/25)*x^5 + + (4/5*i - 2/5)*x^3 - x)/(x^4 + (-4/5*i + 2/5)*x^2 + (-4/25*i - 3/25)), + ((11/125*i + 2/125)*x^6*y + (-23/125*i + 64/125)*x^4*y + + (141/125*i + 162/125)*x^2*y + + (3/25*i - 4/25)*y)/(x^6 + (-6/5*i + 3/5)*x^4 + + (-12/25*i - 9/25)*x^2 + (2/125*i - 11/125))) An example of 5-isogenies over a number field:: - sage: K. = NumberField(x**4+20*x**2-80) - sage: K(5).is_square() #necessary but not sufficient! + sage: K. = NumberField(x**4 + 20*x**2 - 80) # optional - sage.rings.number_field + sage: K(5).is_square() # necessary but not sufficient! # optional - sage.rings.number_field True - sage: E = EllipticCurve(K,[0,0,0,1,0]) - sage: isogenies_5_1728(E) - [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in a with defining polynomial x^4 + 20*x^2 - 80 to Elliptic Curve defined by y^2 = x^3 + (-753/4*a^2-4399)*x + (2779*a^3+65072*a) over Number Field in a with defining polynomial x^4 + 20*x^2 - 80, - Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in a with defining polynomial x^4 + 20*x^2 - 80 to Elliptic Curve defined by y^2 = x^3 + (-753/4*a^2-4399)*x + (-2779*a^3-65072*a) over Number Field in a with defining polynomial x^4 + 20*x^2 - 80] + sage: E = EllipticCurve(K, [0,0,0,1,0]) # optional - sage.rings.number_field + sage: isogenies_5_1728(E) # optional - sage.rings.number_field + [Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + x + over Number Field in a with defining polynomial x^4 + 20*x^2 - 80 + to Elliptic Curve defined by y^2 = x^3 + (-753/4*a^2-4399)*x + (2779*a^3+65072*a) + over Number Field in a with defining polynomial x^4 + 20*x^2 - 80, + Isogeny of degree 5 + from Elliptic Curve defined by y^2 = x^3 + x + over Number Field in a with defining polynomial x^4 + 20*x^2 - 80 + to Elliptic Curve defined by y^2 = x^3 + (-753/4*a^2-4399)*x + (-2779*a^3-65072*a) + over Number Field in a with defining polynomial x^4 + 20*x^2 - 80] See :trac:`19840`:: - sage: K. = NumberField(x^4 - 5*x^2 + 5) - sage: E = EllipticCurve([a^2 + a + 1, a^3 + a^2 + a + 1, a^2 + a, 17*a^3 + 34*a^2 - 16*a - 37, 54*a^3 + 105*a^2 - 66*a - 135]) - sage: len(E.isogenies_prime_degree(5)) + sage: K. = NumberField(x^4 - 5*x^2 + 5) # optional - sage.rings.number_field + sage: E = EllipticCurve([a^2 + a + 1, a^3 + a^2 + a + 1, a^2 + a, + ....: 17*a^3 + 34*a^2 - 16*a - 37, + ....: 54*a^3 + 105*a^2 - 66*a - 135]) + sage: len(E.isogenies_prime_degree(5)) # optional - sage.rings.number_field 2 sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_5_1728 - sage: [phi.codomain().j_invariant() for phi in isogenies_5_1728(E)] + sage: [phi.codomain().j_invariant() for phi in isogenies_5_1728(E)] # optional - sage.rings.number_field [19691491018752*a^2 - 27212977933632, 19691491018752*a^2 - 27212977933632] """ F = E.base_field() @@ -965,46 +1082,74 @@ def isogenies_7_0(E, minimal_models=True): First some examples of endomorphisms:: sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_0 - sage: K. = QuadraticField(-3) - sage: E = EllipticCurve(K, [0,1]) - sage: isogenies_7_0(E) - [Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r with defining polynomial x^2 + 3 with r = 1.732050807568878?*I to Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r with defining polynomial x^2 + 3 with r = 1.732050807568878?*I, - Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r with defining polynomial x^2 + 3 with r = 1.732050807568878?*I to Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r with defining polynomial x^2 + 3 with r = 1.732050807568878?*I] - - sage: E = EllipticCurve(GF(13^2,'a'),[0,-3]) - sage: isogenies_7_0(E) - [Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2] + sage: K. = QuadraticField(-3) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,1]) # optional - sage.rings.number_field + sage: isogenies_7_0(E) # optional - sage.rings.number_field + [Isogeny of degree 7 + from Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r + with defining polynomial x^2 + 3 with r = 1.732050807568878?*I + to Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r + with defining polynomial x^2 + 3 with r = 1.732050807568878?*I, + Isogeny of degree 7 + from Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r + with defining polynomial x^2 + 3 with r = 1.732050807568878?*I + to Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r + with defining polynomial x^2 + 3 with r = 1.732050807568878?*I] + + sage: E = EllipticCurve(GF(13^2,'a'), [0,-3]) # optional - sage.rings.finite_rings + sage: isogenies_7_0(E) # optional - sage.rings.finite_rings + [Isogeny of degree 7 + from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 + to Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2, + Isogeny of degree 7 + from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 + to Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2] Now some examples of 7-isogenies which are not endomorphisms:: - sage: K = GF(101) - sage: E = EllipticCurve(K, [0,1]) - sage: isogenies_7_0(E) - [Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 55*x + 100 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 83*x + 26 over Finite Field of size 101] + sage: K = GF(101) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(K, [0,1]) # optional - sage.rings.finite_rings + sage: isogenies_7_0(E) # optional - sage.rings.finite_rings + [Isogeny of degree 7 + from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 101 + to Elliptic Curve defined by y^2 = x^3 + 55*x + 100 over Finite Field of size 101, + Isogeny of degree 7 + from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 101 + to Elliptic Curve defined by y^2 = x^3 + 83*x + 26 over Finite Field of size 101] Examples over a number field:: sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_0 - sage: E = EllipticCurve('27a1').change_ring(QuadraticField(-3,'r')) - sage: isogenies_7_0(E) - [Isogeny of degree 7 from Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r with defining polynomial x^2 + 3 with r = 1.732050807568878?*I to Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r with defining polynomial x^2 + 3 with r = 1.732050807568878?*I, - Isogeny of degree 7 from Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r with defining polynomial x^2 + 3 with r = 1.732050807568878?*I to Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r with defining polynomial x^2 + 3 with r = 1.732050807568878?*I] - - sage: K. = NumberField(x^6 + 1512*x^3 - 21168) - sage: E = EllipticCurve(K, [0,1]) - sage: isogs = isogenies_7_0(E) - sage: [phi.codomain().a_invariants() for phi in isogs] + sage: E = EllipticCurve('27a1').change_ring(QuadraticField(-3,'r')) # optional - sage.rings.number_field + sage: isogenies_7_0(E) # optional - sage.rings.number_field + [Isogeny of degree 7 + from Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r + with defining polynomial x^2 + 3 with r = 1.732050807568878?*I + to Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r + with defining polynomial x^2 + 3 with r = 1.732050807568878?*I, + Isogeny of degree 7 + from Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r + with defining polynomial x^2 + 3 with r = 1.732050807568878?*I + to Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r + with defining polynomial x^2 + 3 with r = 1.732050807568878?*I] + + sage: K. = NumberField(x^6 + 1512*x^3 - 21168) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,1]) # optional - sage.rings.number_field + sage: isogs = isogenies_7_0(E) # optional - sage.rings.number_field + sage: [phi.codomain().a_invariants() for phi in isogs] # optional - sage.rings.number_field [(0, 0, 0, -415/98*a^5 - 675/14*a^4 + 2255/7*a^3 - 74700/7*a^2 - 25110*a - 66420, - -141163/56*a^5 + 1443453/112*a^4 - 374275/2*a^3 - 3500211/2*a^2 - 17871975/4*a - 7710065), + -141163/56*a^5 + 1443453/112*a^4 - 374275/2*a^3 + - 3500211/2*a^2 - 17871975/4*a - 7710065), (0, 0, 0, -24485/392*a^5 - 1080/7*a^4 - 2255/7*a^3 - 1340865/14*a^2 - 230040*a - 553500, - 1753037/56*a^5 + 8345733/112*a^4 + 374275/2*a^3 + 95377029/2*a^2 + 458385345/4*a + 275241835)] - sage: [phi.codomain().j_invariant() for phi in isogs] + 1753037/56*a^5 + 8345733/112*a^4 + 374275/2*a^3 + + 95377029/2*a^2 + 458385345/4*a + 275241835)] + sage: [phi.codomain().j_invariant() for phi in isogs] # optional - sage.rings.number_field [158428486656000/7*a^3 - 313976217600000, -158428486656000/7*a^3 - 34534529335296000] """ @@ -1071,34 +1216,42 @@ def isogenies_7_1728(E, minimal_models=True): EXAMPLES:: sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_1728 - sage: E = EllipticCurve(GF(47), [1, 0]) - sage: isogenies_7_1728(E) - [Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 47 to Elliptic Curve defined by y^2 = x^3 + 26 over Finite Field of size 47, - Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 47 to Elliptic Curve defined by y^2 = x^3 + 21 over Finite Field of size 47] + sage: E = EllipticCurve(GF(47), [1, 0]) # optional - sage.rings.finite_rings + sage: isogenies_7_1728(E) # optional - sage.rings.finite_rings + [Isogeny of degree 7 + from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 47 + to Elliptic Curve defined by y^2 = x^3 + 26 over Finite Field of size 47, + Isogeny of degree 7 + from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 47 + to Elliptic Curve defined by y^2 = x^3 + 21 over Finite Field of size 47] An example in characteristic 53 (for which an earlier implementation did not work):: sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_1728 - sage: E = EllipticCurve(GF(53), [1, 0]) - sage: isogenies_7_1728(E) + sage: E = EllipticCurve(GF(53), [1, 0]) # optional - sage.rings.finite_rings + sage: isogenies_7_1728(E) # optional - sage.rings.finite_rings [] - sage: E = EllipticCurve(GF(53^2,'a'), [1, 0]) - sage: [iso.codomain().ainvs() for iso in isogenies_7_1728(E)] - [(0, 0, 0, 36, 19*a + 15), (0, 0, 0, 36, 34*a + 38), (0, 0, 0, 33, 39*a + 28), (0, 0, 0, 33, 14*a + 25), (0, 0, 0, 19, 45*a + 16), (0, 0, 0, 19, 8*a + 37), (0, 0, 0, 3, 45*a + 16), (0, 0, 0, 3, 8*a + 37)] + sage: E = EllipticCurve(GF(53^2,'a'), [1, 0]) # optional - sage.rings.finite_rings + sage: [iso.codomain().ainvs() for iso in isogenies_7_1728(E)] # optional - sage.rings.finite_rings + [(0, 0, 0, 36, 19*a + 15), (0, 0, 0, 36, 34*a + 38), (0, 0, 0, 33, 39*a + 28), + (0, 0, 0, 33, 14*a + 25), (0, 0, 0, 19, 45*a + 16), (0, 0, 0, 19, 8*a + 37), + (0, 0, 0, 3, 45*a + 16), (0, 0, 0, 3, 8*a + 37)] :: - sage: K. = NumberField(x^8 + 84*x^6 - 1890*x^4 + 644*x^2 - 567) - sage: E = EllipticCurve(K, [1, 0]) - sage: isogs = isogenies_7_1728(E) - sage: [phi.codomain().j_invariant() for phi in isogs] - [-526110256146528/53*a^6 + 183649373229024*a^4 - 3333881559996576/53*a^2 + 2910267397643616/53, - -526110256146528/53*a^6 + 183649373229024*a^4 - 3333881559996576/53*a^2 + 2910267397643616/53] - sage: E1 = isogs[0].codomain() - sage: E2 = isogs[1].codomain() - sage: E1.is_isomorphic(E2) + sage: K. = NumberField(x^8 + 84*x^6 - 1890*x^4 + 644*x^2 - 567) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [1, 0]) # optional - sage.rings.number_field + sage: isogs = isogenies_7_1728(E) # optional - sage.rings.number_field + sage: [phi.codomain().j_invariant() for phi in isogs] # optional - sage.rings.number_field + [-526110256146528/53*a^6 + 183649373229024*a^4 + - 3333881559996576/53*a^2 + 2910267397643616/53, + -526110256146528/53*a^6 + 183649373229024*a^4 + - 3333881559996576/53*a^2 + 2910267397643616/53] + sage: E1 = isogs[0].codomain() # optional - sage.rings.number_field + sage: E2 = isogs[1].codomain() # optional - sage.rings.number_field + sage: E1.is_isomorphic(E2) # optional - sage.rings.number_field False - sage: E1.is_quadratic_twist(E2) + sage: E1.is_quadratic_twist(E2) # optional - sage.rings.number_field -1 """ if E.j_invariant()!=1728: @@ -1163,49 +1316,81 @@ def isogenies_13_0(E, minimal_models=True): Endomorphisms of degree 13 will exist when -3 is a square:: - sage: K. = QuadraticField(-3) - sage: E = EllipticCurve(K, [0, r]); E - Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3 with r = 1.732050807568878?*I - sage: isogenies_13_0(E) - [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3 with r = 1.732050807568878?*I to Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3 with r = 1.732050807568878?*I, - Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3 with r = 1.732050807568878?*I to Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3 with r = 1.732050807568878?*I] - sage: isogenies_13_0(E)[0].rational_maps() - (((7/338*r + 23/338)*x^13 + (-164/13*r - 420/13)*x^10 + (720/13*r + 3168/13)*x^7 + (3840/13*r - 576/13)*x^4 + (4608/13*r + 2304/13)*x)/(x^12 + (4*r + 36)*x^9 + (1080/13*r + 3816/13)*x^6 + (2112/13*r - 5184/13)*x^3 + (-17280/169*r - 1152/169)), ((18/2197*r + 35/2197)*x^18*y + (23142/2197*r + 35478/2197)*x^15*y + (-1127520/2197*r - 1559664/2197)*x^12*y + (-87744/2197*r + 5992704/2197)*x^9*y + (-6625152/2197*r - 9085824/2197)*x^6*y + (-28919808/2197*r - 2239488/2197)*x^3*y + (-1990656/2197*r - 3870720/2197)*y)/(x^18 + (6*r + 54)*x^15 + (3024/13*r + 11808/13)*x^12 + (31296/13*r + 51840/13)*x^9 + (487296/169*r - 2070144/169)*x^6 + (-940032/169*r + 248832/169)*x^3 + (1990656/2197*r + 3870720/2197))) + sage: K. = QuadraticField(-3) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0, r]); E # optional - sage.rings.number_field + Elliptic Curve defined by y^2 = x^3 + r over Number Field in r + with defining polynomial x^2 + 3 with r = 1.732050807568878?*I + sage: isogenies_13_0(E) # optional - sage.rings.number_field + [Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + r over Number Field in r + with defining polynomial x^2 + 3 with r = 1.732050807568878?*I + to Elliptic Curve defined by y^2 = x^3 + r over Number Field in r + with defining polynomial x^2 + 3 with r = 1.732050807568878?*I, + Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + r over Number Field in r + with defining polynomial x^2 + 3 with r = 1.732050807568878?*I + to Elliptic Curve defined by y^2 = x^3 + r over Number Field in r + with defining polynomial x^2 + 3 with r = 1.732050807568878?*I] + sage: isogenies_13_0(E)[0].rational_maps() # optional - sage.rings.number_field + (((7/338*r + 23/338)*x^13 + (-164/13*r - 420/13)*x^10 + + (720/13*r + 3168/13)*x^7 + (3840/13*r - 576/13)*x^4 + + (4608/13*r + 2304/13)*x)/(x^12 + (4*r + 36)*x^9 + (1080/13*r + 3816/13)*x^6 + + (2112/13*r - 5184/13)*x^3 + (-17280/169*r - 1152/169)), + ((18/2197*r + 35/2197)*x^18*y + (23142/2197*r + 35478/2197)*x^15*y + + (-1127520/2197*r - 1559664/2197)*x^12*y + (-87744/2197*r + 5992704/2197)*x^9*y + + (-6625152/2197*r - 9085824/2197)*x^6*y + (-28919808/2197*r - 2239488/2197)*x^3*y + + (-1990656/2197*r - 3870720/2197)*y)/(x^18 + (6*r + 54)*x^15 + + (3024/13*r + 11808/13)*x^12 + (31296/13*r + 51840/13)*x^9 + + (487296/169*r - 2070144/169)*x^6 + (-940032/169*r + 248832/169)*x^3 + + (1990656/2197*r + 3870720/2197))) An example of endomorphisms over a finite field:: - sage: K = GF(19^2,'a') - sage: E = EllipticCurve(j=K(0)); E - Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2 - sage: isogenies_13_0(E) - [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2 to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2, - Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2 to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2] - sage: isogenies_13_0(E)[0].rational_maps() - ((6*x^13 - 6*x^10 - 3*x^7 + 6*x^4 + x)/(x^12 - 5*x^9 - 9*x^6 - 7*x^3 + 5), (-8*x^18*y - 9*x^15*y + 9*x^12*y - 5*x^9*y + 5*x^6*y - 7*x^3*y + 7*y)/(x^18 + 2*x^15 + 3*x^12 - x^9 + 8*x^6 - 9*x^3 + 7)) + sage: K = GF(19^2,'a') # optional - sage.rings.finite_rings + sage: E = EllipticCurve(j=K(0)); E # optional - sage.rings.finite_rings + Elliptic Curve defined by y^2 = x^3 + 1 + over Finite Field in a of size 19^2 + sage: isogenies_13_0(E) # optional - sage.rings.finite_rings + [Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2 + to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2, + Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2 + to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2] + sage: isogenies_13_0(E)[0].rational_maps() # optional - sage.rings.finite_rings + ((6*x^13 - 6*x^10 - 3*x^7 + 6*x^4 + x)/(x^12 - 5*x^9 - 9*x^6 - 7*x^3 + 5), + (-8*x^18*y - 9*x^15*y + 9*x^12*y - 5*x^9*y + + 5*x^6*y - 7*x^3*y + 7*y)/(x^18 + 2*x^15 + 3*x^12 - x^9 + 8*x^6 - 9*x^3 + 7)) A previous implementation did not work in some characteristics:: - sage: K = GF(29) - sage: E = EllipticCurve(j=K(0)) - sage: isogenies_13_0(E) - [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 29 to Elliptic Curve defined by y^2 = x^3 + 26*x + 12 over Finite Field of size 29, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 29 to Elliptic Curve defined by y^2 = x^3 + 16*x + 28 over Finite Field of size 29] + sage: K = GF(29) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(j=K(0)) # optional - sage.rings.finite_rings + sage: isogenies_13_0(E) # optional - sage.rings.finite_rings + [Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 29 + to Elliptic Curve defined by y^2 = x^3 + 26*x + 12 over Finite Field of size 29, + Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 29 + to Elliptic Curve defined by y^2 = x^3 + 16*x + 28 over Finite Field of size 29] :: - sage: K = GF(101) - sage: E = EllipticCurve(j=K(0)); E.ainvs() + sage: K = GF(101) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(j=K(0)); E.ainvs() # optional - sage.rings.finite_rings (0, 0, 0, 0, 1) - sage: [phi.codomain().ainvs() for phi in isogenies_13_0(E)] + sage: [phi.codomain().ainvs() for phi in isogenies_13_0(E)] # optional - sage.rings.finite_rings [(0, 0, 0, 64, 36), (0, 0, 0, 42, 66)] :: sage: x = polygen(QQ) sage: f = x^12 + 78624*x^9 - 130308048*x^6 + 2270840832*x^3 - 54500179968 - sage: K. = NumberField(f) - sage: E = EllipticCurve(j=K(0)); E.ainvs() + sage: K. = NumberField(f) # optional - sage.rings.number_field + sage: E = EllipticCurve(j=K(0)); E.ainvs() # optional - sage.rings.number_field (0, 0, 0, 0, 1) - sage: len([phi.codomain().ainvs() for phi in isogenies_13_0(E)]) # long time (4s) + sage: len([phi.codomain().ainvs() # long time (4s) # optional - sage.rings.number_field + ....: for phi in isogenies_13_0(E)]) 2 """ if E.j_invariant()!=0: @@ -1280,51 +1465,78 @@ def isogenies_13_1728(E, minimal_models=True): sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_13_1728 - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve([0,0,0,i,0]); E.ainvs() + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,0,0,i,0]); E.ainvs() # optional - sage.rings.number_field (0, 0, 0, i, 0) - sage: isogenies_13_1728(E) - [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I to Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I, - Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I to Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I] + sage: isogenies_13_1728(E) # optional - sage.rings.number_field + [Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + to Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I, + Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + to Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I] :: - sage: K = GF(83) - sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs() + sage: K = GF(83) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs() # optional - sage.rings.finite_rings (0, 0, 0, 5, 0) - sage: isogenies_13_1728(E) + sage: isogenies_13_1728(E) # optional - sage.rings.finite_rings [] - sage: K = GF(89) - sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs() + sage: K = GF(89) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs() # optional - sage.rings.finite_rings (0, 0, 0, 5, 0) - sage: isogenies_13_1728(E) - [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89 to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89, - Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89 to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89] + sage: isogenies_13_1728(E) # optional - sage.rings.finite_rings + [Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89 + to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89, + Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89 + to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89] :: - sage: K = GF(23) - sage: E = EllipticCurve(K, [1,0]) - sage: isogenies_13_1728(E) - [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 23 to Elliptic Curve defined by y^2 = x^3 + 16 over Finite Field of size 23, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 23 to Elliptic Curve defined by y^2 = x^3 + 7 over Finite Field of size 23] + sage: K = GF(23) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(K, [1,0]) # optional - sage.rings.finite_rings + sage: isogenies_13_1728(E) # optional - sage.rings.finite_rings + [Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 23 + to Elliptic Curve defined by y^2 = x^3 + 16 over Finite Field of size 23, + Isogeny of degree 13 + from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 23 + to Elliptic Curve defined by y^2 = x^3 + 7 over Finite Field of size 23] :: sage: x = polygen(QQ) - sage: f = x^12 + 1092*x^10 - 432432*x^8 + 6641024*x^6 - 282896640*x^4 - 149879808*x^2 - 349360128 - sage: K. = NumberField(f) - sage: E = EllipticCurve(K, [1,0]) - sage: [phi.codomain().ainvs() for phi in isogenies_13_1728(E)] # long time (3s) + sage: f = (x^12 + 1092*x^10 - 432432*x^8 + 6641024*x^6 + ....: - 282896640*x^4 - 149879808*x^2 - 349360128) + sage: K. = NumberField(f) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [1,0]) # optional - sage.rings.number_field + sage: [phi.codomain().ainvs() # long time (3s) # optional - sage.rings.number_field + ....: for phi in isogenies_13_1728(E)] [(0, - 0, - 0, - -4225010072113/3063768069807341568*a^10 - 24841071989413/15957125363579904*a^8 + 11179537789374271/21276167151439872*a^6 - 407474562289492049/47871376090739712*a^4 + 1608052769560747/4522994717568*a^2 + 7786720245212809/36937790193472, - -363594277511/574456513088876544*a^11 - 7213386922793/2991961005671232*a^9 - 2810970361185589/1329760446964992*a^7 + 281503836888046601/8975883017013696*a^5 - 1287313166530075/848061509544*a^3 + 9768837984886039/6925835661276*a), - (0, - 0, - 0, - -4225010072113/3063768069807341568*a^10 - 24841071989413/15957125363579904*a^8 + 11179537789374271/21276167151439872*a^6 - 407474562289492049/47871376090739712*a^4 + 1608052769560747/4522994717568*a^2 + 7786720245212809/36937790193472, - 363594277511/574456513088876544*a^11 + 7213386922793/2991961005671232*a^9 + 2810970361185589/1329760446964992*a^7 - 281503836888046601/8975883017013696*a^5 + 1287313166530075/848061509544*a^3 - 9768837984886039/6925835661276*a)] + 0, + 0, + -4225010072113/3063768069807341568*a^10 - 24841071989413/15957125363579904*a^8 + + 11179537789374271/21276167151439872*a^6 - 407474562289492049/47871376090739712*a^4 + + 1608052769560747/4522994717568*a^2 + 7786720245212809/36937790193472, + -363594277511/574456513088876544*a^11 - 7213386922793/2991961005671232*a^9 + - 2810970361185589/1329760446964992*a^7 + 281503836888046601/8975883017013696*a^5 + - 1287313166530075/848061509544*a^3 + 9768837984886039/6925835661276*a), + (0, + 0, + 0, + -4225010072113/3063768069807341568*a^10 - 24841071989413/15957125363579904*a^8 + + 11179537789374271/21276167151439872*a^6 - 407474562289492049/47871376090739712*a^4 + + 1608052769560747/4522994717568*a^2 + 7786720245212809/36937790193472, + 363594277511/574456513088876544*a^11 + 7213386922793/2991961005671232*a^9 + + 2810970361185589/1329760446964992*a^7 - 281503836888046601/8975883017013696*a^5 + + 1287313166530075/848061509544*a^3 - 9768837984886039/6925835661276*a)] """ if E.j_invariant()!=1728: raise ValueError("j-invariant must be 1728.") @@ -1537,7 +1749,12 @@ def Psi2(l): sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Psi2 sage: Psi2(11) - x^5 - 55*x^4*u + 994*x^3*u^2 - 8774*x^2*u^3 + 41453*x*u^4 - 928945/11*u^5 + 33*x^4 + 276*x^3*u - 7794*x^2*u^2 + 4452*x*u^3 + 1319331/11*u^4 + 216*x^3*v - 4536*x^2*u*v + 31752*x*u^2*v - 842616/11*u^3*v + 162*x^3 + 38718*x^2*u - 610578*x*u^2 + 33434694/11*u^3 - 4536*x^2*v + 73872*x*u*v - 2745576/11*u^2*v - 16470*x^2 + 580068*x*u - 67821354/11*u^2 - 185976*x*v + 14143896/11*u*v + 7533*x - 20437029/11*u - 12389112/11*v + 19964151/11 + x^5 - 55*x^4*u + 994*x^3*u^2 - 8774*x^2*u^3 + 41453*x*u^4 - 928945/11*u^5 + + 33*x^4 + 276*x^3*u - 7794*x^2*u^2 + 4452*x*u^3 + 1319331/11*u^4 + 216*x^3*v + - 4536*x^2*u*v + 31752*x*u^2*v - 842616/11*u^3*v + 162*x^3 + 38718*x^2*u + - 610578*x*u^2 + 33434694/11*u^3 - 4536*x^2*v + 73872*x*u*v - 2745576/11*u^2*v + - 16470*x^2 + 580068*x*u - 67821354/11*u^2 - 185976*x*v + 14143896/11*u*v + + 7533*x - 20437029/11*u - 12389112/11*v + 19964151/11 sage: p = Psi2(71) # long time sage: (x,u,v) = p.variables() # long time sage: p.coefficient({x: 0, u: 210, v: 0}) # long time @@ -1622,62 +1839,147 @@ def isogenies_prime_degree_genus_plus_0(E, l=None, minimal_models=True): sage: E = EllipticCurve('121a1') sage: isogenies_prime_degree_genus_plus_0(E, 11) - [Isogeny of degree 11 from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888 over Rational Field] + [Isogeny of degree 11 + from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76 + over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888 + over Rational Field] sage: E = EllipticCurve([1, 1, 0, -660, -7600]) sage: isogenies_prime_degree_genus_plus_0(E, 17) - [Isogeny of degree 17 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750 over Rational Field] + [Isogeny of degree 17 + from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600 + over Rational Field + to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750 + over Rational Field] sage: E = EllipticCurve([0, 0, 1, -1862, -30956]) sage: isogenies_prime_degree_genus_plus_0(E, 19) - [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 over Rational Field] - - sage: K = QuadraticField(-295,'a') - sage: a = K.gen() - sage: E = EllipticCurve_from_j(-484650135/16777216*a + 4549855725/16777216) - sage: isogenies_prime_degree_genus_plus_0(E, 23) - [Isogeny of degree 23 from Elliptic Curve defined by y^2 = x^3 + (-14460494784192904095/140737488355328*a+270742665778826768325/140737488355328)*x + (37035998788154488846811217135/590295810358705651712*a-1447451882571839266752561148725/590295810358705651712) over Number Field in a with defining polynomial x^2 + 295 with a = 17.17556403731767?*I to Elliptic Curve defined by y^2 = x^3 + (-5130542435555445498495/140737488355328*a+173233955029127361005925/140737488355328)*x + (-1104699335561165691575396879260545/590295810358705651712*a+3169785826904210171629535101419675/590295810358705651712) over Number Field in a with defining polynomial x^2 + 295 with a = 17.17556403731767?*I] - - sage: K = QuadraticField(-199,'a') - sage: a = K.gen() - sage: E = EllipticCurve_from_j(94743000*a + 269989875) - sage: isogenies_prime_degree_genus_plus_0(E, 29) - [Isogeny of degree 29 from Elliptic Curve defined by y^2 = x^3 + (-153477413215038000*a+5140130723072965125)*x + (297036215130547008455526000*a+2854277047164317800973582250) over Number Field in a with defining polynomial x^2 + 199 with a = 14.106735979665884?*I to Elliptic Curve defined by y^2 = x^3 + (251336161378040805000*a-3071093219933084341875)*x + (-8411064283162168580187643221000*a+34804337770798389546017184785250) over Number Field in a with defining polynomial x^2 + 199 with a = 14.106735979665884?*I] - - sage: K = QuadraticField(253,'a') - sage: a = K.gen() - sage: E = EllipticCurve_from_j(208438034112000*a - 3315409892960000) - sage: isogenies_prime_degree_genus_plus_0(E, 31) - [Isogeny of degree 31 from Elliptic Curve defined by y^2 = x^3 + (4146345122185433034677956608000*a-65951656549965037259634800640000)*x + (-18329111516954473474583425393698245080252416000*a+291542366110383928366510368064204147260129280000) over Number Field in a with defining polynomial x^2 - 253 with a = 15.905973720586867? to Elliptic Curve defined by y^2 = x^3 + (200339763852548615776123686912000*a-3186599019027216904280948275200000)*x + (7443671791411479629112717260182286294850207744000*a-118398847898864757209685951728838895495168655360000) over Number Field in a with defining polynomial x^2 - 253 with a = 15.905973720586867?] - - sage: E = EllipticCurve_from_j(GF(5)(1)) - sage: isogenies_prime_degree_genus_plus_0(E, 41) - [Isogeny of degree 41 from Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 5 to Elliptic Curve defined by y^2 = x^3 + x + 3 over Finite Field of size 5, Isogeny of degree 41 from Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 5 to Elliptic Curve defined by y^2 = x^3 + x + 3 over Finite Field of size 5] - - sage: K = QuadraticField(5,'a') - sage: a = K.gen() - sage: E = EllipticCurve_from_j(184068066743177379840*a - 411588709724712960000) - sage: isogenies_prime_degree_genus_plus_0(E, 47) # long time (2s) - [Isogeny of degree 47 from Elliptic Curve defined by y^2 = x^3 + (454562028554080355857852049849975895490560*a-1016431595837124114668689286176511361024000)*x + (-249456798429896080881440540950393713303830363999480904280965120*a+557802358738710443451273320227578156598454035482869042774016000) over Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? to Elliptic Curve defined by y^2 = x^3 + (39533118442361013730577638493616965245992960*a-88398740199669828340617478832005245173760000)*x + (214030321479466610282320528611562368963830105830555363061803253760*a-478586348074220699687616322532666163722004497458452316582576128000) over Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790?] - - sage: K = QuadraticField(-66827,'a') - sage: a = K.gen() - sage: E = EllipticCurve_from_j(-98669236224000*a + 4401720074240000) + [Isogeny of degree 19 + from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 + over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 + over Rational Field] + + sage: K = QuadraticField(-295,'a') # optional - sage.rings.number_field + sage: a = K.gen() # optional - sage.rings.number_field + sage: E = EllipticCurve_from_j(-484650135/16777216*a + 4549855725/16777216) # optional - sage.rings.number_field + sage: isogenies_prime_degree_genus_plus_0(E, 23) # optional - sage.rings.number_field + [Isogeny of degree 23 + from Elliptic Curve defined by + y^2 = x^3 + (-14460494784192904095/140737488355328*a+270742665778826768325/140737488355328)*x + + (37035998788154488846811217135/590295810358705651712*a-1447451882571839266752561148725/590295810358705651712) + over Number Field in a with defining polynomial x^2 + 295 + with a = 17.17556403731767?*I + to Elliptic Curve defined by + y^2 = x^3 + (-5130542435555445498495/140737488355328*a+173233955029127361005925/140737488355328)*x + + (-1104699335561165691575396879260545/590295810358705651712*a+3169785826904210171629535101419675/590295810358705651712) + over Number Field in a with defining polynomial x^2 + 295 + with a = 17.17556403731767?*I] + + sage: K = QuadraticField(-199,'a') # optional - sage.rings.number_field + sage: a = K.gen() # optional - sage.rings.number_field + sage: E = EllipticCurve_from_j(94743000*a + 269989875) # optional - sage.rings.number_field + sage: isogenies_prime_degree_genus_plus_0(E, 29) # optional - sage.rings.number_field + [Isogeny of degree 29 + from Elliptic Curve defined by + y^2 = x^3 + (-153477413215038000*a+5140130723072965125)*x + + (297036215130547008455526000*a+2854277047164317800973582250) + over Number Field in a with defining polynomial x^2 + 199 + with a = 14.106735979665884?*I + to Elliptic Curve defined by + y^2 = x^3 + (251336161378040805000*a-3071093219933084341875)*x + + (-8411064283162168580187643221000*a+34804337770798389546017184785250) + over Number Field in a with defining polynomial x^2 + 199 + with a = 14.106735979665884?*I] + + sage: K = QuadraticField(253,'a') # optional - sage.rings.number_field + sage: a = K.gen() # optional - sage.rings.number_field + sage: E = EllipticCurve_from_j(208438034112000*a - 3315409892960000) # optional - sage.rings.number_field + sage: isogenies_prime_degree_genus_plus_0(E, 31) # optional - sage.rings.number_field + [Isogeny of degree 31 + from Elliptic Curve defined by + y^2 = x^3 + (4146345122185433034677956608000*a-65951656549965037259634800640000)*x + + (-18329111516954473474583425393698245080252416000*a+291542366110383928366510368064204147260129280000) + over Number Field in a with defining polynomial x^2 - 253 + with a = 15.905973720586867? + to Elliptic Curve defined by + y^2 = x^3 + (200339763852548615776123686912000*a-3186599019027216904280948275200000)*x + + (7443671791411479629112717260182286294850207744000*a-118398847898864757209685951728838895495168655360000) + over Number Field in a with defining polynomial x^2 - 253 + with a = 15.905973720586867?] + + sage: E = EllipticCurve_from_j(GF(5)(1)) # optional - sage.rings.finite_rings + sage: isogenies_prime_degree_genus_plus_0(E, 41) # optional - sage.rings.finite_rings + [Isogeny of degree 41 + from Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 5 + to Elliptic Curve defined by y^2 = x^3 + x + 3 over Finite Field of size 5, + Isogeny of degree 41 + from Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 5 + to Elliptic Curve defined by y^2 = x^3 + x + 3 over Finite Field of size 5] + + sage: K = QuadraticField(5,'a') # optional - sage.rings.number_field + sage: a = K.gen() # optional - sage.rings.number_field + sage: E = EllipticCurve_from_j(184068066743177379840*a # optional - sage.rings.number_field + ....: - 411588709724712960000) + sage: isogenies_prime_degree_genus_plus_0(E, 47) # long time (2s) # optional - sage.rings.number_field + [Isogeny of degree 47 + from Elliptic Curve defined by + y^2 = x^3 + (454562028554080355857852049849975895490560*a-1016431595837124114668689286176511361024000)*x + + (-249456798429896080881440540950393713303830363999480904280965120*a+557802358738710443451273320227578156598454035482869042774016000) + over Number Field in a with defining polynomial x^2 - 5 + with a = 2.236067977499790? + to Elliptic Curve defined by + y^2 = x^3 + (39533118442361013730577638493616965245992960*a-88398740199669828340617478832005245173760000)*x + + (214030321479466610282320528611562368963830105830555363061803253760*a-478586348074220699687616322532666163722004497458452316582576128000) + over Number Field in a with defining polynomial x^2 - 5 + with a = 2.236067977499790?] + + sage: K = QuadraticField(-66827,'a') # optional - sage.rings.number_field + sage: a = K.gen() # optional - sage.rings.number_field + sage: E = EllipticCurve_from_j(-98669236224000*a + 4401720074240000) # optional - sage.rings.number_field sage: isogenies_prime_degree_genus_plus_0(E, 59) # long time (5s) - [Isogeny of degree 59 from Elliptic Curve defined by y^2 = x^3 + (2605886146782144762297974784000*a+1893681048912773634944634716160000)*x + (-116918454256410782232296183198067568744071168000*a+17012043538294664027185882358514011304812871680000) over Number Field in a with defining polynomial x^2 + 66827 with a = 258.5091874576221?*I to Elliptic Curve defined by y^2 = x^3 + (-19387084027159786821400775098368000*a-4882059104868154225052787156713472000)*x + (-25659862010101415428713331477227179429538847260672000*a-2596038148441293485938798119003462972840818381946880000) over Number Field in a with defining polynomial x^2 + 66827 with a = 258.5091874576221?*I] - - sage: E = EllipticCurve_from_j(GF(13)(5)) - sage: isogenies_prime_degree_genus_plus_0(E, 71) - [Isogeny of degree 71 from Elliptic Curve defined by y^2 = x^3 + x + 4 over Finite Field of size 13 to Elliptic Curve defined by y^2 = x^3 + 10*x + 7 over Finite Field of size 13, Isogeny of degree 71 from Elliptic Curve defined by y^2 = x^3 + x + 4 over Finite Field of size 13 to Elliptic Curve defined by y^2 = x^3 + 10*x + 7 over Finite Field of size 13] - - sage: E = EllipticCurve(GF(13),[0,1,1,1,0]) - sage: isogenies_prime_degree_genus_plus_0(E) - [Isogeny of degree 17 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 1 over Finite Field of size 13, - Isogeny of degree 17 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 4 over Finite Field of size 13, - Isogeny of degree 29 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 6 over Finite Field of size 13, - Isogeny of degree 29 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 5*x + 6 over Finite Field of size 13, - Isogeny of degree 41 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 4 over Finite Field of size 13, - Isogeny of degree 41 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 5*x + 6 over Finite Field of size 13] + [Isogeny of degree 59 + from Elliptic Curve defined by + y^2 = x^3 + (2605886146782144762297974784000*a+1893681048912773634944634716160000)*x + + (-116918454256410782232296183198067568744071168000*a+17012043538294664027185882358514011304812871680000) + over Number Field in a with defining polynomial x^2 + 66827 + with a = 258.5091874576221?*I + to Elliptic Curve defined by + y^2 = x^3 + (-19387084027159786821400775098368000*a-4882059104868154225052787156713472000)*x + + (-25659862010101415428713331477227179429538847260672000*a-2596038148441293485938798119003462972840818381946880000) + over Number Field in a with defining polynomial x^2 + 66827 + with a = 258.5091874576221?*I] + + sage: E = EllipticCurve_from_j(GF(13)(5)) # optional - sage.rings.finite_rings + sage: isogenies_prime_degree_genus_plus_0(E, 71) # optional - sage.rings.finite_rings + [Isogeny of degree 71 + from Elliptic Curve defined by y^2 = x^3 + x + 4 over Finite Field of size 13 + to Elliptic Curve defined by y^2 = x^3 + 10*x + 7 over Finite Field of size 13, + Isogeny of degree 71 + from Elliptic Curve defined by y^2 = x^3 + x + 4 over Finite Field of size 13 + to Elliptic Curve defined by y^2 = x^3 + 10*x + 7 over Finite Field of size 13] + + sage: E = EllipticCurve(GF(13), [0,1,1,1,0]) # optional - sage.rings.finite_rings + sage: isogenies_prime_degree_genus_plus_0(E) # optional - sage.rings.finite_rings + [Isogeny of degree 17 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 1 over Finite Field of size 13, + Isogeny of degree 17 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 4 over Finite Field of size 13, + Isogeny of degree 29 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 6 over Finite Field of size 13, + Isogeny of degree 29 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 5*x + 6 over Finite Field of size 13, + Isogeny of degree 41 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 4 over Finite Field of size 13, + Isogeny of degree 41 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 5*x + 6 over Finite Field of size 13] """ if l is None: return sum([isogenies_prime_degree_genus_plus_0(E, ell, minimal_models=minimal_models) @@ -1764,10 +2066,25 @@ def isogenies_prime_degree_genus_plus_0_j0(E, l, minimal_models=True): sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0_j0 sage: u = polygen(QQ) - sage: K. = NumberField(u^4+228*u^3+486*u^2-540*u+225) - sage: E = EllipticCurve(K,[0,-121/5*a^3-20691/5*a^2-29403/5*a+3267]) - sage: isogenies_prime_degree_genus_plus_0_j0(E,11) - [Isogeny of degree 11 from Elliptic Curve defined by y^2 = x^3 + (-121/5*a^3-20691/5*a^2-29403/5*a+3267) over Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225 to Elliptic Curve defined by y^2 = x^3 + (-44286*a^2+178596*a-32670)*x + (-17863351/5*a^3+125072739/5*a^2-74353653/5*a-682803) over Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225, Isogeny of degree 11 from Elliptic Curve defined by y^2 = x^3 + (-121/5*a^3-20691/5*a^2-29403/5*a+3267) over Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225 to Elliptic Curve defined by y^2 = x^3 + (-3267*a^3-740157*a^2+600039*a-277695)*x + (-17863351/5*a^3-4171554981/5*a^2+3769467867/5*a-272366523) over Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225] + sage: K. = NumberField(u^4 + 228*u^3 + 486*u^2 - 540*u + 225) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0, -121/5*a^3 - 20691/5*a^2 - 29403/5*a + 3267]) # optional - sage.rings.number_field + sage: isogenies_prime_degree_genus_plus_0_j0(E, 11) # optional - sage.rings.number_field + [Isogeny of degree 11 + from Elliptic Curve defined by + y^2 = x^3 + (-121/5*a^3-20691/5*a^2-29403/5*a+3267) over + Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225 + to Elliptic Curve defined by + y^2 = x^3 + (-44286*a^2+178596*a-32670)*x + + (-17863351/5*a^3+125072739/5*a^2-74353653/5*a-682803) over + Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225, + Isogeny of degree 11 + from Elliptic Curve defined by + y^2 = x^3 + (-121/5*a^3-20691/5*a^2-29403/5*a+3267) over + Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225 + to Elliptic Curve defined by + y^2 = x^3 + (-3267*a^3-740157*a^2+600039*a-277695)*x + + (-17863351/5*a^3-4171554981/5*a^2+3769467867/5*a-272366523) over + Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225] sage: E = EllipticCurve(GF(5^6,'a'),[0,1]) sage: isogenies_prime_degree_genus_plus_0_j0(E,17) @@ -1851,17 +2168,48 @@ def isogenies_prime_degree_genus_plus_0_j1728(E, l, minimal_models=True): sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0_j1728 sage: u = polygen(QQ) - sage: K. = NumberField(u^6 - 522*u^5 - 10017*u^4 + 2484*u^3 - 5265*u^2 + 12150*u - 5103) - sage: E = EllipticCurve(K,[-75295/1335852*a^5+13066735/445284*a^4+44903485/74214*a^3+17086861/24738*a^2+11373021/16492*a-1246245/2356,0]) - sage: isogenies_prime_degree_genus_plus_0_j1728(E,11) - [Isogeny of degree 11 from Elliptic Curve defined by y^2 = x^3 + (-75295/1335852*a^5+13066735/445284*a^4+44903485/74214*a^3+17086861/24738*a^2+11373021/16492*a-1246245/2356)*x over Number Field in a with defining polynomial x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103 to Elliptic Curve defined by y^2 = x^3 + (9110695/1335852*a^5-1581074935/445284*a^4-5433321685/74214*a^3-3163057249/24738*a^2+1569269691/16492*a+73825125/2356)*x + (-3540460*a^3+30522492*a^2-7043652*a-5031180) over Number Field in a with defining polynomial x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103, Isogeny of degree 11 from Elliptic Curve defined by y^2 = x^3 + (-75295/1335852*a^5+13066735/445284*a^4+44903485/74214*a^3+17086861/24738*a^2+11373021/16492*a-1246245/2356)*x over Number Field in a with defining polynomial x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103 to Elliptic Curve defined by y^2 = x^3 + (9110695/1335852*a^5-1581074935/445284*a^4-5433321685/74214*a^3-3163057249/24738*a^2+1569269691/16492*a+73825125/2356)*x + (3540460*a^3-30522492*a^2+7043652*a+5031180) over Number Field in a with defining polynomial x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103] - sage: i = QuadraticField(-1,'i').gen() - sage: E = EllipticCurve([-1-2*i,0]) - sage: isogenies_prime_degree_genus_plus_0_j1728(E,17) - [Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + (-2*i-1)*x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I to Elliptic Curve defined by y^2 = x^3 + (-82*i-641)*x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I, - Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + (-2*i-1)*x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I to Elliptic Curve defined by y^2 = x^3 + (-562*i+319)*x over Number Field in i with defining polynomial x^2 + 1 with i = 1*I] - sage: Emin = E.global_minimal_model() - sage: [(p,len(isogenies_prime_degree_genus_plus_0_j1728(Emin,p))) for p in [17, 29, 41]] + sage: K. = NumberField(u^6 - 522*u^5 - 10017*u^4 # optional - sage.rings.number_field + ....: + 2484*u^3 - 5265*u^2 + 12150*u - 5103) + sage: E = EllipticCurve(K, [-75295/1335852*a^5 + 13066735/445284*a^4 # optional - sage.rings.number_field + ....: + 44903485/74214*a^3 + 17086861/24738*a^2 + ....: + 11373021/16492*a - 1246245/2356, 0]) + sage: isogenies_prime_degree_genus_plus_0_j1728(E, 11) # optional - sage.rings.number_field + [Isogeny of degree 11 + from Elliptic Curve defined by + y^2 = x^3 + (-75295/1335852*a^5+13066735/445284*a^4+44903485/74214*a^3+17086861/24738*a^2+11373021/16492*a-1246245/2356)*x + over Number Field in a with defining polynomial + x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103 + to Elliptic Curve defined by + y^2 = x^3 + (9110695/1335852*a^5-1581074935/445284*a^4-5433321685/74214*a^3-3163057249/24738*a^2+1569269691/16492*a+73825125/2356)*x + + (-3540460*a^3+30522492*a^2-7043652*a-5031180) + over Number Field in a with defining polynomial + x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103, + Isogeny of degree 11 + from Elliptic Curve defined by + y^2 = x^3 + (-75295/1335852*a^5+13066735/445284*a^4+44903485/74214*a^3+17086861/24738*a^2+11373021/16492*a-1246245/2356)*x + over Number Field in a with defining polynomial + x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103 + to Elliptic Curve defined by + y^2 = x^3 + (9110695/1335852*a^5-1581074935/445284*a^4-5433321685/74214*a^3-3163057249/24738*a^2+1569269691/16492*a+73825125/2356)*x + + (3540460*a^3-30522492*a^2+7043652*a+5031180) + over Number Field in a with defining polynomial + x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103] + sage: i = QuadraticField(-1,'i').gen() # optional - sage.rings.number_field + sage: E = EllipticCurve([-1 - 2*i, 0]) # optional - sage.rings.number_field + sage: isogenies_prime_degree_genus_plus_0_j1728(E, 17) # optional - sage.rings.number_field + [Isogeny of degree 17 + from Elliptic Curve defined by y^2 = x^3 + (-2*i-1)*x + over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + to Elliptic Curve defined by y^2 = x^3 + (-82*i-641)*x + over Number Field in i with defining polynomial x^2 + 1 with i = 1*I, + Isogeny of degree 17 + from Elliptic Curve defined by y^2 = x^3 + (-2*i-1)*x + over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + to Elliptic Curve defined by y^2 = x^3 + (-562*i+319)*x + over Number Field in i with defining polynomial x^2 + 1 with i = 1*I] + sage: Emin = E.global_minimal_model() # optional - sage.rings.number_field + sage: [(p, len(isogenies_prime_degree_genus_plus_0_j1728(Emin, p))) # optional - sage.rings.number_field + ....: for p in [17, 29, 41]] [(17, 2), (29, 2), (41, 2)] """ if l not in hyperelliptic_primes: @@ -1985,22 +2333,22 @@ def is_kernel_polynomial(E, m, f): sage: from sage.schemes.elliptic_curves.isogeny_small_degree import is_kernel_polynomial sage: E = EllipticCurve([0, -1, 1, -10, -20]) sage: x = polygen(QQ) - sage: is_kernel_polynomial(E,5,x^2 + x - 29/5) + sage: is_kernel_polynomial(E, 5, x^2 + x - 29/5) True - sage: is_kernel_polynomial(E,5,(x - 16) * (x - 5)) + sage: is_kernel_polynomial(E, 5, (x - 16) * (x - 5)) True An example from [KT2013]_, where the 13-division polynomial splits into 14 factors each of degree 6, but only two of these is a kernel polynomial for a 13-isogeny:: - sage: F = GF(3) - sage: E = EllipticCurve(F,[0,0,0,-1,0]) - sage: f13 = E.division_polynomial(13) - sage: factors = [f for f,e in f13.factor()] - sage: all(f.degree() == 6 for f in factors) + sage: F = GF(3) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F, [0,0,0,-1,0]) # optional - sage.rings.finite_rings + sage: f13 = E.division_polynomial(13) # optional - sage.rings.finite_rings + sage: factors = [f for f, e in f13.factor()] # optional - sage.rings.finite_rings + sage: all(f.degree() == 6 for f in factors) # optional - sage.rings.finite_rings True - sage: [is_kernel_polynomial(E,13,f) for f in factors] + sage: [is_kernel_polynomial(E, 13, f) for f in factors] # optional - sage.rings.finite_rings [True, True, False, @@ -2018,15 +2366,15 @@ def is_kernel_polynomial(E, m, f): See :trac:`22232`:: - sage: K =GF(47^2) - sage: E = EllipticCurve([0, K.gen()]) - sage: psi7 = E.division_polynomial(7) - sage: f = psi7.factor()[4][0] - sage: f + sage: K = GF(47^2) # optional - sage.rings.finite_rings + sage: E = EllipticCurve([0, K.gen()]) # optional - sage.rings.finite_rings + sage: psi7 = E.division_polynomial(7) # optional - sage.rings.finite_rings + sage: f = psi7.factor()[4][0] # optional - sage.rings.finite_rings + sage: f # optional - sage.rings.finite_rings x^3 + (7*z2 + 11)*x^2 + (25*z2 + 33)*x + 25*z2 - sage: f.divides(psi7) + sage: f.divides(psi7) # optional - sage.rings.finite_rings True - sage: is_kernel_polynomial(E,7, f) + sage: is_kernel_polynomial(E, 7, f) # optional - sage.rings.finite_rings False """ m2 = m // 2 @@ -2092,27 +2440,57 @@ def isogenies_prime_degree_general(E, l, minimal_models=True): EXAMPLES:: sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_general - sage: E = EllipticCurve_from_j(GF(2^6,'a')(1)) - sage: isogenies_prime_degree_general(E, 7) - [Isogeny of degree 7 from Elliptic Curve defined by y^2 + x*y = x^3 + 1 over Finite Field in a of size 2^6 to Elliptic Curve defined by y^2 + x*y = x^3 + x over Finite Field in a of size 2^6] - sage: E = EllipticCurve_from_j(GF(3^12,'a')(2)) - sage: isogenies_prime_degree_general(E, 17) - [Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2 over Finite Field in a of size 3^12 to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x over Finite Field in a of size 3^12, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2 over Finite Field in a of size 3^12 to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + x + 2 over Finite Field in a of size 3^12] + sage: E = EllipticCurve_from_j(GF(2^6,'a')(1)) # optional - sage.rings.finite_rings + sage: isogenies_prime_degree_general(E, 7) # optional - sage.rings.finite_rings + [Isogeny of degree 7 + from Elliptic Curve defined by y^2 + x*y = x^3 + 1 + over Finite Field in a of size 2^6 + to Elliptic Curve defined by y^2 + x*y = x^3 + x + over Finite Field in a of size 2^6] + sage: E = EllipticCurve_from_j(GF(3^12,'a')(2)) # optional - sage.rings.finite_rings + sage: isogenies_prime_degree_general(E, 17) # optional - sage.rings.finite_rings + [Isogeny of degree 17 + from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2 + over Finite Field in a of size 3^12 + to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x + over Finite Field in a of size 3^12, + Isogeny of degree 17 + from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2 + over Finite Field in a of size 3^12 + to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + x + 2 + over Finite Field in a of size 3^12] sage: E = EllipticCurve('50a1') sage: isogenies_prime_degree_general(E, 3) - [Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 over Rational Field] + [Isogeny of degree 3 + from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 + over Rational Field] sage: isogenies_prime_degree_general(E, 5) - [Isogeny of degree 5 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 over Rational Field] + [Isogeny of degree 5 + from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 + over Rational Field] sage: E = EllipticCurve([0, 0, 1, -1862, -30956]) sage: isogenies_prime_degree_general(E, 19) - [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 over Rational Field] + [Isogeny of degree 19 + from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 + over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 + over Rational Field] sage: E = EllipticCurve([0, -1, 0, -6288, 211072]) sage: isogenies_prime_degree_general(E, 37) # long time (2s) - [Isogeny of degree 37 from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072 over Rational Field to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728 over Rational Field] + [Isogeny of degree 37 + from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072 + over Rational Field + to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728 + over Rational Field] sage: E = EllipticCurve([-3440, 77658]) sage: isogenies_prime_degree_general(E, 43) # long time (2s) - [Isogeny of degree 43 from Elliptic Curve defined by y^2 = x^3 - 3440*x + 77658 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 6360560*x - 6174354606 over Rational Field] + [Isogeny of degree 43 + from Elliptic Curve defined by y^2 = x^3 - 3440*x + 77658 over Rational Field + to Elliptic Curve defined by y^2 = x^3 - 6360560*x - 6174354606 + over Rational Field] Isogenies of degree equal to the characteristic are computed (but only the separable isogeny). In the following example we consider @@ -2121,15 +2499,33 @@ def isogenies_prime_degree_general(E, l, minimal_models=True): sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_general sage: ainvs = (0,1,1,-1,-1) - sage: for l in prime_range(50): + sage: for l in prime_range(50): # optional - sage.rings.finite_rings ....: E = EllipticCurve(GF(l),ainvs) ....: isogenies_prime_degree_general(E,l) [] - [Isogeny of degree 3 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 2*x + 2 over Finite Field of size 3 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 3] - [Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5] - [Isogeny of degree 7 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 6*x + 6 over Finite Field of size 7 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4 over Finite Field of size 7] - [Isogeny of degree 11 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 10 over Finite Field of size 11 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x + 1 over Finite Field of size 11] - [Isogeny of degree 13 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13] + [Isogeny of degree 3 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 2*x + 2 + over Finite Field of size 3 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 3] + [Isogeny of degree 5 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 + over Finite Field of size 5 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 + over Finite Field of size 5] + [Isogeny of degree 7 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 6*x + 6 + over Finite Field of size 7 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4 over Finite Field of size 7] + [Isogeny of degree 11 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 10 + over Finite Field of size 11 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x + 1 + over Finite Field of size 11] + [Isogeny of degree 13 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 + over Finite Field of size 13 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 + over Finite Field of size 13] [Isogeny of degree 17 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 16 over Finite Field of size 17 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15 over Finite Field of size 17] [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 18*x + 18 over Finite Field of size 19 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x + 12 over Finite Field of size 19] [Isogeny of degree 23 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23] @@ -2140,33 +2536,35 @@ def isogenies_prime_degree_general(E, l, minimal_models=True): [Isogeny of degree 43 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 42 over Finite Field of size 43 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36 over Finite Field of size 43] [Isogeny of degree 47 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 46*x + 46 over Finite Field of size 47 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 34 over Finite Field of size 47] - Note that not all factors of degree (l-1)/2 of the l-division + Note that not all factors of degree `(l-1)/2` of the `l`-division polynomial are kernel polynomials. In this example, the 13-division polynomial factors as a product of 14 irreducible factors of degree 6 each, but only two those are kernel polynomials:: - sage: F3 = GF(3) - sage: E = EllipticCurve(F3,[0,0,0,-1,0]) - sage: Psi13 = E.division_polynomial(13) - sage: len([f for f,e in Psi13.factor() if f.degree()==6]) + sage: F3 = GF(3) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(F3, [0,0,0,-1,0]) # optional - sage.rings.finite_rings + sage: Psi13 = E.division_polynomial(13) # optional - sage.rings.finite_rings + sage: len([f for f, e in Psi13.factor() if f.degree() == 6]) # optional - sage.rings.finite_rings 14 - sage: len(E.isogenies_prime_degree(13)) + sage: len(E.isogenies_prime_degree(13)) # optional - sage.rings.finite_rings 2 Over GF(9) the other factors of degree 6 split into pairs of cubics which can be rearranged to give the remaining 12 kernel polynomials:: - sage: len(E.change_ring(GF(3^2,'a')).isogenies_prime_degree(13)) + sage: len(E.change_ring(GF(3^2,'a')).isogenies_prime_degree(13)) # optional - sage.rings.finite_rings 14 See :trac:`18589`: the following example took 20s before, now only 4s:: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve(K,[0,0,0,1,0]) - sage: [phi.codomain().ainvs() for phi in E.isogenies_prime_degree(37)] # long time (6s) - [(0, 0, 0, -840*i + 1081, 0), (0, 0, 0, 840*i + 1081, 0)] + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K,[0,0,0,1,0]) # optional - sage.rings.number_field + sage: [phi.codomain().ainvs() # long time (6s) # optional - sage.rings.number_field + ....: for phi in E.isogenies_prime_degree(37)] + [(0, 0, 0, -840*i + 1081, 0), + (0, 0, 0, 840*i + 1081, 0)] """ if not l.is_prime(): raise ValueError("%s is not prime." % l) @@ -2266,23 +2664,48 @@ def isogenies_prime_degree(E, l, minimal_models=True): EXAMPLES:: sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree - sage: E = EllipticCurve_from_j(GF(2^6,'a')(1)) - sage: isogenies_prime_degree(E, 7) - [Isogeny of degree 7 from Elliptic Curve defined by y^2 + x*y = x^3 + 1 over Finite Field in a of size 2^6 to Elliptic Curve defined by y^2 + x*y = x^3 + x over Finite Field in a of size 2^6] - sage: E = EllipticCurve_from_j(GF(3^12,'a')(2)) - sage: isogenies_prime_degree(E, 17) - [Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2 over Finite Field in a of size 3^12 to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x over Finite Field in a of size 3^12, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2 over Finite Field in a of size 3^12 to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + x + 2 over Finite Field in a of size 3^12] + sage: E = EllipticCurve_from_j(GF(2^6,'a')(1)) # optional - sage.rings.finite_rings + sage: isogenies_prime_degree(E, 7) # optional - sage.rings.finite_rings + [Isogeny of degree 7 + from Elliptic Curve defined by y^2 + x*y = x^3 + 1 + over Finite Field in a of size 2^6 + to Elliptic Curve defined by y^2 + x*y = x^3 + x + over Finite Field in a of size 2^6] + sage: E = EllipticCurve_from_j(GF(3^12,'a')(2)) # optional - sage.rings.finite_rings + sage: isogenies_prime_degree(E, 17) # optional - sage.rings.finite_rings + [Isogeny of degree 17 + from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2 + over Finite Field in a of size 3^12 + to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x + over Finite Field in a of size 3^12, + Isogeny of degree 17 + from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2 + over Finite Field in a of size 3^12 + to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + x + 2 + over Finite Field in a of size 3^12] sage: E = EllipticCurve('50a1') sage: isogenies_prime_degree(E, 3) - [Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 over Rational Field] + [Isogeny of degree 3 + from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 over Rational Field] sage: isogenies_prime_degree(E, 5) - [Isogeny of degree 5 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 over Rational Field] + [Isogeny of degree 5 + from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field + to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 over Rational Field] sage: E = EllipticCurve([0, 0, 1, -1862, -30956]) sage: isogenies_prime_degree(E, 19) - [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 over Rational Field] + [Isogeny of degree 19 + from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 + over Rational Field + to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 + over Rational Field] sage: E = EllipticCurve([0, -1, 0, -6288, 211072]) sage: isogenies_prime_degree(E, 37) - [Isogeny of degree 37 from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072 over Rational Field to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728 over Rational Field] + [Isogeny of degree 37 + from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072 + over Rational Field + to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728 + over Rational Field] Isogenies of degree equal to the characteristic are computed (but only the separable isogeny). In the following example we consider @@ -2291,43 +2714,85 @@ def isogenies_prime_degree(E, l, minimal_models=True): sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree sage: ainvs = (0,1,1,-1,-1) - sage: for l in prime_range(50): - ....: E = EllipticCurve(GF(l),ainvs) - ....: isogenies_prime_degree(E,l) + sage: for l in prime_range(50): # optional - sage.rings.finite_rings + ....: E = EllipticCurve(GF(l), ainvs) + ....: isogenies_prime_degree(E, l) [] - [Isogeny of degree 3 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 2*x + 2 over Finite Field of size 3 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 3] - [Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5] - [Isogeny of degree 7 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 6*x + 6 over Finite Field of size 7 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4 over Finite Field of size 7] - [Isogeny of degree 11 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 10 over Finite Field of size 11 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x + 1 over Finite Field of size 11] - [Isogeny of degree 13 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13] - [Isogeny of degree 17 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 16 over Finite Field of size 17 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15 over Finite Field of size 17] - [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 18*x + 18 over Finite Field of size 19 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x + 12 over Finite Field of size 19] - [Isogeny of degree 23 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23] - [Isogeny of degree 29 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 28*x + 28 over Finite Field of size 29 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 7*x + 27 over Finite Field of size 29] - [Isogeny of degree 31 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 30*x + 30 over Finite Field of size 31 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15*x + 16 over Finite Field of size 31] - [Isogeny of degree 37 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36*x + 36 over Finite Field of size 37 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 17 over Finite Field of size 37] - [Isogeny of degree 41 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 40*x + 40 over Finite Field of size 41 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 33*x + 16 over Finite Field of size 41] - [Isogeny of degree 43 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 42 over Finite Field of size 43 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36 over Finite Field of size 43] - [Isogeny of degree 47 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 46*x + 46 over Finite Field of size 47 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 34 over Finite Field of size 47] + [Isogeny of degree 3 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 2*x + 2 over Finite Field of size 3 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 3] + [Isogeny of degree 5 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5] + [Isogeny of degree 7 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 6*x + 6 over Finite Field of size 7 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4 over Finite Field of size 7] + [Isogeny of degree 11 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 10 over Finite Field of size 11 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x + 1 over Finite Field of size 11] + [Isogeny of degree 13 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13] + [Isogeny of degree 17 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 16 over Finite Field of size 17 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15 over Finite Field of size 17] + [Isogeny of degree 19 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 18*x + 18 over Finite Field of size 19 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x + 12 over Finite Field of size 19] + [Isogeny of degree 23 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23] + [Isogeny of degree 29 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 28*x + 28 over Finite Field of size 29 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 7*x + 27 over Finite Field of size 29] + [Isogeny of degree 31 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 30*x + 30 over Finite Field of size 31 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15*x + 16 over Finite Field of size 31] + [Isogeny of degree 37 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36*x + 36 over Finite Field of size 37 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 17 over Finite Field of size 37] + [Isogeny of degree 41 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 40*x + 40 over Finite Field of size 41 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 33*x + 16 over Finite Field of size 41] + [Isogeny of degree 43 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 42 over Finite Field of size 43 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36 over Finite Field of size 43] + [Isogeny of degree 47 + from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 46*x + 46 over Finite Field of size 47 + to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 34 over Finite Field of size 47] Note that the computation is faster for degrees equal to one of the genus 0 primes (2, 3, 5, 7, 13) or one of the hyperelliptic primes (11, 17, 19, 23, 29, 31, 41, 47, 59, 71) than when the generic code must be used:: - sage: E = EllipticCurve(GF(101), [-3440, 77658]) - sage: E.isogenies_prime_degree(71) # fast + sage: E = EllipticCurve(GF(101), [-3440, 77658]) # optional - sage.rings.finite_rings + sage: E.isogenies_prime_degree(71) # fast # optional - sage.rings.finite_rings [] - sage: E.isogenies_prime_degree(73) # long time (2s) + sage: E.isogenies_prime_degree(73) # long time (2s) # optional - sage.rings.finite_rings [] Test that :trac:`32269` is fixed:: - sage: K = QuadraticField(-11) - sage: E = EllipticCurve(K, [0,1,0,-117,-541]) - sage: E.isogenies_prime_degree(37) # long time (9s) - [Isogeny of degree 37 from Elliptic Curve defined by y^2 = x^3 + x^2 + (-117)*x + (-541) over Number Field in a with defining polynomial x^2 + 11 with a = 3.316624790355400?*I to Elliptic Curve defined by y^2 = x^3 + x^2 + (30800*a+123963)*x + (3931312*a-21805005) over Number Field in a with defining polynomial x^2 + 11 with a = 3.316624790355400?*I, - Isogeny of degree 37 from Elliptic Curve defined by y^2 = x^3 + x^2 + (-117)*x + (-541) over Number Field in a with defining polynomial x^2 + 11 with a = 3.316624790355400?*I to Elliptic Curve defined by y^2 = x^3 + x^2 + (-30800*a+123963)*x + (-3931312*a-21805005) over Number Field in a with defining polynomial x^2 + 11 with a = 3.316624790355400?*I] + sage: K = QuadraticField(-11) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,1,0,-117,-541]) # optional - sage.rings.number_field + sage: E.isogenies_prime_degree(37) # long time (9s) # optional - sage.rings.number_field + [Isogeny of degree 37 + from Elliptic Curve defined by y^2 = x^3 + x^2 + (-117)*x + (-541) + over Number Field in a with defining polynomial x^2 + 11 + with a = 3.316624790355400?*I + to Elliptic Curve defined by + y^2 = x^3 + x^2 + (30800*a+123963)*x + (3931312*a-21805005) + over Number Field in a with defining polynomial x^2 + 11 + with a = 3.316624790355400?*I, + Isogeny of degree 37 + from Elliptic Curve defined by y^2 = x^3 + x^2 + (-117)*x + (-541) + over Number Field in a with defining polynomial x^2 + 11 + with a = 3.316624790355400?*I + to Elliptic Curve defined by + y^2 = x^3 + x^2 + (-30800*a+123963)*x + (-3931312*a-21805005) + over Number Field in a with defining polynomial x^2 + 11 + with a = 3.316624790355400?*I] """ if not l.is_prime(): raise ValueError("%s is not prime."%l) diff --git a/src/sage/schemes/elliptic_curves/jacobian.py b/src/sage/schemes/elliptic_curves/jacobian.py index 6cf48d0760a..1a33c7e4726 100644 --- a/src/sage/schemes/elliptic_curves/jacobian.py +++ b/src/sage/schemes/elliptic_curves/jacobian.py @@ -13,17 +13,17 @@ EXAMPLES:: sage: R. = QQ[] - sage: Jacobian(u^3+v^3+w^3) + sage: Jacobian(u^3 + v^3 + w^3) Elliptic Curve defined by y^2 = x^3 - 27/4 over Rational Field - sage: Jacobian(u^4+v^4+w^2) + sage: Jacobian(u^4 + v^4 + w^2) Elliptic Curve defined by y^2 = x^3 - 4*x over Rational Field - sage: C = Curve(u^3+v^3+w^3) + sage: C = Curve(u^3 + v^3 + w^3) sage: Jacobian(C) Elliptic Curve defined by y^2 = x^3 - 27/4 over Rational Field sage: P2. = ProjectiveSpace(2, QQ) - sage: C = P2.subscheme(u^3+v^3+w^3) + sage: C = P2.subscheme(u^3 + v^3 + w^3) sage: Jacobian(C) Elliptic Curve defined by y^2 = x^3 - 27/4 over Rational Field @@ -36,7 +36,7 @@ sage: C = HyperellipticCurve(f) sage: Jacobian(C) Jacobian of Hyperelliptic Curve over Rational Field defined - by y^2 = x^5 + 1184*x^3 + 1846*x^2 + 956*x + 560 + by y^2 = x^5 + 1184*x^3 + 1846*x^2 + 956*x + 560 REFERENCES: @@ -76,15 +76,15 @@ def Jacobian(X, **kwds): EXAMPLES:: sage: R. = QQ[] - sage: Jacobian(u^3+v^3+w^3) + sage: Jacobian(u^3 + v^3 + w^3) Elliptic Curve defined by y^2 = x^3 - 27/4 over Rational Field - sage: C = Curve(u^3+v^3+w^3) + sage: C = Curve(u^3 + v^3 + w^3) sage: Jacobian(C) Elliptic Curve defined by y^2 = x^3 - 27/4 over Rational Field sage: P2. = ProjectiveSpace(2, QQ) - sage: C = P2.subscheme(u^3+v^3+w^3) + sage: C = P2.subscheme(u^3 + v^3 + w^3) sage: Jacobian(C) Elliptic Curve defined by y^2 = x^3 - 27/4 over Rational Field @@ -95,8 +95,8 @@ def Jacobian(X, **kwds): To: Elliptic Curve defined by y^2 = x^3 - 27/4 over Rational Field Defn: Defined on coordinates by sending (u : v : w) to (-u^4*v^4*w - u^4*v*w^4 - u*v^4*w^4 : - 1/2*u^6*v^3 - 1/2*u^3*v^6 - 1/2*u^6*w^3 + 1/2*v^6*w^3 + 1/2*u^3*w^6 - 1/2*v^3*w^6 : - u^3*v^3*w^3) + 1/2*u^6*v^3 - 1/2*u^3*v^6 - 1/2*u^6*w^3 + 1/2*v^6*w^3 + 1/2*u^3*w^6 - 1/2*v^3*w^6 : + u^3*v^3*w^3) """ try: return X.jacobian(**kwds) @@ -125,14 +125,12 @@ def Jacobian_of_curve(curve, morphism=False): - ``curve`` -- a one-dimensional algebraic variety of genus one. - OUTPUT: - - Its Jacobian elliptic curve. + OUTPUT: Its Jacobian elliptic curve. EXAMPLES:: sage: R. = QQ[] - sage: C = Curve(u^3+v^3+w^3) + sage: C = Curve(u^3 + v^3 + w^3) sage: Jacobian(C) Elliptic Curve defined by y^2 = x^3 - 27/4 over Rational Field """ @@ -178,22 +176,23 @@ def Jacobian_of_equation(polynomial, variables=None, curve=None): EXAMPLES:: sage: R. = QQ[] - sage: f = a^3+b^3+60*c^3 + sage: f = a^3 + b^3 + 60*c^3 sage: Jacobian(f) Elliptic Curve defined by y^2 = x^3 - 24300 over Rational Field sage: Jacobian(f.subs(c=1)) Elliptic Curve defined by y^2 = x^3 - 24300 over Rational Field - If we specify the domain curve the birational covering is returned:: + If we specify the domain curve, the birational covering is returned:: sage: h = Jacobian(f, curve=Curve(f)); h Scheme morphism: From: Projective Plane Curve over Rational Field defined by a^3 + b^3 + 60*c^3 To: Elliptic Curve defined by y^2 = x^3 - 24300 over Rational Field Defn: Defined on coordinates by sending (a : b : c) to - (-216000*a^4*b^4*c - 12960000*a^4*b*c^4 - 12960000*a*b^4*c^4 : - 108000*a^6*b^3 - 108000*a^3*b^6 - 6480000*a^6*c^3 + 6480000*b^6*c^3 + 388800000*a^3*c^6 - 388800000*b^3*c^6 : - 216000*a^3*b^3*c^3) + (-216000*a^4*b^4*c - 12960000*a^4*b*c^4 - 12960000*a*b^4*c^4 + : 108000*a^6*b^3 - 108000*a^3*b^6 - 6480000*a^6*c^3 + 6480000*b^6*c^3 + + 388800000*a^3*c^6 - 388800000*b^3*c^6 + : 216000*a^3*b^3*c^3) sage: h([1,-1,0]) (0 : 1 : 0) @@ -203,18 +202,18 @@ def Jacobian_of_equation(polynomial, variables=None, curve=None): sage: E = h.codomain() sage: E.defining_polynomial()(h.defining_polynomials()).factor() - (2519424000000000) * c^3 * b^3 * a^3 * (a^3 + b^3 + 60*c^3) * - (a^9*b^6 + a^6*b^9 - 120*a^9*b^3*c^3 + 900*a^6*b^6*c^3 - 120*a^3*b^9*c^3 + - 3600*a^9*c^6 + 54000*a^6*b^3*c^6 + 54000*a^3*b^6*c^6 + 3600*b^9*c^6 + - 216000*a^6*c^9 - 432000*a^3*b^3*c^9 + 216000*b^6*c^9) + (2519424000000000) * c^3 * b^3 * a^3 * (a^3 + b^3 + 60*c^3) + * (a^9*b^6 + a^6*b^9 - 120*a^9*b^3*c^3 + 900*a^6*b^6*c^3 - 120*a^3*b^9*c^3 + + 3600*a^9*c^6 + 54000*a^6*b^3*c^6 + 54000*a^3*b^6*c^6 + 3600*b^9*c^6 + + 216000*a^6*c^9 - 432000*a^3*b^3*c^9 + 216000*b^6*c^9) By specifying the variables, we can also construct an elliptic curve over a polynomial ring:: sage: R. = QQ[] - sage: Jacobian(u^3+v^3+t, variables=[u,v]) + sage: Jacobian(u^3 + v^3 + t, variables=[u,v]) Elliptic Curve defined by y^2 = x^3 + (-27/4*t^2) over - Multivariate Polynomial Ring in u, v, t over Rational Field + Multivariate Polynomial Ring in u, v, t over Rational Field TESTS:: diff --git a/src/sage/schemes/elliptic_curves/lseries_ell.py b/src/sage/schemes/elliptic_curves/lseries_ell.py index e1506b17910..7f0e4d3e5e5 100644 --- a/src/sage/schemes/elliptic_curves/lseries_ell.py +++ b/src/sage/schemes/elliptic_curves/lseries_ell.py @@ -42,7 +42,8 @@ def __init__(self, E): EXAMPLES:: sage: EllipticCurve([1..5]).lseries() - Complex L-series of the Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field + Complex L-series of the Elliptic Curve + defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field """ self.__E = E @@ -935,7 +936,8 @@ def zero_sums(self, N=None): sage: E = EllipticCurve("5077a") sage: E.lseries().zero_sums() - Zero sum estimator for L-function attached to Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field + Zero sum estimator for L-function attached to + Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field """ from sage.lfunctions.zero_sums import LFunctionZeroSum return LFunctionZeroSum(self.__E, N=N) diff --git a/src/sage/schemes/elliptic_curves/mod_sym_num.pyx b/src/sage/schemes/elliptic_curves/mod_sym_num.pyx index 369cd98a293..6e1b888d9cf 100644 --- a/src/sage/schemes/elliptic_curves/mod_sym_num.pyx +++ b/src/sage/schemes/elliptic_curves/mod_sym_num.pyx @@ -62,7 +62,7 @@ The most likely usage for the code is through the functions ``modular_symbol_numerical``:: sage: E = EllipticCurve("5077a1") - sage: M = E.modular_symbol(implementation = "num") + sage: M = E.modular_symbol(implementation="num") sage: M(0) 0 sage: M(1/123) @@ -80,7 +80,8 @@ accessible, too):: 35261176 sage: M = E.modular_symbol(implementation="num", sign=-1) sage: M - Numerical modular symbol attached to Elliptic Curve defined by y^2 = x^3 + 101*x + 103 over Rational Field + Numerical modular symbol attached to + Elliptic Curve defined by y^2 = x^3 + 101*x + 103 over Rational Field We can then compute the value `[13/17]^{-}` and `[1/17]^{+}` by calling the function ``M``. The value of `[0]^{+}=0` tells us that the rank of diff --git a/src/sage/schemes/elliptic_curves/modular_parametrization.py b/src/sage/schemes/elliptic_curves/modular_parametrization.py index 57a90190fe5..ee38d1ffe53 100644 --- a/src/sage/schemes/elliptic_curves/modular_parametrization.py +++ b/src/sage/schemes/elliptic_curves/modular_parametrization.py @@ -16,11 +16,14 @@ sage: phi = EllipticCurve('11a1').modular_parametrization() sage: phi - Modular parameterization from the upper half plane to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Modular parameterization + from the upper half plane + to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: phi(0.5+CDF(I)) (285684.320516... + 7.0...e-11*I : 1.526964169...e8 + 5.6...e-8*I : 1.00000000000000) sage: phi.power_series(prec = 7) - (q^-2 + 2*q^-1 + 4 + 5*q + 8*q^2 + q^3 + 7*q^4 + O(q^5), -q^-3 - 3*q^-2 - 7*q^-1 - 13 - 17*q - 26*q^2 - 19*q^3 + O(q^4)) + (q^-2 + 2*q^-1 + 4 + 5*q + 8*q^2 + q^3 + 7*q^4 + O(q^5), + -q^-3 - 3*q^-2 - 7*q^-1 - 13 - 17*q - 26*q^2 - 19*q^3 + O(q^4)) AUTHORS: @@ -64,7 +67,10 @@ class ModularParameterization: sage: phi = EllipticCurve('11a1').modular_parametrization() sage: phi - Modular parameterization from the upper half plane to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Modular parameterization + from the upper half plane + to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 + over Rational Field """ def __init__(self, E): r""" @@ -264,7 +270,7 @@ def power_series(self, prec=20): sage: E = EllipticCurve('389a1') sage: phi = E.modular_parametrization() - sage: X,Y = phi.power_series(prec=10) + sage: X, Y = phi.power_series(prec=10) sage: X q^-2 + 2*q^-1 + 4 + 7*q + 13*q^2 + 18*q^3 + 31*q^4 + 49*q^5 + 74*q^6 + 111*q^7 + O(q^8) sage: Y diff --git a/src/sage/schemes/elliptic_curves/period_lattice.py b/src/sage/schemes/elliptic_curves/period_lattice.py index 7224988fc27..0b8cb197840 100644 --- a/src/sage/schemes/elliptic_curves/period_lattice.py +++ b/src/sage/schemes/elliptic_curves/period_lattice.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Period lattices of elliptic curves and related functions @@ -17,64 +16,72 @@ EXAMPLES:: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,1,0,a,a]) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field First we try a real embedding:: - sage: emb = K.embeddings(RealField())[0] - sage: L = E.period_lattice(emb); L - Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a over Number Field in a with defining polynomial x^3 - 2 with respect to the embedding Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Algebraic Real Field - Defn: a |--> 1.259921049894873? + sage: emb = K.embeddings(RealField())[0] # optional - sage.rings.number_field + sage: L = E.period_lattice(emb); L # optional - sage.rings.number_field + Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a + over Number Field in a with defining polynomial x^3 - 2 + with respect to the embedding Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Algebraic Real Field + Defn: a |--> 1.259921049894873? The first basis period is real:: - sage: L.basis() + sage: L.basis() # optional - sage.rings.number_field (3.81452977217855, 1.90726488608927 + 1.34047785962440*I) - sage: L.is_real() + sage: L.is_real() # optional - sage.rings.number_field True For a basis `\omega_1,\omega_2` normalised so that `\omega_1/\omega_2` is in the fundamental region of the upper half-plane, use the function ``normalised_basis()`` instead:: - sage: L.normalised_basis() + sage: L.normalised_basis() # optional - sage.rings.number_field (1.90726488608927 - 1.34047785962440*I, -1.90726488608927 - 1.34047785962440*I) Next a complex embedding:: - sage: emb = K.embeddings(ComplexField())[0] - sage: L = E.period_lattice(emb); L - Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a over Number Field in a with defining polynomial x^3 - 2 with respect to the embedding Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Algebraic Field - Defn: a |--> -0.6299605249474365? - 1.091123635971722?*I + sage: emb = K.embeddings(ComplexField())[0] # optional - sage.rings.number_field + sage: L = E.period_lattice(emb); L # optional - sage.rings.number_field + Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a + over Number Field in a with defining polynomial x^3 - 2 + with respect to the embedding Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Algebraic Field + Defn: a |--> -0.6299605249474365? - 1.091123635971722?*I In this case, the basis `\omega_1`, `\omega_2` is always normalised so that `\tau = \omega_1/\omega_2` is in the fundamental region in the upper half plane:: - sage: w1,w2 = L.basis(); w1,w2 + sage: w1, w2 = L.basis(); w1, w2 # optional - sage.rings.number_field (-1.37588604166076 - 2.58560946624443*I, -2.10339907847356 + 0.428378776460622*I) - sage: L.is_real() + sage: L.is_real() # optional - sage.rings.number_field False - sage: tau = w1/w2; tau + sage: tau = w1/w2; tau # optional - sage.rings.number_field 0.387694505032876 + 1.30821088214407*I - sage: L.normalised_basis() + sage: L.normalised_basis() # optional - sage.rings.number_field (-1.37588604166076 - 2.58560946624443*I, -2.10339907847356 + 0.428378776460622*I) We test that bug :trac:`8415` (caused by a PARI bug fixed in v2.3.5) is OK:: - sage: E = EllipticCurve('37a') - sage: K. = QuadraticField(-7) - sage: EK = E.change_ring(K) - sage: EK.period_lattice(K.complex_embeddings()[0]) - Period lattice associated to Elliptic Curve defined by y^2 + y = x^3 + (-1)*x over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I with respect to the embedding Ring morphism: - From: Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I - To: Algebraic Field - Defn: a |--> -2.645751311064591?*I + sage: E = EllipticCurve('37a') # optional - sage.rings.number_field + sage: K. = QuadraticField(-7) # optional - sage.rings.number_field + sage: EK = E.change_ring(K) # optional - sage.rings.number_field + sage: EK.period_lattice(K.complex_embeddings()[0]) # optional - sage.rings.number_field + Period lattice associated to Elliptic Curve defined by y^2 + y = x^3 + (-1)*x + over Number Field in a with defining polynomial x^2 + 7 + with a = 2.645751311064591?*I + with respect to the embedding Ring morphism: + From: Number Field in a with defining polynomial x^2 + 7 + with a = 2.645751311064591?*I + To: Algebraic Field + Defn: a |--> -2.645751311064591?*I REFERENCES: @@ -167,34 +174,39 @@ def __init__(self, E, embedding=None): sage: from sage.schemes.elliptic_curves.period_lattice import PeriodLattice_ell sage: E = EllipticCurve('37a') sage: PeriodLattice_ell(E) - Period lattice associated to Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field + Period lattice associated to + Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field :: - sage: K. = NumberField(x^3-2) - sage: emb = K.embeddings(RealField())[0] - sage: E = EllipticCurve([0,1,0,a,a]) - sage: L = PeriodLattice_ell(E,emb); L - Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a over Number Field in a with defining polynomial x^3 - 2 with respect to the embedding Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Algebraic Real Field - Defn: a |--> 1.259921049894873? - - sage: emb = K.embeddings(ComplexField())[0] - sage: L = PeriodLattice_ell(E,emb); L - Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a over Number Field in a with defining polynomial x^3 - 2 with respect to the embedding Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Algebraic Field - Defn: a |--> -0.6299605249474365? - 1.091123635971722?*I + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: emb = K.embeddings(RealField())[0] # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: L = PeriodLattice_ell(E, emb); L # optional - sage.rings.number_field + Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a + over Number Field in a with defining polynomial x^3 - 2 + with respect to the embedding Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Algebraic Real Field + Defn: a |--> 1.259921049894873? + + sage: emb = K.embeddings(ComplexField())[0] # optional - sage.rings.number_field + sage: L = PeriodLattice_ell(E, emb); L # optional - sage.rings.number_field + Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a + over Number Field in a with defining polynomial x^3 - 2 + with respect to the embedding Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Algebraic Field + Defn: a |--> -0.6299605249474365? - 1.091123635971722?*I TESTS:: sage: from sage.schemes.elliptic_curves.period_lattice import PeriodLattice_ell - sage: K. = NumberField(x^3-2) - sage: emb = K.embeddings(RealField())[0] - sage: E = EllipticCurve([0,1,0,a,a]) - sage: L = PeriodLattice_ell(E,emb) - sage: L == loads(dumps(L)) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: emb = K.embeddings(RealField())[0] # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: L = PeriodLattice_ell(E,emb) # optional - sage.rings.number_field + sage: L == loads(dumps(L)) # optional - sage.rings.number_field True """ # First we cache the elliptic curve with this period lattice: @@ -267,11 +279,11 @@ def __richcmp__(self, other, op): TESTS:: sage: from sage.schemes.elliptic_curves.period_lattice import PeriodLattice_ell - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,1,0,a,a]) - sage: embs = K.embeddings(ComplexField()) - sage: L1,L2,L3 = [PeriodLattice_ell(E,e) for e in embs] - sage: L1 < L2 < L3 + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: embs = K.embeddings(ComplexField()) # optional - sage.rings.number_field + sage: L1, L2, L3 = [PeriodLattice_ell(E, e) for e in embs] # optional - sage.rings.number_field + sage: L1 < L2 < L3 # optional - sage.rings.number_field True """ if not isinstance(other, PeriodLattice_ell): @@ -297,14 +309,15 @@ def __repr__(self): :: - sage: K. = NumberField(x^3-2) - sage: emb = K.embeddings(RealField())[0] - sage: E = EllipticCurve([0,1,0,a,a]) - sage: L = E.period_lattice(emb); L - Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a over Number Field in a with defining polynomial x^3 - 2 with respect to the embedding Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Algebraic Real Field - Defn: a |--> 1.259921049894873? + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: emb = K.embeddings(RealField())[0] # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: L = E.period_lattice(emb); L # optional - sage.rings.number_field + Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a over Number Field in a + with defining polynomial x^3 - 2 with respect to the embedding Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Algebraic Real Field + Defn: a |--> 1.259921049894873? """ if self.E.base_field() is QQ: return "Period lattice associated to %s"%(self.E) @@ -344,7 +357,7 @@ def __call__(self, P, prec=None): False sage: L(P, prec=96) 0.4793482501902193161295330101 + 0.985868850775824102211203849...*I - sage: Q=E([3,5]) + sage: Q = E([3,5]) sage: Q.is_on_identity_component() True sage: L(Q, prec=96) @@ -422,20 +435,20 @@ def basis(self, prec=None, algorithm='sage'): :: - sage: K. = NumberField(x^3-2) - sage: emb = K.embeddings(RealField())[0] - sage: E = EllipticCurve([0,1,0,a,a]) - sage: L = E.period_lattice(emb) - sage: L.basis(64) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: emb = K.embeddings(RealField())[0] # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: L = E.period_lattice(emb) # optional - sage.rings.number_field + sage: L.basis(64) # optional - sage.rings.number_field (3.81452977217854509, 1.90726488608927255 + 1.34047785962440202*I) - sage: emb = K.embeddings(ComplexField())[0] - sage: L = E.period_lattice(emb) - sage: w1,w2 = L.basis(); w1,w2 + sage: emb = K.embeddings(ComplexField())[0] # optional - sage.rings.number_field + sage: L = E.period_lattice(emb) # optional - sage.rings.number_field + sage: w1, w2 = L.basis(); w1, w2 # optional - sage.rings.number_field (-1.37588604166076 - 2.58560946624443*I, -2.10339907847356 + 0.428378776460622*I) - sage: L.is_real() + sage: L.is_real() # optional - sage.rings.number_field False - sage: tau = w1/w2; tau + sage: tau = w1/w2; tau # optional - sage.rings.number_field 0.387694505032876 + 1.30821088214407*I """ # We divide into two cases: (1) Q, or a number field with a @@ -486,7 +499,7 @@ def gens(self, prec=None, algorithm='sage'): sage: E.period_lattice().gens() (2.99345864623196, 2.45138938198679*I) - sage: E.period_lattice().gens(prec = 100) + sage: E.period_lattice().gens(prec=100) (2.9934586462319596298320099794, 2.4513893819867900608542248319*I) """ return tuple(self.basis(prec=prec, algorithm=algorithm)) @@ -523,20 +536,22 @@ def normalised_basis(self, prec=None, algorithm='sage'): :: - sage: K. = NumberField(x^3-2) - sage: emb = K.embeddings(RealField())[0] - sage: E = EllipticCurve([0,1,0,a,a]) - sage: L = E.period_lattice(emb) - sage: L.normalised_basis(64) - (1.90726488608927255 - 1.34047785962440202*I, -1.90726488608927255 - 1.34047785962440202*I) - - sage: emb = K.embeddings(ComplexField())[0] - sage: L = E.period_lattice(emb) - sage: w1,w2 = L.normalised_basis(); w1,w2 - (-1.37588604166076 - 2.58560946624443*I, -2.10339907847356 + 0.428378776460622*I) - sage: L.is_real() + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: emb = K.embeddings(RealField())[0] # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: L = E.period_lattice(emb) # optional - sage.rings.number_field + sage: L.normalised_basis(64) # optional - sage.rings.number_field + (1.90726488608927255 - 1.34047785962440202*I, + -1.90726488608927255 - 1.34047785962440202*I) + + sage: emb = K.embeddings(ComplexField())[0] # optional - sage.rings.number_field + sage: L = E.period_lattice(emb) # optional - sage.rings.number_field + sage: w1, w2 = L.normalised_basis(); w1, w2 # optional - sage.rings.number_field + (-1.37588604166076 - 2.58560946624443*I, + -2.10339907847356 + 0.428378776460622*I) + sage: L.is_real() # optional - sage.rings.number_field False - sage: tau = w1/w2; tau + sage: tau = w1/w2; tau # optional - sage.rings.number_field 0.387694505032876 + 1.30821088214407*I """ w1, w2 = self.basis(prec=prec, algorithm=algorithm) @@ -574,24 +589,24 @@ def tau(self, prec=None, algorithm='sage'): :: - sage: K. = NumberField(x^3-2) - sage: emb = K.embeddings(RealField())[0] - sage: E = EllipticCurve([0,1,0,a,a]) - sage: L = E.period_lattice(emb) - sage: tau = L.tau(); tau + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: emb = K.embeddings(RealField())[0] # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: L = E.period_lattice(emb) # optional - sage.rings.number_field + sage: tau = L.tau(); tau # optional - sage.rings.number_field -0.338718341018919 + 0.940887817679340*I - sage: tau.abs() + sage: tau.abs() # optional - sage.rings.number_field 1.00000000000000 - sage: -0.5 <= tau.real() <= 0.5 + sage: -0.5 <= tau.real() <= 0.5 # optional - sage.rings.number_field True - sage: emb = K.embeddings(ComplexField())[0] - sage: L = E.period_lattice(emb) - sage: tau = L.tau(); tau + sage: emb = K.embeddings(ComplexField())[0] # optional - sage.rings.number_field + sage: L = E.period_lattice(emb) # optional - sage.rings.number_field + sage: tau = L.tau(); tau # optional - sage.rings.number_field 0.387694505032876 + 1.30821088214407*I - sage: tau.abs() + sage: tau.abs() # optional - sage.rings.number_field 1.36444961115933 - sage: -0.5 <= tau.real() <= 0.5 + sage: -0.5 <= tau.real() <= 0.5 # optional - sage.rings.number_field True """ w1, w2 = self.normalised_basis(prec=prec, algorithm=algorithm) @@ -620,16 +635,16 @@ def _compute_periods_real(self, prec=None, algorithm='sage'): EXAMPLES:: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,1,0,a,a]) - sage: embs = K.embeddings(CC) - sage: Ls = [E.period_lattice(e) for e in embs] - sage: [L.is_real() for L in Ls] + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: embs = K.embeddings(CC) # optional - sage.rings.number_field + sage: Ls = [E.period_lattice(e) for e in embs] # optional - sage.rings.number_field + sage: [L.is_real() for L in Ls] # optional - sage.rings.number_field [False, False, True] - sage: Ls[2]._compute_periods_real(100) + sage: Ls[2]._compute_periods_real(100) # optional - sage.rings.number_field (3.8145297721785450936365098936, 1.9072648860892725468182549468 + 1.3404778596244020196600112394*I) - sage: Ls[2]._compute_periods_real(100, algorithm='pari') + sage: Ls[2]._compute_periods_real(100, algorithm='pari') # optional - sage.rings.number_field (3.8145297721785450936365098936, 1.9072648860892725468182549468 - 1.3404778596244020196600112394*I) """ @@ -690,31 +705,32 @@ def _compute_periods_complex(self, prec=None, normalise=True): EXAMPLES:: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,1,0,a,a]) - sage: embs = K.embeddings(CC) - sage: Ls = [E.period_lattice(e) for e in embs] - sage: [L.is_real() for L in Ls] + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: embs = K.embeddings(CC) # optional - sage.rings.number_field + sage: Ls = [E.period_lattice(e) for e in embs] # optional - sage.rings.number_field + sage: [L.is_real() for L in Ls] # optional - sage.rings.number_field [False, False, True] - sage: L = Ls[0] - sage: w1,w2 = L._compute_periods_complex(100); w1,w2 - (-1.3758860416607626645495991458 - 2.5856094662444337042877901304*I, -2.1033990784735587243397865076 + 0.42837877646062187766760569686*I) - sage: tau = w1/w2; tau + sage: L = Ls[0] # optional - sage.rings.number_field + sage: w1,w2 = L._compute_periods_complex(100); w1,w2 # optional - sage.rings.number_field + (-1.3758860416607626645495991458 - 2.5856094662444337042877901304*I, + -2.1033990784735587243397865076 + 0.42837877646062187766760569686*I) + sage: tau = w1/w2; tau # optional - sage.rings.number_field 0.38769450503287609349437509561 + 1.3082108821440725664008561928*I - sage: tau.real() + sage: tau.real() # optional - sage.rings.number_field 0.38769450503287609349437509561 - sage: tau.abs() + sage: tau.abs() # optional - sage.rings.number_field 1.3644496111593345713923386773 Without normalisation:: - sage: w1,w2 = L._compute_periods_complex(normalise=False); w1,w2 + sage: w1,w2 = L._compute_periods_complex(normalise=False); w1,w2 # optional - sage.rings.number_field (2.10339907847356 - 0.428378776460622*I, 0.727513036812796 - 3.01398824270506*I) - sage: tau = w1/w2; tau + sage: tau = w1/w2; tau # optional - sage.rings.number_field 0.293483964608883 + 0.627038168678760*I - sage: tau.real() + sage: tau.real() # optional - sage.rings.number_field 0.293483964608883 - sage: tau.abs() # > 1 + sage: tau.abs() # > 1 # optional - sage.rings.number_field 0.692321964451917 """ if prec is None: @@ -751,18 +767,18 @@ def is_real(self): :: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve(K,[0,0,0,i,2*i]) - sage: emb = K.embeddings(ComplexField())[0] - sage: L = E.period_lattice(emb) - sage: L.is_real() + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,0,0,i,2*i]) # optional - sage.rings.number_field + sage: emb = K.embeddings(ComplexField())[0] # optional - sage.rings.number_field + sage: L = E.period_lattice(emb) # optional - sage.rings.number_field + sage: L.is_real() # optional - sage.rings.number_field False :: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,1,0,a,a]) - sage: [E.period_lattice(emb).is_real() for emb in K.embeddings(CC)] + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: [E.period_lattice(emb).is_real() for emb in K.embeddings(CC)] # optional - sage.rings.number_field [False, False, True] ALGORITHM: @@ -834,11 +850,11 @@ def real_period(self, prec=None, algorithm='sage'): :: - sage: K. = NumberField(x^3-2) - sage: emb = K.embeddings(RealField())[0] - sage: E = EllipticCurve([0,1,0,a,a]) - sage: L = E.period_lattice(emb) - sage: L.real_period(64) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: emb = K.embeddings(RealField())[0] # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: L = E.period_lattice(emb) # optional - sage.rings.number_field + sage: L.real_period(64) # optional - sage.rings.number_field 3.81452977217854509 """ if self.is_real(): @@ -881,7 +897,7 @@ def omega(self, prec=None, bsd_normalise=False): This is not a minimal model:: - sage: E = EllipticCurve([0,-432*6^2]) + sage: E = EllipticCurve([0, -432*6^2]) sage: E.period_lattice().omega() 0.486109385710056 @@ -895,11 +911,11 @@ def omega(self, prec=None, bsd_normalise=False): :: - sage: K. = NumberField(x^3-2) - sage: emb = K.embeddings(RealField())[0] - sage: E = EllipticCurve([0,1,0,a,a]) - sage: L = E.period_lattice(emb) - sage: L.omega(64) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: emb = K.embeddings(RealField())[0] # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: L = E.period_lattice(emb) # optional - sage.rings.number_field + sage: L.omega(64) # optional - sage.rings.number_field 3.81452977217854509 A complex example (taken from J.E.Cremona and E.Whitley, @@ -907,14 +923,14 @@ def omega(self, prec=None, bsd_normalise=False): quadratic fields*, Mathematics of Computation 62 No. 205 (1994), 407-429). See :trac:`29645` and :trac:`29782`:: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve([0,1-i,i,-i,0]) - sage: L = E.period_lattice(K.embeddings(CC)[0]) - sage: L.omega() + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1-i,i,-i,0]) # optional - sage.rings.number_field + sage: L = E.period_lattice(K.embeddings(CC)[0]) # optional - sage.rings.number_field + sage: L.omega() # optional - sage.rings.number_field 8.80694160502647 - sage: L.omega(prec=200) + sage: L.omega(prec=200) # optional - sage.rings.number_field 8.8069416050264741493250743632295462227858630765392114070032 - sage: L.omega(bsd_normalise=True) + sage: L.omega(bsd_normalise=True) # optional - sage.rings.number_field 17.6138832100529 """ if self.is_real(): @@ -952,11 +968,11 @@ def basis_matrix(self, prec=None, normalised=False): :: - sage: K. = NumberField(x^3-2) - sage: emb = K.embeddings(RealField())[0] - sage: E = EllipticCurve([0,1,0,a,a]) - sage: L = E.period_lattice(emb) - sage: L.basis_matrix(64) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: emb = K.embeddings(RealField())[0] # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: L = E.period_lattice(emb) # optional - sage.rings.number_field + sage: L.basis_matrix(64) # optional - sage.rings.number_field [ 3.81452977217854509 0.000000000000000000] [ 1.90726488608927255 1.34047785962440202] @@ -1009,7 +1025,7 @@ def complex_area(self, prec=None): :: - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: embs = K.embeddings(ComplexField()) sage: E = EllipticCurve([0,1,0,a,a]) sage: [E.period_lattice(emb).is_real() for emb in K.embeddings(CC)] @@ -1033,11 +1049,11 @@ def sigma(self, z, prec=None, flag=0): - ``flag`` -- - 0: (default) ???; + 0: (default) ???; - 1: computes an arbitrary determination of log(sigma(z)) + 1: computes an arbitrary determination of log(sigma(z)) - 2, 3: same using the product expansion instead of theta series. ??? + 2, 3: same using the product expansion instead of theta series. ??? .. NOTE:: @@ -1075,21 +1091,22 @@ def curve(self): :: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,1,0,a,a]) - sage: L = E.period_lattice(K.embeddings(RealField())[0]) - sage: L.curve() is E + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: L = E.period_lattice(K.embeddings(RealField())[0]) # optional - sage.rings.number_field + sage: L.curve() is E # optional - sage.rings.number_field True - sage: L = E.period_lattice(K.embeddings(ComplexField())[0]) - sage: L.curve() is E + sage: L = E.period_lattice(K.embeddings(ComplexField())[0]) # optional - sage.rings.number_field + sage: L.curve() is E # optional - sage.rings.number_field True """ return self.E def ei(self): r""" - Return the x-coordinates of the 2-division points of the elliptic curve associated with this period lattice, as elements of QQbar. + Return the x-coordinates of the 2-division points of the elliptic curve associated + with this period lattice, as elements of ``QQbar``. EXAMPLES:: @@ -1103,22 +1120,22 @@ def ei(self): :: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,1,0,a,a]) - sage: L = E.period_lattice(K.embeddings(RealField())[0]) - sage: x1,x2,x3 = L.ei() - sage: abs(x1.real())+abs(x2.real())<1e-14 + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,1,0,a,a]) # optional - sage.rings.number_field + sage: L = E.period_lattice(K.embeddings(RealField())[0]) # optional - sage.rings.number_field + sage: x1,x2,x3 = L.ei() # optional - sage.rings.number_field + sage: abs(x1.real()) + abs(x2.real()) < 1e-14 # optional - sage.rings.number_field True - sage: x1.imag(),x2.imag(),x3 + sage: x1.imag(), x2.imag(), x3 # optional - sage.rings.number_field (-1.122462048309373?, 1.122462048309373?, -1.000000000000000?) :: - sage: L = E.period_lattice(K.embeddings(ComplexField())[0]) - sage: L.ei() + sage: L = E.period_lattice(K.embeddings(ComplexField())[0]) # optional - sage.rings.number_field + sage: L.ei() # optional - sage.rings.number_field [-1.000000000000000? + 0.?e-1...*I, - -0.9720806486198328? - 0.561231024154687?*I, - 0.9720806486198328? + 0.561231024154687?*I] + -0.9720806486198328? - 0.561231024154687?*I, + 0.9720806486198328? + 0.561231024154687?*I] """ return self._ei @@ -1140,12 +1157,12 @@ def coordinates(self, z, rounding=None): are a basis for the lattice (normalised in the case of complex embeddings). - When ``rounding`` is 'round', returns a tuple of integers `n_1`, + When ``rounding`` is ``'round'``, returns a tuple of integers `n_1`, `n_2` which are the closest integers to the `x`, `y` defined above. If `z` is in the lattice these are the coordinates of `z` with respect to the lattice basis. - When ``rounding`` is 'floor', returns a tuple of integers + When ``rounding`` is ``'floor'``, returns a tuple of integers `n_1`, `n_2` which are the integer parts to the `x`, `y` defined above. These are used in :meth:`.reduce` @@ -1159,14 +1176,14 @@ def coordinates(self, z, rounding=None): 0.47934825019021931612953301006 + 0.98586885077582410221120384908*I sage: L.coordinates(zP) (0.19249290511394227352563996419, 0.50000000000000000000000000000) - sage: sum([x*w for x,w in zip(L.coordinates(zP), L.basis(prec=100))]) + sage: sum([x*w for x, w in zip(L.coordinates(zP), L.basis(prec=100))]) 0.47934825019021931612953301006 + 0.98586885077582410221120384908*I - sage: L.coordinates(12*w1+23*w2) + sage: L.coordinates(12*w1 + 23*w2) (12.000000000000000000000000000, 23.000000000000000000000000000) - sage: L.coordinates(12*w1+23*w2, rounding='floor') + sage: L.coordinates(12*w1 + 23*w2, rounding='floor') (11, 22) - sage: L.coordinates(12*w1+23*w2, rounding='round') + sage: L.coordinates(12*w1 + 23*w2, rounding='round') (12, 23) """ C = z.parent() @@ -1222,7 +1239,7 @@ def reduce(self, z): sage: P = E([-1,1]) sage: zP = P.elliptic_logarithm(precision=100); zP 0.47934825019021931612953301006 + 0.98586885077582410221120384908*I - sage: z = zP+10*w1-20*w2; z + sage: z = zP + 10*w1 - 20*w2; z 25.381473858740770069343110929 - 38.448885180257139986236950114*I sage: L.reduce(z) 0.47934825019021931612953301006 + 0.98586885077582410221120384908*I @@ -1230,7 +1247,7 @@ def reduce(self, z): 0.958696500380439 sage: L.reduce(L.elliptic_logarithm(2*P)) 0.958696500380439 - sage: L.reduce(L.elliptic_logarithm(2*P)+10*w1-20*w2) + sage: L.reduce(L.elliptic_logarithm(2*P) + 10*w1 - 20*w2) 0.958696500380444 """ C = z.parent() @@ -1318,44 +1335,44 @@ def e_log_RC(self, xP, yP, prec=None, reduce=True): A number field example:: - sage: K. = NumberField(x^3-2) - sage: E = EllipticCurve([0,0,0,0,a]) - sage: v = K.real_places()[0] - sage: L = E.period_lattice(v) - sage: P = E.lift_x(1/3*a^2 + a + 5/3) - sage: L(P) + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,0,0,0,a]) # optional - sage.rings.number_field + sage: v = K.real_places()[0] # optional - sage.rings.number_field + sage: L = E.period_lattice(v) # optional - sage.rings.number_field + sage: P = E.lift_x(1/3*a^2 + a + 5/3) # optional - sage.rings.number_field + sage: L(P) # optional - sage.rings.number_field 3.51086196882538 - sage: xP, yP = [v(c) for c in P.xy()] - sage: L.e_log_RC(xP, yP) + sage: xP, yP = [v(c) for c in P.xy()] # optional - sage.rings.number_field + sage: L.e_log_RC(xP, yP) # optional - sage.rings.number_field 3.51086196882538 Elliptic logs of real points which do not come from algebraic points:: - sage: ER = EllipticCurve([v(ai) for ai in E.a_invariants()]) - sage: P = ER.lift_x(12.34) - sage: xP, yP = P.xy() - sage: xP, yP + sage: ER = EllipticCurve([v(ai) for ai in E.a_invariants()]) # optional - sage.rings.number_field + sage: P = ER.lift_x(12.34) # optional - sage.rings.number_field + sage: xP, yP = P.xy() # optional - sage.rings.number_field + sage: xP, yP # optional - sage.rings.number_field (12.3400000000000, 43.3628968710567) - sage: L.e_log_RC(xP, yP) + sage: L.e_log_RC(xP, yP) # optional - sage.rings.number_field 3.76298229503967 - sage: xP, yP = ER.lift_x(0).xy() - sage: L.e_log_RC(xP, yP) + sage: xP, yP = ER.lift_x(0).xy() # optional - sage.rings.number_field + sage: L.e_log_RC(xP, yP) # optional - sage.rings.number_field 2.69842609082114 Elliptic logs of complex points:: - sage: v = K.complex_embeddings()[0] - sage: L = E.period_lattice(v) - sage: P = E.lift_x(1/3*a^2 + a + 5/3) - sage: L(P) + sage: v = K.complex_embeddings()[0] # optional - sage.rings.number_field + sage: L = E.period_lattice(v) # optional - sage.rings.number_field + sage: P = E.lift_x(1/3*a^2 + a + 5/3) # optional - sage.rings.number_field + sage: L(P) # optional - sage.rings.number_field 1.68207104397706 - 1.87873661686704*I - sage: xP, yP = [v(c) for c in P.xy()] - sage: L.e_log_RC(xP, yP) + sage: xP, yP = [v(c) for c in P.xy()] # optional - sage.rings.number_field + sage: L.e_log_RC(xP, yP) # optional - sage.rings.number_field 1.68207104397706 - 1.87873661686704*I - sage: EC = EllipticCurve([v(ai) for ai in E.a_invariants()]) - sage: xP, yP = EC.lift_x(0).xy() - sage: L.e_log_RC(xP, yP) + sage: EC = EllipticCurve([v(ai) for ai in E.a_invariants()]) # optional - sage.rings.number_field + sage: xP, yP = EC.lift_x(0).xy() # optional - sage.rings.number_field + sage: L.e_log_RC(xP, yP) # optional - sage.rings.number_field 1.03355715602040 - 0.867257428417356*I """ if prec is None: @@ -1539,32 +1556,34 @@ def elliptic_logarithm(self, P, prec=None, reduce=True): An example where precision is problematic:: - sage: E = EllipticCurve([1, 0, 1, -85357462, 303528987048]) #18074g1 + sage: E = EllipticCurve([1, 0, 1, -85357462, 303528987048]) #18074g1 sage: P = E([4458713781401/835903744, -64466909836503771/24167649046528, 1]) sage: L = E.period_lattice() sage: L.ei() - [5334.003952567705? - 1.964393150436?e-6*I, 5334.003952567705? + 1.964393150436?e-6*I, -10668.25790513541?] + [5334.003952567705? - 1.964393150436?e-6*I, + 5334.003952567705? + 1.964393150436?e-6*I, + -10668.25790513541?] sage: L.elliptic_logarithm(P,prec=100) 0.27656204014107061464076203097 Some complex examples, taken from the paper by Cremona and Thongjunthug:: - sage: K. = QuadraticField(-1) - sage: a4 = 9*i-10 - sage: a6 = 21-i - sage: E = EllipticCurve([0,0,0,a4,a6]) - sage: e1 = 3-2*i; e2 = 1+i; e3 = -4+i - sage: emb = K.embeddings(CC)[1] - sage: L = E.period_lattice(emb) - sage: P = E(2-i,4+2*i) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: a4 = 9*i - 10 # optional - sage.rings.number_field + sage: a6 = 21 - i # optional - sage.rings.number_field + sage: E = EllipticCurve([0,0,0,a4,a6]) # optional - sage.rings.number_field + sage: e1 = 3 - 2*i; e2 = 1 + i; e3 = -4 + i # optional - sage.rings.number_field + sage: emb = K.embeddings(CC)[1] # optional - sage.rings.number_field + sage: L = E.period_lattice(emb) # optional - sage.rings.number_field + sage: P = E(2 - i, 4 + 2*i) # optional - sage.rings.number_field By default, the output is reduced with respect to the normalised lattice basis, so that its coordinates with respect to that basis lie in the interval [0,1):: - sage: z = L.elliptic_logarithm(P,prec=100); z + sage: z = L.elliptic_logarithm(P, prec=100); z # optional - sage.rings.number_field 0.70448375537782208460499649302 - 0.79246725643650979858266018068*I - sage: L.coordinates(z) + sage: L.coordinates(z) # optional - sage.rings.number_field (0.46247636364807931766105406092, 0.79497588726808704200760395829) Using ``reduce=False`` this step can be omitted. In this case @@ -1572,76 +1591,76 @@ def elliptic_logarithm(self, P, prec=None, reduce=True): this is not guaranteed. This option is mainly for testing purposes:: - sage: z = L.elliptic_logarithm(P,prec=100, reduce=False); z + sage: z = L.elliptic_logarithm(P, prec=100, reduce=False); z # optional - sage.rings.number_field 0.57002153834710752778063503023 + 0.46476340520469798857457031393*I - sage: L.coordinates(z) + sage: L.coordinates(z) # optional - sage.rings.number_field (0.46247636364807931766105406092, -0.20502411273191295799239604171) The elliptic logs of the 2-torsion points are half-periods:: - sage: L.elliptic_logarithm(E(e1,0),prec=100) + sage: L.elliptic_logarithm(E(e1, 0), prec=100) # optional - sage.rings.number_field 0.64607575874356525952487867052 + 0.22379609053909448304176885364*I - sage: L.elliptic_logarithm(E(e2,0),prec=100) + sage: L.elliptic_logarithm(E(e2, 0), prec=100) # optional - sage.rings.number_field 0.71330686725892253793705940192 - 0.40481924028150941053684639367*I - sage: L.elliptic_logarithm(E(e3,0),prec=100) + sage: L.elliptic_logarithm(E(e3, 0), prec=100) # optional - sage.rings.number_field 0.067231108515357278412180731396 - 0.62861533082060389357861524731*I We check this by doubling and seeing that the resulting coordinates are integers:: - sage: L.coordinates(2*L.elliptic_logarithm(E(e1,0),prec=100)) + sage: L.coordinates(2*L.elliptic_logarithm(E(e1, 0), prec=100)) # optional - sage.rings.number_field (1.0000000000000000000000000000, 0.00000000000000000000000000000) - sage: L.coordinates(2*L.elliptic_logarithm(E(e2,0),prec=100)) + sage: L.coordinates(2*L.elliptic_logarithm(E(e2, 0), prec=100)) # optional - sage.rings.number_field (1.0000000000000000000000000000, 1.0000000000000000000000000000) - sage: L.coordinates(2*L.elliptic_logarithm(E(e3,0),prec=100)) + sage: L.coordinates(2*L.elliptic_logarithm(E(e3, 0), prec=100)) # optional - sage.rings.number_field (0.00000000000000000000000000000, 1.0000000000000000000000000000) :: - sage: a4 = -78*i + 104 - sage: a6 = -216*i - 312 - sage: E = EllipticCurve([0,0,0,a4,a6]) - sage: emb = K.embeddings(CC)[1] - sage: L = E.period_lattice(emb) - sage: P = E(3+2*i,14-7*i) - sage: L.elliptic_logarithm(P) + sage: a4 = -78*i + 104 # optional - sage.rings.number_field + sage: a6 = -216*i - 312 # optional - sage.rings.number_field + sage: E = EllipticCurve([0,0,0,a4,a6]) # optional - sage.rings.number_field + sage: emb = K.embeddings(CC)[1] # optional - sage.rings.number_field + sage: L = E.period_lattice(emb) # optional - sage.rings.number_field + sage: P = E(3 + 2*i, 14 - 7*i) # optional - sage.rings.number_field + sage: L.elliptic_logarithm(P) # optional - sage.rings.number_field 0.297147783912228 - 0.546125549639461*I - sage: L.coordinates(L.elliptic_logarithm(P)) + sage: L.coordinates(L.elliptic_logarithm(P)) # optional - sage.rings.number_field (0.628653378040238, 0.371417754610223) - sage: e1 = 1+3*i; e2 = -4-12*i; e3=-e1-e2 - sage: L.coordinates(L.elliptic_logarithm(E(e1,0))) + sage: e1 = 1 + 3*i; e2 = -4 - 12*i; e3 = -e1 - e2 # optional - sage.rings.number_field + sage: L.coordinates(L.elliptic_logarithm(E(e1, 0))) # optional - sage.rings.number_field (0.500000000000000, 0.500000000000000) - sage: L.coordinates(L.elliptic_logarithm(E(e2,0))) + sage: L.coordinates(L.elliptic_logarithm(E(e2, 0))) # optional - sage.rings.number_field (1.00000000000000, 0.500000000000000) - sage: L.coordinates(L.elliptic_logarithm(E(e3,0))) + sage: L.coordinates(L.elliptic_logarithm(E(e3, 0))) # optional - sage.rings.number_field (0.500000000000000, 0.000000000000000) TESTS: See :trac:`10026` and :trac:`11767`:: - sage: K. = QuadraticField(2) - sage: E = EllipticCurve([ 0, -1, 1, -3*w -4, 3*w + 4 ]) - sage: T = E.simon_two_descent(lim1=20,lim3=5,limtriv=20) - sage: P,Q = T[2] - sage: embs = K.embeddings(CC) - sage: Lambda = E.period_lattice(embs[0]) - sage: Lambda.elliptic_logarithm(P, 100) + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: E = EllipticCurve([0, -1, 1, -3*w - 4, 3*w + 4]) # optional - sage.rings.number_field + sage: T = E.simon_two_descent(lim1=20, lim3=5, limtriv=20) # optional - sage.rings.number_field + sage: P, Q = T[2] # optional - sage.rings.number_field + sage: embs = K.embeddings(CC) # optional - sage.rings.number_field + sage: Lambda = E.period_lattice(embs[0]) # optional - sage.rings.number_field + sage: Lambda.elliptic_logarithm(P, 100) # optional - sage.rings.number_field 4.7100131126199672766973600998 sage: R. = QQ[] - sage: K. = NumberField(x^2 + x + 5) - sage: E = EllipticCurve(K, [0,0,1,-3,-5]) - sage: P = E([0,a]) - sage: Lambda = P.curve().period_lattice(K.embeddings(ComplexField(600))[0]) - sage: Lambda.elliptic_logarithm(P, prec=600) + sage: K. = NumberField(x^2 + x + 5) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,0,1,-3,-5]) # optional - sage.rings.number_field + sage: P = E([0,a]) # optional - sage.rings.number_field + sage: Lambda = P.curve().period_lattice(K.embeddings(ComplexField(600))[0]) # optional - sage.rings.number_field + sage: Lambda.elliptic_logarithm(P, prec=600) # optional - sage.rings.number_field -0.842248166487739393375018008381693990800588864069506187033873183845246233548058477561706400464057832396643843146464236956684557207157300006542470428493573195030603817094900751609464 - 0.571366031453267388121279381354098224265947866751130917440598461117775339240176310729173301979590106474259885638797913383502735083088736326391919063211421189027226502851390118943491*I - sage: K. = QuadraticField(-5) - sage: E = EllipticCurve([1,1,a,a,0]) - sage: P = E(0,0) - sage: L = P.curve().period_lattice(K.embeddings(ComplexField())[0]) - sage: L.elliptic_logarithm(P, prec=500) + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: E = EllipticCurve([1,1,a,a,0]) # optional - sage.rings.number_field + sage: P = E(0, 0) # optional - sage.rings.number_field + sage: L = P.curve().period_lattice(K.embeddings(ComplexField())[0]) # optional - sage.rings.number_field + sage: L.elliptic_logarithm(P, prec=500) # optional - sage.rings.number_field 1.17058357737548897849026170185581196033579563441850967539191867385734983296504066660506637438866628981886518901958717288150400849746892393771983141354 - 1.13513899565966043682474529757126359416758251309237866586896869548539516543734207347695898664875799307727928332953834601460994992792519799260968053875*I - sage: L.elliptic_logarithm(P, prec=1000) + sage: L.elliptic_logarithm(P, prec=1000) # optional - sage.rings.number_field 1.17058357737548897849026170185581196033579563441850967539191867385734983296504066660506637438866628981886518901958717288150400849746892393771983141354014895386251320571643977497740116710952913769943240797618468987304985625823413440999754037939123032233879499904283600304184828809773650066658885672885 - 1.13513899565966043682474529757126359416758251309237866586896869548539516543734207347695898664875799307727928332953834601460994992792519799260968053875387282656993476491590607092182964878750169490985439873220720963653658829712494879003124071110818175013453207439440032582917366703476398880865439217473*I """ if not P.curve() is self.E: @@ -1693,62 +1712,76 @@ def elliptic_exponential(self, z, to_curve=True): EXAMPLES:: sage: E = EllipticCurve([1,1,1,-8,6]) - sage: P = E(1,-2) + sage: P = E(1, -2) sage: L = E.period_lattice() sage: z = L(P); z 1.17044757240090 sage: L.elliptic_exponential(z) (0.999999999999999 : -2.00000000000000 : 1.00000000000000) sage: _.curve() - Elliptic Curve defined by y^2 + 1.00000000000000*x*y + 1.00000000000000*y = x^3 + 1.00000000000000*x^2 - 8.00000000000000*x + 6.00000000000000 over Real Field with 53 bits of precision + Elliptic Curve defined by y^2 + 1.00000000000000*x*y + 1.00000000000000*y + = x^3 + 1.00000000000000*x^2 - 8.00000000000000*x + 6.00000000000000 + over Real Field with 53 bits of precision sage: L.elliptic_exponential(z,to_curve=False) (1.41666666666667, -2.00000000000000) - sage: z = L(P,prec=201); z + sage: z = L(P, prec=201); z 1.17044757240089592298992188482371493504472561677451007994189 sage: L.elliptic_exponential(z) - (1.00000000000000000000000000000000000000000000000000000000000 : -2.00000000000000000000000000000000000000000000000000000000000 : 1.00000000000000000000000000000000000000000000000000000000000) + (1.00000000000000000000000000000000000000000000000000000000000 + : -2.00000000000000000000000000000000000000000000000000000000000 + : 1.00000000000000000000000000000000000000000000000000000000000) Examples over number fields:: sage: x = polygen(QQ) - sage: K. = NumberField(x^3-2) - sage: embs = K.embeddings(CC) - sage: E = EllipticCurve('37a') - sage: EK = E.change_ring(K) - sage: Li = [EK.period_lattice(e) for e in embs] - sage: P = EK(-1,-1) - sage: Q = EK(a-1,1-a^2) - sage: zi = [L.elliptic_logarithm(P) for L in Li] - sage: [c.real() for c in Li[0].elliptic_exponential(zi[0])] + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: embs = K.embeddings(CC) # optional - sage.rings.number_field + sage: E = EllipticCurve('37a') # optional - sage.rings.number_field + sage: EK = E.change_ring(K) # optional - sage.rings.number_field + sage: Li = [EK.period_lattice(e) for e in embs] # optional - sage.rings.number_field + sage: P = EK(-1, -1) # optional - sage.rings.number_field + sage: Q = EK(a - 1, 1 - a^2) # optional - sage.rings.number_field + sage: zi = [L.elliptic_logarithm(P) for L in Li] # optional - sage.rings.number_field + sage: [c.real() for c in Li[0].elliptic_exponential(zi[0])] # optional - sage.rings.number_field [-1.00000000000000, -1.00000000000000, 1.00000000000000] - sage: [c.real() for c in Li[0].elliptic_exponential(zi[1])] + sage: [c.real() for c in Li[0].elliptic_exponential(zi[1])] # optional - sage.rings.number_field [-1.00000000000000, -1.00000000000000, 1.00000000000000] - sage: [c.real() for c in Li[0].elliptic_exponential(zi[2])] + sage: [c.real() for c in Li[0].elliptic_exponential(zi[2])] # optional - sage.rings.number_field [-1.00000000000000, -1.00000000000000, 1.00000000000000] - sage: zi = [L.elliptic_logarithm(Q) for L in Li] - sage: Li[0].elliptic_exponential(zi[0]) - (-1.62996052494744 - 1.09112363597172*I : 1.79370052598410 - 1.37472963699860*I : 1.00000000000000) - sage: [embs[0](c) for c in Q] - [-1.62996052494744 - 1.09112363597172*I, 1.79370052598410 - 1.37472963699860*I, 1.00000000000000] - sage: Li[1].elliptic_exponential(zi[1]) - (-1.62996052494744 + 1.09112363597172*I : 1.79370052598410 + 1.37472963699860*I : 1.00000000000000) - sage: [embs[1](c) for c in Q] - [-1.62996052494744 + 1.09112363597172*I, 1.79370052598410 + 1.37472963699860*I, 1.00000000000000] - sage: [c.real() for c in Li[2].elliptic_exponential(zi[2])] + sage: zi = [L.elliptic_logarithm(Q) for L in Li] # optional - sage.rings.number_field + sage: Li[0].elliptic_exponential(zi[0]) # optional - sage.rings.number_field + (-1.62996052494744 - 1.09112363597172*I + : 1.79370052598410 - 1.37472963699860*I + : 1.00000000000000) + sage: [embs[0](c) for c in Q] # optional - sage.rings.number_field + [-1.62996052494744 - 1.09112363597172*I, + 1.79370052598410 - 1.37472963699860*I, + 1.00000000000000] + sage: Li[1].elliptic_exponential(zi[1]) # optional - sage.rings.number_field + (-1.62996052494744 + 1.09112363597172*I + : 1.79370052598410 + 1.37472963699860*I + : 1.00000000000000) + sage: [embs[1](c) for c in Q] # optional - sage.rings.number_field + [-1.62996052494744 + 1.09112363597172*I, + 1.79370052598410 + 1.37472963699860*I, + 1.00000000000000] + sage: [c.real() for c in Li[2].elliptic_exponential(zi[2])] # optional - sage.rings.number_field [0.259921049894873, -0.587401051968199, 1.00000000000000] - sage: [embs[2](c) for c in Q] + sage: [embs[2](c) for c in Q] # optional - sage.rings.number_field [0.259921049894873, -0.587401051968200, 1.00000000000000] Test to show that :trac:`8820` is fixed:: sage: E = EllipticCurve('37a') - sage: K. = QuadraticField(-5) - sage: L = E.change_ring(K).period_lattice(K.places()[0]) - sage: L.elliptic_exponential(CDF(.1,.1)) - (0.0000142854026029... - 49.9960001066650*I : 249.520141250950 + 250.019855549131*I : 1.00000000000000) - sage: L.elliptic_exponential(CDF(.1,.1), to_curve=False) - (0.0000142854026029447 - 49.9960001066650*I, 500.040282501900 + 500.039711098263*I) + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: L = E.change_ring(K).period_lattice(K.places()[0]) # optional - sage.rings.number_field + sage: L.elliptic_exponential(CDF(.1,.1)) # optional - sage.rings.number_field + (0.0000142854026029... - 49.9960001066650*I + : 249.520141250950 + 250.019855549131*I : 1.00000000000000) + sage: L.elliptic_exponential(CDF(.1,.1), to_curve=False) # optional - sage.rings.number_field + (0.0000142854026029447 - 49.9960001066650*I, + 500.040282501900 + 500.039711098263*I) `z=0` is treated as a special case:: @@ -1762,19 +1795,21 @@ def elliptic_exponential(self, z, to_curve=True): :: sage: E = EllipticCurve('37a') - sage: K. = QuadraticField(-5) - sage: L = E.change_ring(K).period_lattice(K.places()[0]) - sage: P = L.elliptic_exponential(0); P + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: L = E.change_ring(K).period_lattice(K.places()[0]) # optional - sage.rings.number_field + sage: P = L.elliptic_exponential(0); P # optional - sage.rings.number_field (0.000000000000000 : 1.00000000000000 : 0.000000000000000) - sage: P.parent() - Abelian group of points on Elliptic Curve defined by y^2 + 1.00000000000000*y = x^3 + (-1.00000000000000)*x over Complex Field with 53 bits of precision + sage: P.parent() # optional - sage.rings.number_field + Abelian group of points on Elliptic Curve defined by + y^2 + 1.00000000000000*y = x^3 + (-1.00000000000000)*x + over Complex Field with 53 bits of precision Very small `z` are handled properly (see :trac:`8820`):: - sage: K. = QuadraticField(-1) - sage: E = EllipticCurve([0,0,0,a,0]) - sage: L = E.period_lattice(K.complex_embeddings()[0]) - sage: L.elliptic_exponential(1e-100) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: E = EllipticCurve([0,0,0,a,0]) # optional - sage.rings.number_field + sage: L = E.period_lattice(K.complex_embeddings()[0]) # optional - sage.rings.number_field + sage: L.elliptic_exponential(1e-100) # optional - sage.rings.number_field (0.000000000000000 : 1.00000000000000 : 0.000000000000000) The elliptic exponential of `z` is returned as (0 : 1 : 0) if @@ -1783,9 +1818,9 @@ def elliptic_exponential(self, z, to_curve=True): sage: (100/log(2.0,10))/0.8 415.241011860920 - sage: L.elliptic_exponential((RealField(415)(1e-100))).is_zero() + sage: L.elliptic_exponential((RealField(415)(1e-100))).is_zero() # optional - sage.rings.number_field True - sage: L.elliptic_exponential((RealField(420)(1e-100))).is_zero() + sage: L.elliptic_exponential((RealField(420)(1e-100))).is_zero() # optional - sage.rings.number_field False """ C = z.parent() @@ -1862,10 +1897,10 @@ def reduce_tau(tau): (tuple) `(\tau',[a,b,c,d])` where `a,b,c,d` are integers such that - - `ad-bc=1`; - - `\tau`=(a\tau+b)/(c\tau+d)`; - - `|\tau'|\ge1`; - - `|\Re(\tau')|\le\frac{1}{2}`. + - `ad-bc=1`; + - `\tau'=(a\tau+b)/(c\tau+d)`; + - `|\tau'|\ge1`; + - `|\Re(\tau')|\le\frac{1}{2}`. EXAMPLES:: @@ -1909,10 +1944,10 @@ def normalise_periods(w1, w2): (tuple) `((\omega_1',\omega_2'),[a,b,c,d])` where `a,b,c,d` are integers such that - - `ad-bc=\pm1`; - - `(\omega_1',\omega_2') = (a\omega_1+b\omega_2,c\omega_1+d\omega_2)`; - - `\tau=\omega_1'/\omega_2'` is in the upper half plane; - - `|\tau|\ge1` and `|\Re(\tau)|\le\frac{1}{2}`. + - `ad-bc=\pm1`; + - `(\omega_1',\omega_2') = (a\omega_1+b\omega_2,c\omega_1+d\omega_2)`; + - `\tau=\omega_1'/\omega_2'` is in the upper half plane; + - `|\tau|\ge1` and `|\Re(\tau)|\le\frac{1}{2}`. EXAMPLES:: @@ -1921,7 +1956,7 @@ def normalise_periods(w1, w2): sage: w2 = CC(1.234, 3.456000001) sage: w1/w2 # in lower half plane! 0.999999999743367 - 9.16334785827644e-11*I - sage: w1w2, abcd = normalise_periods(w1,w2) + sage: w1w2, abcd = normalise_periods(w1, w2) sage: a,b,c,d = abcd sage: w1w2 == (a*w1+b*w2, c*w1+d*w2) True @@ -1958,12 +1993,12 @@ def extended_agm_iteration(a, b, c): EXAMPLES:: sage: from sage.schemes.elliptic_curves.period_lattice import extended_agm_iteration - sage: extended_agm_iteration(RR(1),RR(2),RR(3)) + sage: extended_agm_iteration(RR(1), RR(2), RR(3)) (1.45679103104691, 1.45679103104691, 3.21245294970054) - sage: extended_agm_iteration(CC(1,2),CC(2,3),CC(3,4)) + sage: extended_agm_iteration(CC(1,2), CC(2,3), CC(3,4)) (1.46242448156430 + 2.47791311676267*I, - 1.46242448156430 + 2.47791311676267*I, - 3.22202144343535 + 4.28383734262540*I) + 1.46242448156430 + 2.47791311676267*I, + 3.22202144343535 + 4.28383734262540*I) TESTS:: diff --git a/src/sage/schemes/elliptic_curves/saturation.py b/src/sage/schemes/elliptic_curves/saturation.py index 57367c515d4..dfd104df210 100644 --- a/src/sage/schemes/elliptic_curves/saturation.py +++ b/src/sage/schemes/elliptic_curves/saturation.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.rings.finite_rings sage.rings.number_field r""" Saturation of Mordell-Weil groups of elliptic curves over number fields @@ -24,7 +24,7 @@ already `p`-saturated this sieving technique can prove their saturation quickly. -The method :meth:`saturation` of the class EllipticCurve_number_field +The method :meth:`saturation` of the class :class:`EllipticCurve_number_field` applies full `p`-saturation at any given set of primes, or can compute a bound on the primes `p` at which the given points may not be `p`-saturated. This involves computing a lower bound for the @@ -55,7 +55,7 @@ from sage.arith.misc import kronecker as kro from sage.structure.sage_object import SageObject -def reduce_mod_q(x,amodq): +def reduce_mod_q(x, amodq): r"""The reduction of ``x`` modulo the prime ideal defined by ``amodq``. INPUT: @@ -64,7 +64,7 @@ def reduce_mod_q(x,amodq): - ``amodq`` -- an element of `GF(q)` which is a root mod `q` of the defining polynomial of `K`. This defines a degree 1 prime - ideal `Q=(q,\alpha-a)` of `K=\QQ(\alpha)`, where `a \mod q = ` + ideal `Q=(q,\alpha-a)` of `K=\QQ(\alpha)`, where `a \bmod q` = ``amodq``. OUTPUT: @@ -75,15 +75,15 @@ def reduce_mod_q(x,amodq): sage: from sage.schemes.elliptic_curves.saturation import reduce_mod_q sage: x = polygen(QQ) - sage: pol = x^3 -x^2 -3*x + 1 + sage: pol = x^3 - x^2 - 3*x + 1 sage: K. = NumberField(pol) - sage: [(q,[(amodq,reduce_mod_q(1-a+a^4,amodq)) - ....: for amodq in sorted(pol.roots(GF(q), multiplicities=False))]) - ....: for q in primes(50,70)] + sage: [(q, [(amodq, reduce_mod_q(1 - a + a^4, amodq)) + ....: for amodq in sorted(pol.roots(GF(q), multiplicities=False))]) + ....: for q in primes(50, 70)] [(53, []), - (59, [(36, 28)]), - (61, [(40, 35)]), - (67, [(10, 8), (62, 28), (63, 60)])] + (59, [(36, 28)]), + (61, [(40, 35)]), + (67, [(10, 8), (62, 28), (63, 60)])] """ Fq = amodq.parent() try: @@ -138,12 +138,13 @@ def __init__(self, E, verbose=False): # and gens are generators of that reduction. def add_reductions(self, q): - r"""Add reduction data at primes above q if not already there. + r""" + Add reduction data at primes above ``q`` if not already there. INPUT: - ``q`` -- a prime number not dividing the defining polynomial - of self.__field. + of ``self.__field``. OUTPUT: @@ -165,8 +166,8 @@ def add_reductions(self, q): {} sage: saturator.add_reductions(19) sage: saturator._reductions - {19: {0: (20, - Elliptic Curve defined by y^2 + y = x^3 + 18*x^2 + 9*x + 18 over Finite Field of size 19)}} + {19: {0: (20, Elliptic Curve defined by y^2 + y = x^3 + 18*x^2 + 9*x + 18 + over Finite Field of size 19)}} Over a number field:: @@ -177,23 +178,23 @@ def add_reductions(self, q): sage: for q in primes(20): ....: saturator.add_reductions(q) sage: saturator._reductions - {2: {}, - 3: {}, - 5: {}, - 7: {}, - 11: {3: (16, - Elliptic Curve defined by y^2 = x^3 + x^2 + 3*x + 3 over Finite Field of size 11), - 8: (8, - Elliptic Curve defined by y^2 = x^3 + x^2 + 8*x + 8 over Finite Field of size 11)}, - 13: {}, - 17: {7: (20, - Elliptic Curve defined by y^2 = x^3 + x^2 + 7*x + 7 over Finite Field of size 17), - 10: (18, - Elliptic Curve defined by y^2 = x^3 + x^2 + 10*x + 10 over Finite Field of size 17)}, - 19: {6: (16, - Elliptic Curve defined by y^2 = x^3 + x^2 + 6*x + 6 over Finite Field of size 19), - 13: (12, - Elliptic Curve defined by y^2 = x^3 + x^2 + 13*x + 13 over Finite Field of size 19)}} + {2: {}, + 3: {}, + 5: {}, + 7: {}, + 11: {3: (16, Elliptic Curve defined by y^2 = x^3 + x^2 + 3*x + 3 + over Finite Field of size 11), + 8: (8, Elliptic Curve defined by y^2 = x^3 + x^2 + 8*x + 8 + over Finite Field of size 11)}, + 13: {}, + 17: {7: (20, Elliptic Curve defined by y^2 = x^3 + x^2 + 7*x + 7 + over Finite Field of size 17), + 10: (18, Elliptic Curve defined by y^2 = x^3 + x^2 + 10*x + 10 + over Finite Field of size 17)}, + 19: {6: (16, Elliptic Curve defined by y^2 = x^3 + x^2 + 6*x + 6 + over Finite Field of size 19), + 13: (12, Elliptic Curve defined by y^2 = x^3 + x^2 + 13*x + 13 + over Finite Field of size 19)}} """ if q in self._reductions: return @@ -228,17 +229,17 @@ def full_p_saturation(self, Plist, p): sage: E = EllipticCurve('389a') sage: K. = QuadraticField(-1) sage: EK = E.change_ring(K) - sage: P = EK(1+i,-1-2*i) + sage: P = EK(1 + i, -1 - 2*i) sage: saturator = EllipticCurveSaturator(EK, verbose=True) - sage: saturator.full_p_saturation([8*P],2) + sage: saturator.full_p_saturation([8*P], 2) --starting full 2-saturation Points were not 2-saturated, exponent was 3 ([(i + 1 : -2*i - 1 : 1)], 3) - sage: Q = EK(0,0) - sage: R = EK(-1,1) + sage: Q = EK(0, 0) + sage: R = EK(-1, 1) sage: saturator = EllipticCurveSaturator(EK, verbose=False) - sage: saturator.full_p_saturation([P,Q,R],3) + sage: saturator.full_p_saturation([P, Q, R], 3) ([(i + 1 : -2*i - 1 : 1), (0 : 0 : 1), (-1 : 1 : 1)], 0) An example where the points are not 7-saturated and we gain @@ -247,11 +248,10 @@ def full_p_saturation(self, Plist, p): `p`-rank 2 (which occurs for the reduction modulo `(16-5i)`), which uses the Weil pairing:: - sage: saturator.full_p_saturation([P,Q+3*R,Q-4*R],7) + sage: saturator.full_p_saturation([P, Q + 3*R, Q - 4*R], 7) ([(i + 1 : -2*i - 1 : 1), - (2869/676 : 154413/17576 : 1), - (-7095/502681 : -366258864/356400829 : 1)], - 1) + (2869/676 : 154413/17576 : 1), + (-7095/502681 : -366258864/356400829 : 1)], 1) """ if not Plist: return Plist, ZZ.zero() @@ -328,23 +328,23 @@ def p_saturation(self, Plist, p, sieve=True): sage: E = EllipticCurve('389a') sage: K. = QuadraticField(-1) sage: EK = E.change_ring(K) - sage: P = EK(1+i,-1-2*i) + sage: P = EK(1 + i, -1 - 2*i) sage: saturator = EllipticCurveSaturator(EK) - sage: saturator.p_saturation([P],2) + sage: saturator.p_saturation([P], 2) False - sage: saturator.p_saturation([2*P],2) + sage: saturator.p_saturation([2*P], 2) (0, (i + 1 : -2*i - 1 : 1)) - sage: Q = EK(0,0) - sage: R = EK(-1,1) - sage: saturator.p_saturation([P,Q,R],3) + sage: Q = EK(0, 0) + sage: R = EK(-1, 1) + sage: saturator.p_saturation([P, Q, R], 3) False Here we see an example where 19-saturation is proved, with the verbose flag set to True so that we can see what is going on:: sage: saturator = EllipticCurveSaturator(EK, verbose=True) - sage: saturator.p_saturation([P,Q,R],19) + sage: saturator.p_saturation([P, Q, R], 19) Using sieve method to saturate... E has 19-torsion over Finite Field of size 197, projecting points --> [(15 : 168 : 1), (0 : 0 : 1), (196 : 1 : 1)] @@ -361,27 +361,27 @@ def p_saturation(self, Plist, p, sieve=True): An example where the points are not 11-saturated:: sage: saturator = EllipticCurveSaturator(EK, verbose=False) - sage: res = saturator.p_saturation([P+5*Q,P-6*Q,R],11); res - (0, - (-5783311/14600041*i + 1396143/14600041 : 37679338314/55786756661*i + 3813624227/55786756661 : 1)) + sage: res = saturator.p_saturation([P + 5*Q, P - 6*Q, R], 11); res + (0, (-5783311/14600041*i + 1396143/14600041 + : 37679338314/55786756661*i + 3813624227/55786756661 : 1)) That means that the 0'th point may be replaced by the displayed point to achieve an index gain of 11:: - sage: saturator.p_saturation([res[1],P-6*Q,R],11) + sage: saturator.p_saturation([res[1], P - 6*Q, R], 11) False TESTS: See :trac:`27387`:: - sage: K. = NumberField(x^2-x-26) - sage: E = EllipticCurve([a,1-a,0,93-16*a, 3150-560*a]) - sage: P = E([65-35*a/3, (959*a-5377)/9]) + sage: K. = NumberField(x^2 - x - 26) + sage: E = EllipticCurve([a, 1 - a, 0, 93 - 16*a, 3150 - 560*a]) + sage: P = E([65 - 35*a/3, (959*a-5377)/9]) sage: T = E.torsion_points()[0] sage: from sage.schemes.elliptic_curves.saturation import EllipticCurveSaturator sage: saturator = EllipticCurveSaturator(E, True) - sage: saturator.p_saturation([P,T], 2) + sage: saturator.p_saturation([P, T], 2) Using sieve method to saturate... ... -- points were not 2-saturated, gaining index 2 @@ -390,7 +390,7 @@ def p_saturation(self, Plist, p, sieve=True): A CM example where large siecing primes are needed (LMFDB label 2.0.3.1-50625.1-CMb2):: - sage: K. = NumberField(x^2-x+1) + sage: K. = NumberField(x^2 - x + 1) sage: E = EllipticCurve(K, [0, 0, 1, -750, 7906]) sage: E.has_rational_cm() True @@ -593,11 +593,11 @@ def p_projections(Eq, Plist, p, debug=False): INPUT: - - `Eq` -- An elliptic curve over a finite field. + - ``Eq`` -- An elliptic curve over a finite field. - - `Plist` -- a list of points on `Eq`. + - ``Plist`` -- a list of points on `Eq`. - - `p` -- a prime number. + - ``p`` -- a prime number. OUTPUT: @@ -626,7 +626,9 @@ def p_projections(Eq, Plist, p, debug=False): sage: EF = E.change_ring(F) sage: G = EF.abelian_group() sage: G - Additive abelian group isomorphic to Z/147 + Z/3 embedded in Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 + 402*x + 6 over Finite Field of size 409 + Additive abelian group isomorphic to Z/147 + Z/3 + embedded in Abelian group of points on Elliptic Curve + defined by y^2 + y = x^3 + 402*x + 6 over Finite Field of size 409 sage: G.order().factor() 3^2 * 7^2 @@ -637,9 +639,9 @@ def p_projections(Eq, Plist, p, debug=False): sage: Plist = [EF([-2,3]), EF([0,2]), EF([1,0])] sage: from sage.schemes.elliptic_curves.saturation import p_projections - sage: [(p,p_projections(EF,Plist,p)) for p in primes(11)] # random + sage: [(p, p_projections(EF, Plist, p)) for p in primes(11)] # random [(2, []), (3, [(0, 2, 2), (2, 2, 1)]), (5, []), (7, [(5, 1, 1)])] - sage: [(p,len(p_projections(EF,Plist,p))) for p in primes(11)] + sage: [(p, len(p_projections(EF, Plist, p))) for p in primes(11)] [(2, 0), (3, 2), (5, 0), (7, 1)] """ if debug: diff --git a/src/sage/schemes/elliptic_curves/sha_tate.py b/src/sage/schemes/elliptic_curves/sha_tate.py index 1e4fe251ff6..33818051b8f 100644 --- a/src/sage/schemes/elliptic_curves/sha_tate.py +++ b/src/sage/schemes/elliptic_curves/sha_tate.py @@ -50,7 +50,8 @@ sage: E = EllipticCurve('389a') sage: S = E.sha(); S - Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field + Tate-Shafarevich group for the + Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field sage: S.an_numerical() 1.00000000000000 sage: S.p_primary_bound(5) @@ -124,7 +125,8 @@ class Sha(SageObject): sage: E = EllipticCurve('389a') sage: S = E.sha(); S - Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field + Tate-Shafarevich group for the + Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field sage: S.an_numerical() 1.00000000000000 sage: S.p_primary_bound(5) # long time @@ -147,7 +149,8 @@ def __init__(self, E): sage: E = EllipticCurve('11a1') sage: S = E.sha() sage: S - Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + Tate-Shafarevich group for the + Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: S == loads(dumps(S)) True @@ -260,11 +263,11 @@ def an_numerical(self, prec=None, sage: sha = EllipticCurve('37a1').sha() sage: [sha.an_numerical(prec) for prec in range(40,100,10)] # long time (3s on sage.math, 2013) [1.0000000000, - 1.0000000000000, - 1.0000000000000000, - 1.0000000000000000000, - 1.0000000000000000000000, - 1.0000000000000000000000000] + 1.0000000000000, + 1.0000000000000000, + 1.0000000000000000000, + 1.0000000000000000000000, + 1.0000000000000000000000000] """ if prec is None: prec = RealField().precision() @@ -324,8 +327,9 @@ def an(self, use_database=False, descent_second_limit=12): sage: E.sha().an() Traceback (most recent call last): ... - RuntimeError: Unable to compute the rank, hence generators, with certainty (lower bound=0, generators found=[]). This could be because Sha(E/Q)[2] is nontrivial. - Try increasing descent_second_limit then trying this command again. + RuntimeError: Unable to compute the rank, hence generators, with certainty + (lower bound=0, generators found=[]). This could be because Sha(E/Q)[2] is + nontrivial. Try increasing descent_second_limit then trying this command again. You can increase the ``descent_second_limit`` (in the above example, set to the default, 12) option to try again:: @@ -388,14 +392,14 @@ def an(self, use_database=False, descent_second_limit=12): In this case the input curve is not minimal, and if this function did not transform it to be minimal, it would give nonsense:: - sage: E = EllipticCurve([0,-432*6^2]) + sage: E = EllipticCurve([0, -432*6^2]) sage: E.sha().an() 1 See :trac:`10096`: this used to give the wrong result 6.0000 before since the minimal model was not used:: - sage: E = EllipticCurve([1215*1216,0]) # non-minimal model + sage: E = EllipticCurve([1215*1216, 0]) # non-minimal model sage: E.sha().an() # long time (2s on sage.math, 2011) 1.00000000000000 sage: E.minimal_model().sha().an() # long time (1s on sage.math, 2011) @@ -523,7 +527,7 @@ def an_padic(self, p, prec=0, use_twists=True): 1 + O(5) sage: EllipticCurve('240d3').sha().an_padic(5) # sha has 4 elements here 4 + O(5) - sage: EllipticCurve('448c5').sha().an_padic(7,prec=4, use_twists=False) # long time (2s on sage.math, 2011) + sage: EllipticCurve('448c5').sha().an_padic(7, prec=4, use_twists=False) # long time (2s on sage.math, 2011) 2 + 7 + O(7^6) sage: EllipticCurve([-19,34]).sha().an_padic(5) # see trac #6455, long time (4s on sage.math, 2011) 1 + O(5) @@ -841,7 +845,9 @@ def p_primary_bound(self, p): sage: E.sha().p_primary_bound(5) Traceback (most recent call last): ... - ValueError: The p-adic Galois representation is not surjective or reducible. Current knowledge about Euler systems does not provide an upper bound in this case. Try an_padic for a conjectural bound. + ValueError: The p-adic Galois representation is not surjective or reducible. + Current knowledge about Euler systems does not provide an upper bound + in this case. Try an_padic for a conjectural bound. sage: E.sha().an_padic(5) # long time 1 + O(5^22) @@ -1075,9 +1081,9 @@ def bound_kato(self): THEOREM: Suppose `L(E,1) \neq 0` and `p \neq 2` is a prime such that - - `E` does not have additive reduction at `p`, - - either the `p`-adic representation is surjective or has its - image contained in a Borel subgroup. + - `E` does not have additive reduction at `p`, + - either the `p`-adic representation is surjective or has its + image contained in a Borel subgroup. Then `{ord}_p(\#Sha(E))` is bounded from above by the `p`-adic valuation of `L(E,1)\cdot\#E(\QQ)_{tor}^2 / (\Omega_E \cdot \prod c_v)`. @@ -1099,15 +1105,15 @@ def bound_kato(self): order of `Sha` (by [GJPST2009]_):: sage: E = EllipticCurve([1, -1, 0, -332311, -73733731]) # 1058D1 - sage: E.sha().bound_kato() # long time (about 1 second) + sage: E.sha().bound_kato() # long time (about 1 second) [2, 5, 23] - sage: E.galois_representation().non_surjective() # long time (about 1 second) + sage: E.galois_representation().non_surjective() # long time (about 1 second) [] For this one, `Sha` is divisible by 7:: sage: E = EllipticCurve([0, 0, 0, -4062871, -3152083138]) # 3364C1 - sage: E.sha().bound_kato() # long time (< 10 seconds) + sage: E.sha().bound_kato() # long time (< 10 seconds) [2, 7, 29] No information about curves of rank > 0:: diff --git a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py index 4db88f1f7f2..91bd26dd30e 100644 --- a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py +++ b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py @@ -379,7 +379,7 @@ class WeierstrassIsomorphism(EllipticCurveHom, baseWI): - ``E`` -- an ``EllipticCurve``, or ``None`` (see below). - ``urst`` -- a 4-tuple `(u,r,s,t)`, a :class:`baseWI` object, - or ``None`` (see below). + or ``None`` (see below). - ``F`` -- an ``EllipticCurve``, or ``None`` (see below). @@ -421,16 +421,16 @@ class WeierstrassIsomorphism(EllipticCurveHom, baseWI): sage: from sage.schemes.elliptic_curves.weierstrass_morphism import * sage: WeierstrassIsomorphism(EllipticCurve([0,1,2,3,4]), (-1,2,3,4)) Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 + 2*y = x^3 + x^2 + 3*x + 4 over Rational Field - To: Elliptic Curve defined by y^2 - 6*x*y - 10*y = x^3 - 2*x^2 - 11*x - 2 over Rational Field - Via: (u,r,s,t) = (-1, 2, 3, 4) + From: Elliptic Curve defined by y^2 + 2*y = x^3 + x^2 + 3*x + 4 over Rational Field + To: Elliptic Curve defined by y^2 - 6*x*y - 10*y = x^3 - 2*x^2 - 11*x - 2 over Rational Field + Via: (u,r,s,t) = (-1, 2, 3, 4) sage: E = EllipticCurve([0,1,2,3,4]) sage: F = EllipticCurve(E.cremona_label()) sage: WeierstrassIsomorphism(E, None, F) Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 + 2*y = x^3 + x^2 + 3*x + 4 over Rational Field - To: Elliptic Curve defined by y^2 = x^3 + x^2 + 3*x + 5 over Rational Field - Via: (u,r,s,t) = (1, 0, 0, -1) + From: Elliptic Curve defined by y^2 + 2*y = x^3 + x^2 + 3*x + 4 over Rational Field + To: Elliptic Curve defined by y^2 = x^3 + x^2 + 3*x + 5 over Rational Field + Via: (u,r,s,t) = (1, 0, 0, -1) sage: w = WeierstrassIsomorphism(None, (1,0,0,-1), F) sage: w._domain == E True @@ -443,10 +443,10 @@ def __init__(self, E=None, urst=None, F=None): Check for :trac:`33215`:: - sage: E = EllipticCurve(GF(71^2),[5,5]) sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: iso = WeierstrassIsomorphism(E, (1,2,3,4)) - sage: ~iso # indirect doctest + sage: E = EllipticCurve(GF(71^2), [5,5]) # optional - sage.rings.finite_rings + sage: iso = WeierstrassIsomorphism(E, (1,2,3,4)) # optional - sage.rings.finite_rings + sage: ~iso # indirect doctest # optional - sage.rings.finite_rings Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + 6*x*y + 8*y = x^3 + 68*x^2 + 64*x + 7 over Finite Field in z2 of size 71^2 To: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field in z2 of size 71^2 @@ -454,8 +454,7 @@ def __init__(self, E=None, urst=None, F=None): Test for :trac:`33312`:: - sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: type(iso.degree()) + sage: type(iso.degree()) # optional - sage.rings.finite_rings """ from .ell_generic import is_EllipticCurve @@ -534,16 +533,16 @@ def _comparison_impl(left, right, op): sage: w1 == w2 False - sage: E = EllipticCurve_from_j(GF(7)(0)) - sage: F = E.change_weierstrass_model(2,3,4,5) - sage: a = E.isomorphisms(F) - sage: b = [w*a[0] for w in F.automorphisms()] - sage: b.sort() - sage: a == b + sage: E = EllipticCurve_from_j(GF(7)(0)) # optional - sage.rings.finite_rings + sage: F = E.change_weierstrass_model(2,3,4,5) # optional - sage.rings.finite_rings + sage: a = E.isomorphisms(F) # optional - sage.rings.finite_rings + sage: b = [w*a[0] for w in F.automorphisms()] # optional - sage.rings.finite_rings + sage: b.sort() # optional - sage.rings.finite_rings + sage: a == b # optional - sage.rings.finite_rings True - sage: c = [a[0]*w for w in E.automorphisms()] - sage: c.sort() - sage: a == c + sage: c = [a[0]*w for w in E.automorphisms()] # optional - sage.rings.finite_rings + sage: c.sort() # optional - sage.rings.finite_rings + sage: a == c # optional - sage.rings.finite_rings True """ if not isinstance(left, WeierstrassIsomorphism) or not isinstance(right, WeierstrassIsomorphism): @@ -589,15 +588,17 @@ def _eval(self, P): EXAMPLES:: sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: E = EllipticCurve([i,0]); E - Elliptic Curve defined by y^2 = x^3 + I*x over Number Field in I with defining polynomial x^2 + 1 with I = 1*I - sage: iso = WeierstrassIsomorphism(E, (i,1,2,3)) - sage: P = E.change_ring(QQbar).lift_x(QQbar.random_element()) - sage: Q = iso._eval(P) - sage: Q.curve() - Elliptic Curve defined by y^2 + (-4*I)*x*y + 6*I*y = x^3 + x^2 + (I-9)*x + (-I+8) over Algebraic Field - sage: y = next(filter(bool, iter(QQbar.random_element, None))) # sample until nonzero - sage: iso._eval((0, y, 0)) == 0 + sage: E = EllipticCurve([i, 0]); E # optional - sage.rings.number_field + Elliptic Curve defined by y^2 = x^3 + I*x + over Number Field in I with defining polynomial x^2 + 1 with I = 1*I + sage: iso = WeierstrassIsomorphism(E, (i,1,2,3)) # optional - sage.rings.number_field + sage: P = E.change_ring(QQbar).lift_x(QQbar.random_element()) # optional - sage.rings.number_field + sage: Q = iso._eval(P) # optional - sage.rings.number_field + sage: Q.curve() # optional - sage.rings.number_field + Elliptic Curve defined by y^2 + (-4*I)*x*y + 6*I*y = x^3 + x^2 + (I-9)*x + (-I+8) + over Algebraic Field + sage: y = next(filter(bool, iter(QQbar.random_element, None))) # sample until nonzero # optional - sage.rings.number_field + sage: iso._eval((0, y, 0)) == 0 # optional - sage.rings.number_field True """ if self._domain.defining_polynomial()(*P): @@ -634,14 +635,14 @@ def __call__(self, P): Check that copying the order over works:: - sage: E = EllipticCurve(GF(431^2), [1,0]) - sage: i = next(a for a in E.automorphisms() if a^2 == -a^24) - sage: P,_ = E.gens() - sage: P._order + sage: E = EllipticCurve(GF(431^2), [1,0]) # optional - sage.rings.finite_rings + sage: i = next(a for a in E.automorphisms() if a^2 == -a^24) # optional - sage.rings.finite_rings + sage: P,_ = E.gens() # optional - sage.rings.finite_rings + sage: P._order # optional - sage.rings.finite_rings 432 - sage: i(P)._order + sage: i(P)._order # optional - sage.rings.finite_rings 432 - sage: E(i(P))._order + sage: E(i(P))._order # optional - sage.rings.finite_rings 432 """ if P[2] == 0: @@ -732,9 +733,9 @@ def __repr__(self): sage: E2 = E1.change_weierstrass_model([2,3,4,5]) sage: E1.isomorphism_to(E2) Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field - To: Elliptic Curve defined by y^2 + 4*x*y + 11/8*y = x^3 - 7/4*x^2 - 3/2*x - 9/32 over Rational Field - Via: (u,r,s,t) = (2, 3, 4, 5) + From: Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field + To: Elliptic Curve defined by y^2 + 4*x*y + 11/8*y = x^3 - 7/4*x^2 - 3/2*x - 9/32 over Rational Field + Via: (u,r,s,t) = (2, 3, 4, 5) """ return EllipticCurveHom.__repr__(self) + "\n Via: (u,r,s,t) = " + baseWI.__repr__(self) @@ -750,8 +751,10 @@ def rational_maps(self): sage: E2 = EllipticCurve_from_j(E1.j_invariant()) sage: iso = E1.isomorphism_to(E2); iso Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 + 11*x*y + 33*y = x^3 + 22*x^2 + 44*x + 55 over Rational Field - To: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 684*x + 6681 over Rational Field + From: Elliptic Curve defined by y^2 + 11*x*y + 33*y = x^3 + 22*x^2 + 44*x + 55 + over Rational Field + To: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 684*x + 6681 + over Rational Field Via: (u,r,s,t) = (1, -17, -5, 77) sage: iso.rational_maps() (x + 17, 5*x + y + 8) @@ -763,11 +766,11 @@ def rational_maps(self): :: - sage: E = EllipticCurve(GF(65537), [1,1,1,1,1]) - sage: w = E.isomorphism_to(E.short_weierstrass_model()) - sage: f,g = w.rational_maps() - sage: P = E.random_point() - sage: w(P).xy() == (f(P.xy()), g(P.xy())) + sage: E = EllipticCurve(GF(65537), [1,1,1,1,1]) # optional - sage.rings.finite_rings + sage: w = E.isomorphism_to(E.short_weierstrass_model()) # optional - sage.rings.finite_rings + sage: f,g = w.rational_maps() # optional - sage.rings.finite_rings + sage: P = E.random_point() # optional - sage.rings.finite_rings + sage: w(P).xy() == (f(P.xy()), g(P.xy())) # optional - sage.rings.finite_rings True TESTS: @@ -791,8 +794,10 @@ def x_rational_map(self): sage: E2 = EllipticCurve_from_j(E1.j_invariant()) sage: iso = E1.isomorphism_to(E2); iso Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 + 11*x*y + 33*y = x^3 + 22*x^2 + 44*x + 55 over Rational Field - To: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 684*x + 6681 over Rational Field + From: Elliptic Curve defined by y^2 + 11*x*y + 33*y = x^3 + 22*x^2 + 44*x + 55 + over Rational Field + To: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 684*x + 6681 + over Rational Field Via: (u,r,s,t) = (1, -17, -5, 77) sage: iso.x_rational_map() x + 17 @@ -824,7 +829,11 @@ def kernel_polynomial(self): sage: iso.kernel_polynomial() 1 sage: psi = E1.isogeny(iso.kernel_polynomial(), codomain=E2); psi - Isogeny of degree 1 from Elliptic Curve defined by y^2 + 11*x*y + 33*y = x^3 + 22*x^2 + 44*x + 55 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 684*x + 6681 over Rational Field + Isogeny of degree 1 + from Elliptic Curve defined by y^2 + 11*x*y + 33*y = x^3 + 22*x^2 + 44*x + 55 + over Rational Field + to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 684*x + 6681 + over Rational Field sage: psi in {iso, -iso} True @@ -844,8 +853,8 @@ def is_separable(self): EXAMPLES:: - sage: E = EllipticCurve(GF(31337), [0,1]) - sage: {f.is_separable() for f in E.automorphisms()} + sage: E = EllipticCurve(GF(31337), [0,1]) # optional - sage.rings.finite_rings + sage: {f.is_separable() for f in E.automorphisms()} # optional - sage.rings.finite_rings {True} """ return True @@ -859,9 +868,9 @@ def dual(self): EXAMPLES:: sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: E = EllipticCurve(QuadraticField(-3), [0,1]) - sage: w = WeierstrassIsomorphism(E, (CyclotomicField(3).gen(),0,0,0)) - sage: (w.dual() * w).rational_maps() + sage: E = EllipticCurve(QuadraticField(-3), [0,1]) # optional - sage.rings.number_field + sage: w = WeierstrassIsomorphism(E, (CyclotomicField(3).gen(),0,0,0)) # optional - sage.rings.number_field + sage: (w.dual() * w).rational_maps() # optional - sage.rings.number_field (x, y) :: @@ -887,7 +896,8 @@ def __neg__(self): sage: -w Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + 11*x*y + 33*y = x^3 + 22*x^2 + 44*x + 55 over Rational Field - To: Elliptic Curve defined by y^2 + 17/6*x*y + 49/13068*y = x^3 - 769/396*x^2 - 3397/862488*x + 44863/7513995456 over Rational Field + To: Elliptic Curve defined by y^2 + 17/6*x*y + 49/13068*y = x^3 - 769/396*x^2 - 3397/862488*x + 44863/7513995456 + over Rational Field Via: (u,r,s,t) = (-66, 77, -99, -979) sage: -(-w) == w True @@ -895,22 +905,22 @@ def __neg__(self): :: sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: K. = QuadraticField(-3) - sage: E = EllipticCurve(K, [0,1]) - sage: w = WeierstrassIsomorphism(E, (CyclotomicField(3).gen(),0,0,0)) - sage: w.tuple() + sage: K. = QuadraticField(-3) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [0,1]) # optional - sage.rings.number_field + sage: w = WeierstrassIsomorphism(E, (CyclotomicField(3).gen(),0,0,0)) # optional - sage.rings.number_field + sage: w.tuple() # optional - sage.rings.number_field (1/2*a - 1/2, 0, 0, 0) - sage: (-w).tuple() + sage: (-w).tuple() # optional - sage.rings.number_field (-1/2*a + 1/2, 0, 0, 0) - sage: (-w)^3 == -(w^3) + sage: (-w)^3 == -(w^3) # optional - sage.rings.number_field True :: sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism, identity_morphism - sage: E = EllipticCurve(QuadraticField(-1), [1,0]) - sage: t = WeierstrassIsomorphism(E, (i,0,0,0)) - sage: -t^2 == identity_morphism(E) + sage: E = EllipticCurve(QuadraticField(-1), [1,0]) # optional - sage.rings.number_field + sage: t = WeierstrassIsomorphism(E, (i,0,0,0)) # optional - sage.rings.number_field + sage: -t^2 == identity_morphism(E) # optional - sage.rings.number_field True """ a1,_,a3,_,_ = self._domain.a_invariants() @@ -931,8 +941,8 @@ def scaling_factor(self): EXAMPLES:: - sage: E = EllipticCurve(QQbar, [0,1]) - sage: all(f.scaling_factor() == f.formal()[1] for f in E.automorphisms()) + sage: E = EllipticCurve(QQbar, [0,1]) # optional - sage.rings.number_field + sage: all(f.scaling_factor() == f.formal()[1] for f in E.automorphisms()) # optional - sage.rings.number_field True ALGORITHM: The scaling factor equals the `u` component of diff --git a/src/sage/schemes/generic/algebraic_scheme.py b/src/sage/schemes/generic/algebraic_scheme.py index 6391bc54eeb..c1434b7c5b4 100644 --- a/src/sage/schemes/generic/algebraic_scheme.py +++ b/src/sage/schemes/generic/algebraic_scheme.py @@ -4,14 +4,14 @@ An algebraic scheme is defined by a set of polynomials in some suitable affine or projective coordinates. Possible ambient spaces are - * Affine spaces (:class:`AffineSpace - `), +* Affine spaces (:class:`AffineSpace + `), - * Projective spaces (:class:`ProjectiveSpace - `), or +* Projective spaces (:class:`ProjectiveSpace + `), or - * Toric varieties (:class:`ToricVariety - `). +* Toric varieties (:class:`ToricVariety + `). Note that while projective spaces are of course toric varieties themselves, they are implemented differently in Sage due to efficiency considerations. @@ -44,9 +44,8 @@ Now we can write polynomial equations in the variables `x` and `y`. For example, one equation cuts out a curve (a one-dimensional subscheme):: - sage: V = A2.subscheme([x^2+y^2-1]); V - Closed subscheme of Affine Space of dimension 2 - over Rational Field defined by: + sage: V = A2.subscheme([x^2 + y^2 - 1]); V + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: x^2 + y^2 - 1 sage: V.dimension() 1 @@ -58,10 +57,8 @@ Defining x0, x1, x2, x3 sage: Q = matrix([[x0, x1, x2], [x1, x2, x3]]).minors(2); Q [-x1^2 + x0*x2, -x1*x2 + x0*x3, -x2^2 + x1*x3] - sage: twisted_cubic = P3.subscheme(Q) - sage: twisted_cubic - Closed subscheme of Projective Space of dimension 3 - over Rational Field defined by: + sage: twisted_cubic = P3.subscheme(Q); twisted_cubic + Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: -x1^2 + x0*x2, -x1*x2 + x0*x3, -x2^2 + x1*x3 @@ -77,25 +74,17 @@ sage: patch = twisted_cubic.affine_patch(0) sage: patch - Closed subscheme of Affine Space of dimension 3 - over Rational Field defined by: + Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: -x1^2 + x2, -x1*x2 + x3, -x2^2 + x1*x3 sage: patch.embedding_morphism() Scheme morphism: - From: Closed subscheme of Affine Space of dimension 3 - over Rational Field defined by: - -x1^2 + x2, - -x1*x2 + x3, - -x2^2 + x1*x3 - To: Closed subscheme of Projective Space of dimension 3 - over Rational Field defined by: - x1^2 - x0*x2, - x1*x2 - x0*x3, - x2^2 - x1*x3 - Defn: Defined on coordinates by sending (x1, x2, x3) to - (1 : x1 : x2 : x3) + From: Closed subscheme of Affine Space of dimension 3 over Rational Field + defined by: -x1^2 + x2, -x1*x2 + x3, -x2^2 + x1*x3 + To: Closed subscheme of Projective Space of dimension 3 over Rational Field + defined by: x1^2 - x0*x2, x1*x2 - x0*x3, x2^2 - x1*x3 + Defn: Defined on coordinates by sending (x1, x2, x3) to (1 : x1 : x2 : x3) AUTHORS: @@ -169,7 +158,7 @@ def is_AlgebraicScheme(x): sage: A2 = AffineSpace(2, QQ, 'x, y') sage: A2.coordinate_ring().inject_variables() Defining x, y - sage: V = A2.subscheme([x^2+y^2]); V + sage: V = A2.subscheme([x^2 + y^2]); V Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: x^2 + y^2 sage: from sage.schemes.generic.algebraic_scheme import is_AlgebraicScheme @@ -193,7 +182,7 @@ def is_AlgebraicScheme(x): sage: A,x = AffineSpace(10, QQ).objgens() sage: X = A.subscheme([sum(x)]); X Closed subscheme of Affine Space of dimension 10 over Rational Field defined by: - x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 sage: is_AlgebraicScheme(X) True @@ -274,14 +263,14 @@ def is_projective(self): EXAMPLES:: - sage: PP. = ProjectiveSpace(3,QQ) + sage: PP. = ProjectiveSpace(3, QQ) sage: f = x^3 + y^3 + z^3 + w^3 sage: R = f.parent() sage: I = [f] + [f.derivative(zz) for zz in PP.gens()] sage: V = PP.subscheme(I) sage: V.is_projective() True - sage: AA. = AffineSpace(4,QQ) + sage: AA. = AffineSpace(4, QQ) sage: V = AA.subscheme(I) sage: V.is_projective() False @@ -310,9 +299,10 @@ def coordinate_ring(self): EXAMPLES:: sage: P. = ProjectiveSpace(2, ZZ) - sage: S = P.subscheme([x-y, x-z]) + sage: S = P.subscheme([x - y, x - z]) sage: S.coordinate_ring() - Quotient of Multivariate Polynomial Ring in x, y, z over Integer Ring by the ideal (x - y, x - z) + Quotient of Multivariate Polynomial Ring in x, y, z over Integer Ring + by the ideal (x - y, x - z) """ try: return self._coordinate_ring @@ -329,13 +319,13 @@ def ambient_space(self): EXAMPLES:: - sage: A. = AffineSpace(2, GF(5)) - sage: S = A.subscheme([]) - sage: S.ambient_space() + sage: A. = AffineSpace(2, GF(5)) # optional - sage.rings.finite_rings + sage: S = A.subscheme([]) # optional - sage.rings.finite_rings + sage: S.ambient_space() # optional - sage.rings.finite_rings Affine Space of dimension 2 over Finite Field of size 5 sage: P. = ProjectiveSpace(2, ZZ) - sage: S = P.subscheme([x-y, x-z]) + sage: S = P.subscheme([x - y, x - z]) sage: S.ambient_space() is P True """ @@ -389,30 +379,27 @@ def embedding_morphism(self): EXAMPLES:: - sage: A2. = AffineSpace(QQ,2) - sage: C = A2.subscheme(x^2+y^2-1) + sage: A2. = AffineSpace(QQ, 2) + sage: C = A2.subscheme(x^2 + y^2 - 1) sage: C.embedding_morphism() Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^2 + y^2 - 1 + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x^2 + y^2 - 1 To: Affine Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (x, y) + Defn: Defined on coordinates by sending (x, y) to (x, y) sage: P1xP1. = toric_varieties.P1xP1() - sage: P1 = P1xP1.subscheme(x-y) + sage: P1 = P1xP1.subscheme(x - y) sage: P1.embedding_morphism() Scheme morphism: - From: Closed subscheme of 2-d CPR-Fano toric variety covered - by 4 affine patches defined by: - x - y - To: 2-d CPR-Fano toric variety covered by 4 affine patches - Defn: Defined on coordinates by sending [x : y : u : v] to - [y : y : u : v] + From: Closed subscheme of 2-d CPR-Fano toric variety covered + by 4 affine patches defined by: x - y + To: 2-d CPR-Fano toric variety covered by 4 affine patches + Defn: Defined on coordinates by sending [x : y : u : v] to [y : y : u : v] So far, the embedding was just in the own ambient space. Now a bit more interesting examples:: - sage: P2. = ProjectiveSpace(QQ,2) + sage: P2. = ProjectiveSpace(QQ, 2) sage: X = P2.subscheme((x^2-y^2)*z) sage: p = (1,1,0) sage: nbhd = X.neighborhood(p) @@ -434,12 +421,11 @@ def embedding_morphism(self): sage: nbhd.embedding_morphism() Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - -y^2*z - 2*y*z - To: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x^2*z - y^2*z - Defn: Defined on coordinates by sending (y, z) to - (1 : y + 1 : z) + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: -y^2*z - 2*y*z + To: Closed subscheme of Projective Space of dimension 2 over Rational Field + defined by: x^2*z - y^2*z + Defn: Defined on coordinates by sending (y, z) to (1 : y + 1 : z) A couple more examples:: @@ -447,24 +433,20 @@ def embedding_morphism(self): sage: patch1 2-d affine toric variety sage: patch1.embedding_morphism() - Scheme morphism: + Scheme morphism: From: 2-d affine toric variety To: 2-d CPR-Fano toric variety covered by 4 affine patches - Defn: Defined on coordinates by sending [y : u] to - [1 : y : u : 1] + Defn: Defined on coordinates by sending [y : u] to [1 : y : u : 1] sage: subpatch = P1.affine_patch(1) sage: subpatch Closed subscheme of 2-d affine toric variety defined by: -y + 1 sage: subpatch.embedding_morphism() Scheme morphism: - From: Closed subscheme of 2-d affine toric variety defined by: - -y + 1 + From: Closed subscheme of 2-d affine toric variety defined by: -y + 1 To: Closed subscheme of 2-d CPR-Fano toric variety covered - by 4 affine patches defined by: - x - y - Defn: Defined on coordinates by sending [y : u] to - [1 : y : u : 1] + by 4 affine patches defined by: x - y + Defn: Defined on coordinates by sending [y : u] to [1 : y : u : 1] """ if '_embedding_morphism' in self.__dict__: hom = self._embedding_morphism @@ -492,7 +474,7 @@ def embedding_center(self): EXAMPLES:: - sage: P3. = ProjectiveSpace(QQ,3) + sage: P3. = ProjectiveSpace(QQ, 3) sage: X = P3.subscheme( (w^2-x^2)*(y^2-z^2) ) sage: p = [1,-1,3,4] sage: nbhd = X.neighborhood(p); nbhd @@ -505,11 +487,11 @@ def embedding_center(self): (1/4 : -1/4 : 3/4 : 1) sage: nbhd.embedding_morphism() Scheme morphism: - From: Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: - w^2*y^2 - x^2*y^2 + 6*w^2*y - 6*x^2*y + 2*w*y^2 + - 2*x*y^2 - 7*w^2 + 7*x^2 + 12*w*y + 12*x*y - 14*w - 14*x - To: Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: - w^2*y^2 - x^2*y^2 - w^2*z^2 + x^2*z^2 + From: Closed subscheme of Affine Space of dimension 3 over Rational Field + defined by: w^2*y^2 - x^2*y^2 + 6*w^2*y - 6*x^2*y + 2*w*y^2 + 2*x*y^2 + - 7*w^2 + 7*x^2 + 12*w*y + 12*x*y - 14*w - 14*x + To: Closed subscheme of Projective Space of dimension 3 over Rational Field + defined by: w^2*y^2 - x^2*y^2 - w^2*z^2 + x^2*z^2 Defn: Defined on coordinates by sending (w, x, y) to (w + 1 : x - 1 : y + 3 : 4) """ @@ -524,12 +506,12 @@ def ngens(self): EXAMPLES:: - sage: A. = AffineSpace(2, GF(5)) - sage: S = A.subscheme([]) - sage: S.ngens() + sage: A. = AffineSpace(2, GF(5)) # optional - sage.rings.finite_rings + sage: S = A.subscheme([]) # optional - sage.rings.finite_rings + sage: S.ngens() # optional - sage.rings.finite_rings 2 sage: P. = ProjectiveSpace(2, ZZ) - sage: S = P.subscheme([x-y, x-z]) + sage: S = P.subscheme([x - y, x - z]) sage: P.ngens() 3 """ @@ -567,7 +549,7 @@ def _homset(self, *args, **kwds): sage: P1. = toric_varieties.P1() sage: type(P1.Hom(P1)) - sage: X = P1.subscheme(x-y) + sage: X = P1.subscheme(x - y) sage: type(X.Hom(X)) @@ -575,7 +557,7 @@ def _homset(self, *args, **kwds): sage: P1xP1 = toric_varieties.P1xP1() sage: P1 = toric_varieties.P1() - sage: P1xP1._homset(P1xP1,P1) + sage: P1xP1._homset(P1xP1, P1) Set of morphisms From: 2-d CPR-Fano toric variety covered by 4 affine patches To: 1-d CPR-Fano toric variety covered by 2 affine patches @@ -628,13 +610,14 @@ class AlgebraicScheme_quasi(AlgebraicScheme): sage: P. = ProjectiveSpace(2, ZZ) sage: S = P.subscheme([]) - sage: T = P.subscheme([x-y]) + sage: T = P.subscheme([x - y]) sage: T.complement(S) - Quasi-projective subscheme X - Y of Projective Space of dimension 2 over - Integer Ring, where X is defined by: - (no polynomials) - and Y is defined by: - x - y + Quasi-projective subscheme X - Y + of Projective Space of dimension 2 over Integer Ring, + where X is defined by: + (no polynomials) + and Y is defined by: + x - y """ def __init__(self, X, Y): @@ -649,13 +632,14 @@ def __init__(self, X, Y): sage: P. = ProjectiveSpace(2, ZZ) sage: S = P.subscheme([]) - sage: T = P.subscheme([x-y]) + sage: T = P.subscheme([x - y]) sage: from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_quasi sage: AlgebraicScheme_quasi(S, T) - Quasi-projective subscheme X - Y of Projective Space of dimension 2 over Integer Ring, where X is defined by: - (no polynomials) - and Y is defined by: - x - y + Quasi-projective subscheme X - Y of Projective Space of dimension 2 over Integer Ring, + where X is defined by: + (no polynomials) + and Y is defined by: + x - y """ self.__X = X self.__Y = Y @@ -680,13 +664,13 @@ def _latex_(self): sage: from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_quasi sage: P. = ProjectiveSpace(2, ZZ) sage: S = P.subscheme([]) - sage: T = P.subscheme([x-y]) + sage: T = P.subscheme([x - y]) sage: U = AlgebraicScheme_quasi(S, T); U - Quasi-projective subscheme X - Y of Projective Space of dimension 2 - over Integer Ring, where X is defined by: - (no polynomials) - and Y is defined by: - x - y + Quasi-projective subscheme X - Y of Projective Space of dimension 2 over Integer Ring, + where X is defined by: + (no polynomials) + and Y is defined by: + x - y sage: U._latex_() '\\text{Quasi-projective subscheme } (X\\setminus Y)\\subset {\\mathbf P}_{\\Bold{Z}}^2,\\text{ where } @@ -717,12 +701,13 @@ def _repr_(self): sage: from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_quasi sage: P. = ProjectiveSpace(2, ZZ) sage: S = P.subscheme([]) - sage: T = P.subscheme([x-y]) + sage: T = P.subscheme([x - y]) sage: U = AlgebraicScheme_quasi(S, T); U - Quasi-projective subscheme X - Y of Projective Space of dimension 2 over Integer Ring, where X is defined by: - (no polynomials) - and Y is defined by: - x - y + Quasi-projective subscheme X - Y of Projective Space of dimension 2 over Integer Ring, + where X is defined by: + (no polynomials) + and Y is defined by: + x - y sage: U._repr_() 'Quasi-projective subscheme X - Y of Projective Space of dimension 2 over Integer Ring, where X is defined by:\n (no polynomials)\nand Y is defined by:\n x - y' """ @@ -743,7 +728,7 @@ def X(self): sage: P. = ProjectiveSpace(2, ZZ) sage: S = P.subscheme([]) - sage: T = P.subscheme([x-y]) + sage: T = P.subscheme([x - y]) sage: U = T.complement(S) sage: U.X() is S True @@ -758,7 +743,7 @@ def Y(self): sage: P. = ProjectiveSpace(2, ZZ) sage: S = P.subscheme([]) - sage: T = P.subscheme([x-y]) + sage: T = P.subscheme([x - y]) sage: U = T.complement(S) sage: U.Y() is T True @@ -774,7 +759,7 @@ def _check_satisfies_equations(self, v): sage: P. = ProjectiveSpace(2, ZZ) sage: S = P.subscheme([]) - sage: T = P.subscheme([x-y]) + sage: T = P.subscheme([x - y]) sage: U = T.complement(S) sage: U._check_satisfies_equations([1, 2, 0]) True @@ -782,28 +767,28 @@ def _check_satisfies_equations(self, v): Traceback (most recent call last): ... TypeError: Coordinates [1, 1, 0] do not define a point on - Quasi-projective subscheme X - Y of Projective Space of dimension 2 - over Integer Ring, where X is defined by: - (no polynomials) - and Y is defined by: - x - y + Quasi-projective subscheme X - Y of Projective Space of dimension 2 over Integer Ring, + where X is defined by: + (no polynomials) + and Y is defined by: + x - y sage: U._check_satisfies_equations([1, 4]) Traceback (most recent call last): ... TypeError: number of arguments does not match number of variables in parent - sage: A. = AffineSpace(2, GF(7)) - sage: S = A.subscheme([x^2-y]) - sage: T = A.subscheme([x-y]) - sage: U = T.complement(S) - sage: U._check_satisfies_equations([2, 4]) + sage: A. = AffineSpace(2, GF(7)) # optional - sage.rings.finite_rings + sage: S = A.subscheme([x^2 - y]) # optional - sage.rings.finite_rings + sage: T = A.subscheme([x - y]) # optional - sage.rings.finite_rings + sage: U = T.complement(S) # optional - sage.rings.finite_rings + sage: U._check_satisfies_equations([2, 4]) # optional - sage.rings.finite_rings True - sage: U.point([2,4]) + sage: U.point([2,4]) # optional - sage.rings.finite_rings (2, 4) - sage: U._check_satisfies_equations(_) + sage: U._check_satisfies_equations(_) # optional - sage.rings.finite_rings True - sage: U._check_satisfies_equations([1, 1]) + sage: U._check_satisfies_equations([1, 1]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: Coordinates [1, 1] do not define a point on Quasi-affine @@ -812,7 +797,7 @@ def _check_satisfies_equations(self, v): x^2 - y and Y is defined by: x - y - sage: U._check_satisfies_equations([1, 0]) + sage: U._check_satisfies_equations([1, 0]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: Coordinates [1, 0] do not define a point on Quasi-affine @@ -860,23 +845,25 @@ def rational_points(self, **kwds): EXAMPLES:: - sage: A. = AffineSpace(2, GF(7)) - sage: S = A.subscheme([x^2-y]) - sage: T = A.subscheme([x-y]) - sage: U = T.complement(S) - sage: U.rational_points() + sage: A. = AffineSpace(2, GF(7)) # optional - sage.rings.finite_rings + sage: S = A.subscheme([x^2 - y]) # optional - sage.rings.finite_rings + sage: T = A.subscheme([x - y]) # optional - sage.rings.finite_rings + sage: U = T.complement(S) # optional - sage.rings.finite_rings + sage: U.rational_points() # optional - sage.rings.finite_rings [(2, 4), (3, 2), (4, 2), (5, 4), (6, 1)] - sage: U.rational_points(F=GF(7^2, 'b')) - [(2, 4), (3, 2), (4, 2), (5, 4), (6, 1), (b, b + 4), (b + 1, 3*b + 5), (b + 2, 5*b + 1), - (b + 3, 6), (b + 4, 2*b + 6), (b + 5, 4*b + 1), (b + 6, 6*b + 5), (2*b, 4*b + 2), - (2*b + 1, b + 3), (2*b + 2, 5*b + 6), (2*b + 3, 2*b + 4), (2*b + 4, 6*b + 4), - (2*b + 5, 3*b + 6), (2*b + 6, 3), (3*b, 2*b + 1), (3*b + 1, b + 2), (3*b + 2, 5), - (3*b + 3, 6*b + 3), (3*b + 4, 5*b + 3), (3*b + 5, 4*b + 5), (3*b + 6, 3*b + 2), - (4*b, 2*b + 1), (4*b + 1, 3*b + 2), (4*b + 2, 4*b + 5), (4*b + 3, 5*b + 3), - (4*b + 4, 6*b + 3), (4*b + 5, 5), (4*b + 6, b + 2), (5*b, 4*b + 2), (5*b + 1, 3), - (5*b + 2, 3*b + 6), (5*b + 3, 6*b + 4), (5*b + 4, 2*b + 4), (5*b + 5, 5*b + 6), - (5*b + 6, b + 3), (6*b, b + 4), (6*b + 1, 6*b + 5), (6*b + 2, 4*b + 1), (6*b + 3, 2*b + 6), - (6*b + 4, 6), (6*b + 5, 5*b + 1), (6*b + 6, 3*b + 5)] + sage: U.rational_points(F=GF(7^2, 'b')) # optional - sage.rings.finite_rings + [(2, 4), (3, 2), (4, 2), (5, 4), (6, 1), (b, b + 4), (b + 1, 3*b + 5), + (b + 2, 5*b + 1), (b + 3, 6), (b + 4, 2*b + 6), (b + 5, 4*b + 1), + (b + 6, 6*b + 5), (2*b, 4*b + 2), (2*b + 1, b + 3), (2*b + 2, 5*b + 6), + (2*b + 3, 2*b + 4), (2*b + 4, 6*b + 4), (2*b + 5, 3*b + 6), (2*b + 6, 3), + (3*b, 2*b + 1), (3*b + 1, b + 2), (3*b + 2, 5), (3*b + 3, 6*b + 3), + (3*b + 4, 5*b + 3), (3*b + 5, 4*b + 5), (3*b + 6, 3*b + 2), + (4*b, 2*b + 1), (4*b + 1, 3*b + 2), (4*b + 2, 4*b + 5), + (4*b + 3, 5*b + 3), (4*b + 4, 6*b + 3), (4*b + 5, 5), (4*b + 6, b + 2), + (5*b, 4*b + 2), (5*b + 1, 3), (5*b + 2, 3*b + 6), (5*b + 3, 6*b + 4), + (5*b + 4, 2*b + 4), (5*b + 5, 5*b + 6), (5*b + 6, b + 3), (6*b, b + 4), + (6*b + 1, 6*b + 5), (6*b + 2, 4*b + 1), (6*b + 3, 2*b + 6), (6*b + 4, 6), + (6*b + 5, 5*b + 1), (6*b + 6, 3*b + 5)] """ F = kwds.get('F', None) bound = kwds.get('bound', 0) @@ -912,9 +899,9 @@ class AlgebraicScheme_subscheme(AlgebraicScheme): - ``A`` - ambient space (e.g. affine or projective `n`-space) - ``polynomials`` - single polynomial, ideal or iterable of defining - polynomials; in any case polynomials must belong to the coordinate - ring of the ambient space and define valid polynomial functions (e.g. - they should be homogeneous in the case of a projective space) + polynomials; in any case polynomials must belong to the coordinate + ring of the ambient space and define valid polynomial functions (e.g. + they should be homogeneous in the case of a projective space) OUTPUT: @@ -924,10 +911,10 @@ class AlgebraicScheme_subscheme(AlgebraicScheme): sage: from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme sage: P. = ProjectiveSpace(2, QQ) - sage: P.subscheme([x^2-y*z]) + sage: P.subscheme([x^2 - y*z]) Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: x^2 - y*z - sage: AlgebraicScheme_subscheme(P, [x^2-y*z]) + sage: AlgebraicScheme_subscheme(P, [x^2 - y*z]) Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: x^2 - y*z """ @@ -940,10 +927,10 @@ def __init__(self, A, polynomials): sage: from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme sage: P. = ProjectiveSpace(2, QQ) - sage: P.subscheme([x^2-y*z]) + sage: P.subscheme([x^2 - y*z]) Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: x^2 - y*z - sage: AlgebraicScheme_subscheme(P, [x^2-y*z]) + sage: AlgebraicScheme_subscheme(P, [x^2 - y*z]) Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: x^2 - y*z """ @@ -979,7 +966,7 @@ def _check_satisfies_equations(self, v): EXAMPLES:: sage: P. = ProjectiveSpace(2, QQ) - sage: S = P.subscheme([x^2-y*z]) + sage: S = P.subscheme([x^2 - y*z]) sage: S._check_satisfies_equations([1, 1, 1]) True sage: S._check_satisfies_equations([1, 0, 1]) @@ -1011,15 +998,17 @@ def base_extend(self, R): EXAMPLES:: - sage: P. = ProjectiveSpace(2, GF(11)) - sage: S = P.subscheme([x^2-y*z]) - sage: S.base_extend(GF(11^2, 'b')) - Closed subscheme of Projective Space of dimension 2 over Finite Field in b of size 11^2 defined by: - x^2 - y*z - sage: S.base_extend(ZZ) + sage: P. = ProjectiveSpace(2, GF(11)) # optional - sage.rings.finite_rings + sage: S = P.subscheme([x^2 - y*z]) # optional - sage.rings.finite_rings + sage: S.base_extend(GF(11^2, 'b')) # optional - sage.rings.finite_rings + Closed subscheme of Projective Space of dimension 2 + over Finite Field in b of size 11^2 + defined by: x^2 - y*z + sage: S.base_extend(ZZ) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: no natural map from the base ring (=Finite Field of size 11) to R (=Integer Ring)! + ValueError: no natural map from the base ring (=Finite Field of size 11) + to R (=Integer Ring)! """ A = self.ambient_space().base_extend(R) return A.subscheme(self.__polys) @@ -1051,19 +1040,19 @@ def _latex_(self): EXAMPLES:: - sage: P. = ProjectiveSpace(2, GF(11)) - sage: S = P.subscheme([x^2-y*z]) - sage: S + sage: P. = ProjectiveSpace(2, GF(11)) # optional - sage.rings.finite_rings + sage: S = P.subscheme([x^2 - y*z]) # optional - sage.rings.finite_rings + sage: S # optional - sage.rings.finite_rings Closed subscheme of Projective Space of dimension 2 over Finite Field of size 11 defined by: x^2 - y*z - sage: S._latex_() + sage: S._latex_() # optional - sage.rings.finite_rings '\\text{Closed subscheme of } {\\mathbf P}_{\\Bold{F}_{11}}^2 \\text{ defined by } x^{2} - y z' - sage: S = P.subscheme([x^2-y*z, x^5]) - sage: S + sage: S = P.subscheme([x^2 - y*z, x^5]) # optional - sage.rings.finite_rings + sage: S # optional - sage.rings.finite_rings Closed subscheme of Projective Space of dimension 2 over Finite Field of size 11 defined by: x^2 - y*z, x^5 - sage: S._latex_() + sage: S._latex_() # optional - sage.rings.finite_rings '\\text{Closed subscheme of } {\\mathbf P}_{\\Bold{F}_{11}}^2 \\text{ defined by } x^{2} - y z, x^{5}' """ polynomials = ', '.join(latex(f) for f in self.defining_polynomials()) @@ -1078,19 +1067,19 @@ def _repr_(self): EXAMPLES:: - sage: P. = ProjectiveSpace(2, GF(11)) - sage: S = P.subscheme([x^2-y*z]) - sage: S + sage: P. = ProjectiveSpace(2, GF(11)) # optional - sage.rings.finite_rings + sage: S = P.subscheme([x^2 - y*z]) # optional - sage.rings.finite_rings + sage: S # optional - sage.rings.finite_rings Closed subscheme of Projective Space of dimension 2 over Finite Field of size 11 defined by: x^2 - y*z - sage: S._repr_() + sage: S._repr_() # optional - sage.rings.finite_rings 'Closed subscheme of Projective Space of dimension 2 over Finite Field of size 11 defined by:\n x^2 - y*z' - sage: S = P.subscheme([x^2-y*z, x^5]) - sage: S + sage: S = P.subscheme([x^2 - y*z, x^5]) # optional - sage.rings.finite_rings + sage: S # optional - sage.rings.finite_rings Closed subscheme of Projective Space of dimension 2 over Finite Field of size 11 defined by: x^2 - y*z, x^5 - sage: S._repr_() + sage: S._repr_() # optional - sage.rings.finite_rings 'Closed subscheme of Projective Space of dimension 2 over Finite Field of size 11 defined by:\n x^2 - y*z,\n x^5' """ polynomials = ',\n '.join(str(f) for f in self.defining_polynomials()) @@ -1112,7 +1101,7 @@ def defining_polynomials(self): EXAMPLES:: sage: P. = ProjectiveSpace(2, ZZ) - sage: S = P.subscheme([x^2-y*z, x^3+z^3]) + sage: S = P.subscheme([x^2 - y*z, x^3 + z^3]) sage: S.defining_polynomials() (x^2 - y*z, x^3 + z^3) """ @@ -1170,9 +1159,10 @@ def defining_ideal(self): EXAMPLES:: sage: P. = ProjectiveSpace(2, ZZ) - sage: S = P.subscheme([x^2-y*z, x^3+z^3]) + sage: S = P.subscheme([x^2 - y*z, x^3 + z^3]) sage: S.defining_ideal() - Ideal (x^2 - y*z, x^3 + z^3) of Multivariate Polynomial Ring in x, y, z over Integer Ring + Ideal (x^2 - y*z, x^3 + z^3) of Multivariate Polynomial Ring in x, y, z + over Integer Ring """ try: return self.__I @@ -1192,7 +1182,7 @@ def codimension(self): EXAMPLES:: - sage: PP. = ProjectiveSpace(4,QQ) + sage: PP. = ProjectiveSpace(4, QQ) sage: V = PP.subscheme(x*y) sage: V.codimension() 1 @@ -1218,24 +1208,24 @@ def irreducible_components(self): We define what is clearly a union of four hypersurfaces in `\P^4_{\QQ}` then find the irreducible components:: - sage: PP. = ProjectiveSpace(4,QQ) - sage: V = PP.subscheme( (x^2 - y^2 - z^2)*(w^5 - 2*v^2*z^3)* w * (v^3 - x^2*z) ) + sage: PP. = ProjectiveSpace(4, QQ) + sage: V = PP.subscheme((x^2 - y^2 - z^2) * (w^5 - 2*v^2*z^3) * w * (v^3 - x^2*z)) sage: V.irreducible_components() [ Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: - w, + w, Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: - x^2 - y^2 - z^2, + x^2 - y^2 - z^2, Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: - x^2*z - v^3, + x^2*z - v^3, Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: - w^5 - 2*z^3*v^2 + w^5 - 2*z^3*v^2 ] We verify that the irrelevant ideal is not accidentally returned (see :trac:`6920`):: - sage: PP. = ProjectiveSpace(3,QQ) + sage: PP. = ProjectiveSpace(3, QQ) sage: f = x^3 + y^3 + z^3 + w^3 sage: R = f.parent() sage: I = [f] + [f.derivative(zz) for zz in PP.gens()] @@ -1249,7 +1239,7 @@ def irreducible_components(self): nontrivial irreducible component in affine space (instead of the empty scheme as above):: - sage: AA. = AffineSpace(4,QQ) + sage: AA. = AffineSpace(4, QQ) sage: V = AA.subscheme(I) sage: V.irreducible_components() [ @@ -1291,10 +1281,10 @@ def is_irreducible(self): EXAMPLES:: - sage: K = QuadraticField(-3) - sage: P. = ProjectiveSpace(K, 5) - sage: X = P.subscheme([x*y - z^2 - K.0*t^2, t*w*x + y*z^2 - u^3]) - sage: X.is_irreducible() + sage: K = QuadraticField(-3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 5) # optional - sage.rings.number_field + sage: X = P.subscheme([x*y - z^2 - K.0*t^2, t*w*x + y*z^2 - u^3]) # optional - sage.rings.number_field + sage: X.is_irreducible() # optional - sage.rings.number_field True :: @@ -1306,10 +1296,12 @@ def is_irreducible(self): :: - sage: A. = AffineSpace(GF(17), 4) - sage: X = A.subscheme([x*y*z^2 - x*y*z*w - z*w^2 + w^3, x^3*y*z*w - x*y^3*z - x^2*y*z*w \ - - x^2*w^3 + y^2*w^2 + x*w^3]) - sage: X.is_irreducible() + sage: A. = AffineSpace(GF(17), 4) # optional - sage.rings.finite_rings + sage: X = A.subscheme([ # optional - sage.rings.finite_rings + ....: x*y*z^2 - x*y*z*w - z*w^2 + w^3, + ....: x^3*y*z*w - x*y^3*z - x^2*y*z*w - x^2*w^3 + y^2*w^2 + x*w^3 + ....: ]) + sage: X.is_irreducible() # optional - sage.rings.finite_rings False """ return self.defining_ideal().is_prime() @@ -1326,7 +1318,7 @@ def Jacobian_matrix(self): EXAMPLES:: sage: P3. = ProjectiveSpace(3, QQ) - sage: twisted_cubic = P3.subscheme(matrix([[w, x, y],[x, y, z]]).minors(2)) + sage: twisted_cubic = P3.subscheme(matrix([[w, x, y], [x, y, z]]).minors(2)) sage: twisted_cubic.Jacobian_matrix() [ y -2*x w 0] [ z -y -x w] @@ -1365,14 +1357,15 @@ def Jacobian(self): EXAMPLES:: sage: P3. = ProjectiveSpace(3, QQ) - sage: twisted_cubic = P3.subscheme(matrix([[w, x, y],[x, y, z]]).minors(2)) + sage: twisted_cubic = P3.subscheme(matrix([[w, x, y], [x, y, z]]).minors(2)) sage: twisted_cubic.Jacobian() - Ideal (-x^2 + w*y, -x*y + w*z, -y^2 + x*z, x*z, -2*w*z, w*y, 3*w*y, -2*w*x, - w^2, y*z, -2*x*z, w*z, 3*w*z, -2*w*y, w*x, z^2, -2*y*z, x*z, 3*x*z, -2*w*z, - w*y) of Multivariate Polynomial Ring in w, x, y, z over Rational Field + Ideal (-x^2 + w*y, -x*y + w*z, -y^2 + x*z, x*z, -2*w*z, w*y, 3*w*y, + -2*w*x, w^2, y*z, -2*x*z, w*z, 3*w*z, -2*w*y, w*x, z^2, -2*y*z, + x*z, 3*x*z, -2*w*z, w*y) + of Multivariate Polynomial Ring in w, x, y, z over Rational Field sage: twisted_cubic.defining_ideal() - Ideal (-x^2 + w*y, -x*y + w*z, -y^2 + x*z) of Multivariate Polynomial Ring - in w, x, y, z over Rational Field + Ideal (-x^2 + w*y, -x*y + w*z, -y^2 + x*z) + of Multivariate Polynomial Ring in w, x, y, z over Rational Field This example addresses issue :trac:`20512`:: @@ -1411,10 +1404,10 @@ def reduce(self): Finally, we verify that the reduced scheme `Y` is the union of those two lines:: - sage: L1 = A.subscheme([x-1]); L1 + sage: L1 = A.subscheme([x - 1]); L1 Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: x - 1 - sage: L2 = A.subscheme([x-y]); L2 + sage: L2 = A.subscheme([x - y]); L2 Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: x - y sage: W = L1.union(L2); W # taken in ambient space @@ -1444,27 +1437,27 @@ def union(self, other): :: sage: A. = AffineSpace(2, QQ) - sage: I = ideal([x,y])^3 + sage: I = ideal([x, y])^3 sage: P = A.subscheme(I) - sage: L = A.subscheme([y-1]) + sage: L = A.subscheme([y - 1]) sage: S = L.union(P); S Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y^4 - y^3, - x*y^3 - x*y^2, - x^2*y^2 - x^2*y, - x^3*y - x^3 + y^4 - y^3, + x*y^3 - x*y^2, + x^2*y^2 - x^2*y, + x^3*y - x^3 sage: S.dimension() 1 sage: S.reduce() Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y^2 - y, - x*y - x + y^2 - y, + x*y - x We can also use the notation "+" for the union:: sage: A.subscheme([x]) + A.subscheme([y^2 - (x^3+1)]) Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^4 - x*y^2 + x + x^4 - x*y^2 + x Saving and loading:: @@ -1492,7 +1485,7 @@ def __pow__(self, m): sage: Z = P2.subscheme([y0^2 - y1*y2, y2]) sage: Z**3 Closed subscheme of Product of projective spaces P^2 x P^2 x P^2 over - Integer Ring defined by: + Integer Ring defined by: x0^2 - x1*x2, x2, x3^2 - x4*x5, @@ -1501,10 +1494,10 @@ def __pow__(self, m): x8 sage: A2. = AffineSpace(QQ, 2) - sage: V = A2.subscheme([x^2-y, x-1]) + sage: V = A2.subscheme([x^2 - y, x - 1]) sage: V**4 Closed subscheme of Affine Space of dimension 8 over Rational Field - defined by: + defined by: x0^2 - x1, x0 - 1, x2^2 - x3, @@ -1518,14 +1511,14 @@ def __pow__(self, m): sage: X = T.subscheme([x0*x4 - x1*x3]) sage: X^2 Closed subscheme of Product of projective spaces P^2 x P^2 x P^2 x P^2 - over Integer Ring defined by: + over Integer Ring defined by: -x1*x3 + x0*x4, -x7*x9 + x6*x10 sage: E = EllipticCurve([0,0,0,0,1]) sage: E^2 - Closed subscheme of Product of projective spaces P^2 x P^2 over Rational - Field defined by: + Closed subscheme of Product of projective spaces P^2 x P^2 + over Rational Field defined by: -x0^3 + x1^2*x2 - x2^3, -x3^3 + x4^2*x5 - x5^3 """ @@ -1555,8 +1548,9 @@ def __mul__(self, right): Defining x0, x1, x2, x3, x4, x5 sage: X = T.subscheme([x0*x4 - x1*x3]) sage: X*S - Closed subscheme of Product of projective spaces P^2 x P^2 x P^1 x P^2 x - P^1 over Integer Ring defined by: + Closed subscheme of + Product of projective spaces P^2 x P^2 x P^1 x P^2 x P^1 over Integer Ring + defined by: -x1*x3 + x0*x4 :: @@ -1565,8 +1559,8 @@ def __mul__(self, right): sage: T. = ProjectiveSpace(ZZ, 3) sage: X = T.subscheme([x0*x2 - x1*x3]) sage: X*S - Closed subscheme of Product of projective spaces P^3 x P^2 - over Integer Ring defined by: + Closed subscheme of Product of projective spaces P^3 x P^2 over Integer Ring + defined by: x0*x2 - x1*x3 :: @@ -1576,7 +1570,7 @@ def __mul__(self, right): sage: X = A3.subscheme([x0*x2 - x1]) sage: X*A2 Closed subscheme of Affine Space of dimension 5 over Integer Ring - defined by: + defined by: x0*x2 - x1 :: @@ -1585,7 +1579,7 @@ def __mul__(self, right): sage: X = T.subscheme([x0*x4 - x1*x3]) sage: X*X Closed subscheme of Product of projective spaces P^2 x P^2 x P^2 x P^2 - over Integer Ring defined by: + over Integer Ring defined by: -x1*x3 + x0*x4, -x7*x9 + x6*x10 @@ -1596,8 +1590,8 @@ def __mul__(self, right): sage: T. = ProductProjectiveSpaces([2,2], ZZ) sage: X = T.subscheme([x0*x4 - x1*x3]) sage: X*Y - Closed subscheme of Product of projective spaces P^2 x P^2 x P^1 over - Integer Ring defined by: + Closed subscheme of Product of projective spaces P^2 x P^2 x P^1 + over Integer Ring defined by: -x1*x3 + x0*x4, z0 - z1 @@ -1605,8 +1599,8 @@ def __mul__(self, right): sage: A3. = AffineSpace(ZZ, 3) sage: X = A3.subscheme([x0*x2 - x1]) - sage: P1.=ProjectiveSpace(ZZ,1) - sage: Y = P1.subscheme([u-v]) + sage: P1. = ProjectiveSpace(ZZ, 1) + sage: Y = P1.subscheme([u - v]) sage: X*Y Traceback (most recent call last): ... @@ -1614,9 +1608,10 @@ def __mul__(self, right): sage: Y*X Traceback (most recent call last): ... - TypeError: Affine Space of dimension 3 over Integer Ring must be a projective space, product of projective spaces, or subscheme - sage: PP.=ProductProjectiveSpaces(ZZ, [1,1]) - sage: Z = PP.subscheme([a*d-b*c]) + TypeError: Affine Space of dimension 3 over Integer Ring must be a projective space, + product of projective spaces, or subscheme + sage: PP. = ProductProjectiveSpaces(ZZ, [1,1]) + sage: Z = PP.subscheme([a*d - b*c]) sage: X*Z Traceback (most recent call last): ... @@ -1624,7 +1619,8 @@ def __mul__(self, right): sage: Z*X Traceback (most recent call last): ... - TypeError: Affine Space of dimension 3 over Integer Ring must be a projective space, product of projective spaces, or subscheme + TypeError: Affine Space of dimension 3 over Integer Ring must be a projective space, + product of projective spaces, or subscheme """ #This will catch any ambient space mismatches AS = self.ambient_space()*right.ambient_space() @@ -1645,7 +1641,7 @@ def intersection(self, other): EXAMPLES:: sage: A. = AffineSpace(2, ZZ) - sage: X = A.subscheme([x^2-y]) + sage: X = A.subscheme([x^2 - y]) sage: Y = A.subscheme([y]) sage: X.intersection(Y) Closed subscheme of Affine Space of dimension 2 over Integer Ring defined by: @@ -1671,35 +1667,39 @@ def complement(self, other=None): EXAMPLES:: sage: A. = AffineSpace(3, ZZ) - sage: X = A.subscheme([x+y-z]) - sage: Y = A.subscheme([x-y+z]) + sage: X = A.subscheme([x + y - z]) + sage: Y = A.subscheme([x - y + z]) sage: Y.complement(X) - Quasi-affine subscheme X - Y of Affine Space of - dimension 3 over Integer Ring, where X is defined by: - x + y - z - and Y is defined by: - x - y + z + Quasi-affine subscheme X - Y of + Affine Space of dimension 3 over Integer Ring, + where X is defined by: + x + y - z + and Y is defined by: + x - y + z sage: Y.complement() - Quasi-affine subscheme X - Y of Affine Space of - dimension 3 over Integer Ring, where X is defined by: - (no polynomials) - and Y is defined by: - x - y + z + Quasi-affine subscheme X - Y of + Affine Space of dimension 3 over Integer Ring, + where X is defined by: + (no polynomials) + and Y is defined by: + x - y + z sage: P. = ProjectiveSpace(2, QQ) - sage: X = P.subscheme([x^2+y^2+z^2]) - sage: Y = P.subscheme([x*y+y*z+z*x]) + sage: X = P.subscheme([x^2 + y^2 + z^2]) + sage: Y = P.subscheme([x*y + y*z + z*x]) sage: Y.complement(X) - Quasi-projective subscheme X - Y of Projective Space of - dimension 2 over Rational Field, where X is defined by: - x^2 + y^2 + z^2 - and Y is defined by: - x*y + x*z + y*z + Quasi-projective subscheme X - Y of + Projective Space of dimension 2 over Rational Field, + where X is defined by: + x^2 + y^2 + z^2 + and Y is defined by: + x*y + x*z + y*z sage: Y.complement(P) - Quasi-projective subscheme X - Y of Projective Space of - dimension 2 over Rational Field, where X is defined by: - (no polynomials) - and Y is defined by: - x*y + x*z + y*z + Quasi-projective subscheme X - Y of + Projective Space of dimension 2 over Rational Field, + where X is defined by: + (no polynomials) + and Y is defined by: + x*y + x*z + y*z """ A = self.ambient_space() if other is None: @@ -1767,10 +1767,10 @@ def rational_points(self, **kwds): Enumerate over a projective scheme over a number field:: sage: u = QQ['u'].0 - sage: K. = NumberField(u^2 + 3) - sage: A. = ProjectiveSpace(K,1) - sage: X=A.subscheme(x^2 - y^2) - sage: X.rational_points(bound=3) + sage: K. = NumberField(u^2 + 3) # optional - sage.rings.number_field + sage: A. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: X = A.subscheme(x^2 - y^2) # optional - sage.rings.number_field + sage: X.rational_points(bound=3) # optional - sage.rings.number_field [(-1 : 1), (1 : 1)] One can enumerate points up to a given bound on a projective scheme @@ -1778,42 +1778,43 @@ def rational_points(self, **kwds): sage: E = EllipticCurve('37a') sage: E.rational_points(bound=8) - [(-1 : -1 : 1), (-1 : 0 : 1), (0 : -1 : 1), (0 : 0 : 1), (0 : 1 : 0), (1/4 : -5/8 : 1), - (1/4 : -3/8 : 1), (1 : -1 : 1), (1 : 0 : 1), (2 : -3 : 1), (2 : 2 : 1)] + [(-1 : -1 : 1), (-1 : 0 : 1), (0 : -1 : 1), (0 : 0 : 1), (0 : 1 : 0), + (1/4 : -5/8 : 1), (1/4 : -3/8 : 1), (1 : -1 : 1), (1 : 0 : 1), + (2 : -3 : 1), (2 : 2 : 1)] For a small finite field, the complete set of points can be enumerated. :: - sage: Etilde = E.base_extend(GF(3)) - sage: Etilde.rational_points() + sage: Etilde = E.base_extend(GF(3)) # optional - sage.rings.finite_rings + sage: Etilde.rational_points() # optional - sage.rings.finite_rings [(0 : 0 : 1), (0 : 1 : 0), (0 : 2 : 1), (1 : 0 : 1), (1 : 2 : 1), (2 : 0 : 1), (2 : 2 : 1)] The class of hyperelliptic curves does not (yet) support desingularization of the places at infinity into two points:: - sage: FF = FiniteField(7) - sage: P. = PolynomialRing(FiniteField(7)) - sage: C = HyperellipticCurve(x^8+x+1) - sage: C.rational_points() + sage: FF = FiniteField(7) # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(FiniteField(7)) # optional - sage.rings.finite_rings + sage: C = HyperellipticCurve(x^8 + x + 1) # optional - sage.rings.finite_rings + sage: C.rational_points() # optional - sage.rings.finite_rings [(0 : 1 : 0), (0 : 1 : 1), (0 : 6 : 1), (2 : 0 : 1), (4 : 0 : 1), (6 : 1 : 1), (6 : 6 : 1)] :: - sage: K. = QuadraticField(-3) - sage: P. = ProjectiveSpace(K, 2) - sage: X = P.subscheme([x^2 - v^2*x*z, y*x-v*z^2]) - sage: X.rational_points(F=CC) + sage: K. = QuadraticField(-3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: X = P.subscheme([x^2 - v^2*x*z, y*x - v*z^2]) # optional - sage.rings.number_field + sage: X.rational_points(F=CC) # optional - sage.rings.number_field [(-3.00000000000000 : -0.577350269189626*I : 1.00000000000000), (0.000000000000000 : 1.00000000000000 : 0.000000000000000)] :: - sage: K. = QuadraticField(3) - sage: A. = AffineSpace(K, 2) - sage: X = A.subscheme([x^2 - v^2*y, y*x-v]) - sage: X.rational_points(F=RR) + sage: K. = QuadraticField(3) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: X = A.subscheme([x^2 - v^2*y, y*x - v]) # optional - sage.rings.number_field + sage: X.rational_points(F=RR) # optional - sage.rings.number_field [(1.73205080756888, 1.00000000000000)] .. TODO:: @@ -1856,97 +1857,98 @@ def change_ring(self, R): EXAMPLES:: sage: P. = ProjectiveSpace(QQ, 1) - sage: X = P.subscheme([3*x^2-y^2]) - sage: H = Hom(X,X) - sage: X.change_ring(GF(3)) - Closed subscheme of Projective Space of dimension 1 over Finite Field of size 3 defined by: - -y^2 + sage: X = P.subscheme([3*x^2 - y^2]) + sage: H = Hom(X, X) + sage: X.change_ring(GF(3)) # optional - sage.rings.finite_rings + Closed subscheme of Projective Space of dimension 1 + over Finite Field of size 3 defined by: -y^2 :: - sage: K. = QuadraticField(2) - sage: R. = K[] - sage: L. = K.extension(z^3-5) - sage: P. = ProjectiveSpace(K, 1) - sage: X = P.subscheme(x - w*y) - sage: X.change_ring(L) - Closed subscheme of Projective Space of dimension 1 over Number Field in v with - defining polynomial z^3 - 5 over its base field defined by: - x + (-w)*y + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: L. = K.extension(z^3 - 5) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: X = P.subscheme(x - w*y) # optional - sage.rings.number_field + sage: X.change_ring(L) # optional - sage.rings.number_field + Closed subscheme of Projective Space of dimension 1 over + Number Field in v with defining polynomial z^3 - 5 over its base field + defined by: x + (-w)*y :: - sage: K. = QuadraticField(2) - sage: R. = K[] - sage: L. = K.extension(z^3-5) - sage: P. = AffineSpace(L,3) - sage: X = P.subscheme([x-w*y, z^2-v*x]) - sage: emb = L.embeddings(QQbar) - sage: X.change_ring(emb[0]) + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: L. = K.extension(z^3 - 5) # optional - sage.rings.number_field + sage: P. = AffineSpace(L, 3) # optional - sage.rings.number_field + sage: X = P.subscheme([x - w*y, z^2 - v*x]) # optional - sage.rings.number_field + sage: emb = L.embeddings(QQbar) # optional - sage.rings.number_field + sage: X.change_ring(emb[0]) # optional - sage.rings.number_field Closed subscheme of Affine Space of dimension 3 over Algebraic Field - defined by: + defined by: x + (-1.414213562373095? + 0.?e-16*I)*y, z^2 + (0.8549879733383485? + 1.480882609682365?*I)*x :: - sage: K. = QuadraticField(2) - sage: R. = K[] - sage: L. = K.extension(z^3-5) - sage: P. = AffineSpace(L,3) - sage: X = P.subscheme([x-w*y, z^2-v*x]) - sage: emb = L.embeddings(QQbar) - sage: X.change_ring(emb[1]) + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: L. = K.extension(z^3 - 5) # optional - sage.rings.number_field + sage: P. = AffineSpace(L, 3) # optional - sage.rings.number_field + sage: X = P.subscheme([x - w*y, z^2 - v*x]) # optional - sage.rings.number_field + sage: emb = L.embeddings(QQbar) # optional - sage.rings.number_field + sage: X.change_ring(emb[1]) # optional - sage.rings.number_field Closed subscheme of Affine Space of dimension 3 over Algebraic Field - defined by: + defined by: x + (-1.414213562373095? + 0.?e-16*I)*y, z^2 + (0.8549879733383485? - 1.480882609682365?*I)*x :: - sage: K. = QuadraticField(-3) - sage: P. = ProjectiveSpace(K, 1) - sage: X = P.subscheme(x-w*y) - sage: X.change_ring(CC) - Closed subscheme of Projective Space of dimension 1 over Complex Field - with 53 bits of precision defined by: + sage: K. = QuadraticField(-3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: X = P.subscheme(x - w*y) # optional - sage.rings.number_field + sage: X.change_ring(CC) # optional - sage.rings.number_field + Closed subscheme of Projective Space of dimension 1 + over Complex Field with 53 bits of precision defined by: x + (-1.73205080756888*I)*y :: - sage: K. = QuadraticField(3) - sage: P. = ProjectiveSpace(K,1) - sage: X = P.subscheme(x-w*y) - sage: X.change_ring(RR) - Closed subscheme of Projective Space of dimension 1 over Real Field - with 53 bits of precision defined by: + sage: K. = QuadraticField(3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: X = P.subscheme(x - w*y) # optional - sage.rings.number_field + sage: X.change_ring(RR) # optional - sage.rings.number_field + Closed subscheme of Projective Space of dimension 1 + over Real Field with 53 bits of precision defined by: x - 1.73205080756888*y :: - sage: K. = CyclotomicField(7) - sage: O = K.maximal_order() - sage: P. = ProjectiveSpace(O, 1) - sage: X = P.subscheme([x^2+O(v)*y^2]) - sage: X.change_ring(CC) - Closed subscheme of Projective Space of dimension 1 over Complex Field - with 53 bits of precision defined by: + sage: K. = CyclotomicField(7) # optional - sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(O, 1) # optional - sage.rings.number_field + sage: X = P.subscheme([x^2 + O(v)*y^2]) # optional - sage.rings.number_field + sage: X.change_ring(CC) # optional - sage.rings.number_field + Closed subscheme of Projective Space of dimension 1 + over Complex Field with 53 bits of precision defined by: x^2 + (0.623489801858734 + 0.781831482468030*I)*y^2 - sage: X.change_ring(K).change_ring(K.embeddings(QQbar)[3]) - Closed subscheme of Projective Space of dimension 1 over Algebraic Field defined by: + sage: X.change_ring(K).change_ring(K.embeddings(QQbar)[3]) # optional - sage.rings.number_field + Closed subscheme of Projective Space of dimension 1 + over Algebraic Field defined by: x^2 + (-0.9009688679024191? - 0.4338837391175581?*I)*y^2 :: sage: R. = QQ[] - sage: f = x^6-2 - sage: L. = NumberField(f, embedding=f.roots(CC)[2][0]) - sage: A. = AffineSpace(L, 2) - sage: H = Hom(A,A) - sage: X = A.subscheme([b*x^2, y^2]) - sage: X.change_ring(CC) - Closed subscheme of Affine Space of dimension 2 over Complex Field with - 53 bits of precision defined by: + sage: f = x^6 - 2 + sage: L. = NumberField(f, embedding=f.roots(CC)[2][0]) # optional - sage.rings.number_field + sage: A. = AffineSpace(L, 2) # optional - sage.rings.number_field + sage: H = Hom(A, A) # optional - sage.rings.number_field + sage: X = A.subscheme([b*x^2, y^2]) # optional - sage.rings.number_field + sage: X.change_ring(CC) # optional - sage.rings.number_field + Closed subscheme of Affine Space of dimension 2 + over Complex Field with 53 bits of precision defined by: (-0.561231024154687 - 0.972080648619833*I)*x^2, y^2 """ @@ -1991,26 +1993,26 @@ def weil_restriction(self): EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(x^5-2) - sage: R. = K[] - sage: L. = K.extension(x^2+1) - sage: A. = AffineSpace(L,2) - sage: X = A.subscheme([y^2-L(w)*x^3-v]) - sage: X.weil_restriction() - Closed subscheme of Affine Space of dimension 4 over Number Field in w - with defining polynomial x^5 - 2 defined by: + sage: K. = NumberField(x^5 - 2) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: L. = K.extension(x^2 + 1) # optional - sage.rings.number_field + sage: A. = AffineSpace(L, 2) # optional - sage.rings.number_field + sage: X = A.subscheme([y^2 - L(w)*x^3 - v]) # optional - sage.rings.number_field + sage: X.weil_restriction() # optional - sage.rings.number_field + Closed subscheme of Affine Space of dimension 4 + over Number Field in w with defining polynomial x^5 - 2 defined by: (-w)*z0^3 + (3*w)*z0*z1^2 + z2^2 - z3^2, (-3*w)*z0^2*z1 + w*z1^3 + 2*z2*z3 - 1 - sage: X.weil_restriction().ambient_space() is A.weil_restriction() + sage: X.weil_restriction().ambient_space() is A.weil_restriction() # optional - sage.rings.number_field True :: - sage: A. = AffineSpace(GF(5^2,'t'),3) - sage: X = A.subscheme([y^2-x*z, z^2+2*y]) - sage: X.weil_restriction() - Closed subscheme of Affine Space of dimension 6 over Finite Field of - size 5 defined by: + sage: A. = AffineSpace(GF(5^2, 't'), 3) # optional - sage.rings.finite_rings + sage: X = A.subscheme([y^2 - x*z, z^2 + 2*y]) # optional - sage.rings.finite_rings + sage: X.weil_restriction() # optional - sage.rings.finite_rings + Closed subscheme of Affine Space of dimension 6 + over Finite Field of size 5 defined by: z2^2 - 2*z3^2 - z0*z4 + 2*z1*z5, 2*z2*z3 + z3^2 - z1*z4 - z0*z5 - z1*z5, z4^2 - 2*z5^2 + 2*z2, @@ -2046,7 +2048,7 @@ def specialization(self, D=None, phi=None): - ``D`` -- dictionary (optional) - - ``phi`` -- SpecializationMorphism (optional) + - ``phi`` -- :class:`SpecializationMorphism` (optional) OUTPUT: :class:`SchemeMorphism_polynomial` @@ -2057,19 +2059,20 @@ def specialization(self, D=None, phi=None): sage: X = P.subscheme([x^2 + c*y^2]) sage: X.specialization(dict({c:2})) Closed subscheme of Projective Space of dimension 1 over Rational Field defined by: - x^2 + 2*y^2 + x^2 + 2*y^2 :: sage: R. = PolynomialRing(QQ) sage: S. = R[] - sage: P. = AffineSpace(S,3) - sage: X = P.subscheme([x^2+a*c*y^2 - b*z^2]) + sage: P. = AffineSpace(S, 3) + sage: X = P.subscheme([x^2 + a*c*y^2 - b*z^2]) sage: from sage.rings.polynomial.flatten import SpecializationMorphism - sage: phi = SpecializationMorphism(P.coordinate_ring(),dict({c:2,a:1})) + sage: phi = SpecializationMorphism(P.coordinate_ring(), dict({c: 2, a: 1})) sage: X.specialization(phi=phi) - Closed subscheme of Affine Space of dimension 3 over Univariate Polynomial Ring in b over Rational Field defined by: - x^2 + 2*y^2 + (-b)*z^2 + Closed subscheme of Affine Space of dimension 3 + over Univariate Polynomial Ring in b over Rational Field defined by: + x^2 + 2*y^2 + (-b)*z^2 """ if D is None: if phi is None: diff --git a/src/sage/schemes/generic/ambient_space.py b/src/sage/schemes/generic/ambient_space.py index 0f9b9b55240..9b7b11feb74 100644 --- a/src/sage/schemes/generic/ambient_space.py +++ b/src/sage/schemes/generic/ambient_space.py @@ -29,7 +29,7 @@ def is_AmbientSpace(x): sage: is_AmbientSpace(AffineSpace(2, QQ)) True sage: P. = ProjectiveSpace(2, ZZ) - sage: is_AmbientSpace(P.subscheme([x+y+z])) + sage: is_AmbientSpace(P.subscheme([x + y + z])) False """ return isinstance(x, AmbientSpace) @@ -196,9 +196,9 @@ def is_projective(self): EXAMPLES:: - sage: AffineSpace(3,QQ).is_projective() + sage: AffineSpace(3, QQ).is_projective() False - sage: ProjectiveSpace(3,QQ).is_projective() + sage: ProjectiveSpace(3, QQ).is_projective() True """ # overloaded in the projective space derived class @@ -227,7 +227,7 @@ def base_extend(self, R): sage: P. = ProjectiveSpace(2, ZZ) sage: PQ = P.base_extend(QQ); PQ Projective Space of dimension 2 over Rational Field - sage: PQ.base_extend(GF(5)) + sage: PQ.base_extend(GF(5)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: no natural map from the base ring (=Rational Field) @@ -257,8 +257,8 @@ def ambient_space(self): sage: P.ambient_space() is P True - sage: A = AffineSpace(2, GF(3)) - sage: A.ambient_space() + sage: A = AffineSpace(2, GF(3)) # optional - sage.rings.finite_rings + sage: A.ambient_space() # optional - sage.rings.finite_rings Affine Space of dimension 2 over Finite Field of size 3 """ return self @@ -285,8 +285,8 @@ def identity_morphism(self): EXAMPLES:: - sage: A = AffineSpace(2, GF(3)) - sage: A.identity_morphism() + sage: A = AffineSpace(2, GF(3)) # optional - sage.rings.finite_rings + sage: A.identity_morphism() # optional - sage.rings.finite_rings Scheme endomorphism of Affine Space of dimension 2 over Finite Field of size 3 Defn: Identity map @@ -325,8 +325,8 @@ def gens(self): sage: AffineSpace(0, QQ).gens() () - sage: P. = ProjectiveSpace(2, GF(5)) - sage: P.gens() + sage: P. = ProjectiveSpace(2, GF(5)) # optional - sage.rings.finite_rings + sage: P.gens() # optional - sage.rings.finite_rings (x, y, z) """ return self.coordinate_ring().gens() diff --git a/src/sage/schemes/generic/divisor.py b/src/sage/schemes/generic/divisor.py index 336fee8304f..847bdfd6f80 100644 --- a/src/sage/schemes/generic/divisor.py +++ b/src/sage/schemes/generic/divisor.py @@ -13,22 +13,22 @@ EXAMPLES:: - sage: x,y,z = ProjectiveSpace(2, GF(5), names='x,y,z').gens() - sage: C = Curve(y^2*z^7 - x^9 - x*z^8) - sage: pts = C.rational_points(); pts + sage: x,y,z = ProjectiveSpace(2, GF(5), names='x,y,z').gens() # optional - sage.rings.finite_rings + sage: C = Curve(y^2*z^7 - x^9 - x*z^8) # optional - sage.rings.finite_rings + sage: pts = C.rational_points(); pts # optional - sage.rings.finite_rings [(0 : 0 : 1), (0 : 1 : 0), (2 : 2 : 1), (2 : 3 : 1), (3 : 1 : 1), (3 : 4 : 1)] - sage: D1 = C.divisor(pts[0])*3 - sage: D2 = C.divisor(pts[1]) - sage: D3 = 10*C.divisor(pts[5]) - sage: D1.parent() is D2.parent() + sage: D1 = C.divisor(pts[0])*3 # optional - sage.rings.finite_rings + sage: D2 = C.divisor(pts[1]) # optional - sage.rings.finite_rings + sage: D3 = 10*C.divisor(pts[5]) # optional - sage.rings.finite_rings + sage: D1.parent() is D2.parent() # optional - sage.rings.finite_rings True - sage: D = D1 - D2 + D3; D + sage: D = D1 - D2 + D3; D # optional - sage.rings.finite_rings 3*(x, y) - (x, z) + 10*(x + 2*z, y + z) - sage: D[1][0] + sage: D[1][0] # optional - sage.rings.finite_rings -1 - sage: D[1][1] + sage: D[1][1] # optional - sage.rings.finite_rings Ideal (x, z) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 5 - sage: C.divisor([(3, pts[0]), (-1, pts[1]), (10,pts[5])]) + sage: C.divisor([(3, pts[0]), (-1, pts[1]), (10, pts[5])]) # optional - sage.rings.finite_rings 3*(x, y) - (x, z) + 10*(x + 2*z, y + z) """ #******************************************************************************* @@ -107,9 +107,9 @@ def is_Divisor(x): EXAMPLES:: sage: from sage.schemes.generic.divisor import is_Divisor - sage: x,y = AffineSpace(2, GF(5), names='xy').gens() - sage: C = Curve(y^2 - x^9 - x) - sage: is_Divisor( C.divisor([]) ) + sage: x,y = AffineSpace(2, GF(5), names='xy').gens() # optional - sage.rings.finite_rings + sage: C = Curve(y^2 - x^9 - x) # optional - sage.rings.finite_rings + sage: is_Divisor(C.divisor([])) # optional - sage.rings.finite_rings True sage: is_Divisor("Ceci n'est pas un diviseur") False @@ -223,13 +223,13 @@ def scheme(self): EXAMPLES:: - sage: A. = AffineSpace(2, GF(5)) - sage: C = Curve(y^2 - x^9 - x) - sage: pts = C.rational_points(); pts + sage: A. = AffineSpace(2, GF(5)) # optional - sage.rings.finite_rings + sage: C = Curve(y^2 - x^9 - x) # optional - sage.rings.finite_rings + sage: pts = C.rational_points(); pts # optional - sage.rings.finite_rings [(0, 0), (2, 2), (2, 3), (3, 1), (3, 4)] - sage: D = C.divisor(pts[0])*3 - C.divisor(pts[1]); D + sage: D = C.divisor(pts[0])*3 - C.divisor(pts[1]); D # optional - sage.rings.finite_rings 3*(x, y) - (x - 2, y - 2) - sage: D.scheme() + sage: D.scheme() # optional - sage.rings.finite_rings Affine Plane Curve over Finite Field of size 5 defined by -x^9 + y^2 - x """ return self.parent().scheme() @@ -291,7 +291,7 @@ def __init__(self, v, parent=None, check=True, reduce=True): sage: P = E(0,0) sage: from sage.schemes.generic.divisor import Divisor_curve sage: from sage.schemes.generic.divisor_group import DivisorGroup - sage: Divisor_curve([(1,P)], parent=DivisorGroup(E)) + sage: Divisor_curve([(1, P)], parent=DivisorGroup(E)) (x, y) """ from sage.schemes.generic.divisor_group import DivisorGroup_curve @@ -369,31 +369,31 @@ def support(self): EXAMPLES:: - sage: x,y = AffineSpace(2, GF(5), names='xy').gens() - sage: C = Curve(y^2 - x^9 - x) - sage: pts = C.rational_points(); pts + sage: x,y = AffineSpace(2, GF(5), names='xy').gens() # optional - sage.rings.finite_rings + sage: C = Curve(y^2 - x^9 - x) # optional - sage.rings.finite_rings + sage: pts = C.rational_points(); pts # optional - sage.rings.finite_rings [(0, 0), (2, 2), (2, 3), (3, 1), (3, 4)] - sage: D = C.divisor_group()([(3,pts[0]), (-1, pts[1])]); D + sage: D = C.divisor_group()([(3, pts[0]), (-1, pts[1])]); D # optional - sage.rings.finite_rings 3*(x, y) - (x - 2, y - 2) - sage: D.support() + sage: D.support() # optional - sage.rings.finite_rings [(0, 0), (2, 2)] TESTS: This checks that :trac:`10732` is fixed:: - sage: R. = GF(5)[] - sage: C = Curve(x^7 + y^7 + z^7) - sage: pts = C.rational_points() - sage: D = C.divisor([(2, pts[0])]) - sage: D.support() + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: C = Curve(x^7 + y^7 + z^7) # optional - sage.rings.finite_rings + sage: pts = C.rational_points() # optional - sage.rings.finite_rings + sage: D = C.divisor([(2, pts[0])]) # optional - sage.rings.finite_rings + sage: D.support() # optional - sage.rings.finite_rings [(0 : 4 : 1)] - sage: (D + D).support() + sage: (D + D).support() # optional - sage.rings.finite_rings [(0 : 4 : 1)] - sage: E = C.divisor([(-3, pts[1]), (1, pts[2])]) - sage: (D - 2*E).support() + sage: E = C.divisor([(-3, pts[1]), (1, pts[2])]) # optional - sage.rings.finite_rings + sage: (D - 2*E).support() # optional - sage.rings.finite_rings [(0 : 4 : 1), (1 : 2 : 1), (2 : 1 : 1)] - sage: (D - D).support() + sage: (D - D).support() # optional - sage.rings.finite_rings [] """ try: @@ -418,18 +418,18 @@ def coefficient(self, P): EXAMPLES:: - sage: x,y = AffineSpace(2, GF(5), names='xy').gens() - sage: C = Curve(y^2 - x^9 - x) - sage: pts = C.rational_points(); pts + sage: x,y = AffineSpace(2, GF(5), names='xy').gens() # optional - sage.rings.finite_rings + sage: C = Curve(y^2 - x^9 - x) # optional - sage.rings.finite_rings + sage: pts = C.rational_points(); pts # optional - sage.rings.finite_rings [(0, 0), (2, 2), (2, 3), (3, 1), (3, 4)] - sage: D = C.divisor(pts[0]) - sage: D.coefficient(pts[0]) + sage: D = C.divisor(pts[0]) # optional - sage.rings.finite_rings + sage: D.coefficient(pts[0]) # optional - sage.rings.finite_rings 1 - sage: D = C.divisor([(3,pts[0]), (-1,pts[1])]); D + sage: D = C.divisor([(3, pts[0]), (-1, pts[1])]); D # optional - sage.rings.finite_rings 3*(x, y) - (x - 2, y - 2) - sage: D.coefficient(pts[0]) + sage: D.coefficient(pts[0]) # optional - sage.rings.finite_rings 3 - sage: D.coefficient(pts[1]) + sage: D.coefficient(pts[1]) # optional - sage.rings.finite_rings -1 """ P = self.parent().scheme()(P) diff --git a/src/sage/schemes/generic/divisor_group.py b/src/sage/schemes/generic/divisor_group.py index 1301f783eb1..dfcb699d457 100644 --- a/src/sage/schemes/generic/divisor_group.py +++ b/src/sage/schemes/generic/divisor_group.py @@ -171,7 +171,7 @@ def _element_constructor_(self, x, check=True, reduce=True): EXAMPLES:: sage: from sage.schemes.generic.divisor_group import DivisorGroup - sage: DivZZ=DivisorGroup(Spec(ZZ)) + sage: DivZZ = DivisorGroup(Spec(ZZ)) sage: DivZZ([(2,5)]) 2*V(5) """ @@ -222,16 +222,16 @@ def base_extend(self, R): EXAMPLES:: sage: from sage.schemes.generic.divisor_group import DivisorGroup - sage: DivisorGroup(Spec(ZZ),ZZ).base_extend(QQ) + sage: DivisorGroup(Spec(ZZ), ZZ).base_extend(QQ) Group of QQ-Divisors on Spectrum of Integer Ring - sage: DivisorGroup(Spec(ZZ),ZZ).base_extend(GF(7)) + sage: DivisorGroup(Spec(ZZ), ZZ).base_extend(GF(7)) # optional - sage.rings.finite_rings Group of (Finite Field of size 7)-Divisors on Spectrum of Integer Ring Divisor groups are unique:: sage: A. = AffineSpace(2, CC) sage: C = Curve(y^2 - x^9 - x) - sage: DivisorGroup(C,ZZ).base_extend(QQ) is DivisorGroup(C,QQ) + sage: DivisorGroup(C, ZZ).base_extend(QQ) is DivisorGroup(C, QQ) True """ if self.base_ring().has_coerce_map_from(R): diff --git a/src/sage/schemes/generic/homset.py b/src/sage/schemes/generic/homset.py index c918e2f4395..8534b9b2fa0 100644 --- a/src/sage/schemes/generic/homset.py +++ b/src/sage/schemes/generic/homset.py @@ -80,8 +80,8 @@ class SchemeHomsetFactory(UniqueFactory): EXAMPLES:: - sage: A2 = AffineSpace(QQ,2) - sage: A3 = AffineSpace(QQ,3) + sage: A2 = AffineSpace(QQ, 2) + sage: A3 = AffineSpace(QQ, 3) sage: Hom = A3.Hom(A2) The Hom-sets are uniquely determined by domain and codomain:: @@ -96,7 +96,7 @@ class SchemeHomsetFactory(UniqueFactory): sage: loads(Hom.dumps()) is Hom True - sage: A3_iso = AffineSpace(QQ,3) + sage: A3_iso = AffineSpace(QQ, 3) sage: A3_iso is A3 True sage: Hom_iso = A3_iso.Hom(A2) @@ -133,15 +133,15 @@ def create_key_and_extra_args(self, X, Y, category=None, base=None, EXAMPLES:: - sage: A2 = AffineSpace(QQ,2) - sage: A3 = AffineSpace(QQ,3) + sage: A2 = AffineSpace(QQ, 2) + sage: A3 = AffineSpace(QQ, 3) sage: A3.Hom(A2) # indirect doctest Set of morphisms From: Affine Space of dimension 3 over Rational Field To: Affine Space of dimension 2 over Rational Field sage: from sage.schemes.generic.homset import SchemeHomsetFactory sage: SHOMfactory = SchemeHomsetFactory('test') - sage: key, extra = SHOMfactory.create_key_and_extra_args(A3,A2,check=False) + sage: key, extra = SHOMfactory.create_key_and_extra_args(A3, A2, check=False) sage: key (..., ..., Category of schemes over Rational Field, False) sage: extra @@ -187,8 +187,8 @@ def create_object(self, version, key, **extra_args): EXAMPLES:: - sage: A2 = AffineSpace(QQ,2) - sage: A3 = AffineSpace(QQ,3) + sage: A2 = AffineSpace(QQ, 2) + sage: A3 = AffineSpace(QQ, 3) sage: A3.Hom(A2) is A3.Hom(A2) # indirect doctest True sage: from sage.schemes.generic.homset import SchemeHomsetFactory @@ -231,7 +231,7 @@ class SchemeHomset_generic(HomsetWithBase): - ``category`` -- a category (optional). The category of the Hom-set. - - ``check`` -- boolean (optional, default=``True``). Whether to + - ``check`` -- boolean (optional, default: ``True``). Whether to check the defining data for consistency. EXAMPLES:: @@ -253,8 +253,8 @@ def __reduce__(self): EXAMPLES:: - sage: A2 = AffineSpace(QQ,2) - sage: A3 = AffineSpace(QQ,3) + sage: A2 = AffineSpace(QQ, 2) + sage: A3 = AffineSpace(QQ, 3) sage: Hom = A3.Hom(A2) sage: loads(Hom.dumps()) == Hom True @@ -271,7 +271,7 @@ def __call__(self, *args, **kwds): EXAMPLES:: - sage: A2 = AffineSpace(QQ,2) + sage: A2 = AffineSpace(QQ, 2) sage: A2(4,5) (4, 5) """ @@ -372,13 +372,13 @@ def _element_constructor_(self, x, check=True): sage: R. = QQ[] sage: A. = AffineSpace(R) - sage: C = A.subscheme(x*y-1) + sage: C = A.subscheme(x*y - 1) sage: H = C.Hom(C); H Set of morphisms - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x*y - 1 - To: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x*y - 1 + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x*y - 1 + To: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x*y - 1 sage: H(1) Traceback (most recent call last): ... @@ -448,7 +448,7 @@ def __reduce__(self): EXAMPLES:: - sage: A2 = AffineSpace(QQ,2) + sage: A2 = AffineSpace(QQ, 2) sage: Hom = A2(QQ) sage: loads(Hom.dumps()) == Hom True @@ -481,7 +481,7 @@ def _coerce_map_from_(self, other): sage: A. = AffineSpace(QQ, 3) sage: H = A.subscheme(z) - sage: L = A.subscheme([z, y+z]) + sage: L = A.subscheme([z, y + z]) sage: A(QQ)._coerce_map_from_(H(QQ)) True sage: H(QQ)._coerce_map_from_(L(QQ)) @@ -516,10 +516,10 @@ def _coerce_map_from_(self, other): :: sage: PS = ProjectiveSpace(ZZ, 1, 'x') - sage: PS2 = ProjectiveSpace(Zp(7), 1, 'x') - sage: PS(ZZ).has_coerce_map_from(PS2(Zp(7))) + sage: PS2 = ProjectiveSpace(Zp(7), 1, 'x') # optional - sage.rings.padics + sage: PS(ZZ).has_coerce_map_from(PS2(Zp(7))) # optional - sage.rings.padics False - sage: PS2(Zp(7)).has_coerce_map_from(PS(ZZ)) + sage: PS2(Zp(7)).has_coerce_map_from(PS(ZZ)) # optional - sage.rings.padics True :: @@ -536,16 +536,16 @@ def _coerce_map_from_(self, other): :: - sage: K. = QuadraticField(2) - sage: A. = AffineSpace(QQ, 3) - sage: H = A.subscheme(z) - sage: A(K).has_coerce_map_from(H(QQ)) + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: A. = AffineSpace(QQ, 3) # optional - sage.rings.number_field + sage: H = A.subscheme(z) # optional - sage.rings.number_field + sage: A(K).has_coerce_map_from(H(QQ)) # optional - sage.rings.number_field True TESTS:: sage: P. = ProjectiveSpace(QQ, 1) - sage: X = P. subscheme ([x-y]) + sage: X = P.subscheme([x - y]) sage: P(1,1) == X(1,1) True @@ -631,24 +631,24 @@ def _element_constructor_(self, *v, **kwds): EXAMPLES:: - sage: A2 = AffineSpace(ZZ,2) - sage: F = GF(3) - sage: F_points = A2(F); type(F_points) + sage: A2 = AffineSpace(ZZ, 2) + sage: F = GF(3) # optional - sage.rings.finite_rings + sage: F_points = A2(F); type(F_points) # optional - sage.rings.finite_rings - sage: F_points([2,5]) + sage: F_points([2,5]) # optional - sage.rings.finite_rings (2, 2) - sage: P2 = ProjectiveSpace(GF(3),2) - sage: F. = GF(9,'a') - sage: F_points = P2(F) - sage: type(F_points) + sage: P2 = ProjectiveSpace(GF(3), 2) # optional - sage.rings.finite_rings + sage: F. = GF(9, 'a') # optional - sage.rings.finite_rings + sage: F_points = P2(F) # optional - sage.rings.finite_rings + sage: type(F_points) # optional - sage.rings.finite_rings - sage: F_points([4,2*a]) + sage: F_points([4,2*a]) # optional - sage.rings.finite_rings (1 : 2*a : 1) TESTS:: - sage: F_points._element_constructor_([4,2*a]) + sage: F_points._element_constructor_([4,2*a]) # optional - sage.rings.finite_rings (1 : 2*a : 1) """ if len(v) == 1: @@ -667,18 +667,18 @@ def extended_codomain(self): EXAMPLES:: - sage: P2 = ProjectiveSpace(QQ,2) - sage: K. = NumberField(x^2 + x - (3^3-3)) - sage: K_points = P2(K); K_points + sage: P2 = ProjectiveSpace(QQ, 2) + sage: K. = NumberField(x^2 + x - (3^3-3)) # optional - sage.rings.number_field + sage: K_points = P2(K); K_points # optional - sage.rings.number_field Set of rational points of Projective Space of dimension 2 - over Number Field in a with defining polynomial x^2 + x - 24 + over Number Field in a with defining polynomial x^2 + x - 24 - sage: K_points.codomain() + sage: K_points.codomain() # optional - sage.rings.number_field Projective Space of dimension 2 over Rational Field - sage: K_points.extended_codomain() - Projective Space of dimension 2 over Number Field in a with - defining polynomial x^2 + x - 24 + sage: K_points.extended_codomain() # optional - sage.rings.number_field + Projective Space of dimension 2 + over Number Field in a with defining polynomial x^2 + x - 24 """ if '_extended_codomain' in self.__dict__: return self._extended_codomain @@ -700,7 +700,7 @@ def _repr_(self): EXAMPLES:: - sage: P2 = ProjectiveSpace(ZZ,2) + sage: P2 = ProjectiveSpace(ZZ, 2) sage: P2(QQ)._repr_() 'Set of rational points of Projective Space of dimension 2 over Rational Field' """ @@ -716,7 +716,7 @@ def value_ring(self): EXAMPLES:: - sage: P2 = ProjectiveSpace(ZZ,2) + sage: P2 = ProjectiveSpace(ZZ, 2) sage: P2(QQ).value_ring() Rational Field """ @@ -738,8 +738,8 @@ def cardinality(self): sage: toric_varieties.P2().point_set().cardinality() +Infinity - sage: P2 = toric_varieties.P2(base_ring=GF(3)) - sage: P2.point_set().cardinality() + sage: P2 = toric_varieties.P2(base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: P2.point_set().cardinality() # optional - sage.rings.finite_rings 13 """ if hasattr(self, 'is_finite') and not self.is_finite(): @@ -759,8 +759,8 @@ def list(self): EXAMPLES:: - sage: P1 = toric_varieties.P1(base_ring=GF(3)) - sage: P1.point_set().list() + sage: P1 = toric_varieties.P1(base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: P1.point_set().list() # optional - sage.rings.finite_rings ([0 : 1], [1 : 0], [1 : 1], [1 : 2]) """ return tuple(self) diff --git a/src/sage/schemes/generic/hypersurface.py b/src/sage/schemes/generic/hypersurface.py index 090ffacf59a..fa2326d43e5 100644 --- a/src/sage/schemes/generic/hypersurface.py +++ b/src/sage/schemes/generic/hypersurface.py @@ -24,20 +24,20 @@ def is_Hypersurface(self): """ - Return True if self is a hypersurface, i.e. an object of the type - ProjectiveHypersurface or AffineHypersurface. + Return True if ``self`` is a hypersurface, i.e. an object of the type + :class:`ProjectiveHypersurface` or :class:`AffineHypersurface`. EXAMPLES:: sage: from sage.schemes.generic.hypersurface import is_Hypersurface sage: R. = ZZ[] - sage: H = ProjectiveHypersurface(x*z+y^2) + sage: H = ProjectiveHypersurface(x*z + y^2) sage: is_Hypersurface(H) True :: - sage: H = AffineHypersurface(x*z+y^2) + sage: H = AffineHypersurface(x*z + y^2) sage: is_Hypersurface(H) True @@ -56,39 +56,40 @@ class ProjectiveHypersurface(AlgebraicScheme_subscheme_projective): EXAMPLES:: sage: P. = ProjectiveSpace(ZZ, 2) - sage: ProjectiveHypersurface(x-y, P) - Projective hypersurface defined by x - y in Projective Space of dimension 2 over Integer Ring + sage: ProjectiveHypersurface(x - y, P) + Projective hypersurface defined by x - y + in Projective Space of dimension 2 over Integer Ring :: sage: R. = QQ[] - sage: ProjectiveHypersurface(x-y) - Projective hypersurface defined by x - y in Projective Space of dimension 2 over Rational Field + sage: ProjectiveHypersurface(x - y) + Projective hypersurface defined by x - y + in Projective Space of dimension 2 over Rational Field """ def __init__(self, poly, ambient=None): """ Return the projective hypersurface in the space ambient - defined by the polynomial poly. + defined by the polynomial ``poly``. - If ambient is not given, it will be constructed based on - poly. + If ambient is not given, it will be constructed based on ``poly``. EXAMPLES:: sage: P. = ProjectiveSpace(ZZ, 2) - sage: ProjectiveHypersurface(x-y, P) + sage: ProjectiveHypersurface(x - y, P) Projective hypersurface defined by x - y in Projective Space of dimension 2 over Integer Ring :: sage: R. = QQ[] - sage: ProjectiveHypersurface(x-y) + sage: ProjectiveHypersurface(x - y) Projective hypersurface defined by x - y in Projective Space of dimension 2 over Rational Field TESTS:: - sage: H = ProjectiveHypersurface(x-y) + sage: H = ProjectiveHypersurface(x - y) sage: H == loads(dumps(H)) True """ @@ -111,9 +112,10 @@ def _repr_(self): EXAMPLES:: sage: R. = ZZ[] - sage: H = ProjectiveHypersurface(x*z+y^2) + sage: H = ProjectiveHypersurface(x*z + y^2) sage: H - Projective hypersurface defined by y^2 + x*z in Projective Space of dimension 2 over Integer Ring + Projective hypersurface defined by y^2 + x*z + in Projective Space of dimension 2 over Integer Ring sage: H._repr_() 'Projective hypersurface defined by y^2 + x*z in Projective Space of dimension 2 over Integer Ring' """ @@ -128,7 +130,7 @@ def defining_polynomial(self): EXAMPLES:: sage: R. = ZZ[] - sage: H = ProjectiveHypersurface(x*z+y^2) + sage: H = ProjectiveHypersurface(x*z + y^2) sage: H.defining_polynomial() y^2 + x*z """ @@ -142,14 +144,16 @@ class AffineHypersurface(AlgebraicScheme_subscheme_affine): EXAMPLES:: sage: A. = AffineSpace(ZZ, 3) - sage: AffineHypersurface(x*y-z^3, A) - Affine hypersurface defined by -z^3 + x*y in Affine Space of dimension 3 over Integer Ring + sage: AffineHypersurface(x*y - z^3, A) + Affine hypersurface defined by -z^3 + x*y + in Affine Space of dimension 3 over Integer Ring :: sage: A. = QQ[] - sage: AffineHypersurface(x*y-z^3) - Affine hypersurface defined by -z^3 + x*y in Affine Space of dimension 3 over Rational Field + sage: AffineHypersurface(x*y - z^3) + Affine hypersurface defined by -z^3 + x*y + in Affine Space of dimension 3 over Rational Field """ def __init__(self, poly, ambient=None): """ @@ -162,18 +166,20 @@ def __init__(self, poly, ambient=None): EXAMPLES:: sage: A. = AffineSpace(ZZ, 3) - sage: AffineHypersurface(x*y-z^3, A) - Affine hypersurface defined by -z^3 + x*y in Affine Space of dimension 3 over Integer Ring + sage: AffineHypersurface(x*y - z^3, A) + Affine hypersurface defined by -z^3 + x*y + in Affine Space of dimension 3 over Integer Ring :: sage: A. = QQ[] - sage: AffineHypersurface(x*y-z^3) - Affine hypersurface defined by -z^3 + x*y in Affine Space of dimension 3 over Rational Field + sage: AffineHypersurface(x*y - z^3) + Affine hypersurface defined by -z^3 + x*y + in Affine Space of dimension 3 over Rational Field TESTS:: - sage: H = AffineHypersurface(x*y-z^3) + sage: H = AffineHypersurface(x*y - z^3) sage: H == loads(dumps(H)) True """ @@ -194,9 +200,10 @@ def _repr_(self): EXAMPLES:: sage: R. = ZZ[] - sage: H = AffineHypersurface(x*z+y^2) + sage: H = AffineHypersurface(x*z + y^2) sage: H - Affine hypersurface defined by y^2 + x*z in Affine Space of dimension 3 over Integer Ring + Affine hypersurface defined by y^2 + x*z + in Affine Space of dimension 3 over Integer Ring sage: H._repr_() 'Affine hypersurface defined by y^2 + x*z in Affine Space of dimension 3 over Integer Ring' """ @@ -211,7 +218,7 @@ def defining_polynomial(self): EXAMPLES:: sage: R. = ZZ[] - sage: H = AffineHypersurface(x*z+y^2) + sage: H = AffineHypersurface(x*z + y^2) sage: H.defining_polynomial() y^2 + x*z """ diff --git a/src/sage/schemes/generic/morphism.py b/src/sage/schemes/generic/morphism.py index d3fe7abd885..086c2960755 100644 --- a/src/sage/schemes/generic/morphism.py +++ b/src/sage/schemes/generic/morphism.py @@ -9,9 +9,9 @@ all schemes. If you want to extend the Sage library with some new kind of scheme, -your new class (say, ``myscheme``) should provide a method +your new class (say, ``MyScheme``) should provide a method -* ``myscheme._morphism(*args, **kwds)`` returning a morphism +* ``MyScheme._morphism(*args, **kwds)`` returning a morphism between two schemes in your category, usually defined via polynomials. Your morphism class should derive from :class:`SchemeMorphism_polynomial`. These morphisms will usually be @@ -22,17 +22,17 @@ subcategory of schemes. If you want to do this, you should also provide a method -* ``myscheme._homset(*args, **kwds)`` returning a +* ``MyScheme._homset(*args, **kwds)`` returning a Hom-set, which must be an element of a derived class of :class:`~sage.schemes.generic.homset.SchemeHomset_generic`. If your - new Hom-set class does not use ``myscheme._morphism`` then you + new Hom-set class does not use ``MyScheme._morphism`` then you do not have to provide it. Note that points on schemes are morphisms `Spec(K)\to X`, too. But we typically use a different notation, so they are implemented in a different derived class. For this, you should implement a method -* ``myscheme._point(*args, **kwds)`` returning a point, that is, +* ``MyScheme._point(*args, **kwds)`` returning a point, that is, a morphism `Spec(K)\to X`. Your point class should derive from :class:`SchemeMorphism_point`. @@ -40,10 +40,10 @@ example the point Hom-set can provide a method to enumerate all points. If you want to do this, you should also provide a method -* ``myscheme._point_homset(*args, **kwds)`` returning +* ``MyScheme._point_homset(*args, **kwds)`` returning the :mod:`~sage.schemes.generic.homset` of points. The Hom-sets of points are implemented in classes named ``SchemeHomset_points_...``. - If your new Hom-set class does not use ``myscheme._point`` then + If your new Hom-set class does not use ``MyScheme._point`` then you do not have to provide it. AUTHORS: @@ -105,11 +105,10 @@ def is_SchemeMorphism(f): EXAMPLES:: - sage: A. = AffineSpace(QQ,2); H = A.Hom(A) - sage: f = H([y,x^2+y]); f + sage: A. = AffineSpace(QQ, 2); H = A.Hom(A) + sage: f = H([y, x^2 + y]); f Scheme endomorphism of Affine Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (y, x^2 + y) + Defn: Defined on coordinates by sending (x, y) to (y, x^2 + y) sage: from sage.schemes.generic.morphism import is_SchemeMorphism sage: is_SchemeMorphism(f) True @@ -143,7 +142,7 @@ class SchemeMorphism(Element): TESTS:: - sage: A2 = AffineSpace(QQ,2) + sage: A2 = AffineSpace(QQ, 2) sage: A2.structure_morphism().domain() Affine Space of dimension 2 over Rational Field sage: A2.structure_morphism().category() @@ -179,7 +178,7 @@ def domain(self): sage: A. = AffineSpace(QQ['x,y']) sage: H = A.Hom(A) - sage: f = H([y,x^2+y]) + sage: f = H([y, x^2 + y]) sage: f.domain() is A True """ @@ -194,7 +193,7 @@ def codomain(self): sage: A. = AffineSpace(QQ['x,y']) sage: H = A.Hom(A) - sage: f = H([y,x^2+y]) + sage: f = H([y, x^2 + y]) sage: f.codomain() is A True """ @@ -217,17 +216,17 @@ def __call__(self, x, *args, **kwds): sage: R. = QQ[] sage: A. = AffineSpace(R) sage: H = A.Hom(A) - sage: f = H([y,x^2+y]) + sage: f = H([y, x^2 + y]) sage: f([2,3]) # indirect doctest (3, 7) An example with optional arguments:: - sage: PS.=ProjectiveSpace(QQ,1) - sage: H=Hom(PS,PS) - sage: f=H([x^3,x*y^2]) - sage: P=PS(0,1) - sage: f(P,check=False) # indirect doctest + sage: PS. = ProjectiveSpace(QQ, 1) + sage: H = Hom(PS, PS) + sage: f = H([x^3, x*y^2]) + sage: P = PS(0, 1) + sage: f(P, check=False) # indirect doctest (0 : 0) """ P = parent(x) @@ -302,7 +301,7 @@ def _repr_type(self): EXAMPLES:: - sage: A2 = AffineSpace(QQ,2) + sage: A2 = AffineSpace(QQ, 2) sage: A2.structure_morphism() # indirect doctest Scheme morphism: From: Affine Space of dimension 2 over Rational Field @@ -353,7 +352,7 @@ def __mul__(self, right): Identity maps do not contribute to the product:: - sage: X = AffineSpace(QQ,2) + sage: X = AffineSpace(QQ, 2) sage: id = X.identity_morphism() sage: id^0 # indirect doctest Scheme endomorphism of Affine Space of dimension 2 over Rational Field @@ -364,12 +363,12 @@ def __mul__(self, right): Here, we see a formal composition:: - sage: X = AffineSpace(QQ,2) + sage: X = AffineSpace(QQ, 2) sage: f = X.structure_morphism() sage: Y = Spec(QQ) sage: g = Y.structure_morphism() sage: g * f # indirect doctest - Composite map: + Composite map: From: Affine Space of dimension 2 over Rational Field To: Spectrum of Integer Ring Defn: Generic morphism: @@ -418,7 +417,7 @@ def __pow__(self, n, dummy=None): EXAMPLES:: - sage: X = AffineSpace(QQ,2) + sage: X = AffineSpace(QQ, 2) sage: id = X.identity_morphism() sage: id^0 Scheme endomorphism of Affine Space of dimension 2 over Rational Field @@ -443,7 +442,7 @@ def category(self): EXAMPLES:: - sage: A2 = AffineSpace(QQ,2) + sage: A2 = AffineSpace(QQ, 2) sage: A2.structure_morphism().category() Category of homsets of schemes """ @@ -455,7 +454,7 @@ def category_for(self): EXAMPLES:: - sage: A2 = AffineSpace(QQ,2) + sage: A2 = AffineSpace(QQ, 2) sage: A2.structure_morphism().category_for() Category of schemes """ @@ -471,7 +470,7 @@ def is_endomorphism(self) -> bool: EXAMPLES:: - sage: X = AffineSpace(QQ,2) + sage: X = AffineSpace(QQ, 2) sage: X.structure_morphism().is_endomorphism() False sage: X.identity_morphism().is_endomorphism() @@ -491,7 +490,7 @@ def base_ring(self): EXAMPLES:: sage: P. = ProjectiveSpace(QQ, 1) - sage: H = Hom(P,P) + sage: H = Hom(P, P) sage: f = H([3/5*x^2, 6*y^2]) sage: f.base_ring() Rational Field @@ -514,9 +513,9 @@ def base_ring(self): :: - sage: E = EllipticCurve(GF((17,2)), [1,2,3,4,5]) - sage: P = E.random_point() - sage: P.base_ring() + sage: E = EllipticCurve(GF((17,2)), [1,2,3,4,5]) # optional - sage.rings.finite_rings + sage: P = E.random_point() # optional - sage.rings.finite_rings + sage: P.base_ring() # optional - sage.rings.finite_rings Finite Field in z2 of size 17^2 """ return self.domain().base_ring() @@ -532,7 +531,7 @@ def _composition(self, right): EXAMPLES:: - sage: X = AffineSpace(QQ,2) + sage: X = AffineSpace(QQ, 2) sage: f = X.structure_morphism() sage: Y = Spec(QQ) sage: g = Y.structure_morphism() @@ -554,7 +553,8 @@ def _composition(self, right): TypeError: self (=Scheme morphism: From: Affine Space of dimension 2 over Rational Field To: Spectrum of Rational Field - Defn: Structure map) domain must equal right (=Scheme morphism: + Defn: Structure map) domain + must equal right (=Scheme morphism: From: Spectrum of Rational Field To: Spectrum of Integer Ring Defn: Structure map) codomain @@ -582,12 +582,12 @@ def _composition_(self, right, homset): EXAMPLES:: - sage: X = AffineSpace(QQ,2) + sage: X = AffineSpace(QQ, 2) sage: f = X.structure_morphism() sage: Y = Spec(QQ) sage: g = Y.structure_morphism() sage: g * f # indirect doctest - Composite map: + Composite map: From: Affine Space of dimension 2 over Rational Field To: Spectrum of Integer Ring Defn: Generic morphism: @@ -640,13 +640,13 @@ def glue_along_domains(self, other): X: Spectrum of Univariate Polynomial Ring in x over Rational Field Y: Spectrum of Univariate Polynomial Ring in y over Rational Field U: Spectrum of Quotient of Multivariate Polynomial Ring in x, y - over Rational Field by the ideal (x*y - 1) + over Rational Field by the ideal (x*y - 1) sage: a, b = P1.gluing_maps() sage: a Affine Scheme morphism: - From: Spectrum of Quotient of Multivariate Polynomial Ring in x, y - over Rational Field by the ideal (x*y - 1) + From: Spectrum of Quotient of Multivariate Polynomial Ring in x, y + over Rational Field by the ideal (x*y - 1) To: Spectrum of Univariate Polynomial Ring in x over Rational Field Defn: Ring morphism: From: Univariate Polynomial Ring in x over Rational Field @@ -956,8 +956,8 @@ class SchemeMorphism_polynomial(SchemeMorphism): sage: R. = QQ[] sage: A2 = AffineSpace(R) sage: H = A2.Hom(A2) - sage: f = H([x-y, x*y]) - sage: f([0,1]) + sage: f = H([x - y, x*y]) + sage: f([0, 1]) (-1, 0) An example involving the projective line:: @@ -965,8 +965,8 @@ class SchemeMorphism_polynomial(SchemeMorphism): sage: R. = QQ[] sage: P1 = ProjectiveSpace(R) sage: H = P1.Hom(P1) - sage: f = H([x^2+y^2,x*y]) - sage: f([0,1]) + sage: f = H([x^2 + y^2, x*y]) + sage: f([0, 1]) (1 : 0) Some checks are performed to make sure the given polynomials @@ -987,12 +987,11 @@ def __init__(self, parent, polys, check=True): EXAMPLES:: - sage: A2. = AffineSpace(QQ,2) + sage: A2. = AffineSpace(QQ, 2) sage: H = A2.Hom(A2) - sage: H([x-y, x*y]) + sage: H([x - y, x*y]) Scheme endomorphism of Affine Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (x - y, x*y) + Defn: Defined on coordinates by sending (x, y) to (x - y, x*y) """ if check: if not isinstance(polys, (list, tuple)): @@ -1054,7 +1053,7 @@ def defining_polynomials(self): sage: R. = QQ[] sage: A. = AffineSpace(R) sage: H = A.Hom(A) - sage: H([x^3+y, 1-x-y]).defining_polynomials() + sage: H([x^3 + y, 1 - x - y]).defining_polynomials() (x^3 + y, -x - y + 1) """ return self._polys @@ -1077,8 +1076,8 @@ def _call_(self, x): sage: R. = QQ[] sage: A. = AffineSpace(R) sage: H = A.Hom(A) - sage: f = H([y,x^2+y]) - sage: f([2,3]) # indirect doctest + sage: f = H([y, x^2 + y]) + sage: f([2, 3]) # indirect doctest (3, 7) An example with algebraic schemes:: @@ -1090,12 +1089,11 @@ def _call_(self, x): sage: f = Hom_XY([y,0]) # (0,y) |-> (y,0) sage: f Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x - To: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y - Defn: Defined on coordinates by sending (x, y) to - (y, 0) + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x + To: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: y + Defn: Defined on coordinates by sending (x, y) to (y, 0) sage: f([0,3]) (3, 0) @@ -1112,24 +1110,24 @@ def _call_(self, x): It is possible to avoid the checks on the resulting point which can be useful for indeterminacies, but be careful!! :: - sage: PS.=ProjectiveSpace(QQ,1) - sage: H=Hom(PS,PS) - sage: f=H([x^3,x*y^2]) - sage: P=PS(0,1) - sage: f(P,check=False) + sage: PS. = ProjectiveSpace(QQ, 1) + sage: H = Hom(PS, PS) + sage: f = H([x^3, x*y^2]) + sage: P = PS(0,1) + sage: f(P, check=False) (0 : 0) - sage: P.=ProjectiveSpace(ZZ,2) - sage: X=P.subscheme(x^2-y^2) - sage: H=Hom(X,X) - sage: f=H([x^2,y^2,z^2]) + sage: P. = ProjectiveSpace(ZZ, 2) + sage: X = P.subscheme(x^2 - y^2) + sage: H = Hom(X, X) + sage: f = H([x^2, y^2, z^2]) sage: f([4,4,1]) (16 : 16 : 1) - sage: P.=ProjectiveSpace(ZZ,2) - sage: X=P.subscheme(x^2-y^2) - sage: H=Hom(X,X) - sage: f=H([x^2,y^2,z^2]) + sage: P. = ProjectiveSpace(ZZ, 2) + sage: X = P.subscheme(x^2 - y^2) + sage: H = Hom(X, X) + sage: f = H([x^2, y^2, z^2]) sage: f(P([4,4,1])) (16 : 16 : 1) """ @@ -1155,7 +1153,7 @@ def _call_with_args(self, x, args, kwds): sage: R. = QQ[] sage: A. = AffineSpace(R) sage: H = A.Hom(A) - sage: f = H([y,x^2+y]) + sage: f = H([y, x^2 + y]) sage: f([2,3]) (3, 7) @@ -1168,12 +1166,11 @@ def _call_with_args(self, x, args, kwds): sage: f = Hom_XY([y,0]) # (0,y) |-> (y,0) sage: f Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x - To: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y - Defn: Defined on coordinates by sending (x, y) to - (y, 0) + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x + To: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: y + Defn: Defined on coordinates by sending (x, y) to (y, 0) sage: f([0,3]) (3, 0) @@ -1190,19 +1187,19 @@ def _call_with_args(self, x, args, kwds): It is possible to avoid the checks on the resulting point which can be useful for indeterminacies, but be careful!! :: - sage: PS.=ProjectiveSpace(QQ,1) - sage: H=Hom(PS,PS) - sage: f=H([x^3,x*y^2]) - sage: P=PS(0,1) - sage: f(P,check=False) # indirect doctest + sage: PS. = ProjectiveSpace(QQ, 1) + sage: H = Hom(PS,PS) + sage: f = H([x^3, x*y^2]) + sage: P = PS(0,1) + sage: f(P, check=False) # indirect doctest (0 : 0) :: - sage: P.=ProjectiveSpace(ZZ,2) - sage: X=P.subscheme(x^2-y^2) - sage: H=Hom(X,X) - sage: f=H([x^2,y^2,z^2]) + sage: P. = ProjectiveSpace(ZZ, 2) + sage: X = P.subscheme(x^2 - y^2) + sage: H = Hom(X, X) + sage: f = H([x^2, y^2, z^2]) sage: f([4,4,1]) (16 : 16 : 1) @@ -1210,7 +1207,7 @@ def _call_with_args(self, x, args, kwds): sage: P. = ProjectiveSpace(ZZ, 2) sage: P2. = ProjectiveSpace(ZZ, 3) - sage: X = P.subscheme(x^2-y^2) + sage: X = P.subscheme(x^2 - y^2) sage: H = Hom(X, X) sage: f = H([x^2, y^2, z^2]) sage: f(P2([4,4,1,1])) @@ -1241,10 +1238,9 @@ def _repr_defn(self): sage: R. = QQ[] sage: A. = AffineSpace(R) sage: H = A.Hom(A) - sage: f = H([y,x^2+y]) + sage: f = H([y, x^2 + y]) sage: print(f._repr_defn()) - Defined on coordinates by sending (x, y) to - (y, x^2 + y) + Defined on coordinates by sending (x, y) to (y, x^2 + y) """ i = self.domain().ambient_space()._repr_generic_point() o = self._codomain.ambient_space()._repr_generic_point(self.defining_polynomials()) @@ -1264,9 +1260,9 @@ def __getitem__(self, i): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,1) - sage: H = Hom(P,P) - sage: f = H([3/5*x^2,6*y^2]) + sage: P. = ProjectiveSpace(QQ, 1) + sage: H = Hom(P, P) + sage: f = H([3/5*x^2, 6*y^2]) sage: f[1] 6*y^2 """ @@ -1282,7 +1278,7 @@ def __copy__(self): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,1) + sage: P. = ProjectiveSpace(QQ, 1) sage: H = Hom(P, P) sage: f = H([3/5*x^2, 6*y^2]) sage: g = copy(f) @@ -1293,7 +1289,7 @@ def __copy__(self): :: - sage: P. = ProjectiveSpace(QQ,2) + sage: P. = ProjectiveSpace(QQ, 2) sage: X = P.subscheme(x^2 - y^2) sage: Q = X(23, 23, 46) sage: P = X(1, 1, 1) @@ -1304,27 +1300,24 @@ def __copy__(self): def coordinate_ring(self): r""" - Returns the coordinate ring of the ambient projective space - the multivariable polynomial ring over the base ring + Return the coordinate ring of the ambient projective space. - OUTPUT: - - - ring + OUTPUT: A multivariable polynomial ring over the base ring. EXAMPLES:: - sage: P.=ProjectiveSpace(QQ,1) - sage: H=Hom(P,P) - sage: f=H([3/5*x^2,6*y^2]) + sage: P. = ProjectiveSpace(QQ, 1) + sage: H = Hom(P, P) + sage: f = H([3/5*x^2, 6*y^2]) sage: f.coordinate_ring() Multivariate Polynomial Ring in x, y over Rational Field :: - sage: R.=PolynomialRing(ZZ,1) - sage: P.=ProjectiveSpace(R,1) - sage: H=Hom(P,P) - sage: f=H([3*x^2,y^2]) + sage: R. = PolynomialRing(ZZ, 1) + sage: P. = ProjectiveSpace(R, 1) + sage: H = Hom(P, P) + sage: f = H([3*x^2, y^2]) sage: f.coordinate_ring() Multivariate Polynomial Ring in x, y over Multivariate Polynomial Ring in t over Integer Ring @@ -1351,25 +1344,25 @@ def change_ring(self, R, check=True): sage: R. = QQ[] sage: K. = QuadraticField(2) - sage: K2. = NumberField(t**4-2) - sage: P. = ProjectiveSpace(QQ,1) - sage: phi = K.embeddings(K2)[0] - sage: f = DynamicalSystem_projective([x**2+3*y**2,y**2]) - sage: f.change_ring(phi) - Dynamical System of Projective Space of dimension 1 over Number Field in w with defining polynomial t^4 - 2 - Defn: Defined on coordinates by sending (x : y) to - (x^2 + 3*y^2 : y^2) + sage: K2. = NumberField(t**4 - 2) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(QQ, 1) # optional - sage.rings.number_field + sage: phi = K.embeddings(K2)[0] # optional - sage.rings.number_field + sage: f = DynamicalSystem_projective([x**2 + 3*y**2, y**2]) # optional - sage.rings.number_field + sage: f.change_ring(phi) # optional - sage.rings.number_field + Dynamical System of Projective Space of dimension 1 over + Number Field in w with defining polynomial t^4 - 2 + Defn: Defined on coordinates by sending (x : y) to (x^2 + 3*y^2 : y^2) :: sage: R. = QQ[] - sage: K. = QuadraticField(2) - sage: K1. = NumberField(t^4-2) - sage: K2. = NumberField(t^8-2) - sage: P. = ProjectiveSpace(K,1) - sage: phi = K1.embeddings(K2)[0] - sage: f = DynamicalSystem_projective([x^2+3*y^2,y^2]) - sage: f.change_ring(phi) + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: K1. = NumberField(t^4 - 2) # optional - sage.rings.number_field + sage: K2. = NumberField(t^8 - 2) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: phi = K1.embeddings(K2)[0] # optional - sage.rings.number_field + sage: f = DynamicalSystem_projective([x^2 + 3*y^2, y^2]) # optional - sage.rings.number_field + sage: f.change_ring(phi) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: no canonical coercion of base ring of morphism to domain of embedding @@ -1378,46 +1371,43 @@ def change_ring(self, R, check=True): EXAMPLES:: sage: P. = ProjectiveSpace(ZZ, 1) - sage: H = Hom(P,P) + sage: H = Hom(P, P) sage: f = H([3*x^2, y^2]) - sage: f.change_ring(GF(3)) + sage: f.change_ring(GF(3)) # optional - sage.rings.finite_rings Scheme endomorphism of Projective Space of dimension 1 over Finite Field of size 3 - Defn: Defined on coordinates by sending (x : y) to - (0 : y^2) + Defn: Defined on coordinates by sending (x : y) to (0 : y^2) :: sage: P. = ProjectiveSpace(QQ, 2) - sage: H = Hom(P,P) - sage: f = H([5/2*x^3 + 3*x*y^2-y^3, 3*z^3 + y*x^2, x^3-z^3]) - sage: f.change_ring(GF(3)) + sage: H = Hom(P, P) + sage: f = H([5/2*x^3 + 3*x*y^2 - y^3, 3*z^3 + y*x^2, x^3 - z^3]) + sage: f.change_ring(GF(3)) # optional - sage.rings.finite_rings Scheme endomorphism of Projective Space of dimension 2 over Finite Field of size 3 - Defn: Defined on coordinates by sending (x : y : z) to + Defn: Defined on coordinates by sending (x : y : z) to (x^3 - y^3 : x^2*y : x^3 - z^3) :: sage: P. = ProjectiveSpace(QQ, 1) sage: X = P.subscheme([5*x^2 - y^2]) - sage: H = Hom(X,X) + sage: H = Hom(X, X) sage: f = H([x, y]) - sage: f.change_ring(GF(3)) - Scheme endomorphism of Closed subscheme of Projective Space of dimension - 1 over Finite Field of size 3 defined by: - -x^2 - y^2 - Defn: Defined on coordinates by sending (x : y) to - (x : y) + sage: f.change_ring(GF(3)) # optional - sage.rings.finite_rings + Scheme endomorphism of Closed subscheme of Projective Space of dimension 1 + over Finite Field of size 3 defined by: -x^2 - y^2 + Defn: Defined on coordinates by sending (x : y) to (x : y) Check that :trac:`16834` is fixed:: sage: A. = AffineSpace(RR, 3) - sage: h = Hom(A,A) - sage: f = h([x^2+1.5, y^3, z^5-2.0]) + sage: h = Hom(A, A) + sage: f = h([x^2 + 1.5, y^3, z^5 - 2.0]) sage: f.change_ring(CC) Scheme endomorphism of Affine Space of dimension 3 over Complex Field with 53 bits of precision - Defn: Defined on coordinates by sending (x, y, z) to - (x^2 + 1.50000000000000, y^3, z^5 - 2.00000000000000) + Defn: Defined on coordinates by sending (x, y, z) to + (x^2 + 1.50000000000000, y^3, z^5 - 2.00000000000000) :: @@ -1429,49 +1419,48 @@ def change_ring(self, R, check=True): Scheme morphism: From: Affine Space of dimension 2 over Rational Field To: Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x, y) to - (x^2 : y^2) + Defn: Defined on coordinates by sending (x, y) to (x^2 : y^2) :: - sage: A. = AffineSpace(QQ,2) - sage: H = Hom(A,A) + sage: A. = AffineSpace(QQ, 2) + sage: H = Hom(A, A) sage: f = H([3*x^2/y, y^2/x]) sage: f.change_ring(RR) Scheme endomorphism of Affine Space of dimension 2 over Real Field with 53 bits of precision - Defn: Defined on coordinates by sending (x, y) to + Defn: Defined on coordinates by sending (x, y) to (3.00000000000000*x^2/y, y^2/x) :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^3-x+1) - sage: P. = ProjectiveSpace(K, 1) - sage: H = End(P) - sage: f = H([x^2 + a*x*y + a^2*y^2, y^2]) - sage: emb = K.embeddings(QQbar) - sage: f.change_ring(emb[0]) - Scheme endomorphism of Projective Space of dimension 1 over Algebraic - Field + sage: K. = NumberField(x^3 - x + 1) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: H = End(P) # optional - sage.rings.number_field + sage: f = H([x^2 + a*x*y + a^2*y^2, y^2]) # optional - sage.rings.number_field + sage: emb = K.embeddings(QQbar) # optional - sage.rings.number_field + sage: f.change_ring(emb[0]) # optional - sage.rings.number_field + Scheme endomorphism of Projective Space of dimension 1 + over Algebraic Field Defn: Defined on coordinates by sending (x : y) to (x^2 + (-1.324717957244746?)*x*y + 1.754877666246693?*y^2 : y^2) - sage: f.change_ring(emb[1]) - Scheme endomorphism of Projective Space of dimension 1 over Algebraic - Field + sage: f.change_ring(emb[1]) # optional - sage.rings.number_field + Scheme endomorphism of Projective Space of dimension 1 + over Algebraic Field Defn: Defined on coordinates by sending (x : y) to - (x^2 + (0.6623589786223730? - 0.5622795120623013?*I)*x*y + - (0.1225611668766537? - 0.744861766619745?*I)*y^2 : y^2) + (x^2 + (0.6623589786223730? - 0.5622795120623013?*I)*x*y + + (0.1225611668766537? - 0.744861766619745?*I)*y^2 : y^2) :: - sage: K. = QuadraticField(2, embedding=QQbar(sqrt(2))) - sage: P. = ProjectiveSpace(K, 1) - sage: H = End(P) - sage: f = H([x^2+v*y^2, y^2]) - sage: f.change_ring(QQbar) - Scheme endomorphism of Projective Space of dimension 1 over Algebraic - Field + sage: K. = QuadraticField(2, embedding=QQbar(sqrt(2))) # optional - sage.rings.number_field sage.symbolic + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field sage.symbolic + sage: H = End(P) # optional - sage.rings.number_field sage.symbolic + sage: f = H([x^2 + v*y^2, y^2]) # optional - sage.rings.number_field sage.symbolic + sage: f.change_ring(QQbar) # optional - sage.rings.number_field sage.symbolic + Scheme endomorphism of Projective Space of dimension 1 + over Algebraic Field Defn: Defined on coordinates by sending (x : y) to (x^2 + 1.414213562373095?*y^2 : y^2) @@ -1479,42 +1468,40 @@ def change_ring(self, R, check=True): sage: from sage.misc.verbose import set_verbose sage: set_verbose(-1) - sage: K. = QuadraticField(2, embedding=QQbar(-sqrt(2))) - sage: P. = ProjectiveSpace(K, 1) - sage: X = P.subscheme(x-y) - sage: H = End(X) - sage: f = H([6*x^2+2*x*y+16*y^2, -w*x^2-4*x*y-4*y^2]) - sage: f.change_ring(QQbar) - Scheme endomorphism of Closed subscheme of Projective Space of dimension - 1 over Algebraic Field defined by: - x - y + sage: K. = QuadraticField(2, embedding=QQbar(-sqrt(2))) # optional - sage.rings.number_field sage.symbolic + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field sage.symbolic + sage: X = P.subscheme(x - y) # optional - sage.rings.number_field sage.symbolic + sage: H = End(X) # optional - sage.rings.number_field sage.symbolic + sage: f = H([6*x^2 + 2*x*y + 16*y^2, -w*x^2 - 4*x*y - 4*y^2]) # optional - sage.rings.number_field sage.symbolic + sage: f.change_ring(QQbar) # optional - sage.rings.number_field sage.symbolic + Scheme endomorphism of Closed subscheme of Projective Space of dimension 1 + over Algebraic Field defined by: x - y Defn: Defined on coordinates by sending (x : y) to - (6*x^2 + 2*x*y + 16*y^2 : 1.414213562373095?*x^2 + (-4)*x*y + (-4)*y^2) + (6*x^2 + 2*x*y + 16*y^2 : 1.414213562373095?*x^2 + (-4)*x*y + (-4)*y^2) :: sage: R. = QQ[] - sage: f = x^6-2 - sage: L. = NumberField(f, embedding=f.roots(QQbar)[1][0]) - sage: A. = AffineSpace(L,2) - sage: H = Hom(A,A) - sage: F = H([b*x/y, 1+y]) - sage: F.change_ring(QQbar) + sage: f = x^6 - 2 + sage: L. = NumberField(f, embedding=f.roots(QQbar)[1][0]) # optional - sage.rings.number_field + sage: A. = AffineSpace(L, 2) # optional - sage.rings.number_field + sage: H = Hom(A, A) # optional - sage.rings.number_field + sage: F = H([b*x/y, 1 + y]) # optional - sage.rings.number_field + sage: F.change_ring(QQbar) # optional - sage.rings.number_field Scheme endomorphism of Affine Space of dimension 2 over Algebraic Field Defn: Defined on coordinates by sending (x, y) to (1.122462048309373?*x/y, y + 1) :: - sage: K. = QuadraticField(-1) - sage: A. = AffineSpace(K, 2) - sage: H = End(A) - sage: phi = H([x/y, y]) - sage: emb = K.embeddings(QQbar)[0] - sage: phi.change_ring(emb) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: A. = AffineSpace(K, 2) # optional - sage.rings.number_field + sage: H = End(A) # optional - sage.rings.number_field + sage: phi = H([x/y, y]) # optional - sage.rings.number_field + sage: emb = K.embeddings(QQbar)[0] # optional - sage.rings.number_field + sage: phi.change_ring(emb) # optional - sage.rings.number_field Scheme endomorphism of Affine Space of dimension 2 over Algebraic Field - Defn: Defined on coordinates by sending (x, y) to - (x/y, y) + Defn: Defined on coordinates by sending (x, y) to (x/y, y) """ T = self.domain().change_ring(R) if self.is_endomorphism(): @@ -1581,11 +1568,10 @@ def specialization(self, D=None, phi=None, homset=None): sage: R. = PolynomialRing(QQ) sage: P. = ProjectiveSpace(R, 1) sage: H = End(P) - sage: f = H([x^2 + c*y^2,y^2]) - sage: f.specialization({c:1}) + sage: f = H([x^2 + c*y^2, y^2]) + sage: f.specialization({c: 1}) Scheme endomorphism of Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y) to - (x^2 + y^2 : y^2) + Defn: Defined on coordinates by sending (x : y) to (x^2 + y^2 : y^2) :: @@ -1594,12 +1580,12 @@ def specialization(self, D=None, phi=None, homset=None): sage: H = End(P) sage: f = H([x^3 + a*x*y^2 + b*y^3, y^3]) sage: from sage.rings.polynomial.flatten import SpecializationMorphism - sage: phi = SpecializationMorphism(P.coordinate_ring(), dict({a:2,b:-1})) + sage: phi = SpecializationMorphism(P.coordinate_ring(), {a: 2, b: -1}) sage: F = f.specialization(phi=phi); F Scheme endomorphism of Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y) to - (x^3 + 2*x*y^2 - y^3 : y^3) - sage: g = H([x^2 + a*y^2,y^2]) + Defn: Defined on coordinates by sending (x : y) to + (x^3 + 2*x*y^2 - y^3 : y^3) + sage: g = H([x^2 + a*y^2, y^2]) sage: G = g.specialization(phi=phi) sage: G.parent() is F.parent() True @@ -1614,19 +1600,18 @@ def specialization(self, D=None, phi=None, homset=None): sage: X = P.subscheme([x - c*y]) sage: H = End(X) sage: f = H([x^2, c*y^2]) - sage: f.specialization({c:2}) - Scheme endomorphism of Closed subscheme of Projective Space of dimension 1 over Rational Field defined by: - x - 2*y - Defn: Defined on coordinates by sending (x : y) to - (x^2 : 2*y^2) + sage: f.specialization({c: 2}) + Scheme endomorphism of Closed subscheme of Projective Space of dimension 1 + over Rational Field defined by: x - 2*y + Defn: Defined on coordinates by sending (x : y) to (x^2 : 2*y^2) :: sage: R. = QQ[] - sage: P. = ProjectiveSpace(R,1) + sage: P. = ProjectiveSpace(R, 1) sage: f = DynamicalSystem_projective([x^2 + c*y^2, y^2], domain=P) sage: F = f.dynatomic_polynomial(3) - sage: g = F.specialization({c:1}); g + sage: g = F.specialization({c: 1}); g x^6 + x^5*y + 4*x^4*y^2 + 3*x^3*y^3 + 7*x^2*y^4 + 4*x*y^5 + 5*y^6 sage: g == f.specialization({c:1}).dynatomic_polynomial(3) True @@ -1634,13 +1619,14 @@ def specialization(self, D=None, phi=None, homset=None): :: sage: R1. = QQ[] - sage: A. = AffineSpace(Frac(R1),1) + sage: A. = AffineSpace(Frac(R1), 1) sage: f = DynamicalSystem_affine([alpha/(x^2 + 1/alpha)/(x - 1/beta^2)]) - sage: f.specialization({alpha:5,beta:10}) + sage: f.specialization({alpha: 5, beta: 10}) Dynamical System of Affine Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x) to (5/(x^3 - 1/100*x^2 + 1/5*x - 1/500)) - sage: f.specialization({alpha:5}).specialization({beta:10}) == f.specialization({alpha:5,beta:10}) + sage: f_5_10 = f.specialization({alpha: 5}).specialization({beta: 10}) + sage: f_5_10 == f.specialization({alpha: 5, beta: 10}) True """ if D is None: @@ -1677,36 +1663,37 @@ def _composition_(self, other, homset): TESTS:: - sage: P. = ProjectiveSpace(QQ,1) - sage: H = Hom(P,P) - sage: f = H([x^2 -29/16*y^2, y^2]) - sage: g = H([y,x+y]) + sage: P. = ProjectiveSpace(QQ, 1) + sage: H = Hom(P, P) + sage: f = H([x^2 - 29/16*y^2, y^2]) + sage: g = H([y, x + y]) sage: h = f*g sage: h - Scheme endomorphism of Projective Space of dimension 1 over Rational - Field + Scheme endomorphism of Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x : y) to (-29/16*x^2 - 29/8*x*y - 13/16*y^2 : x^2 + 2*x*y + y^2) sage: p = P((1,3)) sage: h(p) == f(g(p)) True - sage: Q = ProjectiveSpace(QQ,2) - sage: H2 = Hom(P,Q) - sage: h2 = H2([x^2+y^2,x^2,y^2+2*x^2]) + sage: Q = ProjectiveSpace(QQ, 2) + sage: H2 = Hom(P, Q) + sage: h2 = H2([x^2 + y^2, x^2, y^2 + 2*x^2]) sage: h2 * f Scheme morphism: From: Projective Space of dimension 1 over Rational Field To: Projective Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x : y) to - (x^4 - 29/8*x^2*y^2 + 1097/256*y^4 : x^4 - 29/8*x^2*y^2 + 841/256*y^4 : 2*x^4 - 29/4*x^2*y^2 + 969/128*y^4) + (x^4 - 29/8*x^2*y^2 + 1097/256*y^4 + : x^4 - 29/8*x^2*y^2 + 841/256*y^4 + : 2*x^4 - 29/4*x^2*y^2 + 969/128*y^4) :: sage: A. = AffineSpace(QQ, 2) sage: A1. = AffineSpace(QQ, 1) sage: H = End(A) - sage: f = H([x^2+y^2, y^2/x]) + sage: f = H([x^2 + y^2, y^2/x]) sage: H1 = Hom(A, A1) sage: g = H1([x + y^2]) sage: g*f @@ -1720,7 +1707,8 @@ def _composition_(self, other, homset): ... TypeError: self (=Scheme endomorphism of Affine Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x, y) to - (x^2 + y^2, y^2/x)) domain must equal right (=Scheme morphism: + (x^2 + y^2, y^2/x)) domain + must equal right (=Scheme morphism: From: Affine Space of dimension 2 over Rational Field To: Affine Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x, y) to @@ -1729,20 +1717,24 @@ def _composition_(self, other, homset): Not both defined by polynomials:: sage: x = polygen(QQ) - sage: K. = NumberField(x^2 - 2) - sage: p1, p2 = K.Hom(K) - sage: R. = K[] - sage: q1 = R.Hom(R)(p1) - sage: A = AffineSpace(R) - sage: f1 = A.Hom(A)(q1) - sage: g = A.Hom(A)([x^2-y, y+1]) - sage: g*f1 + sage: K. = NumberField(x^2 - 2) # optional - sage.rings.number_field + sage: p1, p2 = K.Hom(K) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: q1 = R.Hom(R)(p1) # optional - sage.rings.number_field + sage: A = AffineSpace(R) # optional - sage.rings.number_field + sage: f1 = A.Hom(A)(q1) # optional - sage.rings.number_field + sage: g = A.Hom(A)([x^2 - y, y + 1]) # optional - sage.rings.number_field + sage: g*f1 # optional - sage.rings.number_field Composite map: - From: Affine Space of dimension 2 over Number Field in a with defining polynomial x^2 - 2 - To: Affine Space of dimension 2 over Number Field in a with defining polynomial x^2 - 2 - Defn: Generic endomorphism of Affine Space of dimension 2 over Number Field in a with defining polynomial x^2 - 2 + From: Affine Space of dimension 2 over Number Field in a + with defining polynomial x^2 - 2 + To: Affine Space of dimension 2 over Number Field in a + with defining polynomial x^2 - 2 + Defn: Generic endomorphism of Affine Space of dimension 2 + over Number Field in a with defining polynomial x^2 - 2 then - Generic endomorphism of Affine Space of dimension 2 over Number Field in a with defining polynomial x^2 - 2 + Generic endomorphism of Affine Space of dimension 2 + over Number Field in a with defining polynomial x^2 - 2 """ try: opolys = tuple(other._polys) @@ -1772,8 +1764,8 @@ def __init__(self, X): TESTS:: - sage: A = AffineSpace(2, GF(3)) - sage: A.identity_morphism().defining_polynomials() + sage: A = AffineSpace(2, GF(3)) # optional - sage.rings.finite_rings + sage: A.identity_morphism().defining_polynomials() # optional - sage.rings.finite_rings (x0, x1) """ super().__init__(X) @@ -1961,7 +1953,7 @@ def scheme(self): def change_ring(self, R, check=True): r""" - Returns a new :class:`SchemeMorphism_point` which is this point coerced to``R``. + Returns a new :class:`SchemeMorphism_point` which is this point coerced to ``R``. If ``check`` is true, then the initialization checks are performed. @@ -1969,8 +1961,6 @@ def change_ring(self, R, check=True): - ``R`` -- ring or morphism. - kwds: - - ``check`` -- Boolean OUTPUT: :class:`SchemeMorphism_point` @@ -1978,62 +1968,63 @@ def change_ring(self, R, check=True): EXAMPLES:: sage: P. = ProjectiveSpace(ZZ, 2) - sage: X = P.subscheme(x^2-y^2) - sage: X(23,23,1).change_ring(GF(13)) + sage: X = P.subscheme(x^2 - y^2) + sage: X(23,23,1).change_ring(GF(13)) # optional - sage.rings.finite_rings (10 : 10 : 1) :: - sage: P. = ProjectiveSpace(QQ,1) + sage: P. = ProjectiveSpace(QQ, 1) sage: P(-2/3,1).change_ring(CC) (-0.666666666666667 : 1.00000000000000) :: - sage: P. = ProjectiveSpace(ZZ,1) - sage: P(152,113).change_ring(Zp(5)) + sage: P. = ProjectiveSpace(ZZ, 1) + sage: P(152,113).change_ring(Zp(5)) # optional - sage.rings.padics (2 + 5^2 + 5^3 + O(5^20) : 3 + 2*5 + 4*5^2 + O(5^20)) :: - sage: K. = QuadraticField(-7) - sage: O = K.maximal_order() - sage: P. = ProjectiveSpace(O, 1) - sage: H = End(P) - sage: F = H([x^2+O(v)*y^2, y^2]) - sage: F.change_ring(K).change_ring(K.embeddings(QQbar)[0]) - Scheme endomorphism of Projective Space of dimension 1 over Algebraic Field + sage: K. = QuadraticField(-7) # optional - sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(O, 1) # optional - sage.rings.number_field + sage: H = End(P) # optional - sage.rings.number_field + sage: F = H([x^2 + O(v)*y^2, y^2]) # optional - sage.rings.number_field + sage: F.change_ring(K).change_ring(K.embeddings(QQbar)[0]) # optional - sage.rings.number_field + Scheme endomorphism of Projective Space of dimension 1 + over Algebraic Field Defn: Defined on coordinates by sending (x : y) to (x^2 + (-2.645751311064591?*I)*y^2 : y^2) :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2-x+1) - sage: P. = ProjectiveSpace(K,1) - sage: Q = P([a+1,1]) - sage: emb = K.embeddings(QQbar) - sage: Q.change_ring(emb[0]) + sage: K. = NumberField(x^2 - x + 1) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: Q = P([a + 1, 1]) # optional - sage.rings.number_field + sage: emb = K.embeddings(QQbar) # optional - sage.rings.number_field + sage: Q.change_ring(emb[0]) # optional - sage.rings.number_field (1.5000000000000000? - 0.866025403784439?*I : 1) - sage: Q.change_ring(emb[1]) + sage: Q.change_ring(emb[1]) # optional - sage.rings.number_field (1.5000000000000000? + 0.866025403784439?*I : 1) :: - sage: K. = QuadraticField(2) - sage: P. = ProjectiveSpace(K,1) - sage: Q = P([v,1]) - sage: Q.change_ring(K.embeddings(QQbar)[0]) + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: Q = P([v,1]) # optional - sage.rings.number_field + sage: Q.change_ring(K.embeddings(QQbar)[0]) # optional - sage.rings.number_field (-1.414213562373095? : 1) :: sage: R. = QQ[] - sage: f = x^6-2 - sage: L. = NumberField(f, embedding=f.roots(QQbar)[1][0]) - sage: A. = AffineSpace(L,2) - sage: P = A([b,1]) - sage: P.change_ring(QQbar) + sage: f = x^6 - 2 + sage: L. = NumberField(f, embedding=f.roots(QQbar)[1][0]) # optional - sage.rings.number_field + sage: A. = AffineSpace(L, 2) # optional - sage.rings.number_field + sage: P = A([b,1]) # optional - sage.rings.number_field + sage: P.change_ring(QQbar) # optional - sage.rings.number_field (1.122462048309373?, 1) """ S = self.codomain().change_ring(R) @@ -2083,16 +2074,16 @@ def specialization(self, D=None, phi=None, ambient=None): sage: R. = PolynomialRing(QQ) sage: P. = ProjectiveSpace(R, 1) sage: Q = P([c,1]) - sage: Q.specialization({c:1}) + sage: Q.specialization({c: 1}) (1 : 1) - :: + :: sage: R. = PolynomialRing(QQ) sage: P. = ProjectiveSpace(R, 1) sage: Q = P([a^2 + 2*a*b + 34, 1]) sage: from sage.rings.polynomial.flatten import SpecializationMorphism - sage: phi = SpecializationMorphism(P.coordinate_ring(),dict({a:2,b:-1})) + sage: phi = SpecializationMorphism(P.coordinate_ring(), {a: 2, b: -1}) sage: T = Q.specialization(phi=phi); T (34 : 1) sage: Q2 = P([a,1]) @@ -2112,8 +2103,8 @@ def specialization(self, D=None, phi=None, ambient=None): sage: Q2 = Q.specialization({c:2}); Q2 (2 : 1) sage: Q2.codomain() - Closed subscheme of Projective Space of dimension 1 over Rational Field defined by: - x - 2*y + Closed subscheme of Projective Space of dimension 1 over Rational Field + defined by: x - 2*y :: @@ -2122,8 +2113,8 @@ def specialization(self, D=None, phi=None, ambient=None): sage: K. = S[] sage: P. = ProjectiveSpace(K, 1) sage: H = End(P) - sage: Q = P([a^2,b^2]) - sage: Q.specialization({a:2}) + sage: Q = P([a^2, b^2]) + sage: Q.specialization({a: 2}) (4 : b^2) """ if D is None: diff --git a/src/sage/schemes/generic/point.py b/src/sage/schemes/generic/point.py index 0cadc10957e..5b2d26550fd 100644 --- a/src/sage/schemes/generic/point.py +++ b/src/sage/schemes/generic/point.py @@ -120,20 +120,19 @@ def _repr_(self): def point_on_affine(self): """ - Return the scheme point on the affine open U. + Return the scheme point on the affine open `U`. """ return self.__x def affine_open(self): """ - Return the affine open subset U. + Return the affine open subset `U`. """ return self.__u.domain() def embedding_of_affine_open(self): """ - Return the embedding from the affine open subset U into this - scheme. + Return the embedding from the affine open subset `U` into this scheme. """ return self.__u @@ -165,8 +164,9 @@ def __init__(self, S, P, check=False): corresponding to a prime ideal:: sage: P2. = ProjectiveSpace(2, QQ) - sage: SchemeTopologicalPoint_prime_ideal(P2, y*z-x^2) - Point on Projective Space of dimension 2 over Rational Field defined by the Ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field + sage: SchemeTopologicalPoint_prime_ideal(P2, y*z - x^2) + Point on Projective Space of dimension 2 over Rational Field defined by + the Ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field """ R = S.coordinate_ring() from sage.rings.ideal import is_Ideal @@ -190,8 +190,9 @@ def _repr_(self): sage: from sage.schemes.generic.point import SchemeTopologicalPoint_prime_ideal sage: P2. = ProjectiveSpace(2, QQ) - sage: pt = SchemeTopologicalPoint_prime_ideal(P2, y*z-x^2); pt - Point on Projective Space of dimension 2 over Rational Field defined by the Ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field + sage: pt = SchemeTopologicalPoint_prime_ideal(P2, y*z - x^2); pt + Point on Projective Space of dimension 2 over Rational Field defined by + the Ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field sage: pt._repr_() 'Point on Projective Space of dimension 2 over Rational Field defined by the Ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field' """ @@ -205,7 +206,7 @@ def prime_ideal(self): sage: from sage.schemes.generic.point import SchemeTopologicalPoint_prime_ideal sage: P2. = ProjectiveSpace(2, QQ) - sage: pt = SchemeTopologicalPoint_prime_ideal(P2, y*z-x^2) + sage: pt = SchemeTopologicalPoint_prime_ideal(P2, y*z - x^2) sage: pt.prime_ideal() Ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field """ diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index 520b1fa6b6d..960a1a928ea 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -167,7 +167,7 @@ def _morphism(self, *args, **kwds): sage: S = Spec(ZZ) sage: f = S.identity_morphism() sage: from sage.schemes.generic.glue import GluedScheme - sage: T = GluedScheme(f,f) + sage: T = GluedScheme(f, f) sage: S.hom([1],T) Traceback (most recent call last): ... @@ -217,16 +217,16 @@ def __call__(self, *args): sage: A(QQ) Set of rational points of Affine Space of dimension 2 over Rational Field sage: A(RR) - Set of rational points of Affine Space of dimension 2 over Real Field - with 53 bits of precision + Set of rational points of Affine Space of dimension 2 + over Real Field with 53 bits of precision Space of dimension 2 over Rational Field:: sage: R. = PolynomialRing(QQ) - sage: A(NumberField(x^2+1, 'a')) - Set of rational points of Affine Space of dimension 2 over Number Field - in a with defining polynomial x^2 + 1 - sage: A(GF(7)) + sage: A(NumberField(x^2 + 1, 'a')) # optional - sage.rings.number_field + Set of rational points of Affine Space of dimension 2 + over Number Field in a with defining polynomial x^2 + 1 + sage: A(GF(7)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: There must be a natural map S --> R, but @@ -246,7 +246,7 @@ def __call__(self, *args): Check that :trac:`16832` is fixed:: sage: P. = ProjectiveSpace(ZZ, 2) - sage: X=P.subscheme(x^2 - y^2) + sage: X = P.subscheme(x^2 - y^2) sage: X(P([4, 4, 1])) (4 : 4 : 1) """ @@ -285,14 +285,14 @@ def point_homset(self, S=None): Set of rational points of Projective Space of dimension 3 over Integer Ring sage: P.point_homset(QQ) Set of rational points of Projective Space of dimension 3 over Rational Field - sage: P.point_homset(GF(11)) + sage: P.point_homset(GF(11)) # optional - sage.rings.finite_rings Set of rational points of Projective Space of dimension 3 over - Finite Field of size 11 + Finite Field of size 11 TESTS:: - sage: P = ProjectiveSpace(QQ,3) - sage: P.point_homset(GF(11)) + sage: P = ProjectiveSpace(QQ, 3) + sage: P.point_homset(GF(11)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: There must be a natural map S --> R, but @@ -321,8 +321,8 @@ def point(self, v, check=True): EXAMPLES:: - sage: A2 = AffineSpace(QQ,2) - sage: A2.point([4,5]) + sage: A2 = AffineSpace(QQ, 2) + sage: A2.point([4, 5]) (4, 5) sage: R. = PolynomialRing(QQ) @@ -386,7 +386,7 @@ def __truediv__(self, Y): Affine Space of dimension 3 over Integer Ring sage: A/QQ Affine Space of dimension 3 over Rational Field - sage: A/GF(7) + sage: A/GF(7) # optional - sage.rings.finite_rings Affine Space of dimension 3 over Finite Field of size 7 """ return self.base_extend(Y) @@ -506,7 +506,8 @@ def coordinate_ring(self): sage: I = (x^2 - y^2)*R sage: X = Spec(R.quotient(I)) sage: X.coordinate_ring() - Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 - y^2) + Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2 - y^2) """ try: return self._coordinate_ring @@ -671,18 +672,18 @@ def count_points(self, n): EXAMPLES:: - sage: P. = PolynomialRing(GF(3)) - sage: C = HyperellipticCurve(x^3+x^2+1) - sage: C.count_points(4) + sage: P. = PolynomialRing(GF(3)) # optional - sage.rings.finite_rings + sage: C = HyperellipticCurve(x^3 + x^2 + 1) # optional - sage.rings.finite_rings + sage: C.count_points(4) # optional - sage.rings.finite_rings [6, 12, 18, 96] - sage: C.base_extend(GF(9,'a')).count_points(2) + sage: C.base_extend(GF(9,'a')).count_points(2) # optional - sage.rings.finite_rings [12, 96] :: - sage: P. = ProjectiveSpace(GF(4,'t'), 2) - sage: X = P.subscheme([y^2*z - x^3 - z^3]) - sage: X.count_points(2) + sage: P. = ProjectiveSpace(GF(4, 't'), 2) # optional - sage.rings.finite_rings + sage: X = P.subscheme([y^2*z - x^3 - z^3]) # optional - sage.rings.finite_rings + sage: X.count_points(2) # optional - sage.rings.finite_rings [5, 17] """ F = self.base_ring() @@ -705,9 +706,9 @@ def zeta_function(self): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(4,'t'), 2) - sage: X = P.subscheme([y^2*z - x^3 - z^3]) - sage: X.zeta_function() + sage: P. = ProjectiveSpace(GF(4, 't'), 2) # optional - sage.rings.finite_rings + sage: X = P.subscheme([y^2*z - x^3 - z^3]) # optional - sage.rings.finite_rings + sage: X.zeta_function() # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError @@ -734,12 +735,12 @@ def zeta_series(self, n, t): EXAMPLES:: - sage: P. = PolynomialRing(GF(3)) - sage: C = HyperellipticCurve(x^3+x^2+1) + sage: P. = PolynomialRing(GF(3)) # optional - sage.rings.finite_rings + sage: C = HyperellipticCurve(x^3 + x^2 + 1) # optional - sage.rings.finite_rings sage: R. = PowerSeriesRing(Integers()) - sage: C.zeta_series(4,t) + sage: C.zeta_series(4, t) # optional - sage.rings.finite_rings 1 + 6*t + 24*t^2 + 78*t^3 + 240*t^4 + O(t^5) - sage: (1+2*t+3*t^2)/(1-t)/(1-3*t) + O(t^5) + sage: (1+2*t+3*t^2)/(1-t)/(1-3*t) + O(t^5) # optional - sage.rings.finite_rings 1 + 6*t + 24*t^2 + 78*t^3 + 240*t^4 + O(t^5) If the scheme has a method ``zeta_function``, this is used to @@ -749,23 +750,23 @@ def zeta_series(self, n, t): Nonetheless, since :trac:`15108` and :trac:`15148`, it supports hyperelliptic curves over non-prime fields:: - sage: C.base_extend(GF(9,'a')).zeta_series(4,t) + sage: C.base_extend(GF(9, 'a')).zeta_series(4, t) # optional - sage.rings.finite_rings 1 + 12*t + 120*t^2 + 1092*t^3 + 9840*t^4 + O(t^5) :: - sage: P. = ProjectiveSpace(GF(4,'t'), 2) - sage: X = P.subscheme([y^2*z - x^3 - z^3]) + sage: P. = ProjectiveSpace(GF(4, 't'), 2) # optional - sage.rings.finite_rings + sage: X = P.subscheme([y^2*z - x^3 - z^3]) # optional - sage.rings.finite_rings sage: R. = PowerSeriesRing(Integers()) - sage: X.zeta_series(2,t) + sage: X.zeta_series(2, t) # optional - sage.rings.finite_rings 1 + 5*t + 21*t^2 + O(t^3) TESTS:: sage: P. = PolynomialRing(ZZ) - sage: C = HyperellipticCurve(x^3+x+1) + sage: C = HyperellipticCurve(x^3 + x + 1) sage: R. = PowerSeriesRing(Integers()) - sage: C.zeta_series(4,t) + sage: C.zeta_series(4, t) Traceback (most recent call last): ... TypeError: zeta functions only defined for schemes @@ -959,8 +960,8 @@ def __call__(self, *args): sage: S = Spec(R) sage: P = S(R.ideal(x, y, z)); P Point on Spectrum of Multivariate Polynomial Ring - in x, y, z over Rational Field defined by the Ideal (x, y, z) - of Multivariate Polynomial Ring in x, y, z over Rational Field + in x, y, z over Rational Field defined by the Ideal (x, y, z) + of Multivariate Polynomial Ring in x, y, z over Rational Field This indicates the fix of :trac:`12734`:: @@ -990,7 +991,8 @@ def __call__(self, *args): sage: R = S.coordinate_ring() sage: S(R.ideal(0)) - Point on Affine Space of dimension 1 over Integer Ring defined by the Ideal (0) of Multivariate Polynomial Ring in x over Integer Ring + Point on Affine Space of dimension 1 over Integer Ring + defined by the Ideal (0) of Multivariate Polynomial Ring in x over Integer Ring This explains why the following example raises an error rather than constructing the topological point defined by the prime @@ -1201,14 +1203,13 @@ def hom(self, x, Y=None): We can construct a morphism to an affine curve (:trac:`7956`):: sage: S. = QQ[] - sage: A1. = AffineSpace(QQ,1) - sage: A1_emb = Curve(p-2) - sage: A1.hom([2,r],A1_emb) + sage: A1. = AffineSpace(QQ, 1) + sage: A1_emb = Curve(p - 2) + sage: A1.hom([2, r], A1_emb) Scheme morphism: From: Affine Space of dimension 1 over Rational Field To: Affine Plane Curve over Rational Field defined by p - 2 - Defn: Defined on coordinates by sending (r) to - (2, r) + Defn: Defined on coordinates by sending (r) to (2, r) """ from sage.categories.map import Map from sage.categories.rings import Rings diff --git a/src/sage/schemes/generic/spec.py b/src/sage/schemes/generic/spec.py index fcbda338c59..60f46664e31 100644 --- a/src/sage/schemes/generic/spec.py +++ b/src/sage/schemes/generic/spec.py @@ -42,9 +42,10 @@ def Spec(R, S=None): Spectrum of Univariate Polynomial Ring in x over Rational Field sage: Spec(PolynomialRing(QQ, 'x', 3)) Spectrum of Multivariate Polynomial Ring in x0, x1, x2 over Rational Field - sage: X = Spec(PolynomialRing(GF(49,'a'), 3, 'x')); X - Spectrum of Multivariate Polynomial Ring in x0, x1, x2 over Finite Field in a of size 7^2 - sage: TestSuite(X).run() + sage: X = Spec(PolynomialRing(GF(49,'a'), 3, 'x')); X # optional - sage.rings.finite_rings + Spectrum of Multivariate Polynomial Ring in x0, x1, x2 + over Finite Field in a of size 7^2 + sage: TestSuite(X).run() # optional - sage.rings.finite_rings Applying ``Spec`` twice to the same ring gives identical output (see :trac:`17008`):: @@ -59,10 +60,11 @@ def Spec(R, S=None): Traceback (most recent call last): ... TypeError: x (=5) is not in Category of commutative rings - sage: Spec(FreeAlgebra(QQ,2, 'x')) + sage: Spec(FreeAlgebra(QQ, 2, 'x')) Traceback (most recent call last): ... - TypeError: x (=Free Algebra on 2 generators (x0, x1) over Rational Field) is not in Category of commutative rings + TypeError: x (=Free Algebra on 2 generators (x0, x1) over Rational Field) + is not in Category of commutative rings TESTS:: @@ -75,9 +77,9 @@ def Spec(R, S=None): Integer Ring sage: X.dimension() 1 - sage: Spec(QQ,QQ).base_scheme() + sage: Spec(QQ, QQ).base_scheme() Spectrum of Rational Field - sage: Spec(RDF,QQ).base_scheme() + sage: Spec(RDF, QQ).base_scheme() Spectrum of Rational Field """ return SpecFunctor(S)(R) @@ -168,11 +170,11 @@ def _apply_functor_to_morphism(self, f): EXAMPLES:: sage: from sage.schemes.generic.spec import SpecFunctor - sage: F = SpecFunctor(GF(7)) - sage: A. = GF(7)[] - sage: B. = GF(7)[] - sage: f = A.hom((t^2, t^3)) - sage: Spec(f) # indirect doctest + sage: F = SpecFunctor(GF(7)) # optional - sage.rings.finite_rings + sage: A. = GF(7)[] # optional - sage.rings.finite_rings + sage: B. = GF(7)[] # optional - sage.rings.finite_rings + sage: f = A.hom((t^2, t^3)) # optional - sage.rings.finite_rings + sage: Spec(f) # indirect doctest # optional - sage.rings.finite_rings Affine Scheme morphism: From: Spectrum of Univariate Polynomial Ring in t over Finite Field of size 7 To: Spectrum of Multivariate Polynomial Ring in x, y over Finite Field of size 7 diff --git a/src/sage/schemes/hyperelliptic_curves/constructor.py b/src/sage/schemes/hyperelliptic_curves/constructor.py index afd87af8cb3..121da1bf072 100644 --- a/src/sage/schemes/hyperelliptic_curves/constructor.py +++ b/src/sage/schemes/hyperelliptic_curves/constructor.py @@ -71,63 +71,69 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): sage: R. = QQ[] sage: HyperellipticCurve(x^5 + x + 1) Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1 - sage: HyperellipticCurve(x^19 + x + 1, x-2) + sage: HyperellipticCurve(x^19 + x + 1, x - 2) Hyperelliptic Curve over Rational Field defined by y^2 + (x - 2)*y = x^19 + x + 1 - sage: k. = GF(9); R. = k[] - sage: HyperellipticCurve(x^3 + x - 1, x+a) - Hyperelliptic Curve over Finite Field in a of size 3^2 defined by y^2 + (x + a)*y = x^3 + x + 2 + sage: k. = GF(9); R. = k[] # optional - sage.rings.finite_rings + sage: HyperellipticCurve(x^3 + x - 1, x+a) # optional - sage.rings.finite_rings + Hyperelliptic Curve over Finite Field in a of size 3^2 + defined by y^2 + (x + a)*y = x^3 + x + 2 Characteristic two:: - sage: P. = GF(8,'a')[] - sage: HyperellipticCurve(x^7+1, x) - Hyperelliptic Curve over Finite Field in a of size 2^3 defined by y^2 + x*y = x^7 + 1 - sage: HyperellipticCurve(x^8+x^7+1, x^4+1) - Hyperelliptic Curve over Finite Field in a of size 2^3 defined by y^2 + (x^4 + 1)*y = x^8 + x^7 + 1 + sage: P. = GF(8, 'a')[] # optional - sage.rings.finite_rings + sage: HyperellipticCurve(x^7 + 1, x) # optional - sage.rings.finite_rings + Hyperelliptic Curve over Finite Field in a of size 2^3 + defined by y^2 + x*y = x^7 + 1 + sage: HyperellipticCurve(x^8 + x^7 + 1, x^4 + 1) # optional - sage.rings.finite_rings + Hyperelliptic Curve over Finite Field in a of size 2^3 + defined by y^2 + (x^4 + 1)*y = x^8 + x^7 + 1 - sage: HyperellipticCurve(x^8+1, x) + sage: HyperellipticCurve(x^8 + 1, x) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Not a hyperelliptic curve: highly singular at infinity. - sage: HyperellipticCurve(x^8+x^7+1, x^4) + sage: HyperellipticCurve(x^8 + x^7 + 1, x^4) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Not a hyperelliptic curve: singularity in the provided affine patch. - sage: F. = PowerSeriesRing(FiniteField(2)) - sage: P. = PolynomialRing(FractionField(F)) - sage: HyperellipticCurve(x^5+t, x) - Hyperelliptic Curve over Laurent Series Ring in t over Finite Field of size 2 defined by y^2 + x*y = x^5 + t + sage: F. = PowerSeriesRing(FiniteField(2)) # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(FractionField(F)) # optional - sage.rings.finite_rings + sage: HyperellipticCurve(x^5 + t, x) # optional - sage.rings.finite_rings + Hyperelliptic Curve over Laurent Series Ring in t over Finite Field of size 2 + defined by y^2 + x*y = x^5 + t We can change the names of the variables in the output:: - sage: k. = GF(9); R. = k[] - sage: HyperellipticCurve(x^3 + x - 1, x+a, names=['X','Y']) - Hyperelliptic Curve over Finite Field in a of size 3^2 defined by Y^2 + (X + a)*Y = X^3 + X + 2 + sage: k. = GF(9); R. = k[] # optional - sage.rings.finite_rings + sage: HyperellipticCurve(x^3 + x - 1, x + a, names=['X','Y']) # optional - sage.rings.finite_rings + Hyperelliptic Curve over Finite Field in a of size 3^2 + defined by Y^2 + (X + a)*Y = X^3 + X + 2 This class also allows curves of genus zero or one, which are strictly speaking not hyperelliptic:: sage: P. = QQ[] - sage: HyperellipticCurve(x^2+1) + sage: HyperellipticCurve(x^2 + 1) Hyperelliptic Curve over Rational Field defined by y^2 = x^2 + 1 - sage: HyperellipticCurve(x^4-1) + sage: HyperellipticCurve(x^4 - 1) Hyperelliptic Curve over Rational Field defined by y^2 = x^4 - 1 - sage: HyperellipticCurve(x^3+2*x+2) + sage: HyperellipticCurve(x^3 + 2*x + 2) Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + 2*x + 2 Double roots:: - sage: P. = GF(7)[] + sage: P. = GF(7)[] # optional - sage.rings.finite_rings sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1)) Traceback (most recent call last): ... ValueError: Not a hyperelliptic curve: singularity in the provided affine patch. - sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1), check_squarefree=False) - Hyperelliptic Curve over Finite Field of size 7 defined by y^2 = x^12 + 5*x^10 + 4*x^9 + x^8 + 3*x^7 + 3*x^6 + 2*x^4 + 3*x^3 + 6*x^2 + 4*x + 3 + sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1), check_squarefree=False) # optional - sage.rings.finite_rings + Hyperelliptic Curve over Finite Field of size 7 defined by + y^2 = x^12 + 5*x^10 + 4*x^9 + x^8 + 3*x^7 + 3*x^6 + 2*x^4 + 3*x^3 + 6*x^2 + 4*x + 3 The input for a (smooth) hyperelliptic curve of genus `g` should not contain polynomials of degree greater than `2g+2`. In the following @@ -137,8 +143,8 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): sage: P. = QQ[] sage: h = x^100 - sage: F = x^6+1 - sage: f = F-h^2/4 + sage: F = x^6 + 1 + sage: f = F - h^2/4 sage: HyperellipticCurve(f, h) Traceback (most recent call last): ... @@ -150,9 +156,9 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): An example with a singularity over an inseparable extension of the base field:: - sage: F. = GF(5)[] - sage: P. = F[] - sage: HyperellipticCurve(x^5+t) + sage: F. = GF(5)[] # optional - sage.rings.finite_rings + sage: P. = F[] # optional - sage.rings.finite_rings + sage: HyperellipticCurve(x^5 + t) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Not a hyperelliptic curve: singularity in the provided affine patch. @@ -163,7 +169,7 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): not checked whether the discriminant is a unit in `\ZZ^*`.:: sage: P. = ZZ[] - sage: HyperellipticCurve(3*x^7+6*x+6) + sage: HyperellipticCurve(3*x^7 + 6*x + 6) Hyperelliptic Curve over Integer Ring defined by y^2 = 3*x^7 + 6*x + 6 TESTS: @@ -176,17 +182,17 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): Check that two curves with the same class name have the same class type:: - sage: R. = PolynomialRing(GF(next_prime(10^9))) - sage: C = HyperellipticCurve(t^5 + t + 1) - sage: C2 = HyperellipticCurve(t^5 + 3*t + 1) - sage: type(C2) == type(C) + sage: R. = PolynomialRing(GF(next_prime(10^9))) # optional - sage.rings.finite_rings + sage: C = HyperellipticCurve(t^5 + t + 1) # optional - sage.rings.finite_rings + sage: C2 = HyperellipticCurve(t^5 + 3*t + 1) # optional - sage.rings.finite_rings + sage: type(C2) == type(C) # optional - sage.rings.finite_rings True Check that the inheritance is correct:: - sage: R. = PolynomialRing(GF(next_prime(10^9))) - sage: C = HyperellipticCurve(t^5 + t + 1) - sage: type(C).mro() + sage: R. = PolynomialRing(GF(next_prime(10^9))) # optional - sage.rings.finite_rings + sage: C = HyperellipticCurve(t^5 + t + 1) # optional - sage.rings.finite_rings + sage: type(C).mro() # optional - sage.rings.finite_rings [, , , diff --git a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py index ab883076d33..d51f9eca1d8 100644 --- a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +++ b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" Hyperelliptic curves over a finite field @@ -7,7 +8,8 @@ sage: x = polygen(K) sage: C = HyperellipticCurve(x^7 - x^5 - 2, x^2 + a) sage: C._points_fast_sqrt() - [(0 : 1 : 0), (a + 1 : a : 1), (a + 1 : a + 1 : 1), (2 : a + 1 : 1), (2*a : 2*a + 2 : 1), (2*a : 2*a : 1), (1 : a + 1 : 1)] + [(0 : 1 : 0), (a + 1 : a : 1), (a + 1 : a + 1 : 1), (2 : a + 1 : 1), + (2*a : 2*a + 2 : 1), (2*a : 2*a : 1), (1 : a + 1 : 1)] AUTHORS: @@ -204,7 +206,8 @@ def frobenius_matrix_hypellfrob(self, N=None): sage: H.frobenius_matrix_hypellfrob() Traceback (most recent call last): ... - NotImplementedError: Computation of Frobenius matrix only implemented for hyperelliptic curves defined over prime fields. + NotImplementedError: Computation of Frobenius matrix only implemented + for hyperelliptic curves defined over prime fields. nor too small characteristic:: @@ -279,7 +282,8 @@ def frobenius_matrix(self, N=None, algorithm='hypellfrob'): sage: H.frobenius_matrix(algorithm='hypellfrob') Traceback (most recent call last): ... - NotImplementedError: Computation of Frobenius matrix only implemented for hyperelliptic curves defined over prime fields. + NotImplementedError: Computation of Frobenius matrix only implemented + for hyperelliptic curves defined over prime fields. nor too small characteristic:: @@ -333,7 +337,7 @@ def frobenius_polynomial_cardinalities(self, a=None): sage: H.frobenius_polynomial_cardinalities() x^4 + 8*x^3 + 70*x^2 + 392*x + 2401 - This method may actually be useful when `hypellfrob` does not work:: + This method may actually be useful when ``hypellfrob`` does not work:: sage: K = GF(7) sage: R. = PolynomialRing(K) @@ -394,10 +398,15 @@ def frobenius_polynomial_matrix(self, M=None, algorithm='hypellfrob'): sage: R. = PolynomialRing(K) sage: H = HyperellipticCurve(t^9 + t^5 + 1) sage: H.frobenius_polynomial_matrix() - x^8 + 281*x^7 + 55939*x^6 + 14144175*x^5 + 3156455369*x^4 + 707194605825*x^3 + 139841906155939*x^2 + 35122892542149719*x + 6249500014999800001 + x^8 + 281*x^7 + 55939*x^6 + 14144175*x^5 + 3156455369*x^4 + 707194605825*x^3 + + 139841906155939*x^2 + 35122892542149719*x + 6249500014999800001 sage: H = HyperellipticCurve(t^15 + t^5 + 1) - sage: H.frobenius_polynomial_matrix() # long time, 8s on a Corei7 - x^14 - 76*x^13 + 220846*x^12 - 12984372*x^11 + 24374326657*x^10 - 1203243210304*x^9 + 1770558798515792*x^8 - 74401511415210496*x^7 + 88526169366991084208*x^6 - 3007987702642212810304*x^5 + 3046608028331197124223343*x^4 - 81145833008762983138584372*x^3 + 69007473838551978905211279154*x^2 - 1187357507124810002849977200076*x + 781140631562281254374947500349999 + sage: H.frobenius_polynomial_matrix() # long time, 8s on a Corei7 + x^14 - 76*x^13 + 220846*x^12 - 12984372*x^11 + 24374326657*x^10 - 1203243210304*x^9 + + 1770558798515792*x^8 - 74401511415210496*x^7 + 88526169366991084208*x^6 + - 3007987702642212810304*x^5 + 3046608028331197124223343*x^4 + - 81145833008762983138584372*x^3 + 69007473838551978905211279154*x^2 + - 1187357507124810002849977200076*x + 781140631562281254374947500349999 This ``hypellfrob`` program doesn't support non-prime fields:: @@ -407,7 +416,8 @@ def frobenius_polynomial_matrix(self, M=None, algorithm='hypellfrob'): sage: H.frobenius_polynomial_matrix(algorithm='hypellfrob') Traceback (most recent call last): ... - NotImplementedError: Computation of Frobenius matrix only implemented for hyperelliptic curves defined over prime fields. + NotImplementedError: Computation of Frobenius matrix only implemented + for hyperelliptic curves defined over prime fields. """ K = self.base_ring() p = K.characteristic() @@ -594,7 +604,8 @@ def _points_fast_sqrt(self): sage: x = polygen(K) sage: C = HyperellipticCurve(x^7 - 1, x^2 + a) sage: C._points_fast_sqrt() - [(0 : 1 : 0), (a : 2*a + 1 : 1), (2 : a + 1 : 1), (2*a + 2 : 2*a : 1), (2*a + 2 : 1 : 1), (1 : 2*a + 2 : 1), (1 : 0 : 1)] + [(0 : 1 : 0), (a : 2*a + 1 : 1), (2 : a + 1 : 1), (2*a + 2 : 2*a : 1), + (2*a + 2 : 1 : 1), (1 : 2*a + 2 : 1), (1 : 0 : 1)] sage: K. = GF(49, 'a') sage: x = polygen(K) sage: C = HyperellipticCurve(x^5 - x^2 - 1, x^2 + a) @@ -614,7 +625,10 @@ def _points_fast_sqrt(self): sage: x = polygen(GF(13)) sage: C = HyperellipticCurve(x^3 + x^2 - 1) sage: C._points_fast_sqrt() - [(0 : 1 : 0), (0 : 5 : 1), (0 : 8 : 1), (1 : 1 : 1), (1 : 12 : 1), (3 : 3 : 1), (3 : 10 : 1), (4 : 1 : 1), (4 : 12 : 1), (6 : 2 : 1), (6 : 11 : 1), (7 : 1 : 1), (7 : 12 : 1), (8 : 4 : 1), (8 : 9 : 1), (9 : 4 : 1), (9 : 9 : 1), (12 : 5 : 1), (12 : 8 : 1)] + [(0 : 1 : 0), (0 : 5 : 1), (0 : 8 : 1), (1 : 1 : 1), (1 : 12 : 1), + (3 : 3 : 1), (3 : 10 : 1), (4 : 1 : 1), (4 : 12 : 1), (6 : 2 : 1), + (6 : 11 : 1), (7 : 1 : 1), (7 : 12 : 1), (8 : 4 : 1), (8 : 9 : 1), + (9 : 4 : 1), (9 : 9 : 1), (12 : 5 : 1), (12 : 8 : 1)] sage: set(C._points_fast_sqrt()) == set(C._points_cache_sqrt()) True """ @@ -714,7 +728,8 @@ def _points_cache_sqrt(self, brute_force=False): sage: x = polygen(GF(7)) sage: C = HyperellipticCurve(x^3 + x^2 - 1) sage: C._points_cache_sqrt() - [(0 : 1 : 0), (1 : 6 : 1), (1 : 1 : 1), (2 : 5 : 1), (2 : 2 : 1), (3 : 0 : 1), (4 : 4 : 1), (4 : 3 : 1), (5 : 4 : 1), (5 : 3 : 1)] + [(0 : 1 : 0), (1 : 6 : 1), (1 : 1 : 1), (2 : 5 : 1), (2 : 2 : 1), + (3 : 0 : 1), (4 : 4 : 1), (4 : 3 : 1), (5 : 4 : 1), (5 : 3 : 1)] sage: set(C._points_cache_sqrt()) == set(C._points_cache_sqrt(brute_force=True)) True """ @@ -796,7 +811,8 @@ def points(self): sage: x = polygen(GF(7)) sage: C = HyperellipticCurve(x^7 - x^2 - 1) sage: C.points() - [(0 : 1 : 0), (2 : 5 : 1), (2 : 2 : 1), (3 : 0 : 1), (4 : 6 : 1), (4 : 1 : 1), (5 : 0 : 1), (6 : 5 : 1), (6 : 2 : 1)] + [(0 : 1 : 0), (2 : 5 : 1), (2 : 2 : 1), (3 : 0 : 1), (4 : 6 : 1), + (4 : 1 : 1), (5 : 0 : 1), (6 : 5 : 1), (6 : 2 : 1)] :: @@ -811,7 +827,8 @@ def points(self): sage: R. = GF(7)[] sage: H = HyperellipticCurve(3*x^2 + 5*x + 1) sage: H.points() - [(0 : 6 : 1), (0 : 1 : 1), (1 : 4 : 1), (1 : 3 : 1), (2 : 4 : 1), (2 : 3 : 1), (3 : 6 : 1), (3 : 1 : 1)] + [(0 : 6 : 1), (0 : 1 : 1), (1 : 4 : 1), (1 : 3 : 1), (2 : 4 : 1), + (2 : 3 : 1), (3 : 6 : 1), (3 : 1 : 1)] The method currently lists points on the plane projective model, that is the closure in `\mathbb{P}^2` of the curve defined by `y^2+hy=f`. @@ -827,7 +844,8 @@ def points(self): sage: R.=GF(11)[] sage: H = HyperellipticCurve(x*(x+1)*(x+2)*(x+3)*(x+4)*(x+5)) sage: H.points() - [(0 : 1 : 0), (0 : 0 : 1), (1 : 7 : 1), (1 : 4 : 1), (5 : 7 : 1), (5 : 4 : 1), (6 : 0 : 1), (7 : 0 : 1), (8 : 0 : 1), (9 : 0 : 1), (10 : 0 : 1)] + [(0 : 1 : 0), (0 : 0 : 1), (1 : 7 : 1), (1 : 4 : 1), (5 : 7 : 1), (5 : 4 : 1), + (6 : 0 : 1), (7 : 0 : 1), (8 : 0 : 1), (9 : 0 : 1), (10 : 0 : 1)] The plane model of the genus 2 hyperelliptic curve in the above example is the curve in `\mathbb{P}^2` defined by `y^2z^4=g(x,z)` where @@ -1571,21 +1589,21 @@ def Cartier_matrix(self): EXAMPLES:: - sage: K.=GF(9,'x')[] - sage: C=HyperellipticCurve(x^7-1,0) + sage: K. = GF(9,'x')[] + sage: C = HyperellipticCurve(x^7 - 1, 0) sage: C.Cartier_matrix() [0 0 2] [0 0 0] [0 1 0] - sage: K.=GF(49,'x')[] - sage: C=HyperellipticCurve(x^5+1,0) + sage: K. = GF(49, 'x')[] + sage: C = HyperellipticCurve(x^5 + 1, 0) sage: C.Cartier_matrix() [0 3] [0 0] - sage: P.=GF(9,'a')[] - sage: E=HyperellipticCurve(x^29+1,0) + sage: P. = GF(9, 'a')[] + sage: E = HyperellipticCurve(x^29 + 1, 0) sage: E.Cartier_matrix() [0 0 1 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 1 0 0 0 0 0 0 0 0] @@ -1769,21 +1787,21 @@ def Hasse_Witt(self): EXAMPLES:: - sage: K.=GF(9,'x')[] - sage: C=HyperellipticCurve(x^7-1,0) + sage: K. = GF(9, 'x')[] + sage: C = HyperellipticCurve(x^7 - 1, 0) sage: C.Hasse_Witt() [0 0 0] [0 0 0] [0 0 0] - sage: K.=GF(49,'x')[] - sage: C=HyperellipticCurve(x^5+1,0) + sage: K. = GF(49, 'x')[] + sage: C = HyperellipticCurve(x^5 + 1, 0) sage: C.Hasse_Witt() [0 0] [0 0] - sage: P.=GF(9,'a')[] - sage: E=HyperellipticCurve(x^29+1,0) + sage: P. = GF(9, 'a')[] + sage: E = HyperellipticCurve(x^29 + 1, 0) sage: E.Hasse_Witt() [0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0] @@ -1823,20 +1841,20 @@ def a_number(self): - ``a`` : a-number - EXAMPLES:: + EXAMPLES:: - sage: K.=GF(49,'x')[] - sage: C=HyperellipticCurve(x^5+1,0) + sage: K. = GF(49, 'x')[] + sage: C = HyperellipticCurve(x^5 + 1, 0) sage: C.a_number() 1 - sage: K.=GF(9,'x')[] - sage: C=HyperellipticCurve(x^7-1,0) + sage: K. = GF(9, 'x')[] + sage: C = HyperellipticCurve(x^7 - 1, 0) sage: C.a_number() 1 - sage: P.=GF(9,'a')[] - sage: E=HyperellipticCurve(x^29+1,0) + sage: P. = GF(9, 'a')[] + sage: E = HyperellipticCurve(x^29 + 1, 0) sage: E.a_number() 5 """ @@ -1867,18 +1885,18 @@ def p_rank(self): EXAMPLES:: - sage: K.=GF(49,'x')[] - sage: C=HyperellipticCurve(x^5+1,0) + sage: K. = GF(49, 'x')[] + sage: C = HyperellipticCurve(x^5 + 1, 0) sage: C.p_rank() 0 - sage: K.=GF(9,'x')[] - sage: C=HyperellipticCurve(x^7-1,0) + sage: K. = GF(9, 'x')[] + sage: C = HyperellipticCurve(x^7 - 1, 0) sage: C.p_rank() 0 - sage: P.=GF(9,'a')[] - sage: E=HyperellipticCurve(x^29+1,0) + sage: P. = GF(9, 'a')[] + sage: E = HyperellipticCurve(x^29 + 1, 0) sage: E.p_rank() 0 """ diff --git a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py index ad3b7d59a53..47dd8025a3f 100644 --- a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +++ b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py @@ -3,10 +3,11 @@ EXAMPLES:: - sage: P. = GF(5)[] - sage: f = x^5 - 3*x^4 - 2*x^3 + 6*x^2 + 3*x - 1 - sage: C = HyperellipticCurve(f); C - Hyperelliptic Curve over Finite Field of size 5 defined by y^2 = x^5 + 2*x^4 + 3*x^3 + x^2 + 3*x + 4 + sage: P. = GF(5)[] # optional - sage.rings.finite_rings + sage: f = x^5 - 3*x^4 - 2*x^3 + 6*x^2 + 3*x - 1 # optional - sage.rings.finite_rings + sage: C = HyperellipticCurve(f); C # optional - sage.rings.finite_rings + Hyperelliptic Curve over Finite Field of size 5 + defined by y^2 = x^5 + 2*x^4 + 3*x^3 + x^2 + 3*x + 4 :: @@ -46,12 +47,13 @@ def is_HyperellipticCurve(C): """ EXAMPLES:: + sage: from sage.schemes.hyperelliptic_curves.hyperelliptic_generic import is_HyperellipticCurve sage: R. = QQ[]; C = HyperellipticCurve(x^3 + x - 1); C Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + x - 1 - sage: sage.schemes.hyperelliptic_curves.hyperelliptic_generic.is_HyperellipticCurve(C) + sage: is_HyperellipticCurve(C) True """ - return isinstance(C,HyperellipticCurve_generic) + return isinstance(C, HyperellipticCurve_generic) class HyperellipticCurve_generic(plane_curve.ProjectivePlaneCurve): @@ -83,14 +85,14 @@ class HyperellipticCurve_generic(plane_curve.ProjectivePlaneCurve): sage: C0 = HyperellipticCurve(f0) sage: f1 = x^5 - x^3 + x - 22 sage: C1 = HyperellipticCurve(f1) - sage: Q. = GF(5)[] - sage: f2 = y^5 - y^3 + y - 22 - sage: C2 = HyperellipticCurve(f2) + sage: Q. = GF(5)[] # optional - sage.rings.finite_rings + sage: f2 = y^5 - y^3 + y - 22 # optional - sage.rings.finite_rings + sage: C2 = HyperellipticCurve(f2) # optional - sage.rings.finite_rings sage: hash(C0) == hash(C0) True sage: hash(C0) == hash(C1) False - sage: hash(C1) == hash(C2) + sage: hash(C1) == hash(C2) # optional - sage.rings.finite_rings False """ def __init__(self, PP, f, h=None, names=None, genus=None): @@ -120,22 +122,26 @@ def __init__(self, PP, f, h=None, names=None, genus=None): def change_ring(self, R): """ - Returns this HyperellipticCurve over a new base ring R. + Returns this HyperellipticCurve over a new base ring ``R``. EXAMPLES:: sage: R. = QQ[] sage: H = HyperellipticCurve(x^5 - 10*x + 9) - sage: K = Qp(3,5) - sage: L. = K.extension(x^30-3) - sage: HK = H.change_ring(K) - sage: HL = HK.change_ring(L); HL - Hyperelliptic Curve over 3-adic Eisenstein Extension Field in a defined by x^30 - 3 defined by (1 + O(a^150))*y^2 = (1 + O(a^150))*x^5 + (2 + 2*a^30 + a^60 + 2*a^90 + 2*a^120 + O(a^150))*x + a^60 + O(a^210) - - sage: R. = FiniteField(7)[] - sage: H = HyperellipticCurve(x^8 + x + 5) - sage: H.base_extend(FiniteField(7^2, 'a')) - Hyperelliptic Curve over Finite Field in a of size 7^2 defined by y^2 = x^8 + x + 5 + sage: K = Qp(3, 5) # optional - sage.rings.padics + sage: L. = K.extension(x^30 - 3) # optional - sage.rings.padics + sage: HK = H.change_ring(K) # optional - sage.rings.padics + sage: HL = HK.change_ring(L); HL # optional - sage.rings.padics + Hyperelliptic Curve + over 3-adic Eisenstein Extension Field in a defined by x^30 - 3 + defined by (1 + O(a^150))*y^2 = (1 + O(a^150))*x^5 + + (2 + 2*a^30 + a^60 + 2*a^90 + 2*a^120 + O(a^150))*x + a^60 + O(a^210) + + sage: R. = FiniteField(7)[] # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(x^8 + x + 5) # optional - sage.rings.finite_rings + sage: H.base_extend(FiniteField(7^2, 'a')) # optional - sage.rings.finite_rings + Hyperelliptic Curve over Finite Field in a of size 7^2 + defined by y^2 = x^8 + x + 5 """ from .constructor import HyperellipticCurve f, h = self._hyperelliptic_polynomials @@ -192,7 +198,7 @@ def is_singular(self): EXAMPLES:: sage: R. = QQ[] - sage: H = HyperellipticCurve(x^5+1) + sage: H = HyperellipticCurve(x^5 + 1) sage: H.is_singular() False @@ -201,7 +207,7 @@ def is_singular(self): the following example.:: sage: R. = QQ[] - sage: H = HyperellipticCurve(x^5+2) + sage: H = HyperellipticCurve(x^5 + 2) sage: from sage.misc.verbose import set_verbose sage: set_verbose(-1) sage: H.is_singular() @@ -219,23 +225,23 @@ def is_smooth(self): EXAMPLES:: - sage: R. = GF(13)[] - sage: H = HyperellipticCurve(x^8+1) - sage: H.is_smooth() + sage: R. = GF(13)[] # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(x^8 + 1) # optional - sage.rings.finite_rings + sage: H.is_smooth() # optional - sage.rings.finite_rings True A hyperelliptic curve with genus at least 2 always has a singularity at infinity when viewed as a *plane* projective curve. This can be seen in the following example.:: - sage: R. = GF(27, 'a')[] - sage: H = HyperellipticCurve(x^10+2) + sage: R. = GF(27, 'a')[] # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(x^10 + 2) # optional - sage.rings.finite_rings sage: from sage.misc.verbose import set_verbose sage: set_verbose(-1) - sage: H.is_smooth() + sage: H.is_smooth() # optional - sage.rings.finite_rings True sage: from sage.schemes.curves.projective_curve import ProjectivePlaneCurve - sage: ProjectivePlaneCurve.is_smooth(H) + sage: ProjectivePlaneCurve.is_smooth(H) # optional - sage.rings.finite_rings False """ return True @@ -285,36 +291,40 @@ def odd_degree_model(self): ... ValueError: No odd degree model exists over field of definition - sage: K2 = QuadraticField(-2, 'a') - sage: Hp2 = H.change_ring(K2).odd_degree_model(); Hp2 - Hyperelliptic Curve over Number Field in a with defining polynomial x^2 + 2 with a = 1.414213562373095?*I defined by y^2 = 6*a*x^5 - 29*x^4 - 20*x^2 + 6*a*x + 1 + sage: K2 = QuadraticField(-2, 'a') # optional - sage.rings.number_field + sage: Hp2 = H.change_ring(K2).odd_degree_model(); Hp2 # optional - sage.rings.number_field + Hyperelliptic Curve over Number Field in a + with defining polynomial x^2 + 2 with a = 1.414213562373095?*I + defined by y^2 = 6*a*x^5 - 29*x^4 - 20*x^2 + 6*a*x + 1 - sage: K3 = QuadraticField(-3, 'b') - sage: Hp3 = H.change_ring(QuadraticField(-3, 'b')).odd_degree_model(); Hp3 - Hyperelliptic Curve over Number Field in b with defining polynomial x^2 + 3 with b = 1.732050807568878?*I defined by y^2 = -4*b*x^5 - 14*x^4 - 20*b*x^3 - 35*x^2 + 6*b*x + 1 + sage: K3 = QuadraticField(-3, 'b') # optional - sage.rings.number_field + sage: Hp3 = H.change_ring(QuadraticField(-3, 'b')).odd_degree_model(); Hp3 # optional - sage.rings.number_field + Hyperelliptic Curve over Number Field in b + with defining polynomial x^2 + 3 with b = 1.732050807568878?*I + defined by y^2 = -4*b*x^5 - 14*x^4 - 20*b*x^3 - 35*x^2 + 6*b*x + 1 - Of course, Hp2 and Hp3 are isomorphic over the composite + Of course, ``Hp2`` and ``Hp3`` are isomorphic over the composite extension. One consequence of this is that odd degree models reduced over "different" fields should have the same number of points on their reductions. 43 and 67 split completely in the compositum, so when we reduce we find: - sage: P2 = K2.factor(43)[0][0] - sage: P3 = K3.factor(43)[0][0] - sage: Hp2.change_ring(K2.residue_field(P2)).frobenius_polynomial() + sage: P2 = K2.factor(43)[0][0] # optional - sage.rings.number_field + sage: P3 = K3.factor(43)[0][0] # optional - sage.rings.number_field + sage: Hp2.change_ring(K2.residue_field(P2)).frobenius_polynomial() # optional - sage.rings.number_field x^4 - 16*x^3 + 134*x^2 - 688*x + 1849 - sage: Hp3.change_ring(K3.residue_field(P3)).frobenius_polynomial() + sage: Hp3.change_ring(K3.residue_field(P3)).frobenius_polynomial() # optional - sage.rings.number_field x^4 - 16*x^3 + 134*x^2 - 688*x + 1849 - sage: H.change_ring(GF(43)).odd_degree_model().frobenius_polynomial() + sage: H.change_ring(GF(43)).odd_degree_model().frobenius_polynomial() # optional - sage.rings.finite_rings x^4 - 16*x^3 + 134*x^2 - 688*x + 1849 - sage: P2 = K2.factor(67)[0][0] - sage: P3 = K3.factor(67)[0][0] - sage: Hp2.change_ring(K2.residue_field(P2)).frobenius_polynomial() + sage: P2 = K2.factor(67)[0][0] # optional - sage.rings.number_field + sage: P3 = K3.factor(67)[0][0] # optional - sage.rings.number_field + sage: Hp2.change_ring(K2.residue_field(P2)).frobenius_polynomial() # optional - sage.rings.number_field x^4 - 8*x^3 + 150*x^2 - 536*x + 4489 - sage: Hp3.change_ring(K3.residue_field(P3)).frobenius_polynomial() + sage: Hp3.change_ring(K3.residue_field(P3)).frobenius_polynomial() # optional - sage.rings.number_field x^4 - 8*x^3 + 150*x^2 - 536*x + 4489 - sage: H.change_ring(GF(67)).odd_degree_model().frobenius_polynomial() + sage: H.change_ring(GF(67)).odd_degree_model().frobenius_polynomial() # optional - sage.rings.finite_rings x^4 - 8*x^3 + 150*x^2 - 536*x + 4489 TESTS:: @@ -373,15 +383,18 @@ def _magma_init_(self, magma): EXAMPLES:: sage: R. = QQ[]; C = HyperellipticCurve(x^3 + x - 1, x); C - Hyperelliptic Curve over Rational Field defined by y^2 + x*y = x^3 + x - 1 - sage: magma(C) # optional - magma + Hyperelliptic Curve over Rational Field + defined by y^2 + x*y = x^3 + x - 1 + sage: magma(C) # optional - magma Hyperelliptic Curve defined by y^2 + x*y = x^3 + x - 1 over Rational Field - sage: R. = GF(9,'a')[]; C = HyperellipticCurve(x^3 + x - 1, x^10); C - Hyperelliptic Curve over Finite Field in a of size 3^2 defined by y^2 + x^10*y = x^3 + x + 2 - sage: D = magma(C); D # optional - magma + sage: R. = GF(9,'a')[]; C = HyperellipticCurve(x^3 + x - 1, x^10); C # optional - sage.rings.finite_rings + Hyperelliptic Curve over Finite Field in a of size 3^2 + defined by y^2 + x^10*y = x^3 + x + 2 + sage: D = magma(C); D # optional - magma # optional - sage.rings.finite_rings Hyperelliptic Curve defined by y^2 + (x^10)*y = x^3 + x + 2 over GF(3^2) - sage: D.sage() # optional - magma - Hyperelliptic Curve over Finite Field in a of size 3^2 defined by y^2 + x^10*y = x^3 + x + 2 + sage: D.sage() # optional - magma # optional - sage.rings.finite_rings + Hyperelliptic Curve over Finite Field in a of size 3^2 + defined by y^2 + x^10*y = x^3 + x + 2 """ f, h = self._hyperelliptic_polynomials return 'HyperellipticCurve(%s, %s)'%(f._magma_init_(magma), h._magma_init_(magma)) @@ -429,15 +442,15 @@ def local_coordinates_at_nonweierstrass(self, P, prec=20, name='t'): EXAMPLES:: sage: R. = QQ['x'] - sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) - sage: P = H(1,6) - sage: x,y = H.local_coordinates_at_nonweierstrass(P,prec=5) + sage: H = HyperellipticCurve(x^5 - 23*x^3 + 18*x^2 + 40*x) + sage: P = H(1, 6) + sage: x, y = H.local_coordinates_at_nonweierstrass(P, prec=5) sage: x 1 + t + O(t^5) sage: y 6 + t - 7/2*t^2 - 1/2*t^3 - 25/48*t^4 + O(t^5) - sage: Q = H(-2,12) - sage: x,y = H.local_coordinates_at_nonweierstrass(Q,prec=5) + sage: Q = H(-2, 12) + sage: x, y = H.local_coordinates_at_nonweierstrass(Q, prec=5) sage: x -2 + t + O(t^5) sage: y @@ -445,7 +458,7 @@ def local_coordinates_at_nonweierstrass(self, P, prec=20, name='t'): AUTHOR: - - Jennifer Balakrishnan (2007-12) + - Jennifer Balakrishnan (2007-12) """ d = P[1] if d == 0: @@ -481,7 +494,7 @@ def local_coordinates_at_weierstrass(self, P, prec=20, name='t'): EXAMPLES:: sage: R. = QQ['x'] - sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) + sage: H = HyperellipticCurve(x^5 - 23*x^3 + 18*x^2 + 40*x) sage: A = H(4, 0) sage: x, y = H.local_coordinates_at_weierstrass(A, prec=7) sage: x @@ -496,7 +509,7 @@ def local_coordinates_at_weierstrass(self, P, prec=20, name='t'): t + O(t^5) AUTHOR: - - Jennifer Balakrishnan (2007-12) + - Jennifer Balakrishnan (2007-12) - Francis Clarke (2012-08-26) """ @@ -533,8 +546,8 @@ def local_coordinates_at_infinity(self, prec=20, name='t'): EXAMPLES:: sage: R. = QQ['x'] - sage: H = HyperellipticCurve(x^5-5*x^2+1) - sage: x,y = H.local_coordinates_at_infinity(10) + sage: H = HyperellipticCurve(x^5 - 5*x^2 + 1) + sage: x, y = H.local_coordinates_at_infinity(10) sage: x t^-2 + 5*t^4 - t^8 - 50*t^10 + O(t^12) sage: y @@ -543,8 +556,8 @@ def local_coordinates_at_infinity(self, prec=20, name='t'): :: sage: R. = QQ['x'] - sage: H = HyperellipticCurve(x^3-x+1) - sage: x,y = H.local_coordinates_at_infinity(10) + sage: H = HyperellipticCurve(x^3 - x + 1) + sage: x, y = H.local_coordinates_at_infinity(10) sage: x t^-2 + t^2 - t^4 - t^6 + 3*t^8 + O(t^12) sage: y @@ -587,16 +600,18 @@ def local_coord(self, P, prec=20, name='t'): EXAMPLES:: sage: R. = QQ['x'] - sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) + sage: H = HyperellipticCurve(x^5 - 23*x^3 + 18*x^2 + 40*x) sage: H.local_coord(H(1 ,6), prec=5) (1 + t + O(t^5), 6 + t - 7/2*t^2 - 1/2*t^3 - 25/48*t^4 + O(t^5)) sage: H.local_coord(H(4, 0), prec=7) (4 + 1/360*t^2 - 191/23328000*t^4 + 7579/188956800000*t^6 + O(t^7), t + O(t^7)) sage: H.local_coord(H(0, 1, 0), prec=5) - (t^-2 + 23*t^2 - 18*t^4 - 569*t^6 + O(t^7), t^-5 + 46*t^-1 - 36*t - 609*t^3 + 1656*t^5 + O(t^6)) + (t^-2 + 23*t^2 - 18*t^4 - 569*t^6 + O(t^7), + t^-5 + 46*t^-1 - 36*t - 609*t^3 + 1656*t^5 + O(t^6)) AUTHOR: - - Jennifer Balakrishnan (2007-12) + + - Jennifer Balakrishnan (2007-12) """ if P[1] == 0: return self.local_coordinates_at_weierstrass(P, prec, name) @@ -614,9 +629,10 @@ def rational_points(self, **kwds): EXAMPLES: - For the LMFDB genus 2 curve `932.a.3728.1 `:: + For the LMFDB genus 2 curve `932.a.3728.1 `_:: - sage: R. = PolynomialRing(QQ); C = HyperellipticCurve(R([0, -1, 1, 0, 1, -2, 1]), R([1])); + sage: R. = PolynomialRing(QQ) + sage: C = HyperellipticCurve(R([0, -1, 1, 0, 1, -2, 1]), R([1])) sage: C.rational_points(bound=8) [(-1 : -3 : 1), (-1 : 2 : 1), @@ -629,9 +645,9 @@ def rational_points(self, **kwds): (1 : 0 : 1)] Check that :trac:`29509` is fixed for the LMFDB genus 2 curve - `169.a.169.1 `:: + `169.a.169.1 `_:: - sage: C = HyperellipticCurve(R([0, 0, 0, 0, 1, 1]), R([1, 1, 0, 1])); + sage: C = HyperellipticCurve(R([0, 0, 0, 0, 1, 1]), R([1, 1, 0, 1])) sage: C.rational_points(bound=10) [(-1 : 0 : 1), (-1 : 1 : 1), @@ -641,9 +657,9 @@ def rational_points(self, **kwds): An example over a number field:: - sage: R. = PolynomialRing(QuadraticField(2)); - sage: C = HyperellipticCurve(R([1, 0, 0, 0, 0, 1])); - sage: C.rational_points(bound=2) + sage: R. = PolynomialRing(QuadraticField(2)) # optional - sage.rings.number_field + sage: C = HyperellipticCurve(R([1, 0, 0, 0, 0, 1])) # optional - sage.rings.number_field + sage: C.rational_points(bound=2) # optional - sage.rings.number_field [(-1 : 0 : 1), (0 : -1 : 1), (0 : 1 : 0), diff --git a/src/sage/schemes/hyperelliptic_curves/invariants.py b/src/sage/schemes/hyperelliptic_curves/invariants.py index a6952117abc..7db44ac03aa 100644 --- a/src/sage/schemes/hyperelliptic_curves/invariants.py +++ b/src/sage/schemes/hyperelliptic_curves/invariants.py @@ -24,14 +24,15 @@ def diffxy(f, x, xtimes, y, ytimes): EXAMPLES:: + sage: from sage.schemes.hyperelliptic_curves.invariants import diffxy sage: R. = QQ[] - sage: sage.schemes.hyperelliptic_curves.invariants.diffxy(u^2*v^3, u, 0, v, 0) + sage: diffxy(u^2*v^3, u, 0, v, 0) u^2*v^3 - sage: sage.schemes.hyperelliptic_curves.invariants.diffxy(u^2*v^3, u, 2, v, 1) + sage: diffxy(u^2*v^3, u, 2, v, 1) 6*v^2 - sage: sage.schemes.hyperelliptic_curves.invariants.diffxy(u^2*v^3, u, 2, v, 2) + sage: diffxy(u^2*v^3, u, 2, v, 2) 12*v - sage: sage.schemes.hyperelliptic_curves.invariants.diffxy(u^2*v^3 + u^4*v^4, u, 2, v, 2) + sage: diffxy(u^2*v^3 + u^4*v^4, u, 2, v, 2) 144*u^2*v^2 + 12*v """ h = f @@ -67,7 +68,8 @@ def differential_operator(f, g, k): sage: differential_operator(x^2*y, x*y^2, 2) 1/36*dfdy^2*dgdx^2 - 1/18*dfdx*dfdy*dgdx*dgdy + 1/36*dfdx^2*dgdy^2 sage: differential_operator(x^2*y, x*y^2, 4) - 1/576*dfdy^4*dgdx^4 - 1/144*dfdx*dfdy^3*dgdx^3*dgdy + 1/96*dfdx^2*dfdy^2*dgdx^2*dgdy^2 - 1/144*dfdx^3*dfdy*dgdx*dgdy^3 + 1/576*dfdx^4*dgdy^4 + 1/576*dfdy^4*dgdx^4 - 1/144*dfdx*dfdy^3*dgdx^3*dgdy + 1/96*dfdx^2*dfdy^2*dgdx^2*dgdy^2 + - 1/144*dfdx^3*dfdy*dgdx*dgdy^3 + 1/576*dfdx^4*dgdy^4 """ (x, y) = f.parent().gens() n = max(ZZ(f.degree()), ZZ(k)) @@ -173,8 +175,8 @@ def ubs(f): 'y2': 0, 'y3': 0} - sage: R. = GF(31)[] - sage: ubs(t^6 + 2*t^5 + t^2 + 3*t + 1) + sage: R. = GF(31)[] # optional - sage.rings.finite_rings + sage: ubs(t^6 + 2*t^5 + t^2 + 3*t + 1) # optional - sage.rings.finite_rings {'A': 0, 'B': -12, 'C': -15, @@ -217,11 +219,11 @@ def clebsch_to_igusa(A, B, C, D): sage: igusa_to_clebsch(*clebsch_to_igusa(2, 3, 4, 5)) (2, 3, 4, 5) - sage: Cs = tuple(map(GF(31), (2, 3, 4, 5))); Cs + sage: Cs = tuple(map(GF(31), (2, 3, 4, 5))); Cs # optional - sage.rings.finite_rings (2, 3, 4, 5) - sage: clebsch_to_igusa(*Cs) + sage: clebsch_to_igusa(*Cs) # optional - sage.rings.finite_rings (8, 10, 15, 26) - sage: igusa_to_clebsch(*clebsch_to_igusa(*Cs)) + sage: igusa_to_clebsch(*clebsch_to_igusa(*Cs)) # optional - sage.rings.finite_rings (2, 3, 4, 5) """ I2 = -120*A @@ -243,11 +245,11 @@ def igusa_to_clebsch(I2, I4, I6, I10): sage: clebsch_to_igusa(*igusa_to_clebsch(-2400, 173700, 23112000, -10309890600)) (-2400, 173700, 23112000, -10309890600) - sage: Is = tuple(map(GF(31), (-2400, 173700, 23112000, -10309890600))); Is + sage: Is = tuple(map(GF(31), (-2400, 173700, 23112000, -10309890600))); Is # optional - sage.rings.finite_rings (18, 7, 12, 27) - sage: igusa_to_clebsch(*Is) + sage: igusa_to_clebsch(*Is) # optional - sage.rings.finite_rings (20, 25, 25, 12) - sage: clebsch_to_igusa(*igusa_to_clebsch(*Is)) + sage: clebsch_to_igusa(*igusa_to_clebsch(*Is)) # optional - sage.rings.finite_rings (18, 7, 12, 27) """ A = -(+ I2) / 120 @@ -274,9 +276,9 @@ def clebsch_invariants(f): sage: clebsch_invariants(x^6 + x^5 + x^4 + x^2 + 2) (62/15, 15434/5625, -236951/140625, 229930748/791015625) - sage: magma(x^6 + 1).ClebschInvariants() # optional - magma + sage: magma(x^6 + 1).ClebschInvariants() # optional - magma [ 2, 2/3, -2/9, 0 ] - sage: magma(x^6 + x^5 + x^4 + x^2 + 2).ClebschInvariants() # optional - magma + sage: magma(x^6 + x^5 + x^4 + x^2 + 2).ClebschInvariants() # optional - magma [ 62/15, 15434/5625, -236951/140625, 229930748/791015625 ] """ R = f.parent().base_ring() @@ -307,9 +309,9 @@ def igusa_clebsch_invariants(f): sage: igusa_clebsch_invariants(x^6 + x^5 + x^4 + x^2 + 2) (-496, 6220, -955932, -1111784) - sage: magma(x^6 + 1).IgusaClebschInvariants() # optional - magma + sage: magma(x^6 + 1).IgusaClebschInvariants() # optional - magma [ -240, 1620, -119880, -46656 ] - sage: magma(x^6 + x^5 + x^4 + x^2 + 2).IgusaClebschInvariants() # optional - magma + sage: magma(x^6 + x^5 + x^4 + x^2 + 2).IgusaClebschInvariants() # optional - magma [ -496, 6220, -955932, -1111784 ] TESTS: @@ -321,10 +323,11 @@ def igusa_clebsch_invariants(f): sage: igusa_clebsch_invariants(x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e)[0] 6*b^2 - 16*a*c + 40*d - sage: absolute_igusa_invariants_wamelen(GF(5)['x'](x^6 - 2*x)) + sage: absolute_igusa_invariants_wamelen(GF(5)['x'](x^6 - 2*x)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - NotImplementedError: Invariants of binary sextics/genus 2 hyperelliptic curves not implemented in characteristics 2, 3, and 5 + NotImplementedError: Invariants of binary sextics/genus 2 hyperelliptic curves + not implemented in characteristics 2, 3, and 5 """ return clebsch_to_igusa(*clebsch_invariants(f)) @@ -348,16 +351,18 @@ def absolute_igusa_invariants_wamelen(f): The following example can be checked against van Wamelen's paper:: - sage: i1, i2, i3 = absolute_igusa_invariants_wamelen(-x^5 + 3*x^4 + 2*x^3 - 6*x^2 - 3*x + 1) + sage: h = -x^5 + 3*x^4 + 2*x^3 - 6*x^2 - 3*x + 1 + sage: i1, i2, i3 = absolute_igusa_invariants_wamelen(h) sage: list(map(factor, (i1, i2, i3))) [2^7 * 3^15, 2^5 * 3^11 * 5, 2^4 * 3^9 * 31] TESTS:: - sage: absolute_igusa_invariants_wamelen(GF(3)['x'](x^5 - 2*x)) + sage: absolute_igusa_invariants_wamelen(GF(3)['x'](x^5 - 2*x)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - NotImplementedError: Invariants of binary sextics/genus 2 hyperelliptic curves not implemented in characteristics 2, 3, and 5 + NotImplementedError: Invariants of binary sextics/genus 2 hyperelliptic curves + not implemented in characteristics 2, 3, and 5 """ I2, I4, I6, I10 = igusa_clebsch_invariants(f) i1 = I2**5/I10 @@ -383,7 +388,8 @@ def absolute_igusa_invariants_kohel(f): The following example can be checked against Kohel's database [KohECHIDNA]_ :: - sage: i1, i2, i3 = absolute_igusa_invariants_kohel(-x^5 + 3*x^4 + 2*x^3 - 6*x^2 - 3*x + 1) + sage: h = -x^5 + 3*x^4 + 2*x^3 - 6*x^2 - 3*x + 1 + sage: i1, i2, i3 = absolute_igusa_invariants_kohel(h) sage: list(map(factor, (i1, i2, i3))) [2^2 * 3^5 * 5 * 31, 2^5 * 3^11 * 5, 2^4 * 3^9 * 31] sage: list(map(factor, (150660, 28343520, 9762768))) @@ -391,10 +397,11 @@ def absolute_igusa_invariants_kohel(f): TESTS:: - sage: absolute_igusa_invariants_kohel(GF(2)['x'](x^5 - x)) + sage: absolute_igusa_invariants_kohel(GF(2)['x'](x^5 - x)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - NotImplementedError: Invariants of binary sextics/genus 2 hyperelliptic curves not implemented in characteristics 2, 3, and 5 + NotImplementedError: Invariants of binary sextics/genus 2 hyperelliptic curves + not implemented in characteristics 2, 3, and 5 """ I2, I4, I6, I10 = igusa_clebsch_invariants(f) i1 = I4*I6/I10 diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py b/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py index 21de152a878..ec04cfd8801 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py @@ -23,21 +23,21 @@ class HyperellipticJacobian_generic(Jacobian_generic): """ EXAMPLES:: - sage: FF = FiniteField(2003) - sage: R. = PolynomialRing(FF) - sage: f = x**5 + 1184*x**3 + 1846*x**2 + 956*x + 560 - sage: C = HyperellipticCurve(f) - sage: J = C.jacobian() - sage: a = x**2 + 376*x + 245; b = 1015*x + 1368 - sage: X = J(FF) - sage: D = X([a,b]) - sage: D + sage: FF = FiniteField(2003) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(FF) # optional - sage.rings.finite_rings + sage: f = x**5 + 1184*x**3 + 1846*x**2 + 956*x + 560 # optional - sage.rings.finite_rings + sage: C = HyperellipticCurve(f) # optional - sage.rings.finite_rings + sage: J = C.jacobian() # optional - sage.rings.finite_rings + sage: a = x**2 + 376*x + 245; b = 1015*x + 1368 # optional - sage.rings.finite_rings + sage: X = J(FF) # optional - sage.rings.finite_rings + sage: D = X([a,b]) # optional - sage.rings.finite_rings + sage: D # optional - sage.rings.finite_rings (x^2 + 376*x + 245, y + 988*x + 635) - sage: J(0) + sage: J(0) # optional - sage.rings.finite_rings (1) - sage: D == J([a,b]) + sage: D == J([a,b]) # optional - sage.rings.finite_rings True - sage: D == D + J(0) + sage: D == D + J(0) # optional - sage.rings.finite_rings True An more extended example, demonstrating arithmetic in J(QQ) and @@ -56,24 +56,29 @@ class HyperellipticJacobian_generic(Jacobian_generic): sage: C.defining_polynomial() -x0^5 + x0*x1*x2^3 + x1^2*x2^3 + x0*x2^4 - x2^5 sage: C(QQ) - Set of rational points of Hyperelliptic Curve over Rational Field defined by v^2 + u*v = u^5 - u + 1 - sage: K. = NumberField(x^2-2) - sage: C(K) - Set of rational points of Hyperelliptic Curve over Number Field in t with defining polynomial x^2 - 2 defined by v^2 + u*v = u^5 - u + 1 + Set of rational points of Hyperelliptic Curve over Rational Field + defined by v^2 + u*v = u^5 - u + 1 + sage: K. = NumberField(x^2 - 2) # optional - sage.rings.number_field + sage: C(K) # optional - sage.rings.number_field + Set of rational points of Hyperelliptic Curve + over Number Field in t with defining polynomial x^2 - 2 + defined by v^2 + u*v = u^5 - u + 1 sage: P = C(QQ)(0,1,1); P (0 : 1 : 1) sage: P == C(0,1,1) True sage: C(0,1,1).parent() - Set of rational points of Hyperelliptic Curve over Rational Field defined by v^2 + u*v = u^5 - u + 1 - sage: P1 = C(K)(P) - sage: P2 = C(K)([2,4*t-1,1]) - sage: P3 = C(K)([-1/2,1/8*(7*t+2),1]) - sage: P1, P2, P3 + Set of rational points of Hyperelliptic Curve over Rational Field + defined by v^2 + u*v = u^5 - u + 1 + sage: P1 = C(K)(P) # optional - sage.rings.number_field + sage: P2 = C(K)([2, 4*t - 1, 1]) # optional - sage.rings.number_field + sage: P3 = C(K)([-1/2, 1/8*(7*t+2), 1]) # optional - sage.rings.number_field + sage: P1, P2, P3 # optional - sage.rings.number_field ((0 : 1 : 1), (2 : 4*t - 1 : 1), (-1/2 : 7/8*t + 1/4 : 1)) sage: J = C.jacobian() sage: J - Jacobian of Hyperelliptic Curve over Rational Field defined by v^2 + u*v = u^5 - u + 1 + Jacobian of Hyperelliptic Curve over Rational Field + defined by v^2 + u*v = u^5 - u + 1 sage: Q = J(QQ)(P); Q (u, v - 1) sage: for i in range(6): Q*i @@ -83,47 +88,54 @@ class HyperellipticJacobian_generic(Jacobian_generic): (u^2, v + 1) (u, v + 1) (1) - sage: Q1 = J(K)(P1); print("%s -> %s"%( P1, Q1 )) + sage: Q1 = J(K)(P1); print("%s -> %s"%( P1, Q1 )) # optional - sage.rings.number_field (0 : 1 : 1) -> (u, v - 1) - sage: Q2 = J(K)(P2); print("%s -> %s"%( P2, Q2 )) + sage: Q2 = J(K)(P2); print("%s -> %s"%( P2, Q2 )) # optional - sage.rings.number_field (2 : 4*t - 1 : 1) -> (u - 2, v - 4*t + 1) - sage: Q3 = J(K)(P3); print("%s -> %s"%( P3, Q3 )) + sage: Q3 = J(K)(P3); print("%s -> %s"%( P3, Q3 )) # optional - sage.rings.number_field (-1/2 : 7/8*t + 1/4 : 1) -> (u + 1/2, v - 7/8*t - 1/4) - sage: R. = PolynomialRing(K) - sage: Q4 = J(K)([x^2-t,R(1)]) - sage: for i in range(4): Q4*i + sage: R. = PolynomialRing(K) # optional - sage.rings.number_field + sage: Q4 = J(K)([x^2 - t, R(1)]) # optional - sage.rings.number_field + sage: for i in range(4): Q4*i # optional - sage.rings.number_field (1) (u^2 - t, v - 1) (u^2 + (-3/4*t - 9/16)*u + 1/2*t + 1/4, v + (-1/32*t - 57/64)*u + 1/2*t + 9/16) - (u^2 + (1352416/247009*t - 1636930/247009)*u - 1156544/247009*t + 1900544/247009, v + (-2326345442/122763473*t + 3233153137/122763473)*u + 2439343104/122763473*t - 3350862929/122763473) - sage: R2 = Q2*5; R2 - (u^2 - 3789465233/116983808*u - 267915823/58491904, v + (-233827256513849/1789384327168*t + 1/2)*u - 15782925357447/894692163584*t) - sage: R3 = Q3*5; R3 - (u^2 + 5663300808399913890623/14426454798950909645952*u - 26531814176395676231273/28852909597901819291904, v + (253155440321645614070860868199103/2450498420175733688903836378159104*t + 1/2)*u + 2427708505064902611513563431764311/4900996840351467377807672756318208*t) - sage: R4 = Q4*5; R4 - (u^2 - 3789465233/116983808*u - 267915823/58491904, v + (233827256513849/1789384327168*t + 1/2)*u + 15782925357447/894692163584*t) + (u^2 + (1352416/247009*t - 1636930/247009)*u - 1156544/247009*t + 1900544/247009, + v + (-2326345442/122763473*t + 3233153137/122763473)*u + + 2439343104/122763473*t - 3350862929/122763473) + sage: R2 = Q2*5; R2 # optional - sage.rings.number_field + (u^2 - 3789465233/116983808*u - 267915823/58491904, + v + (-233827256513849/1789384327168*t + 1/2)*u - 15782925357447/894692163584*t) + sage: R3 = Q3*5; R3 # optional - sage.rings.number_field + (u^2 + 5663300808399913890623/14426454798950909645952*u + - 26531814176395676231273/28852909597901819291904, + v + (253155440321645614070860868199103/2450498420175733688903836378159104*t + 1/2)*u + + 2427708505064902611513563431764311/4900996840351467377807672756318208*t) + sage: R4 = Q4*5; R4 # optional - sage.rings.number_field + (u^2 - 3789465233/116983808*u - 267915823/58491904, + v + (233827256513849/1789384327168*t + 1/2)*u + 15782925357447/894692163584*t) Thus we find the following identity:: - sage: 5*Q2 + 5*Q4 + sage: 5*Q2 + 5*Q4 # optional - sage.rings.number_field (1) Moreover the following relation holds in the 5-torsion subgroup:: - sage: Q2 + Q4 == 2*Q1 + sage: Q2 + Q4 == 2*Q1 # optional - sage.rings.number_field True TESTS:: - sage: k. = GF(9); R. = k[] - sage: J1 = HyperellipticCurve(x^3 + x - 1, x+a).jacobian() - sage: FF = FiniteField(2003) - sage: R. = PolynomialRing(FF) - sage: f = x**5 + 1184*x**3 + 1846*x**2 + 956*x + 560 - sage: J2 = HyperellipticCurve(f).jacobian() - sage: J1 == J1 + sage: k. = GF(9); R. = k[] # optional - sage.rings.finite_rings + sage: J1 = HyperellipticCurve(x^3 + x - 1, x + a).jacobian() # optional - sage.rings.finite_rings + sage: FF = FiniteField(2003) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(FF) # optional - sage.rings.finite_rings + sage: f = x**5 + 1184*x**3 + 1846*x**2 + 956*x + 560 # optional - sage.rings.finite_rings + sage: J2 = HyperellipticCurve(f).jacobian() # optional - sage.rings.finite_rings + sage: J1 == J1 # optional - sage.rings.finite_rings True - sage: J1 == J2 + sage: J1 == J2 # optional - sage.rings.finite_rings False """ def dimension(self): @@ -136,12 +148,12 @@ def dimension(self): EXAMPLES:: - sage: k. = GF(9); R. = k[] - sage: HyperellipticCurve(x^3 + x - 1, x+a).jacobian().dimension() + sage: k. = GF(9); R. = k[] # optional - sage.rings.finite_rings + sage: HyperellipticCurve(x^3 + x - 1, x + a).jacobian().dimension() # optional - sage.rings.finite_rings 1 - sage: g = HyperellipticCurve(x^6 + x - 1, x+a).jacobian().dimension(); g + sage: g = HyperellipticCurve(x^6 + x - 1, x + a).jacobian().dimension(); g # optional - sage.rings.finite_rings 2 - sage: type(g) + sage: type(g) # optional - sage.rings.finite_rings <... 'sage.rings.integer.Integer'> """ return Integer(self.curve().genus()) diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py b/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py index 74cdccbaa49..f205b79b433 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py @@ -8,7 +8,8 @@ sage: C = HyperellipticCurve(f); C Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1 sage: C(QQ) - Set of rational points of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1 + Set of rational points of Hyperelliptic Curve over Rational Field + defined by y^2 = x^5 + x + 1 sage: P = C([0,1,1]) sage: J = C.jacobian(); J Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1 @@ -21,23 +22,18 @@ :: - sage: F. = GF(3) - sage: R. = F[] - sage: f = x^5-1 - sage: C = HyperellipticCurve(f) - sage: J = C.jacobian() - sage: X = J(F) - sage: a = x^2-x+1 - sage: b = -x +1 - sage: c = x-1 - sage: d = 0 - sage: D1 = X([a,b]) - sage: D1 + sage: F. = GF(3) # optional - sage.rings.finite_rings + sage: R. = F[] # optional - sage.rings.finite_rings + sage: f = x^5 - 1 # optional - sage.rings.finite_rings + sage: C = HyperellipticCurve(f) # optional - sage.rings.finite_rings + sage: J = C.jacobian() # optional - sage.rings.finite_rings + sage: X = J(F) # optional - sage.rings.finite_rings + sage: a = x^2 - x + 1; b = -x + 1; c = x - 1; d = 0 # optional - sage.rings.finite_rings + sage: D1 = X([a,b]); D1 # optional - sage.rings.finite_rings (x^2 + 2*x + 1, y + x + 2) - sage: D2 = X([c,d]) - sage: D2 + sage: D2 = X([c,d]); D2 # optional - sage.rings.finite_rings (x + 2, y) - sage: D1+D2 + sage: D1 + D2 # optional - sage.rings.finite_rings (x^2 + 2*x + 2, y + 2*x + 1) """ # **************************************************************************** @@ -102,23 +98,18 @@ def __call__(self, P): :: - sage: F. = GF(3) - sage: R. = F[] - sage: f = x^5-1 - sage: C = HyperellipticCurve(f) - sage: J = C.jacobian() - sage: X = J(F) - sage: a = x^2-x+1 - sage: b = -x +1 - sage: c = x-1 - sage: d = 0 - sage: D1 = X([a,b]) - sage: D1 + sage: F. = GF(3) # optional - sage.rings.finite_rings + sage: R. = F[] # optional - sage.rings.finite_rings + sage: f = x^5 - 1 # optional - sage.rings.finite_rings + sage: C = HyperellipticCurve(f) # optional - sage.rings.finite_rings + sage: J = C.jacobian() # optional - sage.rings.finite_rings + sage: X = J(F) # optional - sage.rings.finite_rings + sage: a = x^2 - x + 1; b = -x + 1; c = x - 1; d = 0 # optional - sage.rings.finite_rings + sage: D1 = X([a,b]); D1 # optional - sage.rings.finite_rings (x^2 + 2*x + 1, y + x + 2) - sage: D2 = X([c,d]) - sage: D2 + sage: D2 = X([c,d]); D2 # optional - sage.rings.finite_rings (x + 2, y) - sage: D1+D2 + sage: D1 + D2 # optional - sage.rings.finite_rings (x^2 + 2*x + 2, y + 2*x + 1) """ if isinstance(P, (Integer, int)) and P == 0: diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py b/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py index 19262aece79..69eed3ee979 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py @@ -36,42 +36,42 @@ :: - sage: x = GF(37)['x'].gen() - sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x); H + sage: x = GF(37)['x'].gen() # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x); H # optional - sage.rings.finite_rings Hyperelliptic Curve over Finite Field of size 37 defined - by y^2 = x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x + by y^2 = x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x At this time, Jacobians of hyperelliptic curves are handled differently than elliptic curves:: - sage: J = H.jacobian(); J + sage: J = H.jacobian(); J # optional - sage.rings.finite_rings Jacobian of Hyperelliptic Curve over Finite Field of size 37 defined - by y^2 = x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x - sage: J = J(J.base_ring()); J + by y^2 = x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x + sage: J = J(J.base_ring()); J # optional - sage.rings.finite_rings Set of rational points of Jacobian of Hyperelliptic Curve over Finite Field - of size 37 defined by y^2 = x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x + of size 37 defined by y^2 = x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x Points on the Jacobian are represented by Mumford's polynomials. First we find a couple of points on the curve:: - sage: P1 = H.lift_x(2); P1 + sage: P1 = H.lift_x(2); P1 # optional - sage.rings.finite_rings (2 : 11 : 1) - sage: Q1 = H.lift_x(10); Q1 + sage: Q1 = H.lift_x(10); Q1 # optional - sage.rings.finite_rings (10 : 18 : 1) Observe that 2 and 10 are the roots of the polynomials in x, respectively:: - sage: P = J(P1); P + sage: P = J(P1); P # optional - sage.rings.finite_rings (x + 35, y + 26) - sage: Q = J(Q1); Q + sage: Q = J(Q1); Q # optional - sage.rings.finite_rings (x + 27, y + 19) :: - sage: P + Q + sage: P + Q # optional - sage.rings.finite_rings (x^2 + 25*x + 20, y + 13*x) - sage: (x^2 + 25*x + 20).roots(multiplicities=False) + sage: (x^2 + 25*x + 20).roots(multiplicities=False) # optional - sage.rings.finite_rings [10, 2] Frobenius satisfies @@ -85,24 +85,24 @@ :: - sage: 1904*P + sage: 1904*P # optional - sage.rings.finite_rings (1) - sage: 34*P == 0 + sage: 34*P == 0 # optional - sage.rings.finite_rings True - sage: 35*P == P + sage: 35*P == P # optional - sage.rings.finite_rings True - sage: 33*P == -P + sage: 33*P == -P # optional - sage.rings.finite_rings True :: - sage: Q*1904 + sage: Q*1904 # optional - sage.rings.finite_rings (1) - sage: Q*238 == 0 + sage: Q*238 == 0 # optional - sage.rings.finite_rings True - sage: Q*239 == Q + sage: Q*239 == Q # optional - sage.rings.finite_rings True - sage: Q*237 == -Q + sage: Q*237 == -Q # optional - sage.rings.finite_rings True """ @@ -136,7 +136,7 @@ def cantor_reduction_simple(a, b, f, genus): Hyperelliptic Curve over Rational Field defined by y^2 = x^5 - x sage: J = H.jacobian()(QQ); J Set of rational points of Jacobian of Hyperelliptic Curve over Rational Field - defined by y^2 = x^5 - x + defined by y^2 = x^5 - x The following point is 2-torsion:: @@ -175,7 +175,7 @@ def cantor_reduction(a, b, f, h, genus): Hyperelliptic Curve over Rational Field defined by y^2 + x*y = x^5 - x sage: J = H.jacobian()(QQ); J Set of rational points of Jacobian of Hyperelliptic Curve over - Rational Field defined by y^2 + x*y = x^5 - x + Rational Field defined by y^2 + x*y = x^5 - x The following point is 2-torsion:: @@ -230,23 +230,22 @@ def cantor_composition_simple(D1,D2,f,genus): :: - sage: F. = NumberField(x^2 - 2, 'a') - sage: J = H.jacobian()(F); J + sage: F. = NumberField(x^2 - 2, 'a') # optional - sage.rings.number_field + sage: J = H.jacobian()(F); J # optional - sage.rings.number_field Set of rational points of Jacobian of Hyperelliptic Curve over - Number Field in a with defining polynomial x^2 - 2 defined - by y^2 = x^5 + x + Number Field in a with defining polynomial x^2 - 2 defined by y^2 = x^5 + x :: - sage: P = J(H.lift_x(F(1))); P + sage: P = J(H.lift_x(F(1))); P # optional - sage.rings.number_field (x - 1, y - a) - sage: Q = J(H.lift_x(F(0))); Q + sage: Q = J(H.lift_x(F(0))); Q # optional - sage.rings.number_field (x, y) - sage: 2*P + 2*Q # indirect doctest + sage: 2*P + 2*Q # indirect doctest # optional - sage.rings.number_field (x^2 - 2*x + 1, y - 3/2*a*x + 1/2*a) - sage: 2*(P + Q) # indirect doctest + sage: 2*(P + Q) # indirect doctest # optional - sage.rings.number_field (x^2 - 2*x + 1, y - 3/2*a*x + 1/2*a) - sage: 3*P # indirect doctest + sage: 3*P # indirect doctest # optional - sage.rings.number_field (x^2 - 25/32*x + 49/32, y - 45/256*a*x - 315/256*a) """ a1, b1 = D1 @@ -272,48 +271,57 @@ def cantor_composition(D1,D2,f,h,genus): r""" EXAMPLES:: - sage: F. = GF(7^2, 'a') - sage: x = F['x'].gen() - sage: f = x^7 + x^2 + a - sage: H = HyperellipticCurve(f, 2*x); H - Hyperelliptic Curve over Finite Field in a of size 7^2 defined by y^2 + 2*x*y = x^7 + x^2 + a - sage: J = H.jacobian()(F); J + sage: F. = GF(7^2, 'a') # optional - sage.rings.finite_rings + sage: x = F['x'].gen() # optional - sage.rings.finite_rings + sage: f = x^7 + x^2 + a # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(f, 2*x); H # optional - sage.rings.finite_rings + Hyperelliptic Curve over Finite Field in a of size 7^2 + defined by y^2 + 2*x*y = x^7 + x^2 + a + sage: J = H.jacobian()(F); J # optional - sage.rings.finite_rings Set of rational points of Jacobian of Hyperelliptic Curve over - Finite Field in a of size 7^2 defined by y^2 + 2*x*y = x^7 + x^2 + a + Finite Field in a of size 7^2 defined by y^2 + 2*x*y = x^7 + x^2 + a :: - sage: Q = J(H.lift_x(F(1))); Q + sage: Q = J(H.lift_x(F(1))); Q # optional - sage.rings.finite_rings (x + 6, y + 2*a + 2) - sage: 10*Q # indirect doctest - (x^3 + (3*a + 1)*x^2 + (2*a + 5)*x + a + 5, y + (4*a + 5)*x^2 + (a + 1)*x + 6*a + 3) - sage: 7*8297*Q + sage: 10*Q # indirect doctest # optional - sage.rings.finite_rings + (x^3 + (3*a + 1)*x^2 + (2*a + 5)*x + a + 5, + y + (4*a + 5)*x^2 + (a + 1)*x + 6*a + 3) + sage: 7*8297*Q # optional - sage.rings.finite_rings (1) :: - sage: Q = J(H.lift_x(F(a+1))); Q + sage: Q = J(H.lift_x(F(a+1))); Q # optional - sage.rings.finite_rings (x + 6*a + 6, y + 2*a) - sage: 7*8297*Q # indirect doctest + sage: 7*8297*Q # indirect doctest # optional - sage.rings.finite_rings (1) A test over a prime field: - sage: F = GF(next_prime(10^30)) - sage: x = F['x'].gen() - sage: f = x^7 + x^2 + 1 - sage: H = HyperellipticCurve(f, 2*x); H - Hyperelliptic Curve over Finite Field of size 1000000000000000000000000000057 defined by y^2 + 2*x*y = x^7 + x^2 + 1 - sage: J = H.jacobian()(F); J - Set of rational points of Jacobian of Hyperelliptic Curve over - Finite Field of size 1000000000000000000000000000057 defined - by y^2 + 2*x*y = x^7 + x^2 + 1 - sage: Q = J(H.lift_x(F(1))); Q + sage: F = GF(next_prime(10^30)) # optional - sage.rings.finite_rings + sage: x = F['x'].gen() # optional - sage.rings.finite_rings + sage: f = x^7 + x^2 + 1 # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(f, 2*x); H # optional - sage.rings.finite_rings + Hyperelliptic Curve over Finite Field of size 1000000000000000000000000000057 + defined by y^2 + 2*x*y = x^7 + x^2 + 1 + sage: J = H.jacobian()(F); J # optional - sage.rings.finite_rings + Set of rational points of Jacobian of Hyperelliptic Curve + over Finite Field of size 1000000000000000000000000000057 + defined by y^2 + 2*x*y = x^7 + x^2 + 1 + sage: Q = J(H.lift_x(F(1))); Q # optional - sage.rings.finite_rings (x + 1000000000000000000000000000056, y + 1000000000000000000000000000056) - sage: 10*Q # indirect doctest - (x^3 + 150296037169838934997145567227*x^2 + 377701248971234560956743242408*x + 509456150352486043408603286615, y + 514451014495791237681619598519*x^2 + 875375621665039398768235387900*x + 861429240012590886251910326876) - sage: 7*8297*Q - (x^3 + 35410976139548567549919839063*x^2 + 26230404235226464545886889960*x + 681571430588959705539385624700, y + 999722365017286747841221441793*x^2 + 262703715994522725686603955650*x + 626219823403254233972118260890) + sage: 10*Q # indirect doctest # optional - sage.rings.finite_rings + (x^3 + 150296037169838934997145567227*x^2 + + 377701248971234560956743242408*x + 509456150352486043408603286615, + y + 514451014495791237681619598519*x^2 + + 875375621665039398768235387900*x + 861429240012590886251910326876) + sage: 7*8297*Q # optional - sage.rings.finite_rings + (x^3 + 35410976139548567549919839063*x^2 + + 26230404235226464545886889960*x + 681571430588959705539385624700, + y + 999722365017286747841221441793*x^2 + + 262703715994522725686603955650*x + 626219823403254233972118260890) """ a1, b1 = D1 a2, b2 = D2 @@ -363,22 +371,22 @@ def __init__(self, parent, polys, check=True): EXAMPLES:: - sage: x = GF(37)['x'].gen() - sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x) - sage: J = H.jacobian()(GF(37)); J + sage: x = GF(37)['x'].gen() # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x) # optional - sage.rings.finite_rings + sage: J = H.jacobian()(GF(37)); J # optional - sage.rings.finite_rings Set of rational points of Jacobian of Hyperelliptic Curve over - Finite Field of size 37 defined by + Finite Field of size 37 defined by y^2 = x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x :: - sage: P1 = J(H.lift_x(2)); P1 # indirect doctest + sage: P1 = J(H.lift_x(2)); P1 # indirect doctest # optional - sage.rings.finite_rings (x + 35, y + 26) - sage: P1.parent() + sage: P1.parent() # optional - sage.rings.finite_rings Set of rational points of Jacobian of Hyperelliptic Curve over - Finite Field of size 37 defined by + Finite Field of size 37 defined by y^2 = x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x - sage: type(P1) + sage: type(P1) # optional - sage.rings.finite_rings """ SchemeMorphism.__init__(self, parent) @@ -400,15 +408,15 @@ def _printing_polys(self): TESTS:: - sage: F. = GF(7^2, 'a') - sage: x = F['x'].gen() - sage: f = x^7 + x^2 + a - sage: H = HyperellipticCurve(f, 2*x) - sage: J = H.jacobian()(F) + sage: F. = GF(7^2, 'a') # optional - sage.rings.finite_rings + sage: x = F['x'].gen() # optional - sage.rings.finite_rings + sage: f = x^7 + x^2 + a # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(f, 2*x) # optional - sage.rings.finite_rings + sage: J = H.jacobian()(F) # optional - sage.rings.finite_rings :: - sage: Q = J(H.lift_x(F(1))); Q # indirect doctest + sage: Q = J(H.lift_x(F(1))); Q # indirect doctest # optional - sage.rings.finite_rings (x + 6, y + 2*a + 2) """ a, b = self.__polys @@ -423,19 +431,19 @@ def _repr_(self): EXAMPLES:: - sage: F. = GF(7^2, 'a') - sage: x = F['x'].gen() - sage: f = x^7 + x^2 + a - sage: H = HyperellipticCurve(f, 2*x) - sage: J = H.jacobian()(F) + sage: F. = GF(7^2, 'a') # optional - sage.rings.finite_rings + sage: x = F['x'].gen() # optional - sage.rings.finite_rings + sage: f = x^7 + x^2 + a # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(f, 2*x) # optional - sage.rings.finite_rings + sage: J = H.jacobian()(F) # optional - sage.rings.finite_rings :: - sage: Q = J(0); Q # indirect doctest + sage: Q = J(0); Q # indirect doctest # optional - sage.rings.finite_rings (1) - sage: Q = J(H.lift_x(F(1))); Q # indirect doctest + sage: Q = J(H.lift_x(F(1))); Q # indirect doctest # optional - sage.rings.finite_rings (x + 6, y + 2*a + 2) - sage: Q + Q # indirect doctest + sage: Q + Q # indirect doctest # optional - sage.rings.finite_rings (x^2 + 5*x + 1, y + 3*a*x + 6*a + 2) """ if self.is_zero(): @@ -449,22 +457,22 @@ def _latex_(self): EXAMPLES:: - sage: F. = GF(7^2) - sage: x = F['x'].gen() - sage: f = x^7 + x^2 + alpha - sage: H = HyperellipticCurve(f, 2*x) - sage: J = H.jacobian()(F) + sage: F. = GF(7^2) # optional - sage.rings.finite_rings + sage: x = F['x'].gen() # optional - sage.rings.finite_rings + sage: f = x^7 + x^2 + alpha # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(f, 2*x) # optional - sage.rings.finite_rings + sage: J = H.jacobian()(F) # optional - sage.rings.finite_rings :: - sage: Q = J(0); print(latex(Q)) # indirect doctest + sage: Q = J(0); print(latex(Q)) # indirect doctest # optional - sage.rings.finite_rings \left(1\right) - sage: Q = J(H.lift_x(F(1))); print(latex(Q)) # indirect doctest + sage: Q = J(H.lift_x(F(1))); print(latex(Q)) # indirect doctest # optional - sage.rings.finite_rings \left(x + 6, y + 2 \alpha + 2\right) :: - sage: print(latex(Q + Q)) + sage: print(latex(Q + Q)) # optional - sage.rings.finite_rings \left(x^{2} + 5 x + 1, y + 3 \alpha x + 6 \alpha + 2\right) """ if self.is_zero(): @@ -474,8 +482,7 @@ def _latex_(self): def scheme(self): r""" - Return the scheme this morphism maps to; or, where this divisor - lives. + Return the scheme this morphism maps to; or, where this divisor lives. .. warning:: @@ -490,16 +497,16 @@ def scheme(self): sage: x = QQ['x'].gen() sage: f = x^5 + x sage: H = HyperellipticCurve(f) - sage: F. = NumberField(x^2 - 2, 'a') - sage: J = H.jacobian()(F); J - Set of rational points of Jacobian of Hyperelliptic Curve over - Number Field in a with defining polynomial x^2 - 2 defined - by y^2 = x^5 + x + sage: F. = NumberField(x^2 - 2, 'a') # optional - sage.rings.number_field + sage: J = H.jacobian()(F); J # optional - sage.rings.number_field + Set of rational points of Jacobian of Hyperelliptic Curve + over Number Field in a with defining polynomial x^2 - 2 + defined by y^2 = x^5 + x :: - sage: P = J(H.lift_x(F(1))) - sage: P.scheme() + sage: P = J(H.lift_x(F(1))) # optional - sage.rings.number_field + sage: P.scheme() # optional - sage.rings.number_field Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x """ return self.codomain() @@ -515,16 +522,16 @@ def __list__(self): sage: x = QQ['x'].gen() sage: f = x^5 + x sage: H = HyperellipticCurve(f) - sage: F. = NumberField(x^2 - 2, 'a') - sage: J = H.jacobian()(F); J - Set of rational points of Jacobian of Hyperelliptic Curve over - Number Field in a with defining polynomial x^2 - 2 defined - by y^2 = x^5 + x + sage: F. = NumberField(x^2 - 2, 'a') # optional - sage.rings.number_field + sage: J = H.jacobian()(F); J # optional - sage.rings.number_field + Set of rational points of Jacobian of Hyperelliptic Curve + over Number Field in a with defining polynomial x^2 - 2 + defined by y^2 = x^5 + x :: - sage: P = J(H.lift_x(F(1))) - sage: list(P) # indirect doctest + sage: P = J(H.lift_x(F(1))) # optional - sage.rings.number_field + sage: list(P) # indirect doctest # optional - sage.rings.number_field [x - 1, a] """ return list(self.__polys) @@ -539,16 +546,16 @@ def __tuple__(self): sage: x = QQ['x'].gen() sage: f = x^5 + x sage: H = HyperellipticCurve(f) - sage: F. = NumberField(x^2 - 2, 'a') - sage: J = H.jacobian()(F); J - Set of rational points of Jacobian of Hyperelliptic Curve over - Number Field in a with defining polynomial x^2 - 2 defined - by y^2 = x^5 + x + sage: F. = NumberField(x^2 - 2, 'a') # optional - sage.rings.number_field + sage: J = H.jacobian()(F); J # optional - sage.rings.number_field + Set of rational points of Jacobian of Hyperelliptic Curve + over Number Field in a with defining polynomial x^2 - 2 + defined by y^2 = x^5 + x :: - sage: P = J(H.lift_x(F(1))) - sage: tuple(P) # indirect doctest + sage: P = J(H.lift_x(F(1))) # optional - sage.rings.number_field + sage: tuple(P) # indirect doctest # optional - sage.rings.number_field (x - 1, a) """ return tuple(self.__polys) @@ -563,22 +570,22 @@ def __getitem__(self, n): sage: x = QQ['x'].gen() sage: f = x^5 + x sage: H = HyperellipticCurve(f) - sage: F. = NumberField(x^2 - 2, 'a') - sage: J = H.jacobian()(F); J - Set of rational points of Jacobian of Hyperelliptic Curve over - Number Field in a with defining polynomial x^2 - 2 defined - by y^2 = x^5 + x + sage: F. = NumberField(x^2 - 2, 'a') # optional - sage.rings.number_field + sage: J = H.jacobian()(F); J # optional - sage.rings.number_field + Set of rational points of Jacobian of Hyperelliptic Curve + over Number Field in a with defining polynomial x^2 - 2 + defined by y^2 = x^5 + x :: - sage: P = J(H.lift_x(F(1))) - sage: P[0] # indirect doctest + sage: P = J(H.lift_x(F(1))) # optional - sage.rings.number_field + sage: P[0] # indirect doctest # optional - sage.rings.number_field x - 1 - sage: P[1] # indirect doctest + sage: P[1] # indirect doctest # optional - sage.rings.number_field a - sage: P[-1] # indirect doctest + sage: P[-1] # indirect doctest # optional - sage.rings.number_field a - sage: P[:1] # indirect doctest + sage: P[:1] # indirect doctest # optional - sage.rings.number_field [x - 1] """ return list(self.__polys)[n] @@ -647,17 +654,17 @@ def __bool__(self): EXAMPLES:: - sage: x = GF(37)['x'].gen() - sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x) - sage: J = H.jacobian()(GF(37)) + sage: x = GF(37)['x'].gen() # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x) # optional - sage.rings.finite_rings + sage: J = H.jacobian()(GF(37)) # optional - sage.rings.finite_rings :: - sage: P1 = J(H.lift_x(2)); P1 + sage: P1 = J(H.lift_x(2)); P1 # optional - sage.rings.finite_rings (x + 35, y + 26) - sage: P1 == 0 # indirect doctest + sage: P1 == 0 # indirect doctest # optional - sage.rings.finite_rings False - sage: P1 - P1 == 0 # indirect doctest + sage: P1 - P1 == 0 # indirect doctest # optional - sage.rings.finite_rings True """ return self.__polys[0] != 1 @@ -670,25 +677,25 @@ def __neg__(self): EXAMPLES:: - sage: x = GF(37)['x'].gen() - sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x) - sage: J = H.jacobian()(GF(37)) - sage: P1 = J(H.lift_x(2)); P1 + sage: x = GF(37)['x'].gen() # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x) # optional - sage.rings.finite_rings + sage: J = H.jacobian()(GF(37)) # optional - sage.rings.finite_rings + sage: P1 = J(H.lift_x(2)); P1 # optional - sage.rings.finite_rings (x + 35, y + 26) - sage: - P1 # indirect doctest + sage: - P1 # indirect doctest # optional - sage.rings.finite_rings (x + 35, y + 11) - sage: P1 + (-P1) # indirect doctest + sage: P1 + (-P1) # indirect doctest # optional - sage.rings.finite_rings (1) :: - sage: H2 = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x, x) - sage: J2 = H2.jacobian()(GF(37)) - sage: P2 = J2(H2.lift_x(2)); P2 + sage: H2 = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x, x) # optional - sage.rings.finite_rings + sage: J2 = H2.jacobian()(GF(37)) # optional - sage.rings.finite_rings + sage: P2 = J2(H2.lift_x(2)); P2 # optional - sage.rings.finite_rings (x + 35, y + 15) - sage: - P2 # indirect doctest + sage: - P2 # indirect doctest # optional - sage.rings.finite_rings (x + 35, y + 24) - sage: P2 + (-P2) # indirect doctest + sage: P2 + (-P2) # indirect doctest # optional - sage.rings.finite_rings (1) TESTS: @@ -697,16 +704,16 @@ def __neg__(self): sage: P. = QQ[] sage: f = x^5 - x + 1; h = x - sage: C = HyperellipticCurve(f,h,'u,v') + sage: C = HyperellipticCurve(f, h, 'u,v') sage: J = C.jacobian() - sage: K. = NumberField(x^2-2) - sage: R. = K[] - sage: Q = J(K)([x^2-t,R(1)]) - sage: Q + sage: K. = NumberField(x^2 - 2) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: Q = J(K)([x^2 - t, R(1)]) # optional - sage.rings.number_field + sage: Q # optional - sage.rings.number_field (u^2 - t, v - 1) - sage: -Q + sage: -Q # optional - sage.rings.number_field (u^2 - t, v + u + 1) - sage: Q + (-Q) # indirect doctest + sage: Q + (-Q) # indirect doctest # optional - sage.rings.number_field (1) """ @@ -733,15 +740,15 @@ def _add_(self,other): EXAMPLES:: - sage: x = GF(37)['x'].gen() - sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x) - sage: J = H.jacobian()(GF(37)) + sage: x = GF(37)['x'].gen() # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x) # optional - sage.rings.finite_rings + sage: J = H.jacobian()(GF(37)) # optional - sage.rings.finite_rings :: - sage: P1 = J(H.lift_x(2)); P1 + sage: P1 = J(H.lift_x(2)); P1 # optional - sage.rings.finite_rings (x + 35, y + 26) - sage: P1 + P1 # indirect doctest + sage: P1 + P1 # indirect doctest # optional - sage.rings.finite_rings (x^2 + 33*x + 4, y + 13*x) """ X = self.parent() @@ -764,30 +771,30 @@ def _sub_(self, other): EXAMPLES:: - sage: x = GF(37)['x'].gen() - sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x) - sage: J = H.jacobian()(GF(37)) + sage: x = GF(37)['x'].gen() # optional - sage.rings.finite_rings + sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x) # optional - sage.rings.finite_rings + sage: J = H.jacobian()(GF(37)) # optional - sage.rings.finite_rings :: - sage: P1 = J(H.lift_x(2)); P1 + sage: P1 = J(H.lift_x(2)); P1 # optional - sage.rings.finite_rings (x + 35, y + 26) - sage: P1 - P1 # indirect doctest + sage: P1 - P1 # indirect doctest # optional - sage.rings.finite_rings (1) :: - sage: P2 = J(H.lift_x(4)); P2 + sage: P2 = J(H.lift_x(4)); P2 # optional - sage.rings.finite_rings (x + 33, y + 34) Observe that the `x`-coordinates are the same but the `y`-coordinates differ:: - sage: P1 - P2 # indirect doctest + sage: P1 - P2 # indirect doctest # optional - sage.rings.finite_rings (x^2 + 31*x + 8, y + 7*x + 12) - sage: P1 + P2 # indirect doctest + sage: P1 + P2 # indirect doctest # optional - sage.rings.finite_rings (x^2 + 31*x + 8, y + 4*x + 18) - sage: (P1 - P2) - (P1 + P2) + 2*P2 # indirect doctest + sage: (P1 - P2) - (P1 + P2) + 2*P2 # indirect doctest # optional - sage.rings.finite_rings (1) """ return self + (-other) diff --git a/src/sage/schemes/hyperelliptic_curves/mestre.py b/src/sage/schemes/hyperelliptic_curves/mestre.py index 31ba672800c..e1685cdd86e 100644 --- a/src/sage/schemes/hyperelliptic_curves/mestre.py +++ b/src/sage/schemes/hyperelliptic_curves/mestre.py @@ -67,26 +67,31 @@ def HyperellipticCurve_from_invariants(i, reduced=True, precision=None, sage: HyperellipticCurve_from_invariants([3840,414720,491028480,2437709561856]) Traceback (most recent call last): ... - NotImplementedError: Reduction of hyperelliptic curves not yet implemented. See trac #14755 and #14756. - sage: HyperellipticCurve_from_invariants([3840,414720,491028480,2437709561856],reduced = False) - Hyperelliptic Curve over Rational Field defined by y^2 = -46656*x^6 + 46656*x^5 - 19440*x^4 + 4320*x^3 - 540*x^2 + 4410*x - 1 + NotImplementedError: Reduction of hyperelliptic curves not yet implemented. + See trac #14755 and #14756. + sage: HyperellipticCurve_from_invariants([3840,414720,491028480,2437709561856], + ....: reduced=False) + Hyperelliptic Curve over Rational Field defined by + y^2 = -46656*x^6 + 46656*x^5 - 19440*x^4 + 4320*x^3 - 540*x^2 + 4410*x - 1 sage: HyperellipticCurve_from_invariants([21, 225/64, 22941/512, 1]) Traceback (most recent call last): ... - NotImplementedError: Reduction of hyperelliptic curves not yet implemented. See trac #14755 and #14756. + NotImplementedError: Reduction of hyperelliptic curves not yet implemented. + See trac #14755 and #14756. An example over a finite field:: - sage: H = HyperellipticCurve_from_invariants([GF(13)(1),3,7,5]); H + sage: H = HyperellipticCurve_from_invariants([GF(13)(1), 3, 7, 5]); H # optional - sage.rings.finite_rings Hyperelliptic Curve over Finite Field of size 13 defined by ... - sage: H.igusa_clebsch_invariants() + sage: H.igusa_clebsch_invariants() # optional - sage.rings.finite_rings (4, 9, 6, 11) An example over a number field:: - sage: K = QuadraticField(353, 'a') - sage: H = HyperellipticCurve_from_invariants([21, 225/64, 22941/512, 1], reduced = false) - sage: f = K['x'](H.hyperelliptic_polynomials()[0]) + sage: K = QuadraticField(353, 'a') # optional - sage.rings.number_field + sage: H = HyperellipticCurve_from_invariants([21, 225/64, 22941/512, 1], # optional - sage.rings.number_field + ....: reduced=false) + sage: f = K['x'](H.hyperelliptic_polynomials()[0]) # optional - sage.rings.number_field If the Mestre Conic defined by the Igusa-Clebsch invariants has no rational points, then there exists no hyperelliptic curve over the base field with @@ -95,14 +100,17 @@ def HyperellipticCurve_from_invariants(i, reduced=True, precision=None, sage: HyperellipticCurve_from_invariants([1,2,3,4]) Traceback (most recent call last): ... - ValueError: No such curve exists over Rational Field as there are no rational points on Projective Conic Curve over Rational Field defined by -2572155000*u^2 - 317736000*u*v + 1250755459200*v^2 + 2501510918400*u*w + 39276887040*v*w + 2736219686912*w^2 + ValueError: No such curve exists over Rational Field as there are + no rational points on Projective Conic Curve over Rational Field defined by + -2572155000*u^2 - 317736000*u*v + 1250755459200*v^2 + 2501510918400*u*w + + 39276887040*v*w + 2736219686912*w^2 Mestre's algorithm only works for generic curves of genus two, so another algorithm is needed for those curves with extra automorphism. See also :trac:`12199`:: sage: P. = QQ[] - sage: C = HyperellipticCurve(x^6+1) + sage: C = HyperellipticCurve(x^6 + 1) sage: i = C.igusa_clebsch_invariants() sage: HyperellipticCurve_from_invariants(i) Traceback (most recent call last): @@ -114,12 +122,13 @@ def HyperellipticCurve_from_invariants(i, reduced=True, precision=None, different from 2, 3, and 5, so another algorithm will be needed for fields of those characteristics. See also :trac:`12200`:: - sage: P. = GF(3)[] - sage: HyperellipticCurve(x^6+x+1).igusa_clebsch_invariants() + sage: P. = GF(3)[] # optional - sage.rings.finite_rings + sage: HyperellipticCurve(x^6 + x + 1).igusa_clebsch_invariants() # optional - sage.rings.finite_rings Traceback (most recent call last): ... - NotImplementedError: Invariants of binary sextics/genus 2 hyperelliptic curves not implemented in characteristics 2, 3, and 5 - sage: HyperellipticCurve_from_invariants([GF(5)(1),1,0,1]) + NotImplementedError: Invariants of binary sextics/genus 2 hyperelliptic curves + not implemented in characteristics 2, 3, and 5 + sage: HyperellipticCurve_from_invariants([GF(5)(1), 1, 0, 1]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: inverse of Mod(0, 5) does not exist @@ -221,7 +230,7 @@ def Mestre_conic(i, xyz=False, names='u,v,w'): invariants: I2, I4, I6, I10 - ``xyz`` - Boolean (default: False) if True, the algorithm also returns three invariants x,y,z used in Mestre's algorithm - - ``names`` (default: 'u,v,w') - the variable names for the Conic + - ``names`` (default: 'u,v,w') - the variable names for the conic OUTPUT: @@ -232,24 +241,33 @@ def Mestre_conic(i, xyz=False, names='u,v,w'): A standard example:: sage: Mestre_conic([1,2,3,4]) - Projective Conic Curve over Rational Field defined by -2572155000*u^2 - 317736000*u*v + 1250755459200*v^2 + 2501510918400*u*w + 39276887040*v*w + 2736219686912*w^2 + Projective Conic Curve over Rational Field defined by + -2572155000*u^2 - 317736000*u*v + 1250755459200*v^2 + 2501510918400*u*w + + 39276887040*v*w + 2736219686912*w^2 Note that the algorithm works over number fields as well:: - sage: k = NumberField(x^2-41,'a') - sage: a = k.an_element() - sage: Mestre_conic([1,2+a,a,4+a]) - Projective Conic Curve over Number Field in a with defining polynomial x^2 - 41 defined by (-801900000*a + 343845000)*u^2 + (855360000*a + 15795864000)*u*v + (312292800000*a + 1284808579200)*v^2 + (624585600000*a + 2569617158400)*u*w + (15799910400*a + 234573143040)*v*w + (2034199306240*a + 16429854656512)*w^2 + sage: k = NumberField(x^2 - 41, 'a') # optional - sage.rings.number_field + sage: a = k.an_element() # optional - sage.rings.number_field + sage: Mestre_conic([1, 2 + a, a, 4 + a]) # optional - sage.rings.number_field + Projective Conic Curve over Number Field in a with defining polynomial x^2 - 41 + defined by (-801900000*a + 343845000)*u^2 + (855360000*a + 15795864000)*u*v + + (312292800000*a + 1284808579200)*v^2 + (624585600000*a + 2569617158400)*u*w + + (15799910400*a + 234573143040)*v*w + (2034199306240*a + 16429854656512)*w^2 And over finite fields:: - sage: Mestre_conic([GF(7)(10),GF(7)(1),GF(7)(2),GF(7)(3)]) - Projective Conic Curve over Finite Field of size 7 defined by -2*u*v - v^2 - 2*u*w + 2*v*w - 3*w^2 + sage: Mestre_conic([GF(7)(10), GF(7)(1), GF(7)(2), GF(7)(3)]) # optional - sage.rings.finite_rings + Projective Conic Curve over Finite Field of size 7 + defined by -2*u*v - v^2 - 2*u*w + 2*v*w - 3*w^2 - An example with xyz:: + An example with ``xyz``:: sage: Mestre_conic([5,6,7,8], xyz=True) - (Projective Conic Curve over Rational Field defined by -415125000*u^2 + 608040000*u*v + 33065136000*v^2 + 66130272000*u*w + 240829440*v*w + 10208835584*w^2, 232/1125, -1072/16875, 14695616/2109375) + (Projective Conic Curve over Rational Field + defined by -415125000*u^2 + 608040000*u*v + 33065136000*v^2 + + 66130272000*u*w + 240829440*v*w + 10208835584*w^2, + 232/1125, -1072/16875, 14695616/2109375) ALGORITHM: diff --git a/src/sage/schemes/jacobians/abstract_jacobian.py b/src/sage/schemes/jacobians/abstract_jacobian.py index e2007663c81..08bee459739 100644 --- a/src/sage/schemes/jacobians/abstract_jacobian.py +++ b/src/sage/schemes/jacobians/abstract_jacobian.py @@ -132,8 +132,8 @@ def __init__(self, C): def __richcmp__(self, J, op): """ - Compare the Jacobian self to `J`. If `J` is a Jacobian, then - self and `J` are equal if and only if their curves are equal. + Compare the Jacobian ``self`` to `J`. If `J` is a Jacobian, then + ``self`` and `J` are equal if and only if their curves are equal. EXAMPLES:: @@ -194,7 +194,7 @@ def _point(self): def curve(self): """ - Return the curve of which self is the Jacobian. + Return the curve of which ``self`` is the Jacobian. EXAMPLES:: @@ -214,45 +214,42 @@ def change_ring(self, R): - ``R`` -- a field. The new base ring. - OUTPUT: - - The Jacobian over the ring `R`. + OUTPUT: The Jacobian over the ring `R`. EXAMPLES:: sage: R. = QQ['x'] - sage: H = HyperellipticCurve(x^3-10*x+9) + sage: H = HyperellipticCurve(x^3 - 10*x + 9) sage: Jac = H.jacobian(); Jac - Jacobian of Hyperelliptic Curve over Rational - Field defined by y^2 = x^3 - 10*x + 9 + Jacobian of Hyperelliptic Curve over Rational Field + defined by y^2 = x^3 - 10*x + 9 sage: Jac.change_ring(RDF) - Jacobian of Hyperelliptic Curve over Real Double - Field defined by y^2 = x^3 - 10.0*x + 9.0 + Jacobian of Hyperelliptic Curve over Real Double Field + defined by y^2 = x^3 - 10.0*x + 9.0 """ return self.curve().change_ring(R).jacobian() def base_extend(self, R): r""" - Return the natural extension of ``self`` over `R` + Return the natural extension of ``self`` over `R`. INPUT: - ``R`` -- a field. The new base field. - OUTPUT: - - The Jacobian over the ring `R`. + OUTPUT: The Jacobian over the ring `R`. EXAMPLES:: sage: R. = QQ['x'] - sage: H = HyperellipticCurve(x^3-10*x+9) + sage: H = HyperellipticCurve(x^3 - 10*x + 9) sage: Jac = H.jacobian(); Jac - Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^3 - 10*x + 9 - sage: F. = QQ.extension(x^2+1) - sage: Jac.base_extend(F) + Jacobian of Hyperelliptic Curve over Rational Field + defined by y^2 = x^3 - 10*x + 9 + sage: F. = QQ.extension(x^2 + 1) # optional - sage.rings.number_field + sage: Jac.base_extend(F) # optional - sage.rings.number_field Jacobian of Hyperelliptic Curve over Number Field in a with defining - polynomial x^2 + 1 defined by y^2 = x^3 - 10*x + 9 + polynomial x^2 + 1 defined by y^2 = x^3 - 10*x + 9 """ if R not in _Fields: raise ValueError('Not a field: ' + str(R)) diff --git a/src/sage/schemes/overview.py b/src/sage/schemes/overview.py index d57b74d8f32..bd83daafac0 100644 --- a/src/sage/schemes/overview.py +++ b/src/sage/schemes/overview.py @@ -117,7 +117,7 @@ :: sage: R. = ZZ[] - sage: S. = R.quo(x^2+5) + sage: S. = R.quo(x^2 + 5) sage: P. = ProjectiveSpace(2, S) sage: P(S) Set of rational points of Projective Space of dimension 2 over diff --git a/src/sage/schemes/plane_conics/con_field.py b/src/sage/schemes/plane_conics/con_field.py index b5454923998..fa813565f7a 100644 --- a/src/sage/schemes/plane_conics/con_field.py +++ b/src/sage/schemes/plane_conics/con_field.py @@ -51,7 +51,8 @@ class ProjectiveConic_field(ProjectivePlaneCurve_field): sage: K = FractionField(PolynomialRing(QQ, 't')) sage: P. = K[] sage: Conic(X^2 + Y^2 - Z^2) - Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by X^2 + Y^2 - Z^2 + Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t + over Rational Field defined by X^2 + Y^2 - Z^2 TESTS:: @@ -79,7 +80,7 @@ def __init__(self, A, f): def _repr_type(self): r""" - Returns ``'Projective Conic'``, which is the first part of the + Return ``'Projective Conic'``, which is the first part of the plain text representation of this object as output by the function ``_repr_`` of the class ``Curve_generic``. @@ -96,7 +97,7 @@ def _repr_type(self): def base_extend(self, S): r""" - Returns the conic over ``S`` given by the same equation as ``self``. + Return the conic over ``S`` given by the same equation as ``self``. EXAMPLES:: @@ -104,9 +105,10 @@ def base_extend(self, S): Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2 sage: c.has_rational_point() False - sage: d = c.base_extend(QuadraticField(-1, 'i')); d - Projective Conic Curve over Number Field in i with defining polynomial x^2 + 1 with i = 1*I defined by x^2 + y^2 + z^2 - sage: d.rational_point(algorithm = 'rnfisnorm') + sage: d = c.base_extend(QuadraticField(-1, 'i')); d # optional - sage.rings.number_field + Projective Conic Curve over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I defined by x^2 + y^2 + z^2 + sage: d.rational_point(algorithm='rnfisnorm') # optional - sage.rings.number_field (i : 1 : 0) """ if S in _Fields: @@ -131,7 +133,7 @@ def base_extend(self, S): def cache_point(self, p): r""" Replace the point in the cache of ``self`` by ``p`` for use - by ``self.rational_point()`` and ``self.parametrization()``. + by :meth:`rational_point` and :meth:`parametrization`. EXAMPLES:: @@ -158,11 +160,12 @@ def coefficients(self): sage: Conic(QQ, [1,2,3,4,5,6]).coefficients() [1, 2, 3, 4, 5, 6] - sage: P. = GF(13)[] - sage: a = Conic(x^2+5*x*y+y^2+z^2).coefficients(); a + sage: P. = GF(13)[] # optional - sage.rings.finite_rings + sage: a = Conic(x^2 + 5*x*y + y^2 + z^2).coefficients(); a # optional - sage.rings.finite_rings [1, 5, 0, 1, 0, 1] - sage: Conic(a) - Projective Conic Curve over Finite Field of size 13 defined by x^2 + 5*x*y + y^2 + z^2 + sage: Conic(a) # optional - sage.rings.finite_rings + Projective Conic Curve over Finite Field of size 13 + defined by x^2 + 5*x*y + y^2 + z^2 """ return self._coefficients @@ -191,12 +194,14 @@ def derivative_matrix(self): An example in characteristic `2`:: - sage: P. = GF(2)[] - sage: c = Conic([t, 1, t^2, 1, 1, 0]); c - Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 2 (using GF2X) defined by t*x^2 + x*y + y^2 + (t^2)*x*z + y*z - sage: c.is_smooth() + sage: P. = GF(2)[] # optional - sage.rings.finite_rings + sage: c = Conic([t, 1, t^2, 1, 1, 0]); c # optional - sage.rings.finite_rings + Projective Conic Curve over Fraction Field of Univariate + Polynomial Ring in t over Finite Field of size 2 (using GF2X) + defined by t*x^2 + x*y + y^2 + (t^2)*x*z + y*z + sage: c.is_smooth() # optional - sage.rings.finite_rings True - sage: c.derivative_matrix() + sage: c.derivative_matrix() # optional - sage.rings.finite_rings [ 0 1 t^2] [ 1 0 1] [t^2 1 0] @@ -208,7 +213,7 @@ def derivative_matrix(self): def determinant(self): r""" - Returns the determinant of the symmetric matrix that defines + Return the determinant of the symmetric matrix that defines the conic ``self``. This is defined only if the base field has characteristic @@ -226,19 +231,21 @@ def determinant(self): Determinants are only defined in characteristic different from `2`:: - sage: C = Conic(GF(2), [1, 1, 1, 1, 1, 0]) - sage: C.is_smooth() + sage: C = Conic(GF(2), [1, 1, 1, 1, 1, 0]) # optional - sage.rings.finite_rings + sage: C.is_smooth() # optional - sage.rings.finite_rings True - sage: C.determinant() + sage: C.determinant() # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: The conic self (= Projective Conic Curve over Finite Field of size 2 defined by x^2 + x*y + y^2 + x*z + y*z) has no symmetric matrix because the base field has characteristic 2 + ValueError: The conic self (= Projective Conic Curve over Finite Field + of size 2 defined by x^2 + x*y + y^2 + x*z + y*z) has no symmetric matrix + because the base field has characteristic 2 """ return self.symmetric_matrix().determinant() def diagonal_matrix(self): r""" - Returns a diagonal matrix `D` and a matrix `T` such that `T^t A T = D` + Return a diagonal matrix `D` and a matrix `T` such that `T^t A T = D` holds, where `(x, y, z) A (x, y, z)^t` is the defining polynomial of the conic ``self``. @@ -263,13 +270,15 @@ def diagonal_matrix(self): :: - sage: c = Conic(GF(4, 'a'), [0, 1, 1, 1, 1, 1]) - sage: c.is_smooth() + sage: c = Conic(GF(4, 'a'), [0, 1, 1, 1, 1, 1]) # optional - sage.rings.finite_rings + sage: c.is_smooth() # optional - sage.rings.finite_rings True - sage: c.diagonal_matrix() + sage: c.diagonal_matrix() # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: The conic self (= Projective Conic Curve over Finite Field in a of size 2^2 defined by x*y + y^2 + x*z + y*z + z^2) has no symmetric matrix because the base field has characteristic 2 + ValueError: The conic self (= Projective Conic Curve over Finite Field + in a of size 2^2 defined by x*y + y^2 + x*z + y*z + z^2) has + no symmetric matrix because the base field has characteristic 2 """ A = self.symmetric_matrix() B = self.base_ring() @@ -298,55 +307,66 @@ def diagonal_matrix(self): def diagonalization(self, names=None): r""" - Returns a diagonal conic `C`, an isomorphism of schemes `M: C` -> ``self`` + Return a diagonal conic `C`, an isomorphism of schemes `M: C` -> ``self`` and the inverse `N` of `M`. EXAMPLES:: - sage: Conic(GF(5), [1,0,1,1,0,1]).diagonalization() - (Projective Conic Curve over Finite Field of size 5 defined by x^2 + y^2 + 2*z^2, + sage: Conic(GF(5), [1,0,1,1,0,1]).diagonalization() # optional - sage.rings.finite_rings + (Projective Conic Curve over Finite Field of size 5 + defined by x^2 + y^2 + 2*z^2, Scheme morphism: - From: Projective Conic Curve over Finite Field of size 5 defined by x^2 + y^2 + 2*z^2 - To: Projective Conic Curve over Finite Field of size 5 defined by x^2 + y^2 + x*z + z^2 - Defn: Defined on coordinates by sending (x : y : z) to - (x + 2*z : y : z), + From: Projective Conic Curve over Finite Field of size 5 + defined by x^2 + y^2 + 2*z^2 + To: Projective Conic Curve over Finite Field of size 5 + defined by x^2 + y^2 + x*z + z^2 + Defn: Defined on coordinates by sending (x : y : z) to (x + 2*z : y : z), Scheme morphism: - From: Projective Conic Curve over Finite Field of size 5 defined by x^2 + y^2 + x*z + z^2 - To: Projective Conic Curve over Finite Field of size 5 defined by x^2 + y^2 + 2*z^2 - Defn: Defined on coordinates by sending (x : y : z) to - (x - 2*z : y : z)) + From: Projective Conic Curve over Finite Field of size 5 + defined by x^2 + y^2 + x*z + z^2 + To: Projective Conic Curve over Finite Field of size 5 + defined by x^2 + y^2 + 2*z^2 + Defn: Defined on coordinates by sending (x : y : z) to (x - 2*z : y : z)) The diagonalization is only defined in characteristic different from 2: :: - sage: Conic(GF(2), [1,1,1,1,1,0]).diagonalization() + sage: Conic(GF(2), [1,1,1,1,1,0]).diagonalization() # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: The conic self (= Projective Conic Curve over Finite Field of size 2 defined by x^2 + x*y + y^2 + x*z + y*z) has no symmetric matrix because the base field has characteristic 2 + ValueError: The conic self (= Projective Conic Curve over Finite Field + of size 2 defined by x^2 + x*y + y^2 + x*z + y*z) has no symmetric matrix + because the base field has characteristic 2 An example over a global function field: :: - sage: K = FractionField(PolynomialRing(GF(7), 't')) - sage: (t,) = K.gens() - sage: C = Conic(K, [t/2,0, 1, 2, 0, 3]) - sage: C.diagonalization() - (Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-3*t)*x^2 + 2*y^2 + (3*t + 3)/t*z^2, + sage: K = FractionField(PolynomialRing(GF(7), 't')) # optional - sage.rings.finite_rings + sage: (t,) = K.gens() # optional - sage.rings.finite_rings + sage: C = Conic(K, [t/2,0, 1, 2, 0, 3]) # optional - sage.rings.finite_rings + sage: C.diagonalization() # optional - sage.rings.finite_rings + (Projective Conic Curve over Fraction Field of Univariate + Polynomial Ring in t over Finite Field of size 7 + defined by (-3*t)*x^2 + 2*y^2 + (3*t + 3)/t*z^2, Scheme morphism: - From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-3*t)*x^2 + 2*y^2 + (3*t + 3)/t*z^2 - To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-3*t)*x^2 + 2*y^2 + x*z + 3*z^2 - Defn: Defined on coordinates by sending (x : y : z) to - (x - 1/t*z : y : z), + From: Projective Conic Curve over Fraction Field of Univariate + Polynomial Ring in t over Finite Field of size 7 + defined by (-3*t)*x^2 + 2*y^2 + (3*t + 3)/t*z^2 + To: Projective Conic Curve over Fraction Field of Univariate + Polynomial Ring in t over Finite Field of size 7 + defined by (-3*t)*x^2 + 2*y^2 + x*z + 3*z^2 + Defn: Defined on coordinates by sending (x : y : z) to (x - 1/t*z : y : z), Scheme morphism: - From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-3*t)*x^2 + 2*y^2 + x*z + 3*z^2 - To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-3*t)*x^2 + 2*y^2 + (3*t + 3)/t*z^2 - Defn: Defined on coordinates by sending (x : y : z) to - (x + 1/t*z : y : z)) - - + From: Projective Conic Curve over Fraction Field of Univariate + Polynomial Ring in t over Finite Field of size 7 + defined by (-3*t)*x^2 + 2*y^2 + x*z + 3*z^2 + To: Projective Conic Curve over Fraction Field of Univariate + Polynomial Ring in t over Finite Field of size 7 + defined by (-3*t)*x^2 + 2*y^2 + (3*t + 3)/t*z^2 + Defn: Defined on coordinates by sending (x : y : z) to (x + 1/t*z : y : z)) """ if names is None: names = self.defining_polynomial().parent().variable_names() @@ -357,14 +377,14 @@ def diagonalization(self, names=None): def gens(self): r""" - Returns the generators of the coordinate ring of ``self``. + Return the generators of the coordinate ring of ``self``. EXAMPLES: :: sage: P. = QQ[] - sage: c = Conic(x^2+y^2+z^2) + sage: c = Conic(x^2 + y^2 + z^2) sage: c.gens() (xbar, ybar, zbar) sage: c.defining_polynomial()(c.gens()) @@ -374,9 +394,10 @@ def gens(self): :: - sage: C. = Conic(GF(3), [1, 1, 1]) - sage: C - Projective Conic Curve over Finite Field of size 3 defined by a^2 + b^2 + c^2 + sage: C. = Conic(GF(3), [1, 1, 1]) # optional - sage.rings.finite_rings + sage: C # optional - sage.rings.finite_rings + Projective Conic Curve over + Finite Field of size 3 defined by a^2 + b^2 + c^2 """ return self.coordinate_ring().gens() @@ -384,7 +405,7 @@ def gens(self): def has_rational_point(self, point=False, algorithm='default', read_cache=True): r""" - Returns True if and only if the conic ``self`` + Return True if and only if the conic ``self`` has a point over its base field `B`. If ``point`` is True, then returns a second output, which is @@ -398,12 +419,12 @@ def has_rational_point(self, point=False, The parameter ``algorithm`` specifies the algorithm to be used: - - ``'default'`` -- If the base field is real or complex, - use an elementary native Sage implementation. + - ``'default'`` -- If the base field is real or complex, + use an elementary native Sage implementation. - - ``'magma'`` (requires Magma to be installed) -- - delegates the task to the Magma computer algebra - system. + - ``'magma'`` (requires Magma to be installed) -- + delegates the task to the Magma computer algebra + system. EXAMPLES:: @@ -424,13 +445,13 @@ def has_rational_point(self, point=False, And they can also be solved with Magma:: - sage: C.has_rational_point(algorithm='magma') # optional - magma + sage: C.has_rational_point(algorithm='magma') # optional - magma True - sage: C.has_rational_point(algorithm='magma', point=True) # optional - magma + sage: C.has_rational_point(algorithm='magma', point=True) # optional - magma (True, (-t : 1 : 1)) sage: D = Conic([t,1,t^2]) - sage: D.has_rational_point(algorithm='magma') # optional - magma + sage: D.has_rational_point(algorithm='magma') # optional - magma False TESTS: @@ -445,12 +466,12 @@ def has_rational_point(self, point=False, From: Number Field in i with defining polynomial x^2 + 1 with i = 1*I To: Complex Lazy Field Defn: i -> 1*I - sage: Conic(K, [1,1,1]).rational_point(algorithm='magma') # optional - magma + sage: Conic(K, [1,1,1]).rational_point(algorithm='magma') # optional - magma (-i : 1 : 0) sage: x = QQ['x'].gen() sage: L. = NumberField(x^2+1, embedding=None) - sage: Conic(L, [1,1,1]).rational_point(algorithm='magma') # optional - magma + sage: Conic(L, [1,1,1]).rational_point(algorithm='magma') # optional - magma (-i : 1 : 0) sage: L == K False @@ -558,15 +579,16 @@ def has_singular_point(self, point=False): sage: c.has_singular_point(point = True) (True, (0 : 1 : 0)) - sage: P. = GF(7)[] - sage: e = Conic((x+y+z)*(x-y+2*z)); e - Projective Conic Curve over Finite Field of size 7 defined by x^2 - y^2 + 3*x*z + y*z + 2*z^2 - sage: e.has_singular_point(point = True) + sage: P. = GF(7)[] # optional - sage.rings.finite_rings + sage: e = Conic((x+y+z)*(x-y+2*z)); e # optional - sage.rings.finite_rings + Projective Conic Curve over Finite Field of size 7 + defined by x^2 - y^2 + 3*x*z + y*z + 2*z^2 + sage: e.has_singular_point(point = True) # optional - sage.rings.finite_rings (True, (2 : 4 : 1)) sage: Conic([1, 1, -1]).has_singular_point() False - sage: Conic([1, 1, -1]).has_singular_point(point = True) + sage: Conic([1, 1, -1]).has_singular_point(point=True) (False, None) ``has_singular_point`` is not implemented over all fields @@ -574,17 +596,19 @@ def has_singular_point(self, point=False): :: - sage: F. = FiniteField(8) - sage: Conic([a, a+1, 1]).has_singular_point(point = True) + sage: F. = FiniteField(8) # optional - sage.rings.finite_rings + sage: Conic([a, a + 1, 1]).has_singular_point(point=True) # optional - sage.rings.finite_rings (True, (a + 1 : 0 : 1)) - sage: P. = GF(2)[] - sage: C = Conic(P, [t,t,1]); C - Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 2 (using GF2X) defined by t*x^2 + t*y^2 + z^2 - sage: C.has_singular_point(point = False) + sage: P. = GF(2)[] # optional - sage.rings.finite_rings + sage: C = Conic(P, [t,t,1]); C # optional - sage.rings.finite_rings + Projective Conic Curve over Fraction Field of Univariate Polynomial Ring + in t over Finite Field of size 2 (using GF2X) defined by t*x^2 + t*y^2 + z^2 + sage: C.has_singular_point(point = False) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - NotImplementedError: Sorry, find singular point on conics not implemented over all fields of characteristic 2. + NotImplementedError: Sorry, find singular point on conics not implemented + over all fields of characteristic 2. """ if not point: ret = self.has_singular_point(point=True) @@ -619,7 +643,7 @@ def hom(self, x, Y=None): EXAMPLES: - Here are a few Morphisms given by matrices. In the first + Here are a few morphisms given by matrices. In the first example, ``Y`` is omitted, in the second example, ``Y`` is specified. :: @@ -629,8 +653,7 @@ def hom(self, x, Y=None): Scheme morphism: From: Projective Conic Curve over Rational Field defined by -x^2 + y^2 + z^2 To: Projective Conic Curve over Rational Field defined by -x^2 + 2*x*y + z^2 - Defn: Defined on coordinates by sending (x : y : z) to - (x + y : y : z) + Defn: Defined on coordinates by sending (x : y : z) to (x + y : y : z) sage: h([-1, 1, 0]) (0 : 1 : 0) @@ -640,8 +663,7 @@ def hom(self, x, Y=None): Scheme morphism: From: Projective Conic Curve over Rational Field defined by -x^2 + y^2 + z^2 To: Projective Conic Curve over Rational Field defined by 4*x^2 + y^2 - z^2 - Defn: Defined on coordinates by sending (x : y : z) to - (1/2*z : y : x) + Defn: Defined on coordinates by sending (x : y : z) to (1/2*z : y : x) ``ValueError`` is raised if the wrong codomain ``Y`` is specified: @@ -652,8 +674,10 @@ def hom(self, x, Y=None): Traceback (most recent call last): ... ValueError: The matrix x (= [ 0 0 1/2] - [ 0 1 0] - [ 1 0 0]) does not define a map from self (= Projective Conic Curve over Rational Field defined by -x^2 + y^2 + z^2) to Y (= Projective Conic Curve over Rational Field defined by -x^2 + y^2 + z^2) + [ 0 1 0] + [ 1 0 0]) does not define a map + from self (= Projective Conic Curve over Rational Field defined by -x^2 + y^2 + z^2) + to Y (= Projective Conic Curve over Rational Field defined by -x^2 + y^2 + z^2) The identity map between two representations of the same conic: @@ -663,10 +687,11 @@ def hom(self, x, Y=None): sage: D = Conic([2,4,6,8,10,12]) sage: C.hom(identity_matrix(3), D) Scheme morphism: - From: Projective Conic Curve over Rational Field defined by x^2 + 2*x*y + 4*y^2 + 3*x*z + 5*y*z + 6*z^2 - To: Projective Conic Curve over Rational Field defined by 2*x^2 + 4*x*y + 8*y^2 + 6*x*z + 10*y*z + 12*z^2 - Defn: Defined on coordinates by sending (x : y : z) to - (x : y : z) + From: Projective Conic Curve over Rational Field + defined by x^2 + 2*x*y + 4*y^2 + 3*x*z + 5*y*z + 6*z^2 + To: Projective Conic Curve over Rational Field + defined by 2*x^2 + 4*x*y + 8*y^2 + 6*x*z + 10*y*z + 12*z^2 + Defn: Defined on coordinates by sending (x : y : z) to (x : y : z) An example not over the rational numbers: @@ -675,13 +700,15 @@ def hom(self, x, Y=None): sage: P. = QQ[] sage: C = Conic([1,0,0,t,0,1/t]) sage: D = Conic([1/t^2, 0, -2/t^2, t, 0, (t + 1)/t^2]) - sage: T = Matrix([[t,0,1],[0,1,0],[0,0,1]]) + sage: T = Matrix([[t,0,1], [0,1,0], [0,0,1]]) sage: C.hom(T, D) Scheme morphism: - From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by x^2 + t*y^2 + 1/t*z^2 - To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by 1/(t^2)*x^2 + t*y^2 - 2/(t^2)*x*z + (t + 1)/(t^2)*z^2 - Defn: Defined on coordinates by sending (x : y : z) to - (t*x + z : y : z) + From: Projective Conic Curve over Fraction Field of Univariate + Polynomial Ring in t over Rational Field defined by x^2 + t*y^2 + 1/t*z^2 + To: Projective Conic Curve over Fraction Field of Univariate + Polynomial Ring in t over Rational Field defined by + 1/(t^2)*x^2 + t*y^2 - 2/(t^2)*x*z + (t + 1)/(t^2)*z^2 + Defn: Defined on coordinates by sending (x : y : z) to (t*x + z : y : z) """ if is_Matrix(x): @@ -702,15 +729,15 @@ def hom(self, x, Y=None): def is_diagonal(self): r""" Return True if and only if the conic has the form - `a*x^2 + b*y^2 + c*z^2`. + `a x^2 + b y^2 + c z^2`. EXAMPLES: :: - sage: c=Conic([1,1,0,1,0,1]); c + sage: c = Conic([1,1,0,1,0,1]); c Projective Conic Curve over Rational Field defined by x^2 + x*y + y^2 + z^2 - sage: d,t = c.diagonal_matrix() + sage: d, t = c.diagonal_matrix() sage: c.is_diagonal() False sage: c.diagonalization()[0].is_diagonal() @@ -720,7 +747,7 @@ def is_diagonal(self): def is_smooth(self): r""" - Returns True if and only if ``self`` is smooth. + Return True if and only if ``self`` is smooth. EXAMPLES: @@ -728,7 +755,7 @@ def is_smooth(self): sage: Conic([1,-1,0]).is_smooth() False - sage: Conic(GF(2),[1,1,1,1,1,0]).is_smooth() + sage: Conic(GF(2),[1,1,1,1,1,0]).is_smooth() # optional - sage.rings.finite_rings True """ if self.base_ring().characteristic() == 2: @@ -746,30 +773,31 @@ def _magma_init_(self, magma): EXAMPLES:: sage: C = Conic(QQ, [1,2,3]) - sage: C._magma_init_(magma) # optional - magma + sage: C._magma_init_(magma) # optional - magma 'Conic([_sage_ref...|1/1,2/1,3/1,0/1,0/1,0/1])' - sage: C = Conic(GF(41), [-1,2,5]) # optional - magma - sage: C._magma_init_(magma) # optional - magma + sage: C = Conic(GF(41), [-1,2,5]) # optional - magma # optional - sage.rings.finite_rings + sage: C._magma_init_(magma) # optional - magma # optional - sage.rings.finite_rings 'Conic([_sage_ref...|GF(41)!40,GF(41)!2,GF(41)!5,GF(41)!0,GF(41)!0,GF(41)!0])' - sage: F. = GF(25) - sage: C = Conic([3,0,1,4,a,2]) - sage: C - Projective Conic Curve over Finite Field in a of size 5^2 defined by -2*x^2 - y^2 + x*z + a*y*z + 2*z^2 - sage: magma(C) # optional - magma + sage: F. = GF(25) # optional - sage.rings.finite_rings + sage: C = Conic([3,0,1,4,a,2]) # optional - sage.rings.finite_rings + sage: C # optional - sage.rings.finite_rings + Projective Conic Curve over Finite Field in a of size 5^2 + defined by -2*x^2 - y^2 + x*z + a*y*z + 2*z^2 + sage: magma(C) # optional - magma # optional - sage.rings.finite_rings Conic over GF(5^2) defined by 3*X^2 + 4*Y^2 + X*Z + a*Y*Z + 2*Z^2 - sage: magma(Conic([1/2,2/3,-4/5,6/7,8/9,-10/11])) # optional - magma + sage: magma(Conic([1/2,2/3,-4/5,6/7,8/9,-10/11])) # optional - magma Conic over Rational Field defined by 1/2*X^2 + 2/3*X*Y + 6/7*Y^2 - 4/5*X*Z + 8/9*Y*Z - 10/11*Z^2 sage: R. = Frac(QQ['x']) - sage: magma(Conic([x,1+x,1-x])) # optional - magma + sage: magma(Conic([x, 1 + x, 1 - x])) # optional - magma Conic over Univariate rational function field over Rational Field defined by x*X^2 + (x + 1)*Y^2 + (-x + 1)*Z^2 sage: P. = QQ[] - sage: K. = NumberField(x^3+x+1) - sage: magma(Conic([b,1,2])) # optional - magma - Conic over Number Field with defining polynomial x^3 + x + 1 over the Rational Field defined by - b*X^2 + Y^2 + 2*Z^2 + sage: K. = NumberField(x^3 + x + 1) # optional - sage.rings.number_field + sage: magma(Conic([b,1,2])) # optional - magma # optional - sage.rings.number_field + Conic over Number Field with defining polynomial x^3 + x + 1 + over the Rational Field defined by b*X^2 + Y^2 + 2*Z^2 """ kmn = magma(self.base_ring())._ref() coeffs = self.coefficients() @@ -778,7 +806,7 @@ def _magma_init_(self, magma): def matrix(self): r""" - Returns a matrix `M` such that `(x, y, z) M (x, y, z)^t` + Return a matrix `M` such that `(x, y, z) M (x, y, z)^t` is the defining equation of ``self``. The matrix `M` is upper triangular if the base field has @@ -793,9 +821,9 @@ def matrix(self): [1/2 1 0] [ 0 0 1] - sage: R. = GF(2)[] - sage: C = Conic(x^2 + x*y + y^2 + x*z + z^2) - sage: C.matrix() + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: C = Conic(x^2 + x*y + y^2 + x*z + z^2) # optional - sage.rings.finite_rings + sage: C.matrix() # optional - sage.rings.finite_rings [1 1 1] [0 1 0] [0 0 1] @@ -812,7 +840,7 @@ def parametrization(self, point=None, morphism=True): inverse of `f`. If ``point`` is specified, then that point is used - for the parametrization. Otherwise, use ``self.rational_point()`` + for the parametrization. Otherwise, use :meth:`rational_point()` to find a point. If ``morphism`` is True, then `f` is returned in the form @@ -823,57 +851,59 @@ def parametrization(self, point=None, morphism=True): An example over a finite field :: - sage: c = Conic(GF(2), [1,1,1,1,1,0]) - sage: f, g = c.parametrization(); f, g + sage: c = Conic(GF(2), [1,1,1,1,1,0]) # optional - sage.rings.finite_rings + sage: f, g = c.parametrization(); f, g # optional - sage.rings.finite_rings (Scheme morphism: From: Projective Space of dimension 1 over Finite Field of size 2 - To: Projective Conic Curve over Finite Field of size 2 defined by x^2 + x*y - + y^2 + x*z + y*z + To: Projective Conic Curve over Finite Field of size 2 + defined by x^2 + x*y + y^2 + x*z + y*z Defn: Defined on coordinates by sending (x : y) to ..., Scheme morphism: - From: Projective Conic Curve over Finite Field of size 2 defined by x^2 + x*y - + y^2 + x*z + y*z + From: Projective Conic Curve over Finite Field of size 2 + defined by x^2 + x*y + y^2 + x*z + y*z To: Projective Space of dimension 1 over Finite Field of size 2 Defn: Defined on coordinates by sending (x : y : z) to ...) - sage: set(f(p) for p in f.domain()) + sage: set(f(p) for p in f.domain()) # optional - sage.rings.finite_rings {(0 : 0 : 1), (0 : 1 : 1), (1 : 0 : 1)} Verfication of the example :: - sage: h = g*f; h - Scheme endomorphism of Projective Space of dimension 1 over Finite Field of size 2 + sage: h = g*f; h # optional - sage.rings.finite_rings + Scheme endomorphism of Projective Space of dimension 1 + over Finite Field of size 2 Defn: Defined on coordinates by sending (x : y) to ... - sage: h[0]/h[1] + sage: h[0]/h[1] # optional - sage.rings.finite_rings x/y - sage: h.is_one() # known bug (see :trac:`31892`) + sage: h.is_one() # known bug (see :trac:`31892`) # optional - sage.rings.finite_rings True - sage: (x,y,z) = c.gens() - sage: x.parent() - Quotient of Multivariate Polynomial Ring in x, y, z over Finite Field of size 2 by the ideal (x^2 + x*y + y^2 + x*z + y*z) - sage: k = f*g - sage: k[0]*z-k[2]*x + sage: (x,y,z) = c.gens() # optional - sage.rings.finite_rings + sage: x.parent() # optional - sage.rings.finite_rings + Quotient of Multivariate Polynomial Ring in x, y, z + over Finite Field of size 2 by the ideal (x^2 + x*y + y^2 + x*z + y*z) + sage: k = f*g # optional - sage.rings.finite_rings + sage: k[0]*z-k[2]*x # optional - sage.rings.finite_rings 0 - sage: k[1]*z-k[2]*y + sage: k[1]*z-k[2]*y # optional - sage.rings.finite_rings 0 The morphisms are mathematically defined in all points, but don't work completely in SageMath (see :trac:`31892`) :: - sage: f, g = c.parametrization([0,0,1]) - sage: g([0,1,1]) + sage: f, g = c.parametrization([0,0,1]) # optional - sage.rings.finite_rings + sage: g([0,1,1]) # optional - sage.rings.finite_rings (1 : 0) - sage: f([1,0]) + sage: f([1,0]) # optional - sage.rings.finite_rings (0 : 1 : 1) - sage: f([1,1]) + sage: f([1,1]) # optional - sage.rings.finite_rings (0 : 0 : 1) - sage: g([0,0,1]) + sage: g([0,0,1]) # optional - sage.rings.finite_rings (1 : 1) An example with ``morphism = False`` :: sage: R. = QQ[] sage: C = Curve(7*x^2 + 2*y*z + z^2) - sage: (p, i) = C.parametrization(morphism = False); (p, i) + sage: (p, i) = C.parametrization(morphism=False); (p, i) ([-2*x*y, x^2 + 7*y^2, -2*x^2], [-1/2*x, 1/7*y + 1/14*z]) sage: C.defining_polynomial()(p) 0 @@ -886,7 +916,8 @@ def parametrization(self, point=None, morphism=True): sage: C.parametrization() Traceback (most recent call last): ... - ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + y^2 + 7*z^2 has no rational points over Rational Field! + ValueError: Conic Projective Conic Curve over Rational Field defined by + x^2 + y^2 + 7*z^2 has no rational points over Rational Field! A ``ValueError`` is raised if ``self`` is not smooth :: @@ -894,7 +925,8 @@ def parametrization(self, point=None, morphism=True): sage: C.parametrization() Traceback (most recent call last): ... - ValueError: The conic self (=Projective Conic Curve over Rational Field defined by x^2 + y^2) is not smooth, hence does not have a parametrization. + ValueError: The conic self (=Projective Conic Curve over Rational Field + defined by x^2 + y^2) is not smooth, hence does not have a parametrization. """ if (self._parametrization is not None) and not point: par = self._parametrization @@ -937,7 +969,7 @@ def point(self, v, check=True): point on ``self``. If no rational point on ``self`` is known yet, then also caches the point - for use by ``self.rational_point()`` and ``self.parametrization()``. + for use by :meth:`rational_point` and :meth:`parametrization`. EXAMPLES:: @@ -963,13 +995,11 @@ def random_rational_point(self, *args1, **args2): ALGORITHM: - 1. Compute a parametrization `f` of ``self`` using - ``self.parametrization()``. - 2. Computes a random point `(x:y)` on the projective - line. - 3. Output `f(x:y)`. + 1. Compute a parametrization `f` of ``self`` using :meth:`parametrization`. + 2. Computes a random point `(x:y)` on the projective line. + 3. Output `f(x:y)`. - The coordinates x and y are computed using + The coordinates `x` and `y` are computed using ``B.random_element``, where ``B`` is the base field of ``self`` and additional arguments to ``random_rational_point`` are passed to ``random_element``. @@ -979,18 +1009,20 @@ def random_rational_point(self, *args1, **args2): EXAMPLES:: - sage: c = Conic(GF(2), [1,1,1,1,1,0]) - sage: [c.random_rational_point() for i in range(10)] # output is random - [(1 : 0 : 1), (1 : 0 : 1), (1 : 0 : 1), (0 : 1 : 1), (1 : 0 : 1), (0 : 0 : 1), (1 : 0 : 1), (1 : 0 : 1), (0 : 0 : 1), (1 : 0 : 1)] + sage: c = Conic(GF(2), [1,1,1,1,1,0]) # optional - sage.rings.finite_rings + sage: [c.random_rational_point() for i in range(10)] # random # optional - sage.rings.finite_rings + [(1 : 0 : 1), (1 : 0 : 1), (1 : 0 : 1), (0 : 1 : 1), (1 : 0 : 1), + (0 : 0 : 1), (1 : 0 : 1), (1 : 0 : 1), (0 : 0 : 1), (1 : 0 : 1)] sage: d = Conic(QQ, [1, 1, -1]) - sage: d.random_rational_point(den_bound = 1, num_bound = 5) # output is random + sage: d.random_rational_point(den_bound=1, num_bound=5) # random (-24/25 : 7/25 : 1) sage: Conic(QQ, [1, 1, 1]).random_rational_point() Traceback (most recent call last): ... - ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2 has no rational points over Rational Field! + ValueError: Conic Projective Conic Curve over Rational Field defined by + x^2 + y^2 + z^2 has no rational points over Rational Field! """ if not self.is_smooth(): @@ -1027,97 +1059,115 @@ def rational_point(self, algorithm='default', read_cache=True): sage: C.rational_point() Traceback (most recent call last): ... - ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + z^2 has no rational points over Rational Field! + ValueError: Conic Projective Conic Curve over Rational Field defined by + x^2 + 2*y^2 + z^2 has no rational points over Rational Field! sage: C = Conic(x^2 + y^2 + 7*z^2) sage: C.rational_point(algorithm = 'rnfisnorm') Traceback (most recent call last): ... - ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + y^2 + 7*z^2 has no rational points over Rational Field! + ValueError: Conic Projective Conic Curve over Rational Field defined by + x^2 + y^2 + 7*z^2 has no rational points over Rational Field! Examples over number fields :: sage: P. = QQ[] - sage: L. = NumberField(x^3-5) - sage: C = Conic(L, [3, 2, -b]) - sage: p = C.rational_point(algorithm = 'rnfisnorm') - sage: p # output is random + sage: L. = NumberField(x^3 - 5) # optional - sage.rings.number_field + sage: C = Conic(L, [3, 2, -b]) # optional - sage.rings.number_field + sage: p = C.rational_point(algorithm = 'rnfisnorm') # optional - sage.rings.number_field + sage: p # output is random # optional - sage.rings.number_field (1/3*b^2 - 4/3*b + 4/3 : b^2 - 2 : 1) - sage: C.defining_polynomial()(list(p)) + sage: C.defining_polynomial()(list(p)) # optional - sage.rings.number_field 0 - sage: K. = QuadraticField(-1) - sage: D = Conic(K, [3, 2, 5]) - sage: D.rational_point(algorithm = 'rnfisnorm') # output is random + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: D = Conic(K, [3, 2, 5]) # optional - sage.rings.number_field + sage: D.rational_point(algorithm = 'rnfisnorm') # output is random # optional - sage.rings.number_field (-3 : 4*i : 1) - sage: L. = QuadraticField(2) - sage: Conic(QQ, [1, 1, -3]).has_rational_point() + sage: L. = QuadraticField(2) # optional - sage.rings.number_field + sage: Conic(QQ, [1, 1, -3]).has_rational_point() # optional - sage.rings.number_field False - sage: E = Conic(L, [1, 1, -3]) - sage: E.rational_point() # output is random + sage: E = Conic(L, [1, 1, -3]) # optional - sage.rings.number_field + sage: E.rational_point() # output is random # optional - sage.rings.number_field (-1 : -s : 1) Currently Magma is better at solving conics over number fields than Sage, so it helps to use the algorithm 'magma' if Magma is installed:: - sage: q = C.rational_point(algorithm = 'magma', read_cache=False) # optional - magma - sage: q # output is random, optional - magma + sage: q = C.rational_point(algorithm='magma', # optional - magma # optional - sage.rings.number_field + ....: read_cache=False) + sage: q # output is random, # optional - magma # optional - sage.rings.number_field (1/5*b^2 : 1/5*b^2 : 1) - sage: C.defining_polynomial()(list(q)) # optional - magma + sage: C.defining_polynomial()(list(q)) # optional - magma # optional - sage.rings.number_field 0 - sage: len(str(p)) > 1.5*len(str(q)) # optional - magma + sage: len(str(p)) > 1.5*len(str(q)) # optional - magma # optional - sage.rings.number_field True - sage: D.rational_point(algorithm = 'magma', read_cache=False) # random, optional - magma + sage: D.rational_point(algorithm='magma', # random, optional - magma # optional - sage.rings.number_field (1 : 2*i : 1) - sage: E.rational_point(algorithm='magma', read_cache=False) # random, optional - magma + sage: E.rational_point(algorithm='magma', # random, optional - magma # optional - sage.rings.number_field + ....: read_cache=False) (-s : 1 : 1) - sage: F = Conic([L.gen(), 30, -20]) - sage: q = F.rational_point(algorithm='magma') # optional - magma - sage: q # output is random, optional - magma + sage: F = Conic([L.gen(), 30, -20]) # optional - sage.rings.number_field + sage: q = F.rational_point(algorithm='magma') # optional - magma # optional - sage.rings.number_field + sage: q # random, optional - magma # optional - sage.rings.number_field (-10/7*s + 40/7 : 5/7*s - 6/7 : 1) - sage: p = F.rational_point(read_cache=False) - sage: p # output is random + sage: p = F.rational_point(read_cache=False) # optional - sage.rings.number_field + sage: p # random # optional - sage.rings.number_field (788210*s - 1114700 : -171135*s + 242022 : 1) - sage: len(str(p)) > len(str(q)) # optional - magma + sage: len(str(p)) > len(str(q)) # optional - magma # optional - sage.rings.number_field True - sage: G = Conic([L.gen(), 30, -21]) - sage: G.has_rational_point(algorithm='magma') # optional - magma + sage: G = Conic([L.gen(), 30, -21]) # optional - sage.rings.number_field + sage: G.has_rational_point(algorithm='magma') # optional - magma # optional - sage.rings.number_field False - sage: G.has_rational_point(read_cache=False) + sage: G.has_rational_point(read_cache=False) # optional - sage.rings.number_field False - sage: G.has_rational_point(algorithm='local', read_cache=False) + sage: G.has_rational_point(algorithm='local', read_cache=False) # optional - sage.rings.number_field False - sage: G.rational_point(algorithm='magma') # optional - magma + sage: G.rational_point(algorithm='magma') # optional - magma # optional - sage.rings.number_field Traceback (most recent call last): ... - ValueError: Conic Projective Conic Curve over Number Field in s with defining polynomial x^2 - 2 with s = 1.414213562373095? defined by s*x^2 + 30*y^2 - 21*z^2 has no rational points over Number Field in s with defining polynomial x^2 - 2 with s = 1.414213562373095?! - sage: G.rational_point(algorithm='magma', read_cache=False) # optional - magma + ValueError: Conic Projective Conic Curve over Number Field in s + with defining polynomial x^2 - 2 with s = 1.414213562373095? + defined by s*x^2 + 30*y^2 - 21*z^2 has no rational points over + Number Field in s with defining polynomial x^2 - 2 with s = 1.414213562373095?! + sage: G.rational_point(algorithm='magma', # optional - magma # optional - sage.rings.number_field + ....: read_cache=False) Traceback (most recent call last): ... - ValueError: Conic Projective Conic Curve over Number Field in s with defining polynomial x^2 - 2 with s = 1.414213562373095? defined by s*x^2 + 30*y^2 - 21*z^2 has no rational points over Number Field in s with defining polynomial x^2 - 2 with s = 1.414213562373095?! + ValueError: Conic Projective Conic Curve over Number Field in s + with defining polynomial x^2 - 2 with s = 1.414213562373095? + defined by s*x^2 + 30*y^2 - 21*z^2 has no rational points over + Number Field in s with defining polynomial x^2 - 2 with s = 1.414213562373095?! Examples over finite fields :: - sage: F. = FiniteField(7^20) - sage: C = Conic([1, a, -5]); C - Projective Conic Curve over Finite Field in a of size 7^20 defined by x^2 + a*y^2 + 2*z^2 - sage: C.rational_point() # output is random - (4*a^19 + 5*a^18 + 4*a^17 + a^16 + 6*a^15 + 3*a^13 + 6*a^11 + a^9 + 3*a^8 + 2*a^7 + 4*a^6 + 3*a^5 + 3*a^4 + a^3 + a + 6 : 5*a^18 + a^17 + a^16 + 6*a^15 + 4*a^14 + a^13 + 5*a^12 + 5*a^10 + 2*a^9 + 6*a^8 + 6*a^7 + 6*a^6 + 2*a^4 + 3 : 1) + sage: F. = FiniteField(7^20) # optional - sage.rings.finite_rings + sage: C = Conic([1, a, -5]); C # optional - sage.rings.finite_rings + Projective Conic Curve over Finite Field in a of size 7^20 + defined by x^2 + a*y^2 + 2*z^2 + sage: C.rational_point() # output is random # optional - sage.rings.finite_rings + (4*a^19 + 5*a^18 + 4*a^17 + a^16 + 6*a^15 + 3*a^13 + 6*a^11 + a^9 + + 3*a^8 + 2*a^7 + 4*a^6 + 3*a^5 + 3*a^4 + a^3 + a + 6 + : 5*a^18 + a^17 + a^16 + 6*a^15 + 4*a^14 + a^13 + 5*a^12 + 5*a^10 + + 2*a^9 + 6*a^8 + 6*a^7 + 6*a^6 + 2*a^4 + 3 + : 1) Examples over `\RR` and `\CC` :: - sage: Conic(CC, [1, 2, 3]).rational_point() + sage: Conic(CC, [1, 2, 3]).rational_point() # optional - sage.rings.finite_rings (0 : 1.22474487139159*I : 1) - sage: Conic(RR, [1, 1, 1]).rational_point() + sage: Conic(RR, [1, 1, 1]).rational_point() # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: Conic Projective Conic Curve over Real Field with 53 bits of precision defined by x^2 + y^2 + z^2 has no rational points over Real Field with 53 bits of precision! + ValueError: Conic Projective Conic Curve over Real Field + with 53 bits of precision defined by x^2 + y^2 + z^2 has + no rational points over Real Field with 53 bits of precision! """ bl, pt = self.has_rational_point(point=True, algorithm=algorithm, read_cache=read_cache) @@ -1128,13 +1178,13 @@ def rational_point(self, algorithm='default', read_cache=True): def singular_point(self): r""" - Returns a singular rational point of ``self`` + Return a singular rational point of ``self``. EXAMPLES: :: - sage: Conic(GF(2), [1,1,1,1,1,1]).singular_point() + sage: Conic(GF(2), [1,1,1,1,1,1]).singular_point() # optional - sage.rings.finite_rings (1 : 1 : 1) ``ValueError`` is raised if the conic has no rational singular point @@ -1144,7 +1194,8 @@ def singular_point(self): sage: Conic(QQ, [1,1,1,1,1,1]).singular_point() Traceback (most recent call last): ... - ValueError: The conic self (= Projective Conic Curve over Rational Field defined by x^2 + x*y + y^2 + x*z + y*z + z^2) has no rational singular point + ValueError: The conic self (= Projective Conic Curve over Rational Field + defined by x^2 + x*y + y^2 + x*z + y*z + z^2) has no rational singular point """ b = self.has_singular_point(point=True) if not b[0]: @@ -1209,14 +1260,13 @@ def upper_triangular_matrix(self): def variable_names(self): r""" - Returns the variable names of the defining polynomial - of ``self``. + Return the variable names of the defining polynomial of ``self``. EXAMPLES: :: - sage: c=Conic([1,1,0,1,0,1], 'x,y,z') + sage: c = Conic([1,1,0,1,0,1], 'x,y,z') sage: c.variable_names() ('x', 'y', 'z') sage: c.variable_name() diff --git a/src/sage/schemes/plane_conics/con_finite_field.py b/src/sage/schemes/plane_conics/con_finite_field.py index 7eb316746f3..5a6ef94bd7e 100644 --- a/src/sage/schemes/plane_conics/con_finite_field.py +++ b/src/sage/schemes/plane_conics/con_finite_field.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" Projective plane conics over finite fields @@ -37,7 +38,8 @@ class ProjectiveConic_finite_field(ProjectiveConic_field, ProjectivePlaneCurve_f sage: K. = FiniteField(9, 'a') sage: P. = K[] sage: Conic(X^2 + Y^2 - a*Z^2) - Projective Conic Curve over Finite Field in a of size 3^2 defined by X^2 + Y^2 + (-a)*Z^2 + Projective Conic Curve over Finite Field in a of size 3^2 + defined by X^2 + Y^2 + (-a)*Z^2 :: @@ -94,36 +96,50 @@ def has_rational_point(self, point=False, read_cache=True, True sage: C = Conic(FiniteField(2), [1, 1, 1, 1, 1, 0]); C - Projective Conic Curve over Finite Field of size 2 defined by x^2 + x*y + y^2 + x*z + y*z + Projective Conic Curve over Finite Field of size 2 + defined by x^2 + x*y + y^2 + x*z + y*z sage: C.has_rational_point(point = True) # output is random (True, (0 : 0 : 1)) sage: p = next_prime(10^50) sage: F = FiniteField(p) sage: C = Conic(F, [1, 2, 3]); C - Projective Conic Curve over Finite Field of size 100000000000000000000000000000000000000000000000151 defined by x^2 + 2*y^2 + 3*z^2 + Projective Conic Curve over Finite Field + of size 100000000000000000000000000000000000000000000000151 + defined by x^2 + 2*y^2 + 3*z^2 sage: C.has_rational_point(point = True) # output is random (True, - (14971942941468509742682168602989039212496867586852 : 75235465708017792892762202088174741054630437326388 : 1) + (14971942941468509742682168602989039212496867586852 + : 75235465708017792892762202088174741054630437326388 : 1) sage: F. = FiniteField(7^20) sage: C = Conic([1, a, -5]); C - Projective Conic Curve over Finite Field in a of size 7^20 defined by x^2 + a*y^2 + 2*z^2 + Projective Conic Curve over Finite Field in a of size 7^20 + defined by x^2 + a*y^2 + 2*z^2 sage: C.has_rational_point(point = True) # output is random (True, - (a^18 + 2*a^17 + 4*a^16 + 6*a^13 + a^12 + 6*a^11 + 3*a^10 + 4*a^9 + 2*a^8 + 4*a^7 + a^6 + 4*a^4 + 6*a^2 + 3*a + 6 : 5*a^19 + 5*a^18 + 5*a^17 + a^16 + 2*a^15 + 3*a^14 + 4*a^13 + 5*a^12 + a^11 + 3*a^10 + 2*a^8 + 3*a^7 + 4*a^6 + 4*a^5 + 6*a^3 + 5*a^2 + 2*a + 4 : 1)) + (a^18 + 2*a^17 + 4*a^16 + 6*a^13 + a^12 + 6*a^11 + 3*a^10 + 4*a^9 + 2*a^8 + + 4*a^7 + a^6 + 4*a^4 + 6*a^2 + 3*a + 6 + : 5*a^19 + 5*a^18 + 5*a^17 + a^16 + 2*a^15 + 3*a^14 + 4*a^13 + 5*a^12 + + a^11 + 3*a^10 + 2*a^8 + 3*a^7 + 4*a^6 + 4*a^5 + 6*a^3 + 5*a^2 + 2*a + 4 + : 1)) TESTS:: sage: l = Sequence(cartesian_product_iterator([[0, 1] for i in range(6)])) sage: bigF = GF(next_prime(2^100)) sage: bigF2 = GF(next_prime(2^50)^2, 'b') - sage: m = [[F(b) for b in a] for a in l for F in [GF(2), GF(4, 'a'), GF(5), GF(9, 'a'), bigF, bigF2]] - sage: m += [[F.random_element() for i in range(6)] for j in range(20) for F in [GF(5), bigF]] + sage: m = [[F(b) for b in a] + ....: for a in l + ....: for F in [GF(2), GF(4, 'a'), GF(5), GF(9, 'a'), bigF, bigF2]] + sage: m += [[F.random_element() for i in range(6)] + ....: for j in range(20) for F in [GF(5), bigF]] sage: c = [Conic(a) for a in m if a != [0,0,0,0,0,0]] sage: assert all(C.has_rational_point() for C in c) sage: r = randrange(0, 5) - sage: assert all(C.defining_polynomial()(Sequence(C.has_rational_point(point = True)[1])) == 0 for C in c[r::5]) # long time (1.4s on sage.math, 2013) + sage: assert all(C.defining_polynomial()( # long time (1.4s on sage.math, 2013) + ....: Sequence(C.has_rational_point(point=True)[1])) == 0 + ....: for C in c[r::5]) """ if not point: return True diff --git a/src/sage/schemes/plane_conics/con_number_field.py b/src/sage/schemes/plane_conics/con_number_field.py index 4d2c55f36d9..2844329e195 100644 --- a/src/sage/schemes/plane_conics/con_number_field.py +++ b/src/sage/schemes/plane_conics/con_number_field.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.number_field r""" Projective plane conics over a number field @@ -36,7 +37,8 @@ class ProjectiveConic_number_field(ProjectiveConic_field): sage: K. = NumberField(x^3 - 2, 'a') sage: P. = K[] sage: Conic(X^2 + Y^2 - a*Z^2) - Projective Conic Curve over Number Field in a with defining polynomial x^3 - 2 defined by X^2 + Y^2 + (-a)*Z^2 + Projective Conic Curve over Number Field in a with defining polynomial x^3 - 2 + defined by X^2 + Y^2 + (-a)*Z^2 TESTS:: @@ -64,7 +66,7 @@ def __init__(self, A, f): def has_rational_point(self, point=False, obstruction=False, algorithm='default', read_cache=True): r""" - Returns ``True`` if and only if ``self`` has a point + Return ``True`` if and only if ``self`` has a point defined over its base field `B`. If ``point`` and ``obstruction`` are both False (default), @@ -74,12 +76,12 @@ def has_rational_point(self, point=False, obstruction=False, If ``point`` or ``obstruction`` is True, then the output is a pair ``(out, S)``, where ``out`` is as above and: - - if ``point`` is True and ``self`` has a rational point, - then ``S`` is a rational point, + - if ``point`` is True and ``self`` has a rational point, + then ``S`` is a rational point, - - if ``obstruction`` is True, ``self`` has no rational point, - then ``S`` is a prime or infinite place of `B` such that no - rational point exists over the completion at ``S``. + - if ``obstruction`` is True, ``self`` has no rational point, + then ``S`` is a prime or infinite place of `B` such that no + rational point exists over the completion at ``S``. Points and obstructions are cached whenever they are found. Cached information is used for the output if available, but only @@ -90,20 +92,20 @@ def has_rational_point(self, point=False, obstruction=False, The parameter ``algorithm`` specifies the algorithm to be used: - - ``'rnfisnorm'`` -- Use PARI's rnfisnorm - (cannot be combined with ``obstruction = True``) + - ``'rnfisnorm'`` -- Use PARI's ``rnfisnorm`` + (cannot be combined with ``obstruction = True``) - - ``'local'`` -- Check if a local solution exists for all primes - and infinite places of `B` and apply the Hasse principle. - (Cannot be combined with ``point = True``.) + - ``'local'`` -- Check if a local solution exists for all primes + and infinite places of `B` and apply the Hasse principle. + (Cannot be combined with ``point = True``.) - - ``'default'`` -- Use algorithm ``'rnfisnorm'`` first. - Then, if no point exists and obstructions are requested, use - algorithm ``'local'`` to find an obstruction. + - ``'default'`` -- Use algorithm ``'rnfisnorm'`` first. + Then, if no point exists and obstructions are requested, use + algorithm ``'local'`` to find an obstruction. - - ``'magma'`` (requires Magma to be installed) -- - delegates the task to the Magma computer algebra - system. + - ``'magma'`` (requires Magma to be installed) -- + delegates the task to the Magma computer algebra + system. EXAMPLES: @@ -111,28 +113,30 @@ def has_rational_point(self, point=False, obstruction=False, An example over `\QQ` :: sage: C = Conic(QQ, [1, 113922743, -310146482690273725409]) - sage: C.has_rational_point(point = True) + sage: C.has_rational_point(point=True) (True, (-76842858034579/5424 : -5316144401/5424 : 1)) - sage: C.has_rational_point(algorithm = 'local', read_cache = False) + sage: C.has_rational_point(algorithm='local', read_cache=False) True Examples over number fields:: sage: K. = QuadraticField(-1) sage: C = Conic(K, [1, 3, -5]) - sage: C.has_rational_point(point = True, obstruction = True) + sage: C.has_rational_point(point=True, obstruction=True) (False, Fractional ideal (-i - 2)) - sage: C.has_rational_point(algorithm = "rnfisnorm") + sage: C.has_rational_point(algorithm="rnfisnorm") False - sage: C.has_rational_point(algorithm = "rnfisnorm", obstruction = True, read_cache=False) + sage: C.has_rational_point(algorithm="rnfisnorm", obstruction=True, + ....: read_cache=False) Traceback (most recent call last): ... - ValueError: Algorithm rnfisnorm cannot be combined with obstruction = True in has_rational_point + ValueError: Algorithm rnfisnorm cannot be combined with + obstruction = True in has_rational_point sage: P. = QQ[] - sage: L. = NumberField(x^3-5) + sage: L. = NumberField(x^3 - 5) sage: C = Conic(L, [1, 2, -3]) - sage: C.has_rational_point(point = True, algorithm = 'rnfisnorm') + sage: C.has_rational_point(point=True, algorithm='rnfisnorm') (True, (5/3 : -1/3 : 1)) sage: K. = NumberField(x^4+2) @@ -140,7 +144,8 @@ def has_rational_point(self, point=False, obstruction=False, False sage: Conic(K, [4,5,6]).has_rational_point() True - sage: Conic(K, [4,5,6]).has_rational_point(algorithm='magma', read_cache=False) # optional - magma + sage: Conic(K, [4,5,6]).has_rational_point(algorithm='magma', # optional - magma + ....: read_cache=False) True sage: P. = QuadraticField(2) @@ -152,13 +157,15 @@ def has_rational_point(self, point=False, obstruction=False, sage: C.has_rational_point(obstruction=True) (False, Ring morphism: - From: Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? + From: Number Field in a with defining polynomial x^2 - 2 + with a = 1.414213562373095? To: Algebraic Real Field Defn: a |--> -1.414213562373095?) sage: C.has_rational_point(point=True, obstruction=True) (False, Ring morphism: - From: Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? + From: Number Field in a with defining polynomial x^2 - 2 + with a = 1.414213562373095? To: Algebraic Real Field Defn: a |--> -1.414213562373095?) @@ -182,12 +189,12 @@ def has_rational_point(self, point=False, obstruction=False, sage: d = [] sage: c = [] sage: c = [Conic(a) for a in m if a != [0,0,0]] - sage: d = [C.has_rational_point(algorithm = 'rnfisnorm', point = True) for C in c] # long time: 3.3 seconds + sage: d = [C.has_rational_point(algorithm='rnfisnorm', point=True) for C in c] # long time: 3.3 seconds sage: all(c[k].defining_polynomial()(Sequence(d[k][1])) == 0 for k in range(len(d)) if d[k][0]) True sage: [C.has_rational_point(algorithm='local', read_cache=False) for C in c] == [o[0] for o in d] # long time: 5 seconds True - sage: [C.has_rational_point(algorithm = 'magma', read_cache=False) for C in c] == [o[0] for o in d] # long time: 3 seconds, optional - magma + sage: [C.has_rational_point(algorithm='magma', read_cache=False) for C in c] == [o[0] for o in d] # long time: 3 seconds, optional - magma True Create a bunch of conics that are known to have rational points @@ -200,8 +207,8 @@ def has_rational_point(self, point=False, obstruction=False, sage: M. = NumberField(x^5+3*x+1) sage: m = [[F(b) for b in a] for a in l for F in [K, L, M]] sage: c = [Conic(a) for a in m if a != [0,0,0] and a != [1,1,1] and a != [-1,-1,-1]] - sage: assert all(C.has_rational_point(algorithm = 'rnfisnorm') for C in c) - sage: assert all(C.defining_polynomial()(Sequence(C.has_rational_point(point = True)[1])) == 0 for C in c) + sage: assert all(C.has_rational_point(algorithm='rnfisnorm') for C in c) + sage: assert all(C.defining_polynomial()(Sequence(C.has_rational_point(point=True)[1])) == 0 for C in c) sage: assert all(C.has_rational_point(algorithm='local', read_cache=False) for C in c) # long time: 1 second """ if read_cache: @@ -332,7 +339,7 @@ def has_rational_point(self, point=False, obstruction=False, def is_locally_solvable(self, p): r""" - Returns ``True`` if and only if ``self`` has a solution over the + Return ``True`` if and only if ``self`` has a solution over the completion of the base field `B` of ``self`` at ``p``. Here ``p`` is a finite prime or infinite place of `B`. @@ -381,7 +388,7 @@ def is_locally_solvable(self, p): def local_obstructions(self, finite=True, infinite=True, read_cache=True): r""" - Returns the sequence of finite primes and/or infinite places + Return the sequence of finite primes and/or infinite places such that ``self`` is locally solvable at those primes and places. If the base field is `\QQ`, then the infinite place is denoted `-1`. @@ -403,10 +410,13 @@ def local_obstructions(self, finite=True, infinite=True, read_cache=True): sage: L. = QuadraticField(5) sage: Conic(L, [1, 2, 3]).local_obstructions() [Ring morphism: - From: Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? + From: Number Field in a with defining polynomial x^2 - 5 + with a = 2.236067977499790? To: Algebraic Real Field - Defn: a |--> -2.236067977499790?, Ring morphism: - From: Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? + Defn: a |--> -2.236067977499790?, + Ring morphism: + From: Number Field in a with defining polynomial x^2 - 5 + with a = 2.236067977499790? To: Algebraic Real Field Defn: a |--> 2.236067977499790?] """ diff --git a/src/sage/schemes/plane_conics/con_rational_field.py b/src/sage/schemes/plane_conics/con_rational_field.py index 8e14d1e2ba7..46de65132b5 100644 --- a/src/sage/schemes/plane_conics/con_rational_field.py +++ b/src/sage/schemes/plane_conics/con_rational_field.py @@ -84,12 +84,12 @@ def has_rational_point(self, point=False, obstruction=False, a pair ``(out, S)``, where ``out`` is as above and the following holds: - - if ``point`` is ``True`` and ``self`` has a rational point, - then ``S`` is a rational point, + - if ``point`` is ``True`` and ``self`` has a rational point, + then ``S`` is a rational point, - - if ``obstruction`` is ``True`` and ``self`` has no rational point, - then ``S`` is a prime such that no rational point exists - over the completion at ``S`` or `-1` if no point exists over `\RR`. + - if ``obstruction`` is ``True`` and ``self`` has no rational point, + then ``S`` is a prime such that no rational point exists + over the completion at ``S`` or `-1` if no point exists over `\RR`. Points and obstructions are cached, whenever they are found. Cached information is used if and only if ``read_cache`` is ``True``. @@ -99,43 +99,44 @@ def has_rational_point(self, point=False, obstruction=False, The parameter ``algorithm`` specifies the algorithm to be used: - - ``'qfsolve'`` -- Use PARI/GP function :pari:`qfsolve` + - ``'qfsolve'`` -- Use PARI/GP function :pari:`qfsolve` - - ``'rnfisnorm'`` -- Use PARI's function :pari:`rnfisnorm` - (cannot be combined with ``obstruction = True``) + - ``'rnfisnorm'`` -- Use PARI's function :pari:`rnfisnorm` + (cannot be combined with ``obstruction = True``) - - ``'local'`` -- Check if a local solution exists for all primes - and infinite places of `\QQ` and apply the Hasse principle - (cannot be combined with ``point = True``) + - ``'local'`` -- Check if a local solution exists for all primes + and infinite places of `\QQ` and apply the Hasse principle + (cannot be combined with ``point = True``) - - ``'default'`` -- Use ``'qfsolve'`` + - ``'default'`` -- Use ``'qfsolve'`` - - ``'magma'`` (requires Magma to be installed) -- - delegates the task to the Magma computer algebra system. + - ``'magma'`` (requires Magma to be installed) -- + delegates the task to the Magma computer algebra system. EXAMPLES:: sage: C = Conic(QQ, [1, 2, -3]) - sage: C.has_rational_point(point = True) + sage: C.has_rational_point(point=True) (True, (1 : 1 : 1)) sage: D = Conic(QQ, [1, 3, -5]) - sage: D.has_rational_point(point = True) + sage: D.has_rational_point(point=True) (False, 3) sage: P. = QQ[] sage: E = Curve(X^2 + Y^2 + Z^2); E Projective Conic Curve over Rational Field defined by X^2 + Y^2 + Z^2 - sage: E.has_rational_point(obstruction = True) + sage: E.has_rational_point(obstruction=True) (False, -1) The following would not terminate quickly with ``algorithm = 'rnfisnorm'`` :: sage: C = Conic(QQ, [1, 113922743, -310146482690273725409]) - sage: C.has_rational_point(point = True) + sage: C.has_rational_point(point=True) (True, (-76842858034579/5424 : -5316144401/5424 : 1)) - sage: C.has_rational_point(algorithm = 'local', read_cache = False) + sage: C.has_rational_point(algorithm='local', read_cache=False) True - sage: C.has_rational_point(point=True, algorithm='magma', read_cache=False) # optional - magma + sage: C.has_rational_point(point=True, algorithm='magma', # optional - magma + ....: read_cache=False) (True, (30106379962113/7913 : 12747947692/7913 : 1)) TESTS: @@ -146,7 +147,11 @@ def has_rational_point(self, point=False, obstruction=False, sage: l = Sequence(cartesian_product_iterator([[-1, 0, 1] for i in range(6)])) sage: c = [Conic(QQ, a) for a in l if a != [0,0,0] and a != (0,0,0,0,0,0)] sage: d = [] - sage: d = [[C]+[C.has_rational_point(algorithm = algorithm, read_cache = False, obstruction = (algorithm != 'rnfisnorm'), point = (algorithm != 'local')) for algorithm in ['local', 'qfsolve', 'rnfisnorm']] for C in c[::10]] # long time: 7 seconds + sage: d = [[C] + [C.has_rational_point(algorithm=algorithm, read_cache=False, # long time: 7 seconds + ....: obstruction=(algorithm != 'rnfisnorm'), + ....: point=(algorithm != 'local')) + ....: for algorithm in ['local', 'qfsolve', 'rnfisnorm']] + ....: for C in c[::10]] sage: assert all(e[1][0] == e[2][0] and e[1][0] == e[3][0] for e in d) sage: assert all(e[0].defining_polynomial()(Sequence(e[i][1])) == 0 for e in d for i in [2,3] if e[1][0]) """ @@ -342,7 +347,7 @@ def parametrization(self, point=None, morphism=True): sage: R. = QQ[] sage: C = Curve(7*x^2 + 2*y*z + z^2) - sage: (p, i) = C.parametrization(morphism = False); (p, i) + sage: (p, i) = C.parametrization(morphism=False); (p, i) ([-2*x*y, x^2 + 7*y^2, -2*x^2], [-1/2*x, 1/7*y + 1/14*z]) sage: C.defining_polynomial()(p) 0 @@ -355,7 +360,8 @@ def parametrization(self, point=None, morphism=True): sage: C.parametrization() Traceback (most recent call last): ... - ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + z^2 has no rational points over Rational Field! + ValueError: Conic Projective Conic Curve over Rational Field defined + by x^2 + 2*y^2 + z^2 has no rational points over Rational Field! A ``ValueError`` is raised if ``self`` is not smooth :: @@ -363,7 +369,8 @@ def parametrization(self, point=None, morphism=True): sage: C.parametrization() Traceback (most recent call last): ... - ValueError: The conic self (=Projective Conic Curve over Rational Field defined by x^2 + y^2) is not smooth, hence does not have a parametrization. + ValueError: The conic self (=Projective Conic Curve over Rational Field defined + by x^2 + y^2) is not smooth, hence does not have a parametrization. """ if (self._parametrization is not None) and not point: par = self._parametrization diff --git a/src/sage/schemes/plane_conics/con_rational_function_field.py b/src/sage/schemes/plane_conics/con_rational_function_field.py index d90909145e3..8e5bf4669c2 100644 --- a/src/sage/schemes/plane_conics/con_rational_function_field.py +++ b/src/sage/schemes/plane_conics/con_rational_function_field.py @@ -24,8 +24,8 @@ Points can be found using :meth:`has_rational_point`:: sage: K. = FractionField(QQ['t']) - sage: C = Conic([1,-t,t]) - sage: C.has_rational_point(point = True) + sage: C = Conic([1, -t, t]) + sage: C.has_rational_point(point=True) (True, (0 : 1 : 1)) """ @@ -127,19 +127,19 @@ def has_rational_point(self, point=False, algorithm='default', and finite fields:: sage: K. = FractionField(PolynomialRing(QQ, 't')) - sage: C = Conic(K, [t^2-2, 2*t^3, -2*t^3-13*t^2-2*t+18]) + sage: C = Conic(K, [t^2 - 2, 2*t^3, -2*t^3 - 13*t^2 - 2*t + 18]) sage: C.has_rational_point(point=True) (True, (-3 : (t + 1)/t : 1)) - sage: R. = FiniteField(23)[] - sage: C = Conic([2, t^2+1, t^2+5]) - sage: C.has_rational_point() + sage: R. = FiniteField(23)[] # optional - sage.rings.finite_rings + sage: C = Conic([2, t^2 + 1, t^2 + 5]) # optional - sage.rings.finite_rings + sage: C.has_rational_point() # optional - sage.rings.finite_rings True - sage: C.has_rational_point(point=True) + sage: C.has_rational_point(point=True) # optional - sage.rings.finite_rings (True, (5*t : 8 : 1)) - sage: F. = QuadraticField(-1) - sage: R. = F[] - sage: C = Conic([1,i*t,-t^2+4]) - sage: C.has_rational_point(point=True) + sage: F. = QuadraticField(-1) # optional - sage.rings.number_field + sage: R. = F[] # optional - sage.rings.number_field + sage: C = Conic([1, i*t, -t^2 + 4]) # optional - sage.rings.number_field + sage: C.has_rational_point(point=True) # optional - sage.rings.number_field (True, (-t - 2*i : -2*i : 1)) It works on non-diagonal conics as well:: @@ -165,8 +165,8 @@ def has_rational_point(self, point=False, algorithm='default', sage: F. = FractionField(QQ['t1']) sage: K. = FractionField(F['t2']) sage: a = K(1) - sage: b = 2*t2^2+2*t1*t2-t1^2 - sage: c = -3*t2^4-4*t1*t2^3+8*t1^2*t2^2+16*t1^3-t2-48*t1^4 + sage: b = 2*t2^2 + 2*t1*t2 - t1^2 + sage: c = -3*t2^4 - 4*t1*t2^3 + 8*t1^2*t2^2 + 16*t1^3 - t2 - 48*t1^4 sage: C = Conic([a,b,c]) sage: C.has_rational_point() Traceback (most recent call last): @@ -183,11 +183,11 @@ def has_rational_point(self, point=False, algorithm='default', sage: P. = QQ[] sage: E = P.fraction_field() sage: Q. = E[] - sage: F. = E.extension(Y^2 - u^3 - 1) - sage: R. = F[] - sage: K = R.fraction_field() - sage: C = Conic(K, [u, v, 1]) - sage: C.has_rational_point() + sage: F. = E.extension(Y^2 - u^3 - 1) # optional - sage.rings.function_field + sage: R. = F[] # optional - sage.rings.function_field + sage: K = R.fraction_field() # optional - sage.rings.function_field + sage: C = Conic(K, [u, v, 1]) # optional - sage.rings.function_field + sage: C.has_rational_point() # optional - sage.rings.function_field Traceback (most recent call last): ... NotImplementedError: has_rational_point not implemented for conics @@ -198,20 +198,32 @@ def has_rational_point(self, point=False, algorithm='default', ``has_rational_point`` fails for some conics over function fields over finite fields, due to :trac:`20003`:: - sage: K. = PolynomialRing(GF(7)) - sage: C = Conic([5*t^2+4, t^2+3*t+3, 6*t^2+3*t+2, 5*t^2+5, 4*t+3, 4*t^2+t+5]) - sage: C.has_rational_point() + sage: K. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: C = Conic([5*t^2 + 4, t^2 + 3*t + 3, 6*t^2 + 3*t + 2, # optional - sage.rings.finite_rings + ....: 5*t^2 + 5, 4*t + 3, 4*t^2 + t + 5]) + sage: C.has_rational_point() # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: self (=Scheme morphism: - From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-2*t^2 - 3)*x^2 + (-t^3 + 3*t^2 - 2*t - 2)/(t + 3)*y^2 + (-t^6 + 3*t^5 + t^3 - t^2 - t + 2)/(t^4 + t^3 - 3*t^2 + 3*t + 1)*z^2 - To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-2*t^2 - 3)*x^2 + (t^2 + 3*t + 3)*x*y + (-2*t^2 - 2)*y^2 + (-t^2 + 3*t + 2)*x*z + (-3*t + 3)*y*z + (-3*t^2 + t - 2)*z^2 + From: Projective Conic Curve over Fraction Field of Univariate + Polynomial Ring in t over Finite Field of size 7 defined by + (-2*t^2 - 3)*x^2 + (-t^3 + 3*t^2 - 2*t - 2)/(t + 3)*y^2 + (-t^6 + 3*t^5 + t^3 - t^2 - t + 2)/(t^4 + t^3 - 3*t^2 + 3*t + 1)*z^2 + To: Projective Conic Curve over Fraction Field of Univariate + Polynomial Ring in t over Finite Field of size 7 defined by + (-2*t^2 - 3)*x^2 + (t^2 + 3*t + 3)*x*y + (-2*t^2 - 2)*y^2 + (-t^2 + 3*t + 2)*x*z + (-3*t + 3)*y*z + (-3*t^2 + t - 2)*z^2 Defn: Defined on coordinates by sending (x : y : z) to - (x + (2*t - 2)/(t + 3)*y + (3*t^4 + 2*t^3 - 2*t^2 - 2*t + 3)/(t^4 + t^3 - 3*t^2 + 3*t + 1)*z : y + (-t^3 - t^2 + 3*t - 1)/(t^3 - 3*t^2 + 2*t + 2)*z : z)) domain must equal right (=Scheme morphism: - From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-2*t^3 - t^2 + 3*t + 3)*x^2 + (t - 3)*y^2 + (-t^7 + 2*t^5 + t^4 + 2*t^3 + 3*t^2 - t - 1)*z^2 - To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by -2/(t^3 - 3*t^2 + 2*t + 2)*x^2 + 1/(t^3 + 3*t^2 - 2*t + 1)*y^2 + (-t^6 + 3*t^5 + t^3 - t^2 - t + 2)/(t^9 - 2*t^8 + t^7 - t^6 + 3*t^5 - 3*t^3 + t^2 - 2*t + 3)*z^2 + (x + (2*t - 2)/(t + 3)*y + (3*t^4 + 2*t^3 - 2*t^2 - 2*t + 3)/(t^4 + t^3 - 3*t^2 + 3*t + 1)*z + : y + (-t^3 - t^2 + 3*t - 1)/(t^3 - 3*t^2 + 2*t + 2)*z : z)) + domain must equal right (=Scheme morphism: + From: Projective Conic Curve over Fraction Field of Univariate + Polynomial Ring in t over Finite Field of size 7 defined by + (-2*t^3 - t^2 + 3*t + 3)*x^2 + (t - 3)*y^2 + (-t^7 + 2*t^5 + t^4 + 2*t^3 + 3*t^2 - t - 1)*z^2 + To: Projective Conic Curve over Fraction Field of Univariate + Polynomial Ring in t over Finite Field of size 7 defined by + -2/(t^3 - 3*t^2 + 2*t + 2)*x^2 + 1/(t^3 + 3*t^2 - 2*t + 1)*y^2 + (-t^6 + 3*t^5 + t^3 - t^2 - t + 2)/(t^9 - 2*t^8 + t^7 - t^6 + 3*t^5 - 3*t^3 + t^2 - 2*t + 3)*z^2 Defn: Defined on coordinates by sending (x : y : z) to - ((t^3 - 3*t^2 + 2*t + 2)*x : (t^2 - 2)*y : (t^5 - 3*t^4 + t^2 + 3*t + 3)*z)) codomain + ((t^3 - 3*t^2 + 2*t + 2)*x : (t^2 - 2)*y : (t^5 - 3*t^4 + t^2 + 3*t + 3)*z)) + codomain @@ -362,7 +374,7 @@ def _reduce_conic(self): EXAMPLES:: sage: K. = FractionField(PolynomialRing(QQ, 't')) - sage: C = Conic(K, [t^2-2, 2*t^3, -2*t^3-13*t^2-2*t+18]) + sage: C = Conic(K, [t^2 - 2, 2*t^3, -2*t^3 - 13*t^2 - 2*t + 18]) sage: C._reduce_conic() ([t^2 - 2, 2*t, -2*t^3 - 13*t^2 - 2*t + 18], [t, 1, t]) """ @@ -459,14 +471,14 @@ def find_point(self, supports, roots, case, solution=0): EXAMPLES:: sage: K. = FractionField(QQ['t']) - sage: C = Conic(K, [t^2-2, 2*t^3, -2*t^3-13*t^2-2*t+18]) + sage: C = Conic(K, [t^2 - 2, 2*t^3, -2*t^3 - 13*t^2 - 2*t + 18]) sage: C.has_rational_point(point=True) # indirect test (True, (-3 : (t + 1)/t : 1)) Different solubility certificates give different points:: sage: K. = PolynomialRing(QQ, 't') - sage: C = Conic(K, [t^2-2, 2*t, -2*t^3-13*t^2-2*t+18]) + sage: C = Conic(K, [t^2 - 2, 2*t, -2*t^3 - 13*t^2 - 2*t + 18]) sage: supp = [[t^2 - 2], [t], [t^3 + 13/2*t^2 + t - 9]] sage: tbar1 = QQ.extension(supp[0][0], 'tbar').gens()[0] sage: tbar2 = QQ.extension(supp[1][0], 'tbar').gens()[0] diff --git a/src/sage/schemes/plane_conics/constructor.py b/src/sage/schemes/plane_conics/constructor.py index f36c078b459..c84e0ef5b2b 100644 --- a/src/sage/schemes/plane_conics/constructor.py +++ b/src/sage/schemes/plane_conics/constructor.py @@ -106,39 +106,42 @@ def Conic(base_field, F=None, names=None, unique=True): sage: X,Y,Z = QQ['X,Y,Z'].gens() sage: Conic(X^2 - X*Y + Y^2 - Z^2) Projective Conic Curve over Rational Field defined by X^2 - X*Y + Y^2 - Z^2 - sage: x,y = GF(7)['x,y'].gens() - sage: Conic(x^2 - x + 2*y^2 - 3, 'U,V,W') - Projective Conic Curve over Finite Field of size 7 defined by U^2 + 2*V^2 - U*W - 3*W^2 + sage: x,y = GF(7)['x,y'].gens() # optional - sage.rings.finite_rings + sage: Conic(x^2 - x + 2*y^2 - 3, 'U,V,W') # optional - sage.rings.finite_rings + Projective Conic Curve over Finite Field of size 7 + defined by U^2 + 2*V^2 - U*W - 3*W^2 Conic curves given by matrices :: sage: Conic(matrix(QQ, [[1, 2, 0], [4, 0, 0], [7, 0, 9]]), 'x,y,z') Projective Conic Curve over Rational Field defined by x^2 + 6*x*y + 7*x*z + 9*z^2 - sage: x,y,z = GF(11)['x,y,z'].gens() - sage: C = Conic(x^2+y^2-2*z^2); C + sage: x,y,z = GF(11)['x,y,z'].gens() # optional - sage.rings.finite_rings + sage: C = Conic(x^2 + y^2 - 2*z^2); C # optional - sage.rings.finite_rings Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2 - sage: Conic(C.symmetric_matrix(), 'x,y,z') + sage: Conic(C.symmetric_matrix(), 'x,y,z') # optional - sage.rings.finite_rings Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2 Conics given by coefficients :: sage: Conic(QQ, [1,2,3]) Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + 3*z^2 - sage: Conic(GF(7), [1,2,3,4,5,6], 'X') - Projective Conic Curve over Finite Field of size 7 defined by X0^2 + 2*X0*X1 - 3*X1^2 + 3*X0*X2 - 2*X1*X2 - X2^2 + sage: Conic(GF(7), [1,2,3,4,5,6], 'X') # optional - sage.rings.finite_rings + Projective Conic Curve over Finite Field of size 7 + defined by X0^2 + 2*X0*X1 - 3*X1^2 + 3*X0*X2 - 2*X1*X2 - X2^2 The conic through a set of points :: sage: C = Conic(QQ, [[10,2],[3,4],[-7,6],[7,8],[9,10]]); C - Projective Conic Curve over Rational Field defined by x^2 + 13/4*x*y - 17/4*y^2 - 35/2*x*z + 91/4*y*z - 37/2*z^2 + Projective Conic Curve over Rational Field + defined by x^2 + 13/4*x*y - 17/4*y^2 - 35/2*x*z + 91/4*y*z - 37/2*z^2 sage: C.rational_point() (10 : 2 : 1) sage: C.point([3,4]) (3 : 4 : 1) - sage: a = AffineSpace(GF(13),2) - sage: Conic([a([x,x^2]) for x in range(5)]) + sage: a = AffineSpace(GF(13), 2) # optional - sage.rings.finite_rings + sage: Conic([a([x,x^2]) for x in range(5)]) # optional - sage.rings.finite_rings Projective Conic Curve over Finite Field of size 13 defined by x^2 - y*z """ if not (base_field is None or isinstance(base_field, IntegralDomain)): diff --git a/src/sage/schemes/plane_quartics/quartic_constructor.py b/src/sage/schemes/plane_quartics/quartic_constructor.py index 274eaf049b6..37c06a1f5c9 100644 --- a/src/sage/schemes/plane_quartics/quartic_constructor.py +++ b/src/sage/schemes/plane_quartics/quartic_constructor.py @@ -15,36 +15,36 @@ def QuarticCurve(F, PP=None, check=False): """ - Returns the quartic curve defined by the polynomial F. + Return the quartic curve defined by the polynomial ``F``. INPUT: - - F -- a polynomial in three variables, homogeneous of degree 4 + - ``F`` -- a polynomial in three variables, homogeneous of degree 4 - - PP -- a projective plane (default:None) + - ``PP`` -- a projective plane (default: None) - - check -- whether to check for smoothness or not (default:False) + - ``check`` -- whether to check for smoothness or not (default: False) EXAMPLES:: - sage: x,y,z=PolynomialRing(QQ,['x','y','z']).gens() - sage: QuarticCurve(x**4+y**4+z**4) + sage: x,y,z = PolynomialRing(QQ, ['x','y','z']).gens() + sage: QuarticCurve(x**4 + y**4 + z**4) Quartic Curve over Rational Field defined by x^4 + y^4 + z^4 TESTS:: - sage: QuarticCurve(x**3+y**3) + sage: QuarticCurve(x**3 + y**3) Traceback (most recent call last): ... ValueError: Argument F (=x^3 + y^3) must be a homogeneous polynomial of degree 4 - sage: QuarticCurve(x**4+y**4+z**3) + sage: QuarticCurve(x**4 + y**4 + z**3) Traceback (most recent call last): ... ValueError: Argument F (=x^4 + y^4 + z^3) must be a homogeneous polynomial of degree 4 sage: x,y=PolynomialRing(QQ,['x','y']).gens() - sage: QuarticCurve(x**4+y**4) + sage: QuarticCurve(x**4 + y**4) Traceback (most recent call last): ... ValueError: Argument F (=x^4 + y^4) must be a polynomial in 3 variables diff --git a/src/sage/schemes/plane_quartics/quartic_generic.py b/src/sage/schemes/plane_quartics/quartic_generic.py index e5e546ad724..ac2cdd84d82 100644 --- a/src/sage/schemes/plane_quartics/quartic_generic.py +++ b/src/sage/schemes/plane_quartics/quartic_generic.py @@ -8,7 +8,8 @@ sage: PP. = ProjectiveSpace(2, QQ) sage: f = X^4 + Y^4 + Z^4 - 3*X*Y*Z*(X+Y+Z) sage: C = QuarticCurve(f); C - Quartic Curve over Rational Field defined by X^4 + Y^4 - 3*X^2*Y*Z - 3*X*Y^2*Z - 3*X*Y*Z^2 + Z^4 + Quartic Curve over Rational Field + defined by X^4 + Y^4 - 3*X^2*Y*Z - 3*X*Y^2*Z - 3*X*Y*Z^2 + Z^4 """ #***************************************************************************** @@ -22,13 +23,13 @@ def is_QuarticCurve(C): """ - Checks whether C is a Quartic Curve + Check whether ``C`` is a Quartic Curve. EXAMPLES:: sage: from sage.schemes.plane_quartics.quartic_generic import is_QuarticCurve - sage: x,y,z=PolynomialRing(QQ,['x','y','z']).gens() - sage: Q = QuarticCurve(x**4+y**4+z**4) + sage: x,y,z = PolynomialRing(QQ, ['x','y','z']).gens() + sage: Q = QuarticCurve(x**4 + y**4 + z**4) sage: is_QuarticCurve(Q) True @@ -40,12 +41,12 @@ class QuarticCurve_generic(projective_curve.ProjectivePlaneCurve): def _repr_type(self): """ - Return the representation of self + Return the representation of ``self``. EXAMPLES:: - sage: x,y,z=PolynomialRing(QQ,['x','y','z']).gens() - sage: Q = QuarticCurve(x**4+y**4+z**4) + sage: x,y,z = PolynomialRing(QQ, ['x','y','z']).gens() + sage: Q = QuarticCurve(x**4 + y**4 + z**4) sage: Q._repr_type() 'Quartic' """ @@ -53,12 +54,12 @@ def _repr_type(self): def genus(self): """ - Returns the genus of self + Return the genus of ``self``. EXAMPLES:: - sage: x,y,z=PolynomialRing(QQ,['x','y','z']).gens() - sage: Q = QuarticCurve(x**4+y**4+z**4) + sage: x,y,z = PolynomialRing(QQ, ['x','y','z']).gens() + sage: Q = QuarticCurve(x**4 + y**4 + z**4) sage: Q.genus() 3 """ diff --git a/src/sage/schemes/product_projective/homset.py b/src/sage/schemes/product_projective/homset.py index b56eccb968e..91af8105def 100644 --- a/src/sage/schemes/product_projective/homset.py +++ b/src/sage/schemes/product_projective/homset.py @@ -31,15 +31,13 @@ class SchemeHomset_points_product_projective_spaces_ring(SchemeHomset_points): r""" Set of rational points of a product of projective spaces. - INPUT: - - See :class:`~sage.schemes.generic.homset.SchemeHomset_generic`. + INPUT: See :class:`~sage.schemes.generic.homset.SchemeHomset_generic`. EXAMPLES:: sage: from sage.schemes.product_projective.homset import SchemeHomset_points_product_projective_spaces_ring - sage: SchemeHomset_points_product_projective_spaces_ring(Spec(QQ), \ - ProductProjectiveSpaces([1, 1], QQ, 'z')) + sage: SchemeHomset_points_product_projective_spaces_ring( + ....: Spec(QQ), ProductProjectiveSpaces([1, 1], QQ, 'z')) Set of rational points of Product of projective spaces P^1 x P^1 over Rational Field """ @@ -93,16 +91,14 @@ def points(self, **kwds): - ``bound`` - a real number - - ``tolerance`` - a rational number in (0,1] used in doyle-krumm algorithm-4 + - ``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. - - ``algorithm`` - either 'sieve' or 'enumerate' algorithms can be used over `QQ`. If - not specified, enumerate is used only for small height bounds. - - OUTPUT: + - ``algorithm`` - either ``'sieve'`` or ``'enumerate'`` algorithms can be used over `\QQ`. If + not specified, ``'enumerate'`` is used only for small height bounds. - - a list of rational points of a projective scheme + OUTPUT: A list of rational points of the projective scheme. EXAMPLES:: @@ -114,49 +110,50 @@ def points(self, **kwds): :: sage: u = QQ['u'].0 - sage: P. = ProductProjectiveSpaces([1,1], NumberField(u^2 - 2, 'v')) - sage: X = P.subscheme([x^2 - y^2, z^2 - 2*w^2]) - sage: sorted(X(P.base_ring()).points()) + sage: K = NumberField(u^2 - 2, 'v') # optional - sage.rings.number_field + sage: P. = ProductProjectiveSpaces([1, 1], K) # optional - sage.rings.number_field + sage: X = P.subscheme([x^2 - y^2, z^2 - 2*w^2]) # optional - sage.rings.number_field + sage: sorted(X(P.base_ring()).points()) # optional - sage.rings.number_field [(-1 : 1 , -v : 1), (-1 : 1 , v : 1), (1 : 1 , -v : 1), (1 : 1 , v : 1)] :: sage: u = QQ['u'].0 - sage: K = NumberField(u^2 + 1, 'v') - sage: P. = ProductProjectiveSpaces([1, 1], K) - sage: P(K).points(bound=1) + sage: K = NumberField(u^2 + 1, 'v') # optional - sage.rings.number_field + sage: P. = ProductProjectiveSpaces([1, 1], K) # optional - sage.rings.number_field + sage: P(K).points(bound=1) # optional - sage.rings.number_field [(-1 : 1 , -1 : 1), (-1 : 1 , -v : 1), (-1 : 1 , 0 : 1), (-1 : 1 , v : 1), - (-1 : 1 , 1 : 0), (-1 : 1 , 1 : 1), (-v : 1 , -1 : 1), (-v : 1 , -v : 1), - (-v : 1 , 0 : 1), (-v : 1 , v : 1), (-v : 1 , 1 : 0), (-v : 1 , 1 : 1), - (0 : 1 , -1 : 1), (0 : 1 , -v : 1), (0 : 1 , 0 : 1), (0 : 1 , v : 1), - (0 : 1 , 1 : 0), (0 : 1 , 1 : 1), (v : 1 , -1 : 1), (v : 1 , -v : 1), - (v : 1 , 0 : 1), (v : 1 , v : 1), (v : 1 , 1 : 0), (v : 1 , 1 : 1), - (1 : 0 , -1 : 1), (1 : 0 , -v : 1), (1 : 0 , 0 : 1), (1 : 0 , v : 1), - (1 : 0 , 1 : 0), (1 : 0 , 1 : 1), (1 : 1 , -1 : 1), (1 : 1 , -v : 1), - (1 : 1 , 0 : 1), (1 : 1 , v : 1), (1 : 1 , 1 : 0), (1 : 1 , 1 : 1)] + (-1 : 1 , 1 : 0), (-1 : 1 , 1 : 1), (-v : 1 , -1 : 1), (-v : 1 , -v : 1), + (-v : 1 , 0 : 1), (-v : 1 , v : 1), (-v : 1 , 1 : 0), (-v : 1 , 1 : 1), + (0 : 1 , -1 : 1), (0 : 1 , -v : 1), (0 : 1 , 0 : 1), (0 : 1 , v : 1), + (0 : 1 , 1 : 0), (0 : 1 , 1 : 1), (v : 1 , -1 : 1), (v : 1 , -v : 1), + (v : 1 , 0 : 1), (v : 1 , v : 1), (v : 1 , 1 : 0), (v : 1 , 1 : 1), + (1 : 0 , -1 : 1), (1 : 0 , -v : 1), (1 : 0 , 0 : 1), (1 : 0 , v : 1), + (1 : 0 , 1 : 0), (1 : 0 , 1 : 1), (1 : 1 , -1 : 1), (1 : 1 , -v : 1), + (1 : 1 , 0 : 1), (1 : 1 , v : 1), (1 : 1 , 1 : 0), (1 : 1 , 1 : 1)] :: - sage: P. = ProductProjectiveSpaces([2, 1], GF(3)) - sage: P(P.base_ring()).points() + sage: P. = ProductProjectiveSpaces([2, 1], GF(3)) # optional - sage.rings.finite_rings + sage: P(P.base_ring()).points() # optional - sage.rings.finite_rings [(0 : 0 : 1 , 0 : 1), (0 : 0 : 1 , 1 : 0), (0 : 0 : 1 , 1 : 1), (0 : 0 : 1 , 2 : 1), - (0 : 1 : 0 , 0 : 1), (0 : 1 : 0 , 1 : 0), (0 : 1 : 0 , 1 : 1), (0 : 1 : 0 , 2 : 1), - (0 : 1 : 1 , 0 : 1), (0 : 1 : 1 , 1 : 0), (0 : 1 : 1 , 1 : 1), (0 : 1 : 1 , 2 : 1), - (0 : 2 : 1 , 0 : 1), (0 : 2 : 1 , 1 : 0), (0 : 2 : 1 , 1 : 1), (0 : 2 : 1 , 2 : 1), - (1 : 0 : 0 , 0 : 1), (1 : 0 : 0 , 1 : 0), (1 : 0 : 0 , 1 : 1), (1 : 0 : 0 , 2 : 1), - (1 : 0 : 1 , 0 : 1), (1 : 0 : 1 , 1 : 0), (1 : 0 : 1 , 1 : 1), (1 : 0 : 1 , 2 : 1), - (1 : 1 : 0 , 0 : 1), (1 : 1 : 0 , 1 : 0), (1 : 1 : 0 , 1 : 1), (1 : 1 : 0 , 2 : 1), - (1 : 1 : 1 , 0 : 1), (1 : 1 : 1 , 1 : 0), (1 : 1 : 1 , 1 : 1), (1 : 1 : 1 , 2 : 1), - (1 : 2 : 1 , 0 : 1), (1 : 2 : 1 , 1 : 0), (1 : 2 : 1 , 1 : 1), (1 : 2 : 1 , 2 : 1), - (2 : 0 : 1 , 0 : 1), (2 : 0 : 1 , 1 : 0), (2 : 0 : 1 , 1 : 1), (2 : 0 : 1 , 2 : 1), - (2 : 1 : 0 , 0 : 1), (2 : 1 : 0 , 1 : 0), (2 : 1 : 0 , 1 : 1), (2 : 1 : 0 , 2 : 1), - (2 : 1 : 1 , 0 : 1), (2 : 1 : 1 , 1 : 0), (2 : 1 : 1 , 1 : 1), (2 : 1 : 1 , 2 : 1), - (2 : 2 : 1 , 0 : 1), (2 : 2 : 1 , 1 : 0), (2 : 2 : 1 , 1 : 1), (2 : 2 : 1 , 2 : 1)] + (0 : 1 : 0 , 0 : 1), (0 : 1 : 0 , 1 : 0), (0 : 1 : 0 , 1 : 1), (0 : 1 : 0 , 2 : 1), + (0 : 1 : 1 , 0 : 1), (0 : 1 : 1 , 1 : 0), (0 : 1 : 1 , 1 : 1), (0 : 1 : 1 , 2 : 1), + (0 : 2 : 1 , 0 : 1), (0 : 2 : 1 , 1 : 0), (0 : 2 : 1 , 1 : 1), (0 : 2 : 1 , 2 : 1), + (1 : 0 : 0 , 0 : 1), (1 : 0 : 0 , 1 : 0), (1 : 0 : 0 , 1 : 1), (1 : 0 : 0 , 2 : 1), + (1 : 0 : 1 , 0 : 1), (1 : 0 : 1 , 1 : 0), (1 : 0 : 1 , 1 : 1), (1 : 0 : 1 , 2 : 1), + (1 : 1 : 0 , 0 : 1), (1 : 1 : 0 , 1 : 0), (1 : 1 : 0 , 1 : 1), (1 : 1 : 0 , 2 : 1), + (1 : 1 : 1 , 0 : 1), (1 : 1 : 1 , 1 : 0), (1 : 1 : 1 , 1 : 1), (1 : 1 : 1 , 2 : 1), + (1 : 2 : 1 , 0 : 1), (1 : 2 : 1 , 1 : 0), (1 : 2 : 1 , 1 : 1), (1 : 2 : 1 , 2 : 1), + (2 : 0 : 1 , 0 : 1), (2 : 0 : 1 , 1 : 0), (2 : 0 : 1 , 1 : 1), (2 : 0 : 1 , 2 : 1), + (2 : 1 : 0 , 0 : 1), (2 : 1 : 0 , 1 : 0), (2 : 1 : 0 , 1 : 1), (2 : 1 : 0 , 2 : 1), + (2 : 1 : 1 , 0 : 1), (2 : 1 : 1 , 1 : 0), (2 : 1 : 1 , 1 : 1), (2 : 1 : 1 , 2 : 1), + (2 : 2 : 1 , 0 : 1), (2 : 2 : 1 , 1 : 0), (2 : 2 : 1 , 1 : 1), (2 : 2 : 1 , 2 : 1)] :: - sage: PP. = ProductProjectiveSpaces([2,1], QQ) - sage: X = PP.subscheme([x + y, u*u-v*u]) + sage: PP. = ProductProjectiveSpaces([2, 1], QQ) + sage: X = PP.subscheme([x + y, u*u - v*u]) sage: X.rational_points(bound=2) [(-2 : 2 : 1 , 0 : 1), (-2 : 2 : 1 , 1 : 1), @@ -177,8 +174,8 @@ def points(self, **kwds): better to enumerate with low codimension:: - sage: PP. = ProductProjectiveSpaces([2,1,2], QQ) - sage: X = PP.subscheme([x*u^2*a, b*z*u*v,z*v^2*c ]) + sage: PP. = ProductProjectiveSpaces([2, 1, 2], QQ) + sage: X = PP.subscheme([x*u^2*a, b*z*u*v, z*v^2*c]) sage: len(X.rational_points(bound=1, algorithm='enumerate')) 232 """ diff --git a/src/sage/schemes/product_projective/morphism.py b/src/sage/schemes/product_projective/morphism.py index b558d88b304..f203611cce6 100644 --- a/src/sage/schemes/product_projective/morphism.py +++ b/src/sage/schemes/product_projective/morphism.py @@ -9,8 +9,7 @@ sage: H = End(P1xP1) sage: H([x^2*u, y^2*v, x*v^2, y*u^2]) Scheme endomorphism of Product of projective spaces P^1 x P^1 over Rational Field - Defn: Defined by sending (x : y , u : v) to - (x^2*u : y^2*v , x*v^2 : y*u^2). + Defn: Defined by sending (x : y , u : v) to (x^2*u : y^2*v , x*v^2 : y*u^2). """ # **************************************************************************** # Copyright (C) 2014 Ben Hutz @@ -41,8 +40,7 @@ class ProductProjectiveSpaces_morphism_ring(SchemeMorphism_polynomial): sage: H = T.Hom(T) sage: H([x^2, y^2, z^2, w^2, u^2]) Scheme endomorphism of Product of projective spaces P^2 x P^1 over Rational Field - Defn: Defined by sending (x : y : z , w : u) to - (x^2 : y^2 : z^2 , w^2 : u^2). + Defn: Defined by sending (x : y : z , w : u) to (x^2 : y^2 : z^2 , w^2 : u^2). """ def __init__(self, parent, polys, check=True): @@ -83,7 +81,7 @@ def __init__(self, parent, polys, check=True): sage: Z. = ProductProjectiveSpaces([1, 2], QQ) sage: P. = ProductProjectiveSpaces([3, 1], QQ) sage: H = Hom(Z,P) - sage: f = H([a^2,b^2,a^2,a*b,a*x,b*z]); f + sage: f = H([a^2, b^2, a^2, a*b, a*x, b*z]); f Scheme morphism: From: Product of projective spaces P^1 x P^2 over Rational Field To: Product of projective spaces P^3 x P^1 over Rational Field @@ -95,7 +93,7 @@ def __init__(self, parent, polys, check=True): sage: Z. = ProductProjectiveSpaces([1, 3], QQ) sage: P. = ProductProjectiveSpaces([2, 2], QQ) sage: H = Hom(Z,P) - sage: f = H([a^2,b^2,c^2,x^2,y^2,z^2]) + sage: f = H([a^2, b^2, c^2, x^2, y^2, z^2]) Traceback (most recent call last): ... TypeError: polys (=[a^2, b^2, c^2, x^2, y^2, z^2]) must be @@ -199,11 +197,11 @@ def __call__(self, P, check=True): :: - sage: PP. = ProductProjectiveSpaces([2,1], ZZ) + sage: PP. = ProductProjectiveSpaces([2, 1], ZZ) sage: Q = PP([1,1,1,2,1]) - sage: Z. = ProductProjectiveSpaces([1,2], ZZ) + sage: Z. = ProductProjectiveSpaces([1, 2], ZZ) sage: H = End(Z) - sage: f = H([a^3, b^3+a*b^2, x^2, y^2-z^2, z*y]) + sage: f = H([a^3, b^3 + a*b^2, x^2, y^2 - z^2, z*y]) sage: f(Q) Traceback (most recent call last): ... @@ -218,7 +216,7 @@ def __call__(self, P, check=True): sage: PP. = ProductProjectiveSpaces(ZZ, [1, 1]) sage: HP = End(PP) sage: g = HP([x^2, y^2, u^2, v^2]) - sage: g([0, 0, 0, 0],check=False) + sage: g([0, 0, 0, 0], check=False) (0 : 0 , 0 : 0) """ from sage.schemes.product_projective.point import ProductProjectiveSpaces_point_ring @@ -315,7 +313,7 @@ def __ne__(self, right): EXAMPLES:: - sage: PP. = ProductProjectiveSpaces([1,2], ZZ) + sage: PP. = ProductProjectiveSpaces([1, 2], ZZ) sage: E = End(PP) sage: f = E([a^3, a*b^2, x*y, y*z, z*x]) sage: g = E([a*b, a^2, x^2, y^2, z^2]) @@ -348,7 +346,7 @@ def __ne__(self, right): def is_morphism(self): r""" - Returns ``True`` if this mapping is a morphism of products of projective spaces. + Return ``True`` if this mapping is a morphism of products of projective spaces. For each component space of the codomain of this mapping we consider the subscheme of the domain of this map generated by the corresponding coordinates of the map. @@ -360,13 +358,13 @@ def is_morphism(self): sage: Z. = ProductProjectiveSpaces([1, 2], ZZ) sage: H = End(Z) - sage: f = H([a^2, b^2, x*z-y*z, x^2-y^2, z^2]) + sage: f = H([a^2, b^2, x*z - y*z, x^2 - y^2, z^2]) sage: f.is_morphism() False :: - sage: P.=ProductProjectiveSpaces([2, 2], QQ) + sage: P. = ProductProjectiveSpaces([2, 2], QQ) sage: H = End(P) sage: f = H([u, v, w, u^2, v^2, w^2]) sage: f.is_morphism() @@ -402,15 +400,15 @@ def is_morphism(self): def as_dynamical_system(self): """ - Return this endomorphism as a :class:`DynamicalSystem_producte_projective`. + Return this endomorphism as a :class:`~sage.dynamics.arithmetic_dynamics.product_projective_ds.DynamicalSystem_product_projective`. OUTPUT: - - :class:`DynamicalSystem_produce_projective` + - :class:`~sage.dynamics.arithmetic_dynamics.product_projective_ds.DynamicalSystem_product_projective` EXAMPLES:: - sage: Z. = ProductProjectiveSpaces([1 , 2], ZZ) + sage: Z. = ProductProjectiveSpaces([1, 2], ZZ) sage: H = End(Z) sage: f = H([a^3, b^3, x^2, y^2, z^2]) sage: type(f.as_dynamical_system()) @@ -423,7 +421,7 @@ def as_dynamical_system(self): def global_height(self, prec=None): r""" - Returns the maximum of the absolute logarithmic heights of the coefficients + Return the maximum of the absolute logarithmic heights of the coefficients in any of the coordinate functions of this map. INPUT: @@ -451,12 +449,12 @@ def global_height(self, prec=None): :: sage: u = QQ['u'].0 - sage: R = NumberField(u^2 - 2, 'v') - sage: PP. = ProductProjectiveSpaces([1, 1], R) - sage: H = End(PP) - sage: O = R.maximal_order() - sage: g = H([3*O(u)*x^2, 13*x*y, 7*a*y, 5*b*x + O(u)*a*y]) - sage: g.global_height() + sage: R = NumberField(u^2 - 2, 'v') # optional - sage.rings.number_field + sage: PP. = ProductProjectiveSpaces([1, 1], R) # optional - sage.rings.number_field + sage: H = End(PP) # optional - sage.rings.number_field + sage: O = R.maximal_order() # optional - sage.rings.number_field + sage: g = H([3*O(u)*x^2, 13*x*y, 7*a*y, 5*b*x + O(u)*a*y]) # optional - sage.rings.number_field + sage: g.global_height() # optional - sage.rings.number_field 2.56494935746154 """ K = self.domain().base_ring() @@ -474,7 +472,7 @@ def global_height(self, prec=None): def local_height(self, v, prec=None): r""" - Returns the maximum of the local height of the coefficients in any + Return the maximum of the local height of the coefficients in any of the coordinate functions of this map. INPUT: @@ -484,26 +482,24 @@ def local_height(self, v, prec=None): - ``prec`` -- desired floating point precision (default: default RealField precision). - OUTPUT: - - - a real number. + OUTPUT: A real number. EXAMPLES:: sage: T. = ProductProjectiveSpaces([2, 1], QQ) sage: H = T.Hom(T) - sage: f = H([4*x^2+3/100*y^2, 8/210*x*y, 1/10000*z^2, 20*w^2, 1/384*u*w]) + sage: f = H([4*x^2 + 3/100*y^2, 8/210*x*y, 1/10000*z^2, 20*w^2, 1/384*u*w]) sage: f.local_height(2) 4.85203026391962 :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(z^2-5) - sage: P. = ProductProjectiveSpaces([1, 1], K) - sage: H = Hom(P,P) - sage: f = H([2*x^2 + w/3*y^2, 1/w*y^2, a^2, 6*b^2 + 1/9*a*b]) - sage: f.local_height(K.ideal(3)) + sage: K. = NumberField(z^2 - 5) # optional - sage.rings.number_field + sage: P. = ProductProjectiveSpaces([1, 1], K) # optional - sage.rings.number_field + sage: H = Hom(P, P) # optional - sage.rings.number_field + sage: f = H([2*x^2 + w/3*y^2, 1/w*y^2, a^2, 6*b^2 + 1/9*a*b]) # optional - sage.rings.number_field + sage: f.local_height(K.ideal(3)) # optional - sage.rings.number_field 2.19722457733622 """ K = FractionField(self.domain().base_ring()) diff --git a/src/sage/schemes/product_projective/point.py b/src/sage/schemes/product_projective/point.py index e884deb2809..09cd0225209 100644 --- a/src/sage/schemes/product_projective/point.py +++ b/src/sage/schemes/product_projective/point.py @@ -41,7 +41,7 @@ class ProductProjectiveSpaces_point_ring(SchemeMorphism_point): EXAMPLES:: sage: T. = ProductProjectiveSpaces([2, 1], QQ) - sage: T.point([1, 2, 3, 4, 5]); + sage: T.point([1, 2, 3, 4, 5]) (1/3 : 2/3 : 1 , 4/5 : 1) """ def __init__(self, parent, polys, check=True): @@ -69,15 +69,15 @@ def __init__(self, parent, polys, check=True): :: - sage: T = ProductProjectiveSpaces([2, 2, 2], GF(5), 'x') - sage: T.point([1, 2, 3, 4, 5, 6, 7, 8, 9]) + sage: T = ProductProjectiveSpaces([2, 2, 2], GF(5), 'x') # optional - sage.rings.finite_rings + sage: T.point([1, 2, 3, 4, 5, 6, 7, 8, 9]) # optional - sage.rings.finite_rings (2 : 4 : 1 , 4 : 0 : 1 , 3 : 2 : 1) :: - sage: T. = ProductProjectiveSpaces([1, 1], GF(5)) - sage: X = T.subscheme([x-y, z-2*w]) - sage: X([1, 1, 2, 1]) + sage: T. = ProductProjectiveSpaces([1, 1], GF(5)) # optional - sage.rings.finite_rings + sage: X = T.subscheme([x - y, z - 2*w]) # optional - sage.rings.finite_rings + sage: X([1, 1, 2, 1]) # optional - sage.rings.finite_rings (1 : 1 , 2 : 1) """ polys = copy(polys) @@ -116,13 +116,13 @@ def __getitem__(self, i): EXAMPLES:: - sage: T = ProductProjectiveSpaces([2, 2, 2], GF(5), 'x') - sage: P = T([1, 0, 1, 1, 0, 0, 0, 0, 1]) - sage: P[1] + sage: T = ProductProjectiveSpaces([2, 2, 2], GF(5), 'x') # optional - sage.rings.finite_rings + sage: P = T([1, 0, 1, 1, 0, 0, 0, 0, 1]) # optional - sage.rings.finite_rings + sage: P[1] # optional - sage.rings.finite_rings (1 : 0 : 0) - sage: P[1].codomain() + sage: P[1].codomain() # optional - sage.rings.finite_rings Projective Space of dimension 2 over Finite Field of size 5 - sage: P[1][0] + sage: P[1][0] # optional - sage.rings.finite_rings 1 """ return self._points[i] @@ -173,26 +173,26 @@ def _richcmp_(self, right, op): EXAMPLES:: - sage: T = ProductProjectiveSpaces([1, 1, 1], GF(5), 'x') - sage: P = T([3, 2, 3, 4, 1, 0]) - sage: Q = T([1, 2, 3, 4, 3, 1]) - sage: P > Q + sage: T = ProductProjectiveSpaces([1, 1, 1], GF(5), 'x') # optional - sage.rings.finite_rings + sage: P = T([3, 2, 3, 4, 1, 0]) # optional - sage.rings.finite_rings + sage: Q = T([1, 2, 3, 4, 3, 1]) # optional - sage.rings.finite_rings + sage: P > Q # optional - sage.rings.finite_rings True :: - sage: T = ProductProjectiveSpaces([1, 1, 1], GF(5), 'x') - sage: P = T([1, 2, 3, 4, 1, 0]) - sage: Q = T([1, 2, 3, 4, 3, 0]) - sage: P == Q + sage: T = ProductProjectiveSpaces([1, 1, 1], GF(5), 'x') # optional - sage.rings.finite_rings + sage: P = T([1, 2, 3, 4, 1, 0]) # optional - sage.rings.finite_rings + sage: Q = T([1, 2, 3, 4, 3, 0]) # optional - sage.rings.finite_rings + sage: P == Q # optional - sage.rings.finite_rings True :: - sage: T = ProductProjectiveSpaces([1, 1, 1], GF(5), 'x') - sage: P = T([1, 2, 3, 4, 1, 0]) - sage: Q = T([1, 2, 3, 4, 3, 1]) - sage: P < Q + sage: T = ProductProjectiveSpaces([1, 1, 1], GF(5), 'x') # optional - sage.rings.finite_rings + sage: P = T([1, 2, 3, 4, 1, 0]) # optional - sage.rings.finite_rings + sage: Q = T([1, 2, 3, 4, 3, 1]) # optional - sage.rings.finite_rings + sage: P < Q # optional - sage.rings.finite_rings True """ #needed for Digraph @@ -281,10 +281,10 @@ def __hash__(self): :: - sage: PP = ProductProjectiveSpaces(GF(7), [1, 1, 1]) - sage: hash(PP([4, 1, 5, 4, 6, 1])) == hash((4, 1, 5, 4, 6, 1)) + sage: PP = ProductProjectiveSpaces(GF(7), [1, 1, 1]) # optional - sage.rings.finite_rings + sage: hash(PP([4, 1, 5, 4, 6, 1])) == hash((4, 1, 5, 4, 6, 1)) # optional - sage.rings.finite_rings False - sage: hash(PP([4, 1, 5, 4, 6, 1])) == hash((4, 1, 3, 1, 6, 1)) + sage: hash(PP([4, 1, 5, 4, 6, 1])) == hash((4, 1, 3, 1, 6, 1)) # optional - sage.rings.finite_rings True """ R = self.codomain().base_ring() @@ -404,15 +404,13 @@ def change_ring(self, R, **kwds): - ``embedding`` -- field embedding from the base ring of this point to ``R``. - OUTPUT: - - :class:`ProductProjectiveSpaces_point`. + OUTPUT: :class:`ProductProjectiveSpaces_point`. EXAMPLES:: sage: T. = ProductProjectiveSpaces([1, 1, 1], ZZ) - sage: P = T.point([5, 3, 15, 4, 2, 6]); - sage: P.change_ring(GF(3)) + sage: P = T.point([5, 3, 15, 4, 2, 6]) + sage: P.change_ring(GF(3)) # optional - sage.rings.finite_rings (1 : 0 , 0 : 1 , 1 : 0) """ check = kwds.get('check', True) @@ -433,20 +431,18 @@ def global_height(self, prec=None): - ``prec`` -- desired floating point precision (default: default RealField precision). - OUTPUT: - - - a real number. + OUTPUT: A real number. EXAMPLES:: - sage: PP = ProductProjectiveSpaces(QQ, [2,2], 'x') + sage: PP = ProductProjectiveSpaces(QQ, [2, 2], 'x') sage: Q = PP([1, 7, 5, 18, 2, 3]) sage: Q.global_height() 2.89037175789616 :: - sage: PP = ProductProjectiveSpaces(ZZ, [1,1], 'x') + sage: PP = ProductProjectiveSpaces(ZZ, [1, 1], 'x') sage: A = PP([-30, 2, 1, 6]) sage: A.global_height() 2.70805020110221 @@ -454,17 +450,17 @@ def global_height(self, prec=None): :: sage: R. = PolynomialRing(QQ) - sage: k. = NumberField(x^2 + 5) - sage: PP = ProductProjectiveSpaces(k, [1, 2], 'y') - sage: Q = PP([3, 5*w+1, 1, 7*w, 10]) - sage: Q.global_height() + sage: k. = NumberField(x^2 + 5) # optional - sage.rings.number_field + sage: PP = ProductProjectiveSpaces(k, [1, 2], 'y') # optional - sage.rings.number_field + sage: Q = PP([3, 5*w + 1, 1, 7*w, 10]) # optional - sage.rings.number_field + sage: Q.global_height() # optional - sage.rings.number_field 2.75062910527236 :: - sage: PP = ProductProjectiveSpaces(QQbar, [1, 1], 'x') - sage: Q = PP([1, QQbar(sqrt(2)), QQbar(5^(1/3)), QQbar(3^(1/3))]) - sage: Q.global_height() + sage: PP = ProductProjectiveSpaces(QQbar, [1, 1], 'x') # optional - sage.rings.number_field + sage: Q = PP([1, QQbar(sqrt(2)), QQbar(5^(1/3)), QQbar(3^(1/3))]) # optional - sage.rings.number_field sage.symbolic + sage: Q.global_height() # optional - sage.rings.number_field sage.symbolic 0.536479304144700 """ K = self.codomain().base_ring() @@ -489,9 +485,7 @@ def local_height(self, v, prec=None): - ``prec`` -- desired floating point precision (default: default RealField precision). - OUTPUT: - - - a real number. + OUTPUT: A real number. EXAMPLES:: @@ -502,7 +496,7 @@ def local_height(self, v, prec=None): :: - sage: P = ProductProjectiveSpaces(QQ, [1,2], 'x') + sage: P = ProductProjectiveSpaces(QQ, [1, 2], 'x') sage: Q = P([1, 4, 1/2, 2, 32]) sage: Q.local_height(2) 4.15888308335967 @@ -532,7 +526,7 @@ def intersection_multiplicity(self, X): EXAMPLES:: - sage: PP. = ProductProjectiveSpaces(QQ, [2,1]) + sage: PP. = ProductProjectiveSpaces(QQ, [2, 1]) sage: X = PP.subscheme([y^2*z^3*u - x^5*v]) sage: Y = PP.subscheme([u^3 - v^3, x - y]) sage: Q = X([0,0,1,1,1]) @@ -555,7 +549,7 @@ def multiplicity(self): EXAMPLES:: - sage: PP. = ProductProjectiveSpaces(QQ, [3,2]) + sage: PP. = ProductProjectiveSpaces(QQ, [3, 2]) sage: X = PP.subscheme([x^8*t - y^8*t + z^5*w^3*v]) sage: Q1 = X([1,1,0,0,-1,-1,1]) sage: Q1.multiplicity() diff --git a/src/sage/schemes/product_projective/rational_point.py b/src/sage/schemes/product_projective/rational_point.py index 53e08bcc171..1aec4b791b8 100644 --- a/src/sage/schemes/product_projective/rational_point.py +++ b/src/sage/schemes/product_projective/rational_point.py @@ -17,7 +17,7 @@ sage: PP. = ProductProjectiveSpaces([1,0], QQ) sage: from sage.schemes.product_projective.rational_point import \ enum_product_projective_rational_field - sage: enum_product_projective_rational_field(PP,3) + sage: enum_product_projective_rational_field(PP, 3) [(-3 : 1 , 1), (-2 : 1 , 1), (-3/2 : 1 , 1), (-1 : 1 , 1), (-2/3 : 1 , 1), (-1/2 : 1 , 1), (-1/3 : 1 , 1), (0 : 1 , 1), (1/3 : 1 , 1), @@ -27,11 +27,11 @@ Product projective over finite field:: - sage: P1. = ProductProjectiveSpaces([1,1], GF(7)) - sage: X = P1.subscheme([2*x+3*y]) + sage: P1. = ProductProjectiveSpaces([1, 1], GF(7)) # optional - sage.rings.finite_rings + sage: X = P1.subscheme([2*x + 3*y]) # optional - sage.rings.finite_rings sage: from sage.schemes.product_projective.rational_point import \ enum_product_projective_finite_field - sage: enum_product_projective_finite_field(X) + sage: enum_product_projective_finite_field(X) # optional - sage.rings.finite_rings [(2 : 1 , 0 : 1), (2 : 1 , 1 : 0), (2 : 1 , 1 : 1), (2 : 1 , 2 : 1), (2 : 1 , 3 : 1), (2 : 1 , 4 : 1), (2 : 1 , 5 : 1), (2 : 1 , 6 : 1)] @@ -89,7 +89,7 @@ def enum_product_projective_rational_field(X, B): sage: PP. = ProductProjectiveSpaces([1, 2], QQ) sage: from sage.schemes.product_projective.rational_point import \ enum_product_projective_rational_field - sage: enum_product_projective_rational_field(PP,1) + sage: enum_product_projective_rational_field(PP, 1) [(-1 : 1 , -1 : -1 : 1), (-1 : 1 , -1 : 0 : 1), (-1 : 1 , -1 : 1 : 0), (-1 : 1 , -1 : 1 : 1), (-1 : 1 , 0 : -1 : 1), (-1 : 1 , 0 : 0 : 1), (-1 : 1 , 0 : 1 : 0), (-1 : 1 , 0 : 1 : 1), (-1 : 1 , 1 : -1 : 1), @@ -111,11 +111,11 @@ def enum_product_projective_rational_field(X, B): :: - sage: PP. = ProductProjectiveSpaces([2,1], QQ) - sage: X = PP.subscheme([x^2 + x*y + y*z, u*u-v*u]) + sage: PP. = ProductProjectiveSpaces([2, 1], QQ) + sage: X = PP.subscheme([x^2 + x*y + y*z, u*u - v*u]) sage: from sage.schemes.product_projective.rational_point import \ enum_product_projective_rational_field - sage: enum_product_projective_rational_field(X,4) + sage: enum_product_projective_rational_field(X, 4) [(-2 : 4 : 1 , 0 : 1), (-2 : 4 : 1 , 1 : 1), (-1 : 1 : 0 , 0 : 1), (-1 : 1 : 0 , 1 : 1), (-2/3 : -4/3 : 1 , 0 : 1), (-2/3 : -4/3 : 1 , 1 : 1), (-1/2 : -1/2 : 1 , 0 : 1), (-1/2 : -1/2 : 1 , 1 : 1), @@ -208,12 +208,12 @@ def enum_product_projective_number_field(X, **kwds): EXAMPLES:: sage: u = QQ['u'].0 - sage: K = NumberField(u^2 + 2, 'v') - sage: PP. = ProductProjectiveSpaces([1, 1], K) - sage: X = PP.subscheme([x^2 + 2*y^2]) + sage: K = NumberField(u^2 + 2, 'v') # optional - sage.rings.number_field + sage: PP. = ProductProjectiveSpaces([1, 1], K) # optional - sage.rings.number_field + sage: X = PP.subscheme([x^2 + 2*y^2]) # optional - sage.rings.number_field sage: from sage.schemes.product_projective.rational_point import \ enum_product_projective_number_field - sage: enum_product_projective_number_field(X, bound=1.5) + sage: enum_product_projective_number_field(X, bound=1.5) # optional - sage.rings.number_field [(-v : 1 , -1 : 1), (-v : 1 , -v : 1), (-v : 1 , -1/2*v : 1), (-v : 1 , 0 : 1), (-v : 1 , 1/2*v : 1), (-v : 1 , v : 1), (-v : 1 , 1 : 0), (-v : 1 , 1 : 1), (v : 1 , -1 : 1), @@ -261,10 +261,10 @@ def enum_product_projective_finite_field(X): EXAMPLES:: - sage: PP. = ProductProjectiveSpaces([1, 1], GF(3)) + sage: PP. = ProductProjectiveSpaces([1, 1], GF(3)) # optional - sage.rings.finite_rings sage: from sage.schemes.product_projective.rational_point import \ enum_product_projective_finite_field - sage: enum_product_projective_finite_field(PP) + sage: enum_product_projective_finite_field(PP) # optional - sage.rings.finite_rings [(0 : 1 , 0 : 1), (0 : 1 , 1 : 0), (0 : 1 , 1 : 1), (0 : 1 , 2 : 1), (1 : 0 , 0 : 1), (1 : 0 , 1 : 0), (1 : 0 , 1 : 1), (1 : 0 , 2 : 1), (1 : 1 , 0 : 1), @@ -274,11 +274,11 @@ def enum_product_projective_finite_field(X): :: - sage: PP. = ProductProjectiveSpaces([1, 1], GF(17)) - sage: X = PP.subscheme([x0^2 + 2*x1^2]) + sage: PP. = ProductProjectiveSpaces([1, 1], GF(17)) # optional - sage.rings.finite_rings + sage: X = PP.subscheme([x0^2 + 2*x1^2]) # optional - sage.rings.finite_rings sage: from sage.schemes.product_projective.rational_point import \ enum_product_projective_finite_field - sage: len(enum_product_projective_finite_field(X)) + sage: len(enum_product_projective_finite_field(X)) # optional - sage.rings.finite_rings 36 """ if is_Scheme(X): @@ -334,8 +334,8 @@ def sieve(X, bound): EXAMPLES:: sage: from sage.schemes.product_projective.rational_point import sieve - sage: PP. = ProductProjectiveSpaces([2,1], QQ) - sage: X = PP.subscheme([x^2 + y^2 - x*z, u*u-v*u]) + sage: PP. = ProductProjectiveSpaces([2, 1], QQ) + sage: X = PP.subscheme([x^2 + y^2 - x*z, u*u - v*u]) sage: sieve(X, 2) [(0 : 0 : 1 , 0 : 1), (0 : 0 : 1 , 1 : 1), (1/2 : -1/2 : 1 , 0 : 1), (1/2 : -1/2 : 1 , 1 : 1), (1/2 : 1/2 : 1 , 0 : 1), (1/2 : 1/2 : 1 , 1 : 1), diff --git a/src/sage/schemes/product_projective/space.py b/src/sage/schemes/product_projective/space.py index 4597d1c3798..c17524ed163 100644 --- a/src/sage/schemes/product_projective/space.py +++ b/src/sage/schemes/product_projective/space.py @@ -105,7 +105,7 @@ def ProductProjectiveSpaces(n, R=None, names='x'): :: - sage: ProductProjectiveSpaces([2, 2],GF(7), 'y') + sage: ProductProjectiveSpaces([2, 2], GF(7), 'y') # optional - sage.rings.finite_rings Product of projective spaces P^2 x P^2 over Finite Field of size 7 :: @@ -396,10 +396,10 @@ def __pow__(self, m): EXAMPLES:: - sage: P1 = ProductProjectiveSpaces([2,1], QQ, 'x') + sage: P1 = ProductProjectiveSpaces([2, 1], QQ, 'x') sage: P1^3 - Product of projective spaces P^2 x P^1 x P^2 x P^1 x P^2 x P^1 over - Rational Field + Product of projective spaces P^2 x P^1 x P^2 x P^1 x P^2 x P^1 + over Rational Field As you see, custom variable names are not preserved by power operator, since there is no natural way to make new ones in general. @@ -435,8 +435,8 @@ def __mul__(self, right): :: - sage: S = ProductProjectiveSpaces([1,2,1], ZZ, 't') - sage: T = ProductProjectiveSpaces([2,2], ZZ, 'x') + sage: S = ProductProjectiveSpaces([1, 2, 1], ZZ, 't') + sage: T = ProductProjectiveSpaces([2, 2], ZZ, 'x') sage: T.inject_variables() Defining x0, x1, x2, x3, x4, x5 sage: X = T.subscheme([x0*x4 - x1*x3]) @@ -479,7 +479,7 @@ def components(self): EXAMPLES:: - sage: P. = ProductProjectiveSpaces(QQ,[2,1]) + sage: P. = ProductProjectiveSpaces(QQ, [2, 1]) sage: P.components() [Projective Space of dimension 2 over Rational Field, Projective Space of dimension 1 over Rational Field] @@ -494,7 +494,7 @@ def dimension_relative(self): EXAMPLES:: - sage: T. = ProductProjectiveSpaces([3,2],QQ) + sage: T. = ProductProjectiveSpaces([3, 2], QQ) sage: T.dimension_relative() 5 """ @@ -508,10 +508,10 @@ def dimension_absolute(self): EXAMPLES:: - sage: T. = ProductProjectiveSpaces([2, 2], GF(17)) - sage: T.dimension_absolute() + sage: T. = ProductProjectiveSpaces([2, 2], GF(17)) # optional - sage.rings.finite_rings + sage: T.dimension_absolute() # optional - sage.rings.finite_rings 4 - sage: T.dimension() + sage: T.dimension() # optional - sage.rings.finite_rings 4 """ base = self.base_scheme() @@ -543,10 +543,10 @@ def dimension_absolute_components(self): EXAMPLES:: - sage: T. = ProductProjectiveSpaces([2, 2], GF(17)) - sage: T.dimension_absolute_components() + sage: T. = ProductProjectiveSpaces([2, 2], GF(17)) # optional - sage.rings.finite_rings + sage: T.dimension_absolute_components() # optional - sage.rings.finite_rings [2, 2] - sage: T.dimension_components() + sage: T.dimension_components() # optional - sage.rings.finite_rings [2, 2] """ base = self.base_scheme() @@ -564,8 +564,8 @@ def num_components(self): EXAMPLES:: - sage: T = ProductProjectiveSpaces([1, 1, 1], GF(5), 'x') - sage: T.num_components() + sage: T = ProductProjectiveSpaces([1, 1, 1], GF(5), 'x') # optional - sage.rings.finite_rings + sage: T.num_components() # optional - sage.rings.finite_rings 3 """ return len(self._components) @@ -581,8 +581,8 @@ def ngens(self): EXAMPLES:: - sage: T = ProductProjectiveSpaces([1, 1, 1], GF(5), 'x') - sage: T.ngens() + sage: T = ProductProjectiveSpaces([1, 1, 1], GF(5), 'x') # optional - sage.rings.finite_rings + sage: T.ngens() # optional - sage.rings.finite_rings 6 """ return sum([P.ngens() for P in self._components]) @@ -722,9 +722,9 @@ def _validate(self, polynomials): :: - sage: R. = PolynomialRing(GF(5)) - sage: T. = ProductProjectiveSpaces([2, 1], QQ) - sage: T._validate([t, t, t, w^2, u^2]) + sage: R. = PolynomialRing(GF(5)) # optional - sage.rings.finite_rings + sage: T. = ProductProjectiveSpaces([2, 1], QQ) # optional - sage.rings.finite_rings + sage: T._validate([t, t, t, w^2, u^2]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: polynomials (=[t, t, t, w^2, u^2]) must be elements of Multivariate @@ -755,9 +755,9 @@ def _check_satisfies_equations(self, v): :: - sage: R. = PolynomialRing(GF(7)) - sage: T. = ProductProjectiveSpaces([2, 1], R) - sage: T._check_satisfies_equations([1 + t, 1, 0, 0, 1]) + sage: R. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: T. = ProductProjectiveSpaces([2, 1], R) # optional - sage.rings.finite_rings + sage: T._check_satisfies_equations([1 + t, 1, 0, 0, 1]) # optional - sage.rings.finite_rings True :: @@ -837,29 +837,29 @@ def subscheme(self, X): EXAMPLES:: - sage: P. = ProductProjectiveSpaces([1, 1],GF(5)) - sage: X = P.subscheme([x-y, z-w]);X - Closed subscheme of Product of projective spaces P^1 x P^1 over Finite Field of size 5 defined by: - x - y, - z - w - sage: X.defining_polynomials () + sage: P. = ProductProjectiveSpaces([1, 1], GF(5)) # optional - sage.rings.finite_rings + sage: X = P.subscheme([x - y, z - w]); X # optional - sage.rings.finite_rings + Closed subscheme of Product of projective spaces P^1 x P^1 + over Finite Field of size 5 defined by: + x - y, + z - w + sage: X.defining_polynomials() # optional - sage.rings.finite_rings [x - y, z - w] - sage: I = X.defining_ideal(); I - Ideal (x - y, z - w) of Multivariate Polynomial Ring in x, y, z, w over - Finite Field of size 5 - sage: X.dimension() + sage: I = X.defining_ideal(); I # optional - sage.rings.finite_rings + Ideal (x - y, z - w) of Multivariate Polynomial Ring in x, y, z, w + over Finite Field of size 5 + sage: X.dimension() # optional - sage.rings.finite_rings 0 - sage: X.base_ring() + sage: X.base_ring() # optional - sage.rings.finite_rings Finite Field of size 5 - sage: X.base_scheme() + sage: X.base_scheme() # optional - sage.rings.finite_rings Spectrum of Finite Field of size 5 - sage: X.structure_morphism() + sage: X.structure_morphism() # optional - sage.rings.finite_rings Scheme morphism: - From: Closed subscheme of Product of projective spaces P^1 x P^1 over Finite Field of size 5 defined by: - x - y, - z - w - To: Spectrum of Finite Field of size 5 - Defn: Structure map + From: Closed subscheme of Product of projective spaces P^1 x P^1 + over Finite Field of size 5 defined by: x - y, z - w + To: Spectrum of Finite Field of size 5 + Defn: Structure map """ return AlgebraicScheme_subscheme_product_projective(self, X) @@ -884,7 +884,7 @@ def change_ring(self, R): EXAMPLES:: sage: T. = ProductProjectiveSpaces([2, 2], QQ) - sage: T.change_ring(GF(17)) + sage: T.change_ring(GF(17)) # optional - sage.rings.finite_rings Product of projective spaces P^2 x P^2 over Finite Field of size 17 """ new_components = [P.change_ring(R) for P in self._components] @@ -915,10 +915,10 @@ def affine_patch(self, I, return_embedding=False): Affine Space of dimension 6 over Integer Ring sage: phi Scheme morphism: - From: Affine Space of dimension 6 over Integer Ring - To: Product of projective spaces P^2 x P^2 x P^2 over Integer Ring - Defn: Defined on coordinates by sending (x0, x1, x2, x3, x4, x5) to - (1 : x0 : x1 , x2 : 1 : x3 , x4 : x5 : 1) + From: Affine Space of dimension 6 over Integer Ring + To: Product of projective spaces P^2 x P^2 x P^2 over Integer Ring + Defn: Defined on coordinates by sending (x0, x1, x2, x3, x4, x5) to + (1 : x0 : x1 , x2 : 1 : x3 , x4 : x5 : 1) """ if not isinstance(I, (list, tuple)): raise TypeError('the argument I=%s must be a list or tuple of positive integers'%I) @@ -980,16 +980,11 @@ def segre_embedding(self, PP=None, var='u'): sage: phi = X.segre_embedding(); phi Scheme morphism: From: Product of projective spaces P^2 x P^2 over Integer Ring - To: Closed subscheme of Projective Space of dimension 8 over Integer Ring defined by: - -u5*u7 + u4*u8, - -u5*u6 + u3*u8, - -u4*u6 + u3*u7, - -u2*u7 + u1*u8, - -u2*u4 + u1*u5, - -u2*u6 + u0*u8, - -u1*u6 + u0*u7, - -u2*u3 + u0*u5, - -u1*u3 + u0*u4 + To: Closed subscheme of Projective Space of dimension 8 over Integer Ring + defined by: + -u5*u7 + u4*u8, -u5*u6 + u3*u8, -u4*u6 + u3*u7, + -u2*u7 + u1*u8, -u2*u4 + u1*u5, -u2*u6 + u0*u8, + -u1*u6 + u0*u7, -u2*u3 + u0*u5, -u1*u3 + u0*u4 Defn: Defined by sending (y0 : y1 : y2 , y3 : y4 : y5) to (y0*y3 : y0*y4 : y0*y5 : y1*y3 : y1*y4 : y1*y5 : y2*y3 : y2*y4 : y2*y5). @@ -998,11 +993,11 @@ def segre_embedding(self, PP=None, var='u'): sage: T = ProductProjectiveSpaces([1, 2], CC, 'z') sage: T.segre_embedding() Scheme morphism: - From: Product of projective spaces P^1 x P^2 over Complex Field with 53 bits of precision - To: Closed subscheme of Projective Space of dimension 5 over Complex Field with 53 bits of precision defined by: - -u2*u4 + u1*u5, - -u2*u3 + u0*u5, - -u1*u3 + u0*u4 + From: Product of projective spaces P^1 x P^2 + over Complex Field with 53 bits of precision + To: Closed subscheme of Projective Space of dimension 5 + over Complex Field with 53 bits of precision defined by: + -u2*u4 + u1*u5, -u2*u3 + u0*u5, -u1*u3 + u0*u4 Defn: Defined by sending (z0 : z1 , z2 : z3 : z4) to (z0*z2 : z0*z3 : z0*z4 : z1*z2 : z1*z3 : z1*z4). @@ -1012,35 +1007,19 @@ def segre_embedding(self, PP=None, var='u'): sage: T.segre_embedding() Scheme morphism: From: Product of projective spaces P^1 x P^2 x P^1 over Rational Field - To: Closed subscheme of Projective Space of dimension 11 over - Rational Field defined by: - -u9*u10 + u8*u11, - -u7*u10 + u6*u11, - -u7*u8 + u6*u9, - -u5*u10 + u4*u11, - -u5*u8 + u4*u9, - -u5*u6 + u4*u7, - -u5*u9 + u3*u11, - -u5*u8 + u3*u10, - -u5*u8 + u2*u11, - -u4*u8 + u2*u10, - -u3*u8 + u2*u9, - -u3*u6 + u2*u7, - -u3*u4 + u2*u5, - -u5*u7 + u1*u11, - -u5*u6 + u1*u10, - -u3*u7 + u1*u9, - -u3*u6 + u1*u8, - -u5*u6 + u0*u11, - -u4*u6 + u0*u10, - -u3*u6 + u0*u9, - -u2*u6 + u0*u8, - -u1*u6 + u0*u7, - -u1*u4 + u0*u5, - -u1*u2 + u0*u3 + To: Closed subscheme of Projective Space of dimension 11 + over Rational Field defined by: + -u9*u10 + u8*u11, -u7*u10 + u6*u11, -u7*u8 + u6*u9, + -u5*u10 + u4*u11, -u5*u8 + u4*u9, -u5*u6 + u4*u7, + -u5*u9 + u3*u11, -u5*u8 + u3*u10, -u5*u8 + u2*u11, + -u4*u8 + u2*u10, -u3*u8 + u2*u9, -u3*u6 + u2*u7, + -u3*u4 + u2*u5, -u5*u7 + u1*u11, -u5*u6 + u1*u10, + -u3*u7 + u1*u9, -u3*u6 + u1*u8, -u5*u6 + u0*u11, + -u4*u6 + u0*u10, -u3*u6 + u0*u9, -u2*u6 + u0*u8, + -u1*u6 + u0*u7, -u1*u4 + u0*u5, -u1*u2 + u0*u3 Defn: Defined by sending (z0 : z1 , z2 : z3 : z4 , z5 : z6) to (z0*z2*z5 : z0*z2*z6 : z0*z3*z5 : z0*z3*z6 : z0*z4*z5 : z0*z4*z6 - : z1*z2*z5 : z1*z2*z6 : z1*z3*z5 : z1*z3*z6 : z1*z4*z5 : z1*z4*z6). + : z1*z2*z5 : z1*z2*z6 : z1*z3*z5 : z1*z3*z6 : z1*z4*z5 : z1*z4*z6). """ N = self._dims M = prod([n+1 for n in N]) - 1 @@ -1109,8 +1088,9 @@ def _point(self, *args, **kwds): EXAMPLES:: sage: u = QQ['u'].0 - sage: P = ProductProjectiveSpaces([1, 2], NumberField(u^2 - 2, 'v'), 'x') - sage: P([1, 3, u, 1, 1]) + sage: K = NumberField(u^2 - 2, 'v') # optional - sage.rings.number_field + sage: P = ProductProjectiveSpaces([1, 2], K, 'x') # optional - sage.rings.number_field + sage: P([1, 3, u, 1, 1]) # optional - sage.rings.number_field (1/3 : 1 , v : 1 : 1) """ return ProductProjectiveSpaces_point_field(*args, **kwds) @@ -1123,10 +1103,10 @@ def _point_homset(self, *args, **kwds): EXAMPLES:: - sage: P. = ProductProjectiveSpaces([1, 1], GF(5)) - sage: P._point_homset(Spec(GF(5)), P) + sage: P. = ProductProjectiveSpaces([1, 1], GF(5)) # optional - sage.rings.finite_rings + sage: P._point_homset(Spec(GF(5)), P) # optional - sage.rings.finite_rings Set of rational points of Product of projective spaces P^1 x P^1 - over Finite Field of size 5 + over Finite Field of size 5 """ return SchemeHomset_points_product_projective_spaces_field(*args, **kwds) @@ -1161,38 +1141,47 @@ def points_of_bounded_height(self, **kwds): sage: PP = ProductProjectiveSpaces(QQ, [1, 2]) sage: sorted(list(PP.points_of_bounded_height(bound=1))) - [(-1 : 1 , -1 : -1 : 1), (-1 : 1 , -1 : 0 : 1), (-1 : 1 , -1 : 1 : 0), (-1 : 1 , -1 : 1 : 1), - (-1 : 1 , 0 : -1 : 1), (-1 : 1 , 0 : 0 : 1), (-1 : 1 , 0 : 1 : 0), (-1 : 1 , 0 : 1 : 1), - (-1 : 1 , 1 : -1 : 1), (-1 : 1 , 1 : 0 : 0), (-1 : 1 , 1 : 0 : 1), (-1 : 1 , 1 : 1 : 0), - (-1 : 1 , 1 : 1 : 1), (0 : 1 , -1 : -1 : 1), (0 : 1 , -1 : 0 : 1), (0 : 1 , -1 : 1 : 0), - (0 : 1 , -1 : 1 : 1), (0 : 1 , 0 : -1 : 1), (0 : 1 , 0 : 0 : 1), (0 : 1 , 0 : 1 : 0), - (0 : 1 , 0 : 1 : 1), (0 : 1 , 1 : -1 : 1), (0 : 1 , 1 : 0 : 0), (0 : 1 , 1 : 0 : 1), - (0 : 1 , 1 : 1 : 0), (0 : 1 , 1 : 1 : 1), (1 : 0 , -1 : -1 : 1), (1 : 0 , -1 : 0 : 1), - (1 : 0 , -1 : 1 : 0), (1 : 0 , -1 : 1 : 1), (1 : 0 , 0 : -1 : 1), (1 : 0 , 0 : 0 : 1), - (1 : 0 , 0 : 1 : 0), (1 : 0 , 0 : 1 : 1), (1 : 0 , 1 : -1 : 1), (1 : 0 , 1 : 0 : 0), - (1 : 0 , 1 : 0 : 1), (1 : 0 , 1 : 1 : 0), (1 : 0 , 1 : 1 : 1), (1 : 1 , -1 : -1 : 1), - (1 : 1 , -1 : 0 : 1), (1 : 1 , -1 : 1 : 0), (1 : 1 , -1 : 1 : 1), (1 : 1 , 0 : -1 : 1), - (1 : 1 , 0 : 0 : 1), (1 : 1 , 0 : 1 : 0), (1 : 1 , 0 : 1 : 1), (1 : 1 , 1 : -1 : 1), - (1 : 1 , 1 : 0 : 0), (1 : 1 , 1 : 0 : 1), (1 : 1 , 1 : 1 : 0), (1 : 1 , 1 : 1 : 1)] + [(-1 : 1 , -1 : -1 : 1), (-1 : 1 , -1 : 0 : 1), (-1 : 1 , -1 : 1 : 0), + (-1 : 1 , -1 : 1 : 1), (-1 : 1 , 0 : -1 : 1), (-1 : 1 , 0 : 0 : 1), + (-1 : 1 , 0 : 1 : 0), (-1 : 1 , 0 : 1 : 1), (-1 : 1 , 1 : -1 : 1), + (-1 : 1 , 1 : 0 : 0), (-1 : 1 , 1 : 0 : 1), (-1 : 1 , 1 : 1 : 0), + (-1 : 1 , 1 : 1 : 1), (0 : 1 , -1 : -1 : 1), (0 : 1 , -1 : 0 : 1), + (0 : 1 , -1 : 1 : 0), (0 : 1 , -1 : 1 : 1), (0 : 1 , 0 : -1 : 1), + (0 : 1 , 0 : 0 : 1), (0 : 1 , 0 : 1 : 0), (0 : 1 , 0 : 1 : 1), + (0 : 1 , 1 : -1 : 1), (0 : 1 , 1 : 0 : 0), (0 : 1 , 1 : 0 : 1), + (0 : 1 , 1 : 1 : 0), (0 : 1 , 1 : 1 : 1), (1 : 0 , -1 : -1 : 1), + (1 : 0 , -1 : 0 : 1), (1 : 0 , -1 : 1 : 0), (1 : 0 , -1 : 1 : 1), + (1 : 0 , 0 : -1 : 1), (1 : 0 , 0 : 0 : 1), (1 : 0 , 0 : 1 : 0), + (1 : 0 , 0 : 1 : 1), (1 : 0 , 1 : -1 : 1), (1 : 0 , 1 : 0 : 0), + (1 : 0 , 1 : 0 : 1), (1 : 0 , 1 : 1 : 0), (1 : 0 , 1 : 1 : 1), + (1 : 1 , -1 : -1 : 1), (1 : 1 , -1 : 0 : 1), (1 : 1 , -1 : 1 : 0), + (1 : 1 , -1 : 1 : 1), (1 : 1 , 0 : -1 : 1), (1 : 1 , 0 : 0 : 1), + (1 : 1 , 0 : 1 : 0), (1 : 1 , 0 : 1 : 1), (1 : 1 , 1 : -1 : 1), + (1 : 1 , 1 : 0 : 0), (1 : 1 , 1 : 0 : 1), (1 : 1 , 1 : 1 : 0), + (1 : 1 , 1 : 1 : 1)] :: sage: u = QQ['u'].0 - sage: P = ProductProjectiveSpaces([1, 1], NumberField(u^2 - 2, 'v')) - sage: sorted(list(P.points_of_bounded_height(bound=1.5))) - [(-v : 1 , -v : 1), (-v : 1 , -1 : 1), (-v : 1 , -1/2*v : 1), (-v : 1 , 0 : 1), (-v : 1 , 1/2*v : 1), - (-v : 1 , 1 : 0), (-v : 1 , 1 : 1), (-v : 1 , v : 1), (-1 : 1 , -v : 1), (-1 : 1 , -1 : 1), - (-1 : 1 , -1/2*v : 1), (-1 : 1 , 0 : 1), (-1 : 1 , 1/2*v : 1), (-1 : 1 , 1 : 0), (-1 : 1 , 1 : 1), - (-1 : 1 , v : 1), (-1/2*v : 1 , -v : 1), (-1/2*v : 1 , -1 : 1), (-1/2*v : 1 , -1/2*v : 1), (-1/2*v : 1 , 0 : 1), - (-1/2*v : 1 , 1/2*v : 1), (-1/2*v : 1 , 1 : 0), (-1/2*v : 1 , 1 : 1), (-1/2*v : 1 , v : 1), (0 : 1 , -v : 1), - (0 : 1 , -1 : 1), (0 : 1 , -1/2*v : 1), (0 : 1 , 0 : 1), (0 : 1 , 1/2*v : 1), (0 : 1 , 1 : 0), - (0 : 1 , 1 : 1), (0 : 1 , v : 1), (1/2*v : 1 , -v : 1), (1/2*v : 1 , -1 : 1), (1/2*v : 1 , -1/2*v : 1), - (1/2*v : 1 , 0 : 1), (1/2*v : 1 , 1/2*v : 1), (1/2*v : 1 , 1 : 0), (1/2*v : 1 , 1 : 1), (1/2*v : 1 , v : 1), - (1 : 0 , -v : 1), (1 : 0 , -1 : 1), (1 : 0 , -1/2*v : 1), (1 : 0 , 0 : 1), (1 : 0 , 1/2*v : 1), - (1 : 0 , 1 : 0), (1 : 0 , 1 : 1), (1 : 0 , v : 1), (1 : 1 , -v : 1), (1 : 1 , -1 : 1), - (1 : 1 , -1/2*v : 1), (1 : 1 , 0 : 1), (1 : 1 , 1/2*v : 1), (1 : 1 , 1 : 0), (1 : 1 , 1 : 1), - (1 : 1 , v : 1), (v : 1 , -v : 1), (v : 1 , -1 : 1), (v : 1 , -1/2*v : 1), (v : 1 , 0 : 1), - (v : 1 , 1/2*v : 1), (v : 1 , 1 : 0), (v : 1 , 1 : 1), (v : 1 , v : 1)] + sage: P = ProductProjectiveSpaces([1, 1], NumberField(u^2 - 2, 'v')) # optional - sage.rings.number_field + sage: sorted(list(P.points_of_bounded_height(bound=1.5))) # optional - sage.rings.number_field + [(-v : 1 , -v : 1), (-v : 1 , -1 : 1), (-v : 1 , -1/2*v : 1), (-v : 1 , 0 : 1), + (-v : 1 , 1/2*v : 1), (-v : 1 , 1 : 0), (-v : 1 , 1 : 1), (-v : 1 , v : 1), + (-1 : 1 , -v : 1), (-1 : 1 , -1 : 1), (-1 : 1 , -1/2*v : 1), (-1 : 1 , 0 : 1), + (-1 : 1 , 1/2*v : 1), (-1 : 1 , 1 : 0), (-1 : 1 , 1 : 1), (-1 : 1 , v : 1), + (-1/2*v : 1 , -v : 1), (-1/2*v : 1 , -1 : 1), (-1/2*v : 1 , -1/2*v : 1), + (-1/2*v : 1 , 0 : 1), (-1/2*v : 1 , 1/2*v : 1), (-1/2*v : 1 , 1 : 0), + (-1/2*v : 1 , 1 : 1), (-1/2*v : 1 , v : 1), (0 : 1 , -v : 1), (0 : 1 , -1 : 1), + (0 : 1 , -1/2*v : 1), (0 : 1 , 0 : 1), (0 : 1 , 1/2*v : 1), (0 : 1 , 1 : 0), + (0 : 1 , 1 : 1), (0 : 1 , v : 1), (1/2*v : 1 , -v : 1), (1/2*v : 1 , -1 : 1), + (1/2*v : 1 , -1/2*v : 1), (1/2*v : 1 , 0 : 1), (1/2*v : 1 , 1/2*v : 1), + (1/2*v : 1 , 1 : 0), (1/2*v : 1 , 1 : 1), (1/2*v : 1 , v : 1), (1 : 0 , -v : 1), + (1 : 0 , -1 : 1), (1 : 0 , -1/2*v : 1), (1 : 0 , 0 : 1), (1 : 0 , 1/2*v : 1), + (1 : 0 , 1 : 0), (1 : 0 , 1 : 1), (1 : 0 , v : 1), (1 : 1 , -v : 1), + (1 : 1 , -1 : 1), (1 : 1 , -1/2*v : 1), (1 : 1 , 0 : 1), (1 : 1 , 1/2*v : 1), + (1 : 1 , 1 : 0), (1 : 1 , 1 : 1), (1 : 1 , v : 1), (v : 1 , -v : 1), + (v : 1 , -1 : 1), (v : 1 , -1/2*v : 1), (v : 1 , 0 : 1), (v : 1 , 1/2*v : 1), + (v : 1 , 1 : 0), (v : 1 , 1 : 1), (v : 1 , v : 1)] """ B = kwds.pop('bound') tol = kwds.pop('tolerance', 1e-2) @@ -1236,8 +1225,8 @@ def _point(self, *args, **kwds): EXAMPLES:: - sage: P = ProductProjectiveSpaces([1, 2], GF(11)) - sage: P([3, 7, 4, 5, 9]) + sage: P = ProductProjectiveSpaces([1, 2], GF(11)) # optional - sage.rings.finite_rings + sage: P([3, 7, 4, 5, 9]) # optional - sage.rings.finite_rings (2 : 1 , 9 : 3 : 1) """ return ProductProjectiveSpaces_point_finite_field(*args, **kwds) @@ -1248,15 +1237,15 @@ def __iter__(self): EXAMPLES:: - sage: P = ProductProjectiveSpaces([2, 1], GF(3)) - sage: [x for x in P] + sage: P = ProductProjectiveSpaces([2, 1], GF(3)) # optional - sage.rings.finite_rings + sage: [x for x in P] # optional - sage.rings.finite_rings [(0 : 0 : 1 , 0 : 1), - (0 : 1 : 1 , 0 : 1), - (0 : 2 : 1 , 0 : 1), - ... - (1 : 1 : 0 , 1 : 0), - (2 : 1 : 0 , 1 : 0), - (1 : 0 : 0 , 1 : 0)] + (0 : 1 : 1 , 0 : 1), + (0 : 2 : 1 , 0 : 1), + ... + (1 : 1 : 0 , 1 : 0), + (2 : 1 : 0 , 1 : 0), + (1 : 0 : 0 , 1 : 0)] """ iters = [iter(T) for T in self._components] L = [] @@ -1281,24 +1270,26 @@ def rational_points(self, F=None): EXAMPLES:: - sage: P = ProductProjectiveSpaces([1, 1], GF(5)) - sage: P.rational_points() + sage: P = ProductProjectiveSpaces([1, 1], GF(5)) # optional - sage.rings.finite_rings + sage: P.rational_points() # optional - sage.rings.finite_rings [(0 : 1 , 0 : 1), (1 : 1 , 0 : 1), (2 : 1 , 0 : 1), (3 : 1 , 0 : 1), (4 : 1 , 0 : 1), (1 : 0 , 0 : 1), - (0 : 1 , 1 : 1), (1 : 1 , 1 : 1), (2 : 1 , 1 : 1), (3 : 1 , 1 : 1), (4 : 1 , 1 : 1), (1 : 0 , 1 : 1), - (0 : 1 , 2 : 1), (1 : 1 , 2 : 1), (2 : 1 , 2 : 1), (3 : 1 , 2 : 1), (4 : 1 , 2 : 1), (1 : 0 , 2 : 1), - (0 : 1 , 3 : 1), (1 : 1 , 3 : 1), (2 : 1 , 3 : 1), (3 : 1 , 3 : 1), (4 : 1 , 3 : 1), (1 : 0 , 3 : 1), - (0 : 1 , 4 : 1), (1 : 1 , 4 : 1), (2 : 1 , 4 : 1), (3 : 1 , 4 : 1), (4 : 1 , 4 : 1), (1 : 0 , 4 : 1), - (0 : 1 , 1 : 0), (1 : 1 , 1 : 0), (2 : 1 , 1 : 0), (3 : 1 , 1 : 0), (4 : 1 , 1 : 0), (1 : 0 , 1 : 0)] + (0 : 1 , 1 : 1), (1 : 1 , 1 : 1), (2 : 1 , 1 : 1), (3 : 1 , 1 : 1), (4 : 1 , 1 : 1), (1 : 0 , 1 : 1), + (0 : 1 , 2 : 1), (1 : 1 , 2 : 1), (2 : 1 , 2 : 1), (3 : 1 , 2 : 1), (4 : 1 , 2 : 1), (1 : 0 , 2 : 1), + (0 : 1 , 3 : 1), (1 : 1 , 3 : 1), (2 : 1 , 3 : 1), (3 : 1 , 3 : 1), (4 : 1 , 3 : 1), (1 : 0 , 3 : 1), + (0 : 1 , 4 : 1), (1 : 1 , 4 : 1), (2 : 1 , 4 : 1), (3 : 1 , 4 : 1), (4 : 1 , 4 : 1), (1 : 0 , 4 : 1), + (0 : 1 , 1 : 0), (1 : 1 , 1 : 0), (2 : 1 , 1 : 0), (3 : 1 , 1 : 0), (4 : 1 , 1 : 0), (1 : 0 , 1 : 0)] :: - sage: P = ProductProjectiveSpaces([1, 1], GF(2)) - sage: P.rational_points(GF(2^2,'a')) - [(0 : 1 , 0 : 1), (a : 1 , 0 : 1), (a + 1 : 1 , 0 : 1), (1 : 1 , 0 : 1), (1 : 0 , 0 : 1), (0 : 1 , a : 1), - (a : 1 , a : 1), (a + 1 : 1 , a : 1), (1 : 1 , a : 1), (1 : 0 , a : 1), (0 : 1 , a + 1 : 1), (a : 1 , a + 1 : 1), - (a + 1 : 1 , a + 1 : 1), (1 : 1 , a + 1 : 1), (1 : 0 , a + 1 : 1), (0 : 1 , 1 : 1), (a : 1 , 1 : 1), - (a + 1 : 1 , 1 : 1), (1 : 1 , 1 : 1), (1 : 0 , 1 : 1), (0 : 1 , 1 : 0), (a : 1 , 1 : 0), (a + 1 : 1 , 1 : 0), - (1 : 1 , 1 : 0), (1 : 0 , 1 : 0)] + sage: P = ProductProjectiveSpaces([1, 1], GF(2)) # optional - sage.rings.finite_rings + sage: P.rational_points(GF(2^2, 'a')) # optional - sage.rings.finite_rings + [(0 : 1 , 0 : 1), (a : 1 , 0 : 1), (a + 1 : 1 , 0 : 1), (1 : 1 , 0 : 1), + (1 : 0 , 0 : 1), (0 : 1 , a : 1), (a : 1 , a : 1), (a + 1 : 1 , a : 1), + (1 : 1 , a : 1), (1 : 0 , a : 1), (0 : 1 , a + 1 : 1), (a : 1 , a + 1 : 1), + (a + 1 : 1 , a + 1 : 1), (1 : 1 , a + 1 : 1), (1 : 0 , a + 1 : 1), + (0 : 1 , 1 : 1), (a : 1 , 1 : 1), (a + 1 : 1 , 1 : 1), (1 : 1 , 1 : 1), + (1 : 0 , 1 : 1), (0 : 1 , 1 : 0), (a : 1 , 1 : 0), (a + 1 : 1 , 1 : 0), + (1 : 1 , 1 : 0), (1 : 0 , 1 : 0)] """ if F is None: return list(self) diff --git a/src/sage/schemes/product_projective/subscheme.py b/src/sage/schemes/product_projective/subscheme.py index 963feea3d09..1678ab2f472 100644 --- a/src/sage/schemes/product_projective/subscheme.py +++ b/src/sage/schemes/product_projective/subscheme.py @@ -45,19 +45,19 @@ class AlgebraicScheme_subscheme_product_projective(AlgebraicScheme_subscheme_pro EXAMPLES:: - sage: P. = ProductProjectiveSpaces([1,1], QQ) - sage: P.subscheme([u*x^2-v*y*x]) - Closed subscheme of Product of projective spaces P^1 x P^1 over Rational - Field defined by: + sage: P. = ProductProjectiveSpaces([1, 1], QQ) + sage: P.subscheme([u*x^2 - v*y*x]) + Closed subscheme of Product of projective spaces P^1 x P^1 over Rational Field + defined by: x^2*u - x*y*v TESTS:: sage: from sage.schemes.product_projective.subscheme \ import AlgebraicScheme_subscheme_product_projective - sage: AlgebraicScheme_subscheme_product_projective(P, [u*x^2-v*y*x]) - Closed subscheme of Product of projective spaces P^1 x P^1 over Rational - Field defined by: + sage: AlgebraicScheme_subscheme_product_projective(P, [u*x^2 - v*y*x]) + Closed subscheme of Product of projective spaces P^1 x P^1 + over Rational Field defined by: x^2*u - x*y*v """ @@ -78,11 +78,11 @@ def segre_embedding(self, PP=None): EXAMPLES:: - sage: X. = ProductProjectiveSpaces([2,2], QQ) - sage: P = ProjectiveSpace(QQ,8,'t') + sage: X. = ProductProjectiveSpaces([2, 2], QQ) + sage: P = ProjectiveSpace(QQ, 8, 't') sage: L = (-w - v)*x + (-w*y - u*z) - sage: Q = (-u*w - v^2)*x^2 + ((-w^2 - u*w + (-u*v - u^2))*y + (-w^2 - u*v)*z)*x + \ - ((-w^2 - u*w - u^2)*y^2 + (-u*w - v^2)*z*y + (-w^2 + (-v - u)*w)*z^2) + sage: Q = ((-u*w - v^2)*x^2 + ((-w^2 - u*w + (-u*v - u^2))*y + (-w^2 - u*v)*z)*x + ....: + ((-w^2 - u*w - u^2)*y^2 + (-u*w - v^2)*z*y + (-w^2 + (-v - u)*w)*z^2)) sage: W = X.subscheme([L,Q]) sage: phi = W.segre_embedding(P) sage: phi.codomain().ambient_space() == P @@ -90,58 +90,39 @@ def segre_embedding(self, PP=None): :: - sage: PP. = ProductProjectiveSpaces([1,1,1], CC) + sage: PP. = ProductProjectiveSpaces([1, 1, 1], CC) sage: PP.subscheme([]).segre_embedding() Scheme morphism: From: Closed subscheme of Product of projective spaces P^1 x P^1 x P^1 - over Complex Field with 53 bits of precision defined by: - (no polynomials) - To: Closed subscheme of Projective Space of dimension 7 over Complex - Field with 53 bits of precision defined by: - -u5*u6 + u4*u7, - -u3*u6 + u2*u7, - -u3*u4 + u2*u5, - -u3*u5 + u1*u7, - -u3*u4 + u1*u6, - -u3*u4 + u0*u7, - -u2*u4 + u0*u6, - -u1*u4 + u0*u5, - -u1*u2 + u0*u3 + over Complex Field with 53 bits of precision defined by: + (no polynomials) + To: Closed subscheme of Projective Space of dimension 7 + over Complex Field with 53 bits of precision defined by: + -u5*u6 + u4*u7, -u3*u6 + u2*u7, -u3*u4 + u2*u5, + -u3*u5 + u1*u7, -u3*u4 + u1*u6, -u3*u4 + u0*u7, + -u2*u4 + u0*u6, -u1*u4 + u0*u5, -u1*u2 + u0*u3 Defn: Defined by sending (x : y , u : v , s : t) to (x*u*s : x*u*t : x*v*s : x*v*t : y*u*s : y*u*t : y*v*s : y*v*t). :: - sage: PP. = ProductProjectiveSpaces([2,1,1], ZZ) - sage: PP.subscheme([x^3, u-v, s^2-t^2]).segre_embedding() + sage: PP. = ProductProjectiveSpaces([2, 1, 1], ZZ) + sage: PP.subscheme([x^3, u - v, s^2 - t^2]).segre_embedding() Scheme morphism: From: Closed subscheme of Product of projective spaces P^2 x P^1 x P^1 - over Integer Ring defined by: - x^3, - u - v, - s^2 - t^2 - To: Closed subscheme of Projective Space of dimension 11 over - Integer Ring defined by: - u10^2 - u11^2, - u9 - u11, - u8 - u10, - -u7*u10 + u6*u11, - u6*u10 - u7*u11, - u6^2 - u7^2, - u5 - u7, - u4 - u6, - u3^3, - -u3*u10 + u2*u11, - u2*u10 - u3*u11, - -u3*u6 + u2*u7, - u2*u6 - u3*u7, - u2*u3^2, - u2^2 - u3^2, - u1 - u3, - u0 - u2 + over Integer Ring defined by: + x^3, u - v, s^2 - t^2 + To: Closed subscheme of Projective Space of dimension 11 + over Integer Ring defined by: + u10^2 - u11^2, u9 - u11, u8 - u10, + -u7*u10 + u6*u11, u6*u10 - u7*u11, u6^2 - u7^2, + u5 - u7, u4 - u6, u3^3, + -u3*u10 + u2*u11, u2*u10 - u3*u11, -u3*u6 + u2*u7, + u2*u6 - u3*u7, u2*u3^2, u2^2 - u3^2, + u1 - u3, u0 - u2 Defn: Defined by sending (x : y : z , u : v , s : t) to - (x*u*s : x*u*t : x*v*s : x*v*t : y*u*s : y*u*t : y*v*s : y*v*t : - z*u*s : z*u*t : z*v*s : z*v*t). + (x*u*s : x*u*t : x*v*s : x*v*t : y*u*s : y*u*t : y*v*s : y*v*t + : z*u*s : z*u*t : z*v*s : z*v*t). """ AS = self.ambient_space() CR = AS.coordinate_ring() @@ -205,43 +186,41 @@ def dimension(self): r""" Return the dimension of the algebraic subscheme. - OUTPUT: - - Integer. + OUTPUT: An integer. EXAMPLES:: - sage: X. = ProductProjectiveSpaces([2,2],QQ) + sage: X. = ProductProjectiveSpaces([2, 2], QQ) sage: L = (-w - v)*x + (-w*y - u*z) - sage: Q = (-u*w - v^2)*x^2 + ((-w^2 - u*w + (-u*v - u^2))*y + (-w^2 - u*v)*z)*x + \ - ((-w^2 - u*w - u^2)*y^2 + (-u*w - v^2)*z*y + (-w^2 + (-v - u)*w)*z^2) - sage: W = X.subscheme([L,Q]) + sage: Q = ((-u*w - v^2)*x^2 + ((-w^2 - u*w + (-u*v - u^2))*y + (-w^2 - u*v)*z)*x + ....: + ((-w^2 - u*w - u^2)*y^2 + (-u*w - v^2)*z*y + (-w^2 + (-v - u)*w)*z^2)) + sage: W = X.subscheme([L, Q]) sage: W.dimension() 2 :: - sage: PP. = ProductProjectiveSpaces([2,1,1], QQ) - sage: X = PP.subscheme([x^3, x^5+y^5, z^6, x*u-v*y, s^2-t^2]) + sage: PP. = ProductProjectiveSpaces([2, 1, 1], QQ) + sage: X = PP.subscheme([x^3, x^5 + y^5, z^6, x*u - v*y, s^2 - t^2]) sage: X.dimension() -1 :: - sage: PP = ProductProjectiveSpaces([2,1,3], CC, 't') + sage: PP = ProductProjectiveSpaces([2, 1, 3], CC, 't') sage: PP.subscheme([]).dimension() 6 :: - sage: PP = ProductProjectiveSpaces([1,3,1], ZZ, 't') + sage: PP = ProductProjectiveSpaces([1, 3, 1], ZZ, 't') sage: PP.subscheme([]).dimension() 5 :: sage: PP. = ProductProjectiveSpaces([1,1,1], CC) - sage: X = PP.subscheme([x^2-y^2, u-v, s^2-t^2]) + sage: X = PP.subscheme([x^2 - y^2, u - v, s^2 - t^2]) sage: X.dimension() 0 """ @@ -270,11 +249,11 @@ def is_smooth(self, point=None): EXAMPLES:: - sage: X. = ProductProjectiveSpaces([2,2],QQ) + sage: X. = ProductProjectiveSpaces([2, 2],QQ) sage: L = (-w - v)*x + (-w*y - u*z) - sage: Q = (-u*w - v^2)*x^2 + ((-w^2 - u*w + (-u*v - u^2))*y + (-w^2 - u*v)*z)*x + \ - ((-w^2 - u*w - u^2)*y^2 + (-u*w - v^2)*z*y + (-w^2 + (-v - u)*w)*z^2) - sage: W = X.subscheme([L,Q]) + sage: Q = ((-u*w - v^2)*x^2 + ((-w^2 - u*w + (-u*v - u^2))*y + (-w^2 - u*v)*z)*x + ....: + ((-w^2 - u*w - u^2)*y^2 + (-u*w - v^2)*z*y + (-w^2 + (-v - u)*w)*z^2)) + sage: W = X.subscheme([L, Q]) sage: W.is_smooth() Traceback (most recent call last): ... @@ -285,7 +264,7 @@ def is_smooth(self, point=None): def affine_patch(self, I, return_embedding=False): r""" Return the `I^{th}` affine patch of this projective scheme - where 'I' is a multi-index. + where `I` is a multi-index. INPUT: @@ -301,21 +280,18 @@ def affine_patch(self, I, return_embedding=False): EXAMPLES:: - sage: PP. = ProductProjectiveSpaces([3,1],QQ) - sage: W = PP.subscheme([y^2*z-x^3,z^2-w^2,u^3-v^3]) - sage: W.affine_patch([0,1],True) + sage: PP. = ProductProjectiveSpaces([3, 1],QQ) + sage: W = PP.subscheme([y^2*z - x^3, z^2 - w^2, u^3 - v^3]) + sage: W.affine_patch([0, 1], True) (Closed subscheme of Affine Space of dimension 4 over Rational Field defined by: x0^2*x1 - 1, x1^2 - x2^2, - x3^3 - 1, Scheme morphism: - From: Closed subscheme of Affine Space of dimension 4 over Rational Field defined by: - x0^2*x1 - 1, - x1^2 - x2^2, - x3^3 - 1 - To: Closed subscheme of Product of projective spaces P^3 x P^1 over Rational Field defined by: - -x^3 + y^2*z, - z^2 - w^2, - u^3 - v^3 + x3^3 - 1, + Scheme morphism: + From: Closed subscheme of Affine Space of dimension 4 + over Rational Field defined by: x0^2*x1 - 1, x1^2 - x2^2, x3^3 - 1 + To: Closed subscheme of Product of projective spaces P^3 x P^1 + over Rational Field defined by: -x^3 + y^2*z, z^2 - w^2, u^3 - v^3 Defn: Defined on coordinates by sending (x0, x1, x2, x3) to (1 : x0 : x1 : x2 , x3 : 1)) """ @@ -377,7 +353,7 @@ def intersection_multiplicity(self, X, P): Multiplicity of a fixed point of the map `z^2 + \frac{1}{4}`:: - sage: PP. = ProductProjectiveSpaces(QQ, [1,1]) + sage: PP. = ProductProjectiveSpaces(QQ, [1, 1]) sage: G = PP.subscheme([(x^2 + 1/4*y^2)*v - y^2*u]) sage: D = PP.subscheme([x*v - y*u]) sage: sorted(G.intersection(D).rational_points()) @@ -388,17 +364,17 @@ def intersection_multiplicity(self, X, P): :: - sage: F. = GF(4) - sage: PP. = ProductProjectiveSpaces(F, [2,2]) - sage: X = PP.subscheme([z^5 + 3*x*y^4 + 8*y^5, u^2 - v^2]) - sage: Y = PP.subscheme([x^6 + z^6, w*z - v*y]) - sage: Q = PP([a,a+1,1,a,a,1]) - sage: X.intersection_multiplicity(Y, Q) + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: PP. = ProductProjectiveSpaces(F, [2, 2]) # optional - sage.rings.finite_rings + sage: X = PP.subscheme([z^5 + 3*x*y^4 + 8*y^5, u^2 - v^2]) # optional - sage.rings.finite_rings + sage: Y = PP.subscheme([x^6 + z^6, w*z - v*y]) # optional - sage.rings.finite_rings + sage: Q = PP([a,a+1,1,a,a,1]) # optional - sage.rings.finite_rings + sage: X.intersection_multiplicity(Y, Q) # optional - sage.rings.finite_rings 16 :: - sage: PP. = ProductProjectiveSpaces(QQ, [2,2]) + sage: PP. = ProductProjectiveSpaces(QQ, [2, 2]) sage: X = PP.subscheme([x^2*u^3 + y*z*u*v^2, x - y]) sage: Y = PP.subscheme([u^3 - w^3, x*v - y*w, z^3*w^2 - y^3*u*v]) sage: Q = PP([0,0,1,0,1,0]) @@ -441,11 +417,11 @@ def multiplicity(self, P): - ``P`` -- a point on this subscheme. - OUTPUT: an integer. + OUTPUT: An integer. EXAMPLES:: - sage: PP. = ProductProjectiveSpaces(QQ, [1,1]) + sage: PP. = ProductProjectiveSpaces(QQ, [1, 1]) sage: X = PP.subscheme([x^4*z^3 - y^4*w^3]) sage: Q1 = PP([1,1,1,1]) sage: X.multiplicity(Q1) @@ -456,13 +432,13 @@ def multiplicity(self, P): :: - sage: PP. = ProductProjectiveSpaces(GF(11), [1,2]) - sage: X = PP.subscheme([x^7*u - y^7*z, u^6*x^2 - w^3*z^3*x*y - w^6*y^2]) - sage: Q1 = PP([1,0,10,1,0]) - sage: X.multiplicity(Q1) + sage: PP. = ProductProjectiveSpaces(GF(11), [1,2]) # optional - sage.rings.finite_rings + sage: X = PP.subscheme([x^7*u - y^7*z, u^6*x^2 - w^3*z^3*x*y - w^6*y^2]) # optional - sage.rings.finite_rings + sage: Q1 = PP([1,0,10,1,0]) # optional - sage.rings.finite_rings + sage: X.multiplicity(Q1) # optional - sage.rings.finite_rings 1 - sage: Q2 = PP([1,0,1,0,0]) - sage: X.multiplicity(Q2) + sage: Q2 = PP([1,0,1,0,0]) # optional - sage.rings.finite_rings + sage: X.multiplicity(Q2) # optional - sage.rings.finite_rings 4 """ PP = self.ambient_space() diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 2f90e1cc1f9..dad84b0000c 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -101,11 +101,11 @@ def IQ_points_of_bounded_height(PN, K, dim, bound): EXAMPLES: sage: from sage.schemes.projective.proj_bdd_height import IQ_points_of_bounded_height - sage: CF. = CyclotomicField(3) - sage: P. = ProjectiveSpace(CF, 2) - sage: len(list(IQ_points_of_bounded_height(P, CF, 2, -1))) + sage: CF. = CyclotomicField(3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(CF, 2) # optional - sage.rings.number_field + sage: len(list(IQ_points_of_bounded_height(P, CF, 2, -1))) # optional - sage.rings.number_field 0 - sage: len(list(IQ_points_of_bounded_height(P, CF, 2, 1))) + sage: len(list(IQ_points_of_bounded_height(P, CF, 2, 1))) # optional - sage.rings.number_field 57 """ if bound < 1: @@ -181,9 +181,9 @@ def points_of_bounded_height(PN, K, dim, bound, prec=53): EXAMPLES: 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(P, K, 2, 1))) + sage: K. = NumberField(x^3 - 7) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: len(list(points_of_bounded_height(P, K, 2, 1))) # optional - sage.rings.number_field 13 """ if bound < 1: diff --git a/src/sage/schemes/projective/projective_homset.py b/src/sage/schemes/projective/projective_homset.py index 3ee0b78876e..c11736d7b25 100644 --- a/src/sage/schemes/projective/projective_homset.py +++ b/src/sage/schemes/projective/projective_homset.py @@ -83,17 +83,17 @@ def points(self, **kwds): kwds: - - ``bound`` - real number (optional, default=0). The bound for the coordinates for + - ``bound`` - real number (optional, default: 0). The bound for the coordinates for subschemes with dimension at least 1. - - ``precision`` - integer (optional, default=53). The precision to use to + - ``precision`` - integer (optional, default: 53). The precision to use to compute the elements of bounded height for number fields. - - ``point_tolerance`` - positive real number (optional, default=10^(-10)). + - ``point_tolerance`` - positive real number (optional, default: `10^{-10}`). For numerically inexact fields, two points are considered the same if their coordinates are within tolerance. - - ``zero_tolerance`` - positive real number (optional, default=10^(-10)). + - ``zero_tolerance`` - positive real number (optional, default: `10^{-10}`). For numerically inexact fields, points are on the subscheme if they satisfy the equations to within tolerance. @@ -112,48 +112,49 @@ def points(self, **kwds): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,1) + sage: P. = ProjectiveSpace(QQ, 1) sage: P(QQ).points(bound=4) [(-4 : 1), (-3 : 1), (-2 : 1), (-3/2 : 1), (-4/3 : 1), (-1 : 1), - (-3/4 : 1), (-2/3 : 1), (-1/2 : 1), (-1/3 : 1), (-1/4 : 1), (0 : 1), - (1/4 : 1), (1/3 : 1), (1/2 : 1), (2/3 : 1), (3/4 : 1), (1 : 0), (1 : 1), - (4/3 : 1), (3/2 : 1), (2 : 1), (3 : 1), (4 : 1)] + (-3/4 : 1), (-2/3 : 1), (-1/2 : 1), (-1/3 : 1), (-1/4 : 1), (0 : 1), + (1/4 : 1), (1/3 : 1), (1/2 : 1), (2/3 : 1), (3/4 : 1), (1 : 0), (1 : 1), + (4/3 : 1), (3/2 : 1), (2 : 1), (3 : 1), (4 : 1)] :: sage: u = QQ['u'].0 - sage: K. = NumberField(u^2 + 3) - sage: P. = ProjectiveSpace(K,2) - sage: len(P(K).points(bound=1.8)) + sage: K. = NumberField(u^2 + 3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: len(P(K).points(bound=1.8)) # optional - sage.rings.number_field 309 :: - sage: P1 = ProjectiveSpace(GF(2),1) - sage: F. = GF(4,'a') - sage: P1(F).points() + sage: P1 = ProjectiveSpace(GF(2), 1) # optional - sage.rings.finite_rings + sage: F. = GF(4, 'a') # optional - sage.rings.finite_rings + sage: P1(F).points() # optional - sage.rings.finite_rings [(0 : 1), (1 : 0), (1 : 1), (a : 1), (a + 1 : 1)] :: - sage: P. = ProjectiveSpace(QQ,2) - sage: E = P.subscheme([(y^3-y*z^2) - (x^3-x*z^2),(y^3-y*z^2) + (x^3-x*z^2)]) + sage: P. = ProjectiveSpace(QQ, 2) + sage: E = P.subscheme([(y^3-y*z^2) - (x^3-x*z^2), (y^3-y*z^2) + (x^3-x*z^2)]) sage: E(P.base_ring()).points() - [(-1 : -1 : 1), (-1 : 0 : 1), (-1 : 1 : 1), (0 : -1 : 1), (0 : 0 : 1), (0 : 1 : 1), - (1 : -1 : 1), (1 : 0 : 1), (1 : 1 : 1)] + [(-1 : -1 : 1), (-1 : 0 : 1), (-1 : 1 : 1), (0 : -1 : 1), (0 : 0 : 1), + (0 : 1 : 1), (1 : -1 : 1), (1 : 0 : 1), (1 : 1 : 1)] :: sage: P. = ProjectiveSpace(CC, 2) sage: E = P.subscheme([y^3 - x^3 - x*z^2, x*y*z]) - sage: L=E(P.base_ring()).points(); sorted(L, key=str) - verbose 0 (...: projective_homset.py, points) Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly. + sage: L = E(P.base_ring()).points(); sorted(L, key=str) + verbose 0 (...: projective_homset.py, points) Warning: computations in + the numerical fields are inexact;points may be computed partially or incorrectly. [(-0.500000000000000 + 0.866025403784439*I : 1.00000000000000 : 0.000000000000000), - (-0.500000000000000 - 0.866025403784439*I : 1.00000000000000 : 0.000000000000000), - (-1.00000000000000*I : 0.000000000000000 : 1.00000000000000), - (0.000000000000000 : 0.000000000000000 : 1.00000000000000), - (1.00000000000000 : 1.00000000000000 : 0.000000000000000), - (1.00000000000000*I : 0.000000000000000 : 1.00000000000000)] + (-0.500000000000000 - 0.866025403784439*I : 1.00000000000000 : 0.000000000000000), + (-1.00000000000000*I : 0.000000000000000 : 1.00000000000000), + (0.000000000000000 : 0.000000000000000 : 1.00000000000000), + (1.00000000000000 : 1.00000000000000 : 0.000000000000000), + (1.00000000000000*I : 0.000000000000000 : 1.00000000000000)] sage: L[0].codomain() Projective Space of dimension 2 over Complex Field with 53 bits of precision @@ -162,7 +163,8 @@ def points(self, **kwds): sage: P. = ProjectiveSpace(CDF, 2) sage: E = P.subscheme([y^2 + x^2 + z^2, x*y*z]) sage: len(E(P.base_ring()).points()) - verbose 0 (...: projective_homset.py, points) Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly. + verbose 0 (...: projective_homset.py, points) Warning: computations in + the numerical fields are inexact;points may be computed partially or incorrectly. 6 """ from sage.schemes.projective.projective_space import is_ProjectiveSpace @@ -305,11 +307,11 @@ def numerical_points(self, F=None, **kwds): kwds: - - ``point_tolerance`` - positive real number (optional, default=10^(-10)). + - ``point_tolerance`` - positive real number (optional, default: `10^{-10}`). For numerically inexact fields, two points are considered the same if their coordinates are within tolerance. - - ``zero_tolerance`` - positive real number (optional, default=10^(-10)). + - ``zero_tolerance`` - positive real number (optional, default: `10^{-10}`). For numerically inexact fields, points are on the subscheme if they satisfy the equations to within tolerance. @@ -333,10 +335,10 @@ def numerical_points(self, F=None, **kwds): :: sage: S. = QQ[] - sage: K. = NumberField(a^5 - 7, embedding=CC((7)**(1/5))) - sage: P. = ProjectiveSpace(K,2) - sage: X = P.subscheme([x^2 - v^2*z^2, y-v*z]) - sage: len(X(K).numerical_points(F=CDF)) + sage: K. = NumberField(a^5 - 7, embedding=CC((7)**(1/5))) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: X = P.subscheme([x^2 - v^2*z^2, y - v*z]) # optional - sage.rings.number_field + sage: len(X(K).numerical_points(F=CDF)) # optional - sage.rings.number_field 2 :: @@ -488,36 +490,35 @@ def points(self, B=0): EXAMPLES:: sage: from sage.schemes.projective.projective_homset import SchemeHomset_points_projective_ring - sage: H = SchemeHomset_points_projective_ring(Spec(ZZ), ProjectiveSpace(ZZ,2)) + sage: H = SchemeHomset_points_projective_ring(Spec(ZZ), ProjectiveSpace(ZZ, 2)) sage: H.points(3) - [(0 : 0 : 1), (0 : 1 : -3), (0 : 1 : -2), (0 : 1 : -1), (0 : 1 : 0), (0 - : 1 : 1), (0 : 1 : 2), (0 : 1 : 3), (0 : 2 : -3), (0 : 2 : -1), (0 : 2 : - 1), (0 : 2 : 3), (0 : 3 : -2), (0 : 3 : -1), (0 : 3 : 1), (0 : 3 : 2), - (1 : -3 : -3), (1 : -3 : -2), (1 : -3 : -1), (1 : -3 : 0), (1 : -3 : 1), - (1 : -3 : 2), (1 : -3 : 3), (1 : -2 : -3), (1 : -2 : -2), (1 : -2 : -1), - (1 : -2 : 0), (1 : -2 : 1), (1 : -2 : 2), (1 : -2 : 3), (1 : -1 : -3), - (1 : -1 : -2), (1 : -1 : -1), (1 : -1 : 0), (1 : -1 : 1), (1 : -1 : 2), - (1 : -1 : 3), (1 : 0 : -3), (1 : 0 : -2), (1 : 0 : -1), (1 : 0 : 0), (1 - : 0 : 1), (1 : 0 : 2), (1 : 0 : 3), (1 : 1 : -3), (1 : 1 : -2), (1 : 1 : - -1), (1 : 1 : 0), (1 : 1 : 1), (1 : 1 : 2), (1 : 1 : 3), (1 : 2 : -3), - (1 : 2 : -2), (1 : 2 : -1), (1 : 2 : 0), (1 : 2 : 1), (1 : 2 : 2), (1 : - 2 : 3), (1 : 3 : -3), (1 : 3 : -2), (1 : 3 : -1), (1 : 3 : 0), (1 : 3 : - 1), (1 : 3 : 2), (1 : 3 : 3), (2 : -3 : -3), (2 : -3 : -2), (2 : -3 : - -1), (2 : -3 : 0), (2 : -3 : 1), (2 : -3 : 2), (2 : -3 : 3), (2 : -2 : - -3), (2 : -2 : -1), (2 : -2 : 1), (2 : -2 : 3), (2 : -1 : -3), (2 : -1 : - -2), (2 : -1 : -1), (2 : -1 : 0), (2 : -1 : 1), (2 : -1 : 2), (2 : -1 : - 3), (2 : 0 : -3), (2 : 0 : -1), (2 : 0 : 1), (2 : 0 : 3), (2 : 1 : -3), - (2 : 1 : -2), (2 : 1 : -1), (2 : 1 : 0), (2 : 1 : 1), (2 : 1 : 2), (2 : - 1 : 3), (2 : 2 : -3), (2 : 2 : -1), (2 : 2 : 1), (2 : 2 : 3), (2 : 3 : - -3), (2 : 3 : -2), (2 : 3 : -1), (2 : 3 : 0), (2 : 3 : 1), (2 : 3 : 2), - (2 : 3 : 3), (3 : -3 : -2), (3 : -3 : -1), (3 : -3 : 1), (3 : -3 : 2), - (3 : -2 : -3), (3 : -2 : -2), (3 : -2 : -1), (3 : -2 : 0), (3 : -2 : 1), - (3 : -2 : 2), (3 : -2 : 3), (3 : -1 : -3), (3 : -1 : -2), (3 : -1 : -1), - (3 : -1 : 0), (3 : -1 : 1), (3 : -1 : 2), (3 : -1 : 3), (3 : 0 : -2), (3 - : 0 : -1), (3 : 0 : 1), (3 : 0 : 2), (3 : 1 : -3), (3 : 1 : -2), (3 : 1 - : -1), (3 : 1 : 0), (3 : 1 : 1), (3 : 1 : 2), (3 : 1 : 3), (3 : 2 : -3), - (3 : 2 : -2), (3 : 2 : -1), (3 : 2 : 0), (3 : 2 : 1), (3 : 2 : 2), (3 : - 2 : 3), (3 : 3 : -2), (3 : 3 : -1), (3 : 3 : 1), (3 : 3 : 2)] + [(0 : 0 : 1), (0 : 1 : -3), (0 : 1 : -2), (0 : 1 : -1), (0 : 1 : 0), (0 : 1 : 1), + (0 : 1 : 2), (0 : 1 : 3), (0 : 2 : -3), (0 : 2 : -1), (0 : 2 : 1), (0 : 2 : 3), + (0 : 3 : -2), (0 : 3 : -1), (0 : 3 : 1), (0 : 3 : 2), (1 : -3 : -3), + (1 : -3 : -2), (1 : -3 : -1), (1 : -3 : 0), (1 : -3 : 1), (1 : -3 : 2), + (1 : -3 : 3), (1 : -2 : -3), (1 : -2 : -2), (1 : -2 : -1), (1 : -2 : 0), + (1 : -2 : 1), (1 : -2 : 2), (1 : -2 : 3), (1 : -1 : -3), (1 : -1 : -2), + (1 : -1 : -1), (1 : -1 : 0), (1 : -1 : 1), (1 : -1 : 2), (1 : -1 : 3), + (1 : 0 : -3), (1 : 0 : -2), (1 : 0 : -1), (1 : 0 : 0), (1 : 0 : 1), (1 : 0 : 2), + (1 : 0 : 3), (1 : 1 : -3), (1 : 1 : -2), (1 : 1 : -1), (1 : 1 : 0), (1 : 1 : 1), + (1 : 1 : 2), (1 : 1 : 3), (1 : 2 : -3), (1 : 2 : -2), (1 : 2 : -1), (1 : 2 : 0), + (1 : 2 : 1), (1 : 2 : 2), (1 : 2 : 3), (1 : 3 : -3), (1 : 3 : -2), (1 : 3 : -1), + (1 : 3 : 0), (1 : 3 : 1), (1 : 3 : 2), (1 : 3 : 3), (2 : -3 : -3), + (2 : -3 : -2), (2 : -3 : -1), (2 : -3 : 0), (2 : -3 : 1), (2 : -3 : 2), + (2 : -3 : 3), (2 : -2 : -3), (2 : -2 : -1), (2 : -2 : 1), (2 : -2 : 3), + (2 : -1 : -3), (2 : -1 : -2), (2 : -1 : -1), (2 : -1 : 0), (2 : -1 : 1), + (2 : -1 : 2), (2 : -1 : 3), (2 : 0 : -3), (2 : 0 : -1), (2 : 0 : 1), + (2 : 0 : 3), (2 : 1 : -3), (2 : 1 : -2), (2 : 1 : -1), (2 : 1 : 0), (2 : 1 : 1), + (2 : 1 : 2), (2 : 1 : 3), (2 : 2 : -3), (2 : 2 : -1), (2 : 2 : 1), (2 : 2 : 3), + (2 : 3 : -3), (2 : 3 : -2), (2 : 3 : -1), (2 : 3 : 0), (2 : 3 : 1), (2 : 3 : 2), + (2 : 3 : 3), (3 : -3 : -2), (3 : -3 : -1), (3 : -3 : 1), (3 : -3 : 2), + (3 : -2 : -3), (3 : -2 : -2), (3 : -2 : -1), (3 : -2 : 0), (3 : -2 : 1), + (3 : -2 : 2), (3 : -2 : 3), (3 : -1 : -3), (3 : -1 : -2), (3 : -1 : -1), + (3 : -1 : 0), (3 : -1 : 1), (3 : -1 : 2), (3 : -1 : 3), (3 : 0 : -2), + (3 : 0 : -1), (3 : 0 : 1), (3 : 0 : 2), (3 : 1 : -3), (3 : 1 : -2), + (3 : 1 : -1), (3 : 1 : 0), (3 : 1 : 1), (3 : 1 : 2), (3 : 1 : 3), (3 : 2 : -3), + (3 : 2 : -2), (3 : 2 : -1), (3 : 2 : 0), (3 : 2 : 1), (3 : 2 : 2), (3 : 2 : 3), + (3 : 3 : -2), (3 : 3 : -1), (3 : 3 : 1), (3 : 3 : 2)] """ R = self.value_ring() if R == ZZ: @@ -578,23 +579,23 @@ class SchemeHomset_points_abelian_variety_field(SchemeHomset_points_projective_f The bug reported at :trac:`1785` is fixed:: - sage: K. = NumberField(x^2 + x - (3^3-3)) - sage: E = EllipticCurve('37a') - sage: X = E(K) - sage: X - Abelian group of points on Elliptic Curve defined by - y^2 + y = x^3 + (-1)*x over Number Field in a with - defining polynomial x^2 + x - 24 - sage: P = X([3,a]) - sage: P + sage: K. = NumberField(x^2 + x - (3^3-3)) # optional - sage.rings.number_field + sage: E = EllipticCurve('37a') # optional - sage.rings.number_field + sage: X = E(K) # optional - sage.rings.number_field + sage: X # optional - sage.rings.number_field + Abelian group of points on + Elliptic Curve defined by y^2 + y = x^3 + (-1)*x + over Number Field in a with defining polynomial x^2 + x - 24 + sage: P = X([3,a]) # optional - sage.rings.number_field + sage: P # optional - sage.rings.number_field (3 : a : 1) - sage: P in E + sage: P in E # optional - sage.rings.number_field False - sage: P in E.base_extend(K) + sage: P in E.base_extend(K) # optional - sage.rings.number_field True - sage: P in X.codomain() + sage: P in X.codomain() # optional - sage.rings.number_field False - sage: P in X.extended_codomain() + sage: P in X.extended_codomain() # optional - sage.rings.number_field True Check for :trac:`11982`:: @@ -677,7 +678,7 @@ def base_extend(self, R): sage: E = EllipticCurve('37a') sage: Hom = E.point_homset(); Hom Abelian group of points on Elliptic Curve defined - by y^2 + y = x^3 - x over Rational Field + by y^2 + y = x^3 - x over Rational Field sage: Hom.base_ring() Rational Field sage: Hom.base_extend(QQ) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 9c608f67a48..43e51dac3c3 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -15,14 +15,12 @@ sage: A2. = AffineSpace(QQ, 2) sage: P2.hom([x0, x1, x1 + x2], P2) Scheme endomorphism of Projective Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x0 : x1 : x2) to - (x0 : x1 : x1 + x2) + Defn: Defined on coordinates by sending (x0 : x1 : x2) to (x0 : x1 : x1 + x2) sage: P2.hom([x1/x0, (x1 + x2)/x0], A2) Scheme morphism: From: Projective Space of dimension 2 over Rational Field To: Affine Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x0 : x1 : x2) to - (x1/x0, (x1 + x2)/x0) + Defn: Defined on coordinates by sending (x0 : x1 : x2) to (x1/x0, (x1 + x2)/x0) AUTHORS: @@ -112,14 +110,14 @@ class SchemeMorphism_polynomial_projective_space(SchemeMorphism_polynomial): An example of a morphism between projective plane curves (see :trac:`10297`):: - sage: P2. = ProjectiveSpace(QQ,2) - sage: f = x^3+y^3+60*z^3 - sage: g = y^2*z-( x^3 - 6400*z^3/3) + sage: P2. = ProjectiveSpace(QQ, 2) + sage: f = x^3 + y^3 + 60*z^3 + sage: g = y^2*z - (x^3 - 6400*z^3/3) sage: C = Curve(f) sage: E = Curve(g) sage: xbar,ybar,zbar = C.coordinate_ring().gens() sage: H = C.Hom(E) - sage: H([zbar,xbar-ybar,-(xbar+ybar)/80]) + sage: H([zbar, xbar - ybar, -(xbar+ybar)/80]) Scheme morphism: From: Projective Plane Curve over Rational Field defined by x^3 + y^3 + 60*z^3 To: Projective Plane Curve over Rational Field defined by -x^3 + y^2*z + 6400/3*z^3 @@ -129,32 +127,31 @@ class SchemeMorphism_polynomial_projective_space(SchemeMorphism_polynomial): A more complicated example:: sage: P2. = ProjectiveSpace(2, QQ) - sage: P1 = P2.subscheme(x-y) + sage: P1 = P2.subscheme(x - y) sage: H12 = P1.Hom(P2) sage: H12([x^2, x*z, z^2]) Scheme morphism: - From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x - y + From: Closed subscheme of Projective Space of dimension 2 over Rational Field + defined by: x - y To: Projective Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x : y : z) to - (x^2 : x*z : z^2) + Defn: Defined on coordinates by sending (x : y : z) to (x^2 : x*z : z^2) We illustrate some error checking:: sage: R. = QQ[] sage: P1 = ProjectiveSpace(R) sage: H = P1.Hom(P1) - sage: f = H([x-y, x*y]) + sage: f = H([x - y, x*y]) Traceback (most recent call last): ... ValueError: polys (=[x - y, x*y]) must be of the same degree - sage: H([x-1, x*y+x]) + sage: H([x - 1, x*y + x]) Traceback (most recent call last): ... ValueError: polys (=[x - 1, x*y + x]) must be homogeneous - sage: H([exp(x),exp(y)]) + sage: H([exp(x), exp(y)]) Traceback (most recent call last): ... TypeError: polys (=[e^x, e^y]) must be elements of @@ -172,7 +169,7 @@ class SchemeMorphism_polynomial_projective_space(SchemeMorphism_polynomial): sage: X = P.subscheme(y-z) sage: f(f(f(X))) Closed subscheme of Projective Space of dimension 2 over Rational Field - defined by: + defined by: y - z :: @@ -182,7 +179,7 @@ class SchemeMorphism_polynomial_projective_space(SchemeMorphism_polynomial): sage: f = H([(x-2*y)^2, (x-2*z)^2, (x-2*w)^2, x^2]) sage: f(P.subscheme([x,y,z])) Closed subscheme of Projective Space of dimension 3 over Rational Field - defined by: + defined by: w, y, x @@ -207,22 +204,20 @@ def __init__(self, parent, polys, check=True): sage: X = P.subscheme([x]) sage: H = End(X) sage: H([x^2, t*y^2, x*z]) - Scheme endomorphism of Closed subscheme of Projective Space of dimension - 2 over Univariate Polynomial Ring in t over Rational Field defined by: - x + Scheme endomorphism of Closed subscheme of Projective Space of dimension 2 + over Univariate Polynomial Ring in t over Rational Field defined by: x Defn: Defined on coordinates by sending (x : y : z) to (x^2 : t*y^2 : x*z) When elements of the quotient ring is used, they are reduced:: sage: P. = ProjectiveSpace(CC, 2) - sage: X = P.subscheme([x-y]) + sage: X = P.subscheme([x - y]) sage: u,v,w = X.coordinate_ring().gens() sage: H = End(X) sage: H([u^2, v^2, w*u]) - Scheme endomorphism of Closed subscheme of Projective Space of dimension - 2 over Complex Field with 53 bits of precision defined by: - x - y + Scheme endomorphism of Closed subscheme of Projective Space of dimension 2 + over Complex Field with 53 bits of precision defined by: x - y Defn: Defined on coordinates by sending (x : y : z) to (y^2 : y^2 : y*z) """ @@ -301,14 +296,14 @@ def __call__(self, x, check=True): sage: P. = ProjectiveSpace(QQ, 2) sage: H = End(P) - sage: f = H([x^2+y^2, y^2, z^2 + y*z]) + sage: f = H([x^2 + y^2, y^2, z^2 + y*z]) sage: f(P([1,1,1])) (1 : 1/2 : 1) :: sage: PS. = ProjectiveSpace(QQ, 2) - sage: P1. = ProjectiveSpace(QQ,1) + sage: P1. = ProjectiveSpace(QQ, 1) sage: H = End(P1) sage: f = H([u^2, v^2]) sage: f(PS([0,1,1])) @@ -333,7 +328,7 @@ def __call__(self, x, check=True): sage: PS. = ProjectiveSpace(QQ, 3) sage: H = End(PS) sage: f = H([y^2, x^2, w^2, z^2]) - sage: X = PS.subscheme([z^2+y*w]) + sage: X = PS.subscheme([z^2 + y*w]) sage: f(X) Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: @@ -345,7 +340,7 @@ def __call__(self, x, check=True): sage: P1. = ProjectiveSpace(ZZ, 1) sage: H = End(PS) sage: f = H([x^2, y^2, z^2]) - sage: X = P1.subscheme([u-v]) + sage: X = P1.subscheme([u - v]) sage: f(X) Traceback (most recent call last): ... @@ -360,7 +355,7 @@ def __call__(self, x, check=True): sage: f([u-v]) Closed subscheme of Projective Space of dimension 1 over Integer Ring defined by: u - v - sage: X = PS.subscheme([x-z]) + sage: X = PS.subscheme([x - z]) sage: f([x-z]) Traceback (most recent call last): ... @@ -380,13 +375,13 @@ def __call__(self, x, check=True): Defn: Defined on coordinates by sending (u : v) to (u^2 + v^2 : u*v) - sage: F. = GF(4) - sage: P = T(F)(1, a) - sage: h(P) + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: P = T(F)(1, a) # optional - sage.rings.finite_rings + sage: h(P) # optional - sage.rings.finite_rings (a : a) - sage: h(P).domain() + sage: h(P).domain() # optional - sage.rings.finite_rings Spectrum of Finite Field in a of size 2^2 - sage: h.change_ring(F)(P) + sage: h.change_ring(F)(P) # optional - sage.rings.finite_rings (1 : 1) """ from sage.schemes.projective.projective_point import SchemeMorphism_point_projective_ring @@ -425,11 +420,12 @@ def _fastpolys(self): EXAMPLES:: - sage: P.=ProjectiveSpace(QQ,1) + sage: P. = ProjectiveSpace(QQ, 1) sage: H = Hom(P,P) - sage: f = H([x^2+y^2,y^2]) + sage: f = H([x^2 + y^2, y^2]) sage: [g.op_list() for g in f._fastpolys] - [[('load_const', 0), ('load_const', 1), ('load_arg', ...), ('ipow', 2), 'mul', 'add', ('load_const', 1), ('load_arg', ...), ('ipow', 2), 'mul', 'add', 'return'], [('load_const', 0), ('load_const', 1), ('load_arg', 1), ('ipow', 2), 'mul', 'add', 'return']] + [[('load_const', 0), ('load_const', 1), ('load_arg', ...), ('ipow', 2), 'mul', 'add', ('load_const', 1), ('load_arg', ...), ('ipow', 2), 'mul', 'add', 'return'], + [('load_const', 0), ('load_const', 1), ('load_arg', 1), ('ipow', 2), 'mul', 'add', 'return']] """ polys = self._polys @@ -460,18 +456,18 @@ def _fast_eval(self, x): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,2) - sage: H = Hom(P,P) - sage: f = H([x^2+y^2, y^2, z^2 + y*z]) + sage: P. = ProjectiveSpace(QQ, 2) + sage: H = Hom(P, P) + sage: f = H([x^2 + y^2, y^2, z^2 + y*z]) sage: f._fast_eval([1,1,1]) [2, 1, 2] :: sage: T. = LaurentSeriesRing(ZZ) - sage: P. = ProjectiveSpace(T,1) + sage: P. = ProjectiveSpace(T, 1) sage: H = End(P) - sage: f = H([x^2+x*y, y^2]) + sage: f = H([x^2 + x*y, y^2]) sage: Q = P(z,1) sage: f._fast_eval(list(Q)) [z + z^2, 1] @@ -480,9 +476,9 @@ def _fast_eval(self, x): sage: T. = PolynomialRing(CC) sage: I = T.ideal(z^3) - sage: P. = ProjectiveSpace(T.quotient_ring(I),1) + sage: P. = ProjectiveSpace(T.quotient_ring(I), 1) sage: H = End(P) - sage: f = H([x^2+x*y, y^2]) + sage: f = H([x^2 + x*y, y^2]) sage: Q = P(z^2, 1) sage: f._fast_eval(list(Q)) [zbar^2, 1.00000000000000] @@ -493,7 +489,7 @@ def _fast_eval(self, x): sage: R. = PolynomialRing(T) sage: P. = ProjectiveSpace(R,1) sage: H = End(P) - sage: f = H([x^2+x*y, y^2]) + sage: f = H([x^2 + x*y, y^2]) sage: Q = P(t^2, z) sage: f._fast_eval(list(Q)) [t^4 + z*t^2, z^2] @@ -517,8 +513,8 @@ def __eq__(self, right): EXAMPLES:: sage: P. = ProjectiveSpace(QQ, 2) - sage: H = Hom(P,P) - sage: f = H([x^2 - 2*x*y + z*x, z^2 -y^2 , 5*z*y]) + sage: H = Hom(P, P) + sage: f = H([x^2 - 2*x*y + z*x, z^2 - y^2, 5*z*y]) sage: g = H([x^2, y^2, z^2]) sage: f == g False @@ -567,17 +563,17 @@ def __ne__(self, right): EXAMPLES:: sage: P. = ProjectiveSpace(QQ, 1) - sage: H = Hom(P,P) - sage: f = H([x^3 - 2*x^2*y , 5*x*y^2]) - sage: g = f.change_ring(GF(7)) - sage: f != g + sage: H = Hom(P, P) + sage: f = H([x^3 - 2*x^2*y, 5*x*y^2]) + sage: g = f.change_ring(GF(7)) # optional - sage.rings.finite_rings + sage: f != g # optional - sage.rings.finite_rings True :: sage: P. = ProjectiveSpace(QQ, 2) sage: H = Hom(P, P) - sage: f = H([x^2 - 2*x*y + z*x, z^2 -y^2 , 5*z*y]) + sage: f = H([x^2 - 2*x*y + z*x, z^2 - y^2, 5*z*y]) sage: f != f False """ @@ -612,12 +608,13 @@ def _matrix_times_polymap_(self, mat, h): :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2+1) - sage: P. = ProjectiveSpace(QQ, 1) - sage: H = Hom(P,P) - sage: f = H([1/3*x^2 + 1/2*y^2, y^2]) - sage: matrix([[i,0], [0,i]]) * f - Scheme endomorphism of Projective Space of dimension 1 over Number Field in i with defining polynomial x^2 + 1 + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(QQ, 1) # optional - sage.rings.number_field + sage: H = Hom(P, P) # optional - sage.rings.number_field + sage: f = H([1/3*x^2 + 1/2*y^2, y^2]) # optional - sage.rings.number_field + sage: matrix([[i,0], [0,i]]) * f # optional - sage.rings.number_field + Scheme endomorphism of Projective Space of dimension 1 over + Number Field in i with defining polynomial x^2 + 1 Defn: Defined on coordinates by sending (x : y) to ((1/3*i)*x^2 + (1/2*i)*y^2 : i*y^2) """ @@ -655,12 +652,13 @@ def _polymap_times_matrix_(self, mat, h): :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2+1) - sage: P. = ProjectiveSpace(QQ, 1) - sage: H = Hom(P,P) - sage: f = H([1/3*x^2 + 1/2*y^2, y^2]) - sage: f * matrix([[i,0], [0,i]]) - Scheme endomorphism of Projective Space of dimension 1 over Number Field in i with defining polynomial x^2 + 1 + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(QQ, 1) # optional - sage.rings.number_field + sage: H = Hom(P, P) # optional - sage.rings.number_field + sage: f = H([1/3*x^2 + 1/2*y^2, y^2]) # optional - sage.rings.number_field + sage: f * matrix([[i,0], [0,i]]) # optional - sage.rings.number_field + Scheme endomorphism of Projective Space of dimension 1 over + Number Field in i with defining polynomial x^2 + 1 Defn: Defined on coordinates by sending (x : y) to (-1/3*x^2 - 1/2*y^2 : -y^2) """ @@ -703,10 +701,10 @@ def as_dynamical_system(self): :: - sage: P. = ProjectiveSpace(GF(5), 1) - sage: H = End(P) - sage: f = H([x^2, y^2]) - sage: type(f.as_dynamical_system()) + sage: P. = ProjectiveSpace(GF(5), 1) # optional - sage.rings.finite_rings + sage: H = End(P) # optional - sage.rings.finite_rings + sage: f = H([x^2, y^2]) # optional - sage.rings.finite_rings + sage: type(f.as_dynamical_system()) # optional - sage.rings.finite_rings :: @@ -736,7 +734,7 @@ def scale_by(self, t): """ Scales each coordinate by a factor of ``t``. - A ``TypeError`` occurs if the point is not in the coordinate_ring + A ``TypeError`` occurs if the point is not in the coordinate ring of the parent after scaling. INPUT: @@ -749,38 +747,34 @@ def scale_by(self, t): EXAMPLES:: - sage: A. = ProjectiveSpace(QQ,1) - sage: H = Hom(A,A) - sage: f = H([x^3-2*x*y^2,x^2*y]) + sage: A. = ProjectiveSpace(QQ, 1) + sage: H = Hom(A, A) + sage: f = H([x^3 - 2*x*y^2, x^2*y]) sage: f.scale_by(1/x) sage: f - Scheme endomorphism of Projective Space of dimension 1 over Rational - Field - Defn: Defined on coordinates by sending (x : y) to - (x^2 - 2*y^2 : x*y) + Scheme endomorphism of Projective Space of dimension 1 over Rational Field + Defn: Defined on coordinates by sending (x : y) to (x^2 - 2*y^2 : x*y) :: sage: R. = PolynomialRing(QQ) - sage: P. = ProjectiveSpace(R,1) + sage: P. = ProjectiveSpace(R, 1) sage: H = Hom(P,P) - sage: f = H([3/5*x^2,6*y^2]) + sage: f = H([3/5*x^2, 6*y^2]) sage: f.scale_by(5/3*t); f - Scheme endomorphism of Projective Space of dimension 1 over Univariate - Polynomial Ring in t over Rational Field - Defn: Defined on coordinates by sending (x : y) to - (t*x^2 : 10*t*y^2) + Scheme endomorphism of Projective Space of dimension 1 over + Univariate Polynomial Ring in t over Rational Field + Defn: Defined on coordinates by sending (x : y) to (t*x^2 : 10*t*y^2) :: - sage: P. = ProjectiveSpace(GF(7),2) - sage: X = P.subscheme(x^2-y^2) - sage: H = Hom(X,X) - sage: f = H([x^2,y^2,z^2]) - sage: f.scale_by(x-y);f - Scheme endomorphism of Closed subscheme of Projective Space of dimension - 2 over Finite Field of size 7 defined by: - x^2 - y^2 + sage: P. = ProjectiveSpace(GF(7), 2) # optional - sage.rings.finite_rings + sage: X = P.subscheme(x^2 - y^2) # optional - sage.rings.finite_rings + sage: H = Hom(X, X) # optional - sage.rings.finite_rings + sage: f = H([x^2, y^2, z^2]) # optional - sage.rings.finite_rings + sage: f.scale_by(x - y); f # optional - sage.rings.finite_rings + Scheme endomorphism of Closed subscheme of Projective Space of dimension 2 + over Finite Field of size 7 defined by: x^2 - y^2 Defn: Defined on coordinates by sending (x : y : z) to (x*y^2 - y^3 : x*y^2 - y^3 : x*z^2 - y*z^2) """ @@ -834,23 +828,19 @@ def normalize_coordinates(self, **kwds): sage: H = Hom(P, P) sage: f = H([5/4*x^3, 5*x*y^2]) sage: f.normalize_coordinates(); f - Scheme endomorphism of Projective Space of dimension 1 over Rational - Field - Defn: Defined on coordinates by sending (x : y) to - (x^2 : 4*y^2) + Scheme endomorphism of Projective Space of dimension 1 over Rational Field + Defn: Defined on coordinates by sending (x : y) to (x^2 : 4*y^2) :: - sage: P. = ProjectiveSpace(GF(7), 2) - sage: X = P.subscheme(x^2 - y^2) - sage: H = Hom(X, X) - sage: f = H([x^3 + x*y^2, x*y^2, x*z^2]) - sage: f.normalize_coordinates(); f - Scheme endomorphism of Closed subscheme of Projective Space of dimension - 2 over Finite Field of size 7 defined by: - x^2 - y^2 - Defn: Defined on coordinates by sending (x : y : z) to - (2*y^2 : y^2 : z^2) + sage: P. = ProjectiveSpace(GF(7), 2) # optional - sage.rings.finite_rings + sage: X = P.subscheme(x^2 - y^2) # optional - sage.rings.finite_rings + sage: H = Hom(X, X) # optional - sage.rings.finite_rings + sage: f = H([x^3 + x*y^2, x*y^2, x*z^2]) # optional - sage.rings.finite_rings + sage: f.normalize_coordinates(); f # optional - sage.rings.finite_rings + Scheme endomorphism of Closed subscheme of Projective Space of dimension 2 + over Finite Field of size 7 defined by: x^2 - y^2 + Defn: Defined on coordinates by sending (x : y : z) to (2*y^2 : y^2 : z^2) :: @@ -859,33 +849,33 @@ def normalize_coordinates(self, **kwds): sage: H = End(P) sage: f = H([a*(x*z + y^2)*x^2, a*b*(x*z + y^2)*y^2, a*(x*z + y^2)*z^2]) sage: f.normalize_coordinates(); f - Scheme endomorphism of Projective Space of dimension 2 over Multivariate - Polynomial Ring in a, b over Rational Field - Defn: Defined on coordinates by sending (x : y : z) to - (x^2 : b*y^2 : z^2) + Scheme endomorphism of Projective Space of dimension 2 over + Multivariate Polynomial Ring in a, b over Rational Field + Defn: Defined on coordinates by sending (x : y : z) to (x^2 : b*y^2 : z^2) :: - sage: K. = QuadraticField(5) - sage: P. = ProjectiveSpace(K, 1) - sage: f = DynamicalSystem([w*x^2 + (1/5*w)*y^2, w*y^2]) - sage: f.normalize_coordinates(); f - Dynamical System of Projective Space of dimension 1 over Number Field in - w with defining polynomial x^2 - 5 with w = 2.236067977499790? - Defn: Defined on coordinates by sending (x : y) to - (5*x^2 + y^2 : 5*y^2) + sage: K. = QuadraticField(5) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: f = DynamicalSystem([w*x^2 + (1/5*w)*y^2, w*y^2]) # optional - sage.rings.number_field + sage: f.normalize_coordinates(); f # optional - sage.rings.number_field + Dynamical System of Projective Space of dimension 1 over Number Field in w + with defining polynomial x^2 - 5 with w = 2.236067977499790? + Defn: Defined on coordinates by sending (x : y) to (5*x^2 + y^2 : 5*y^2) :: sage: R. = PolynomialRing(ZZ) - sage: K. = NumberField(t^3 - 11) - sage: a = 7/(b - 1) - sage: P. = ProjectiveSpace(K, 1) - sage: f = DynamicalSystem_projective([a*y^2 - (a*y - x)^2, y^2]) - sage: f.normalize_coordinates(); f - Dynamical System of Projective Space of dimension 1 over Number Field in b with defining polynomial t^3 - 11 - Defn: Defined on coordinates by sending (x : y) to - (-100*x^2 + (140*b^2 + 140*b + 140)*x*y + (-77*b^2 - 567*b - 1057)*y^2 : 100*y^2) + sage: K. = NumberField(t^3 - 11) # optional - sage.rings.number_field + sage: a = 7/(b - 1) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: f = DynamicalSystem_projective([a*y^2 - (a*y - x)^2, y^2]) # optional - sage.rings.number_field + sage: f.normalize_coordinates(); f # optional - sage.rings.number_field + Dynamical System of Projective Space of dimension 1 over + Number Field in b with defining polynomial t^3 - 11 + Defn: Defined on coordinates by sending (x : y) to + (-100*x^2 + (140*b^2 + 140*b + 140)*x*y + (-77*b^2 - 567*b - 1057)*y^2 + : 100*y^2) We can used ``ideal`` to scale with respect to a norm defined by an ideal:: @@ -893,37 +883,36 @@ def normalize_coordinates(self, **kwds): sage: f = DynamicalSystem_projective([2*x^3, 2*x^2*y + 4*x*y^2]) sage: f.normalize_coordinates(ideal=2); f Dynamical System of Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y) to - (x^3 : x^2*y + 2*x*y^2) + Defn: Defined on coordinates by sending (x : y) to (x^3 : x^2*y + 2*x*y^2) :: sage: R. = QQ[] - sage: A. = NumberField(w^2 + 1) - sage: P. = ProjectiveSpace(A, 2) - sage: X = P.subscheme(x^2-y^2) - sage: H = Hom(X,X) - sage: f = H([(a+1)*x^3 + 2*x*y^2, 4*x*y^2, 8*x*z^2]) - sage: f.normalize_coordinates(ideal=A.prime_above(2)); f + sage: A. = NumberField(w^2 + 1) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(A, 2) # optional - sage.rings.number_field + sage: X = P.subscheme(x^2 - y^2) # optional - sage.rings.number_field + sage: H = Hom(X, X) # optional - sage.rings.number_field + sage: f = H([(a+1)*x^3 + 2*x*y^2, 4*x*y^2, 8*x*z^2]) # optional - sage.rings.number_field + sage: f.normalize_coordinates(ideal=A.prime_above(2)); f # optional - sage.rings.number_field Scheme endomorphism of Closed subscheme of Projective Space of dimension 2 over - Number Field in a with defining polynomial w^2 + 1 defined by: - x^2 - y^2 + Number Field in a with defining polynomial w^2 + 1 defined by: x^2 - y^2 Defn: Defined on coordinates by sending (x : y : z) to ((-a + 2)*x*y^2 : (-2*a + 2)*x*y^2 : (-4*a + 4)*x*z^2) We can pass in a valuation to ``valuation``:: - sage: g = H([(a+1)*x^3 + 2*x*y^2, 4*x*y^2, 8*x*z^2]) - sage: g.normalize_coordinates(valuation=A.valuation(A.prime_above(2))) - sage: g == f + sage: g = H([(a+1)*x^3 + 2*x*y^2, 4*x*y^2, 8*x*z^2]) # optional - sage.rings.number_field + sage: g.normalize_coordinates(valuation=A.valuation(A.prime_above(2))) # optional - sage.rings.number_field + sage: g == f # optional - sage.rings.number_field True :: - sage: P. = ProjectiveSpace(Qp(3), 1) - sage: f = DynamicalSystem_projective([3*x^2+6*y^2, 9*x*y]) - sage: f.normalize_coordinates(); f - Dynamical System of Projective Space of dimension 1 over 3-adic Field with capped relative precision 20 + sage: P. = ProjectiveSpace(Qp(3), 1) # optional - sage.rings.padics + sage: f = DynamicalSystem_projective([3*x^2 + 6*y^2, 9*x*y]) # optional - sage.rings.padics + sage: f.normalize_coordinates(); f # optional - sage.rings.padics + Dynamical System of Projective Space of dimension 1 over + 3-adic Field with capped relative precision 20 Defn: Defined on coordinates by sending (x : y) to (x^2 + (2 + O(3^20))*y^2 : (3 + O(3^21))*x*y) """ @@ -1038,34 +1027,34 @@ def degree(self): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,1) - sage: H = Hom(P,P) - sage: f = H([x^2+y^2, y^2]) + sage: P. = ProjectiveSpace(QQ, 1) + sage: H = Hom(P, P) + sage: f = H([x^2 + y^2, y^2]) sage: f.degree() 2 :: - sage: P. = ProjectiveSpace(CC,2) - sage: H = Hom(P,P) - sage: f = H([x^3+y^3, y^2*z, z*x*y]) + sage: P. = ProjectiveSpace(CC, 2) + sage: H = Hom(P, P) + sage: f = H([x^3 + y^3, y^2*z, z*x*y]) sage: f.degree() 3 :: sage: R. = PolynomialRing(QQ) - sage: P. = ProjectiveSpace(R,2) - sage: H = Hom(P,P) - sage: f = H([x^2+t*y^2, (2-t)*y^2, z^2]) + sage: P. = ProjectiveSpace(R, 2) + sage: H = Hom(P, P) + sage: f = H([x^2 + t*y^2, (2-t)*y^2, z^2]) sage: f.degree() 2 :: - sage: P. = ProjectiveSpace(ZZ,2) - sage: X = P.subscheme(x^2-y^2) - sage: H = Hom(X,X) + sage: P. = ProjectiveSpace(ZZ, 2) + sage: X = P.subscheme(x^2 - y^2) + sage: H = Hom(X, X) sage: f = H([x^2, y^2, z^2]) sage: f.degree() 2 @@ -1074,7 +1063,7 @@ def degree(self): def dehomogenize(self, n): r""" - Returns the standard dehomogenization at the ``n[0]`` coordinate for the domain + Return the standard dehomogenization at the ``n[0]`` coordinate for the domain and the ``n[1]`` coordinate for the codomain. Note that the new function is defined over the fraction field @@ -1091,31 +1080,29 @@ def dehomogenize(self, n): EXAMPLES:: - sage: P. = ProjectiveSpace(ZZ,1) - sage: H = Hom(P,P) - sage: f = H([x^2+y^2, y^2]) + sage: P. = ProjectiveSpace(ZZ, 1) + sage: H = Hom(P, P) + sage: f = H([x^2 + y^2, y^2]) sage: f.dehomogenize(0) Scheme endomorphism of Affine Space of dimension 1 over Integer Ring - Defn: Defined on coordinates by sending (y) to - (y^2/(y^2 + 1)) + Defn: Defined on coordinates by sending (y) to (y^2/(y^2 + 1)) :: - sage: P. = ProjectiveSpace(QQ,1) - sage: H = Hom(P,P) - sage: f = H([x^2-y^2, y^2]) + sage: P. = ProjectiveSpace(QQ, 1) + sage: H = Hom(P, P) + sage: f = H([x^2 - y^2, y^2]) sage: f.dehomogenize((0,1)) Scheme morphism: From: Affine Space of dimension 1 over Rational Field To: Affine Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (y) to - ((-y^2 + 1)/y^2) + Defn: Defined on coordinates by sending (y) to ((-y^2 + 1)/y^2) :: - sage: P. = ProjectiveSpace(QQ,2) - sage: H = Hom(P,P) - sage: f = H([x^2+y^2, y^2-z^2, 2*z^2]) + sage: P. = ProjectiveSpace(QQ, 2) + sage: H = Hom(P, P) + sage: f = H([x^2 + y^2, y^2 - z^2, 2*z^2]) sage: f.dehomogenize(2) Scheme endomorphism of Affine Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x, y) to @@ -1126,28 +1113,27 @@ def dehomogenize(self, n): sage: R. = PolynomialRing(QQ) sage: P. = ProjectiveSpace(FractionField(R),2) sage: H = Hom(P,P) - sage: f = H([x^2+t*y^2, t*y^2-z^2, t*z^2]) + sage: f = H([x^2 + t*y^2, t*y^2 - z^2, t*z^2]) sage: f.dehomogenize(2) Scheme endomorphism of Affine Space of dimension 2 over Fraction Field - of Univariate Polynomial Ring in t over Rational Field + of Univariate Polynomial Ring in t over Rational Field Defn: Defined on coordinates by sending (x, y) to (1/t*x^2 + y^2, y^2 - 1/t) :: - sage: P. = ProjectiveSpace(ZZ,2) - sage: X = P.subscheme(x^2-y^2) - sage: H = Hom(X,X) + sage: P. = ProjectiveSpace(ZZ, 2) + sage: X = P.subscheme(x^2 - y^2) + sage: H = Hom(X, X) sage: f = H([x^2, y^2, x*z]) sage: f.dehomogenize(2) - Scheme endomorphism of Closed subscheme of Affine Space of dimension 2 over Integer Ring defined by: - x^2 - y^2 - Defn: Defined on coordinates by sending (x, y) to - (x, y^2/x) + Scheme endomorphism of Closed subscheme of Affine Space of dimension 2 + over Integer Ring defined by: x^2 - y^2 + Defn: Defined on coordinates by sending (x, y) to (x, y^2/x) :: - sage: P. = ProjectiveSpace(QQ,1) + sage: P. = ProjectiveSpace(QQ, 1) sage: H = End(P) sage: f = H([x^2 - 2*x*y, y^2]) sage: f.dehomogenize(0).homogenize(0) == f @@ -1155,28 +1141,28 @@ def dehomogenize(self, n): :: - sage: K. = QuadraticField(3) - sage: O = K.ring_of_integers() - sage: P. = ProjectiveSpace(O,1) - sage: H = End(P) - sage: f = H([x^2 - O(w)*y^2,y^2]) - sage: f.dehomogenize(1) - Scheme endomorphism of Affine Space of dimension 1 over Maximal Order in Number Field in w with defining polynomial x^2 - 3 with w = 1.732050807568878? - Defn: Defined on coordinates by sending (x) to - (x^2 - w) + sage: K. = QuadraticField(3) # optional - sage.rings.number_field + sage: O = K.ring_of_integers() # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(O, 1) # optional - sage.rings.number_field + sage: H = End(P) # optional - sage.rings.number_field + sage: f = H([x^2 - O(w)*y^2, y^2]) # optional - sage.rings.number_field + sage: f.dehomogenize(1) # optional - sage.rings.number_field + Scheme endomorphism of Affine Space of dimension 1 over + Maximal Order in Number Field in w with defining polynomial x^2 - 3 + with w = 1.732050807568878? + Defn: Defined on coordinates by sending (x) to (x^2 - w) :: - sage: P1. = ProjectiveSpace(QQ,1) - sage: P2. = ProjectiveSpace(QQ,2) - sage: H = Hom(P2,P1) - sage: f = H([u*w,v^2 + w^2]) + sage: P1. = ProjectiveSpace(QQ, 1) + sage: P2. = ProjectiveSpace(QQ, 2) + sage: H = Hom(P2, P1) + sage: f = H([u*w, v^2 + w^2]) sage: f.dehomogenize((2,1)) Scheme morphism: From: Affine Space of dimension 2 over Rational Field To: Affine Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (u, v) to - (u/(v^2 + 1)) + Defn: Defined on coordinates by sending (u, v) to (u/(v^2 + 1)) """ # the dehomogenizations are stored for future use try: @@ -1221,7 +1207,7 @@ def dehomogenize(self, n): @cached_method def is_morphism(self): r""" - returns ``True`` if this map is a morphism. + Return ``True`` if this map is a morphism. The map is a morphism if and only if the ideal generated by the defining polynomials is the unit ideal @@ -1233,35 +1219,35 @@ def is_morphism(self): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,1) - sage: H = Hom(P,P) - sage: f = H([x^2+y^2, y^2]) + sage: P. = ProjectiveSpace(QQ, 1) + sage: H = Hom(P, P) + sage: f = H([x^2 + y^2, y^2]) sage: f.is_morphism() True :: - sage: P. = ProjectiveSpace(RR,2) - sage: H = Hom(P,P) - sage: f = H([x*z-y*z, x^2-y^2, z^2]) + sage: P. = ProjectiveSpace(RR, 2) + sage: H = Hom(P, P) + sage: f = H([x*z - y*z, x^2 - y^2, z^2]) sage: f.is_morphism() False :: - sage: R. = PolynomialRing(GF(5)) - sage: P. = ProjectiveSpace(R,2) - sage: H = Hom(P,P) - sage: f = H([x*z-t*y^2, x^2-y^2, t*z^2]) - sage: f.is_morphism() + sage: R. = PolynomialRing(GF(5)) # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(R, 2) # optional - sage.rings.finite_rings + sage: H = Hom(P, P) # optional - sage.rings.finite_rings + sage: f = H([x*z - t*y^2, x^2 - y^2, t*z^2]) # optional - sage.rings.finite_rings + sage: f.is_morphism() # optional - sage.rings.finite_rings True Map that is not morphism on projective space, but is over a subscheme:: - sage: P. = ProjectiveSpace(RR,2) + sage: P. = ProjectiveSpace(RR, 2) sage: X = P.subscheme([x*y + y*z]) - sage: H = Hom(X,X) - sage: f = H([x*z-y*z, x^2-y^2, z^2]) + sage: H = Hom(X, X) + sage: f = H([x*z - y*z, x^2 - y^2, z^2]) sage: f.is_morphism() True """ @@ -1321,21 +1307,21 @@ def global_height(self, prec=None): :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(z^2 - 2) - sage: O = K.maximal_order() - sage: P. = ProjectiveSpace(O, 1) - sage: H = Hom(P, P) - sage: f = H([2*x^2 + 3*O(w)*y^2, O(w)*y^2]) - sage: f.global_height() + sage: K. = NumberField(z^2 - 2) # optional - sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(O, 1) # optional - sage.rings.number_field + sage: H = Hom(P, P) # optional - sage.rings.number_field + sage: f = H([2*x^2 + 3*O(w)*y^2, O(w)*y^2]) # optional - sage.rings.number_field + sage: f.global_height() # optional - sage.rings.number_field 1.09861228866811 :: - sage: P. = ProjectiveSpace(QQbar, 1) - sage: P2. = ProjectiveSpace(QQbar, 2) - sage: H = Hom(P, P2) - sage: f = H([x^2 + QQbar(I)*x*y + 3*y^2, y^2, QQbar(sqrt(5))*x*y]) - sage: f.global_height() + sage: P. = ProjectiveSpace(QQbar, 1) # optional - sage.rings.number_field + sage: P2. = ProjectiveSpace(QQbar, 2) # optional - sage.rings.number_field + sage: H = Hom(P, P2) # optional - sage.rings.number_field + sage: f = H([x^2 + QQbar(I)*x*y + 3*y^2, y^2, QQbar(sqrt(5))*x*y]) # optional - sage.rings.number_field + sage: f.global_height() # optional - sage.rings.number_field 1.09861228866811 :: @@ -1383,7 +1369,7 @@ def global_height(self, prec=None): def local_height(self, v, prec=None): r""" - Returns the maximum of the local height of the coefficients in any + Return the maximum of the local height of the coefficients in any of the coordinate functions of this map. INPUT: @@ -1399,25 +1385,25 @@ def local_height(self, v, prec=None): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,1) - sage: H = Hom(P,P) - sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y]); + sage: P. = ProjectiveSpace(QQ, 1) + sage: H = Hom(P, P) + sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y]) sage: f.local_height(1331) 7.19368581839511 :: - sage: P. = ProjectiveSpace(QQ,1) - sage: H = Hom(P,P) - sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y]); + sage: P. = ProjectiveSpace(QQ, 1) + sage: H = Hom(P, P) + sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y]) sage: f.local_height(1331, prec=2) 8.0 This function does not automatically normalize:: - sage: P. = ProjectiveSpace(QQ,2) - sage: H = Hom(P,P) - sage: f = H([4*x^2 + 3/100*y^2, 8/210*x*y, 1/10000*z^2]); + sage: P. = ProjectiveSpace(QQ, 2) + sage: H = Hom(P, P) + sage: f = H([4*x^2 + 3/100*y^2, 8/210*x*y, 1/10000*z^2]) sage: f.local_height(2) 2.77258872223978 sage: f.normalize_coordinates() @@ -1427,11 +1413,11 @@ def local_height(self, v, prec=None): :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(z^2-2) - sage: P. = ProjectiveSpace(K,1) - sage: H = Hom(P,P) - sage: f = H([2*x^2 + w/3*y^2, 1/w*y^2]) - sage: f.local_height(K.ideal(3)) + sage: K. = NumberField(z^2 - 2) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: H = Hom(P, P) # optional - sage.rings.number_field + sage: f = H([2*x^2 + w/3*y^2, 1/w*y^2]) # optional - sage.rings.number_field + sage: f.local_height(K.ideal(3)) # optional - sage.rings.number_field 1.09861228866811 """ K = FractionField(self.domain().base_ring()) @@ -1441,7 +1427,7 @@ def local_height(self, v, prec=None): def local_height_arch(self, i, prec=None): r""" - Returns the maximum of the local height at the ``i``-th infinite place of the coefficients in any + Return the maximum of the local height at the ``i``-th infinite place of the coefficients in any of the coordinate functions of this map. INPUT: @@ -1459,26 +1445,26 @@ def local_height_arch(self, i, prec=None): sage: P. = ProjectiveSpace(QQ, 1) sage: H = Hom(P, P) - sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y]); + sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y]) sage: f.local_height_arch(0) 5.34710753071747 :: - sage: P. = ProjectiveSpace(QQ,1) - sage: H = Hom(P,P) - sage: f = H([1/1331*x^2+1/4000*y^2, 210*x*y]); + sage: P. = ProjectiveSpace(QQ, 1) + sage: H = Hom(P, P) + sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y]) sage: f.local_height_arch(0, prec=5) 5.2 :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(z^2 - 2) - sage: P. = ProjectiveSpace(K,1) - sage: H = Hom(P, P) - sage: f = H([2*x^2 + w/3*y^2, 1/w*y^2]) - sage: f.local_height_arch(1) + sage: K. = NumberField(z^2 - 2) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: H = Hom(P, P) # optional - sage.rings.number_field + sage: f = H([2*x^2 + w/3*y^2, 1/w*y^2]) # optional - sage.rings.number_field + sage: f.local_height_arch(1) # optional - sage.rings.number_field 0.6931471805599453094172321214582 """ K = FractionField(self.domain().base_ring()) @@ -1491,7 +1477,7 @@ def local_height_arch(self, i, prec=None): def wronskian_ideal(self): r""" - Returns the ideal generated by the critical point locus. + Return the ideal generated by the critical point locus. This is the vanishing of the maximal minors of the Jacobian matrix. Not implemented for subvarieties. @@ -1501,23 +1487,23 @@ def wronskian_ideal(self): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2+11) - sage: P. = ProjectiveSpace(K,1) - sage: H = End(P) - sage: f = H([x^2-w*y^2, w*y^2]) - sage: f.wronskian_ideal() - Ideal ((4*w)*x*y) of Multivariate Polynomial Ring in x, y over Number - Field in w with defining polynomial x^2 + 11 + sage: K. = NumberField(x^2 + 11) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: H = End(P) # optional - sage.rings.number_field + sage: f = H([x^2 - w*y^2, w*y^2]) # optional - sage.rings.number_field + sage: f.wronskian_ideal() # optional - sage.rings.number_field + Ideal ((4*w)*x*y) of Multivariate Polynomial Ring in x, y + over Number Field in w with defining polynomial x^2 + 11 :: - sage: P. = ProjectiveSpace(QQ,1) - sage: P2. = ProjectiveSpace(K,2) + sage: P. = ProjectiveSpace(QQ, 1) + sage: P2. = ProjectiveSpace(K, 2) sage: H = Hom(P,P2) - sage: f = H([x^2-2*y^2, y^2, x*y]) + sage: f = H([x^2 - 2*y^2, y^2, x*y]) sage: f.wronskian_ideal() - Ideal (4*x*y, 2*x^2 + 4*y^2, -2*y^2) of Multivariate Polynomial Ring in - x, y over Rational Field + Ideal (4*x*y, 2*x^2 + 4*y^2, -2*y^2) of + Multivariate Polynomial Ring in x, y over Rational Field """ dom = self.domain() from sage.schemes.projective.projective_space import is_ProjectiveSpace @@ -1564,8 +1550,9 @@ def rational_preimages(self, Q, k=1): sage: P. = ProjectiveSpace(QQ, 2) sage: H = End(P) - sage: f = H([76*x^2 - 180*x*y + 45*y^2 + 14*x*z + 45*y*z\ - - 90*z^2, 67*x^2 - 180*x*y - 157*x*z + 90*y*z, -90*z^2]) + sage: f = H([76*x^2 - 180*x*y + 45*y^2 + 14*x*z + 45*y*z - 90*z^2, + ....: 67*x^2 - 180*x*y - 157*x*z + 90*y*z, + ....: -90*z^2]) sage: f.rational_preimages(P(-9, -4, 1)) [(0 : 4 : 1)] @@ -1581,8 +1568,9 @@ def rational_preimages(self, Q, k=1): sage: P. = ProjectiveSpace(QQ, 3) sage: H = End(P) - sage: f = H([x^2 - 2*y*w - 3*w^2, -2*x^2 + y^2 - 2*x*z\ - + 4*y*w + 3*w^2, x^2 - y^2 + 2*x*z + z^2 - 2*y*w - w^2, w^2]) + sage: f = H([x^2 - 2*y*w - 3*w^2, -2*x^2 + y^2 - 2*x*z + 4*y*w + 3*w^2, + ....: x^2 - y^2 + 2*x*z + z^2 - 2*y*w - w^2, + ....: w^2]) sage: f.rational_preimages(P(0, -1, 0, 1)) [] @@ -1599,22 +1587,22 @@ def rational_preimages(self, Q, k=1): A number field example :: sage: z = QQ['z'].0 - sage: K. = NumberField(z^2 - 2); - sage: P. = ProjectiveSpace(K, 1) - sage: H = End(P) - sage: f = H([x^2 + y^2, y^2]) - sage: f.rational_preimages(P(3, 1)) + sage: K. = NumberField(z^2 - 2) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: H = End(P) # optional - sage.rings.number_field + sage: f = H([x^2 + y^2, y^2]) # optional - sage.rings.number_field + sage: f.rational_preimages(P(3, 1)) # optional - sage.rings.number_field [(-a : 1), (a : 1)] :: sage: z = QQ['z'].0 - sage: K. = NumberField(z^2 - 2); - sage: P. = ProjectiveSpace(K, 2) - sage: X = P.subscheme([x^2 - z^2]) - sage: H = End(X) - sage: f= H([x^2 - z^2, a*y^2, z^2 - x^2]) - sage: f.rational_preimages(X([1, 2, -1])) + sage: K. = NumberField(z^2 - 2) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: X = P.subscheme([x^2 - z^2]) # optional - sage.rings.number_field + sage: H = End(X) # optional - sage.rings.number_field + sage: f= H([x^2 - z^2, a*y^2, z^2 - x^2]) # optional - sage.rings.number_field + sage: f.rational_preimages(X([1, 2, -1])) # optional - sage.rings.number_field [] :: @@ -1625,20 +1613,19 @@ def rational_preimages(self, Q, k=1): sage: f = H([x^2-z^2, y^2, z^2-x^2]) sage: f.rational_preimages(X([0, 1, 0])) Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x^2 - z^2, - -x^2 + z^2, - 0, - -x^2 + z^2 + x^2 - z^2, + -x^2 + z^2, + 0, + -x^2 + z^2 :: sage: P. = ProjectiveSpace(QQ, 1) sage: H = End(P) - sage: f = H([x^2-y^2, y^2]) + sage: f = H([x^2 - y^2, y^2]) sage: f.rational_preimages(P.subscheme([x])) Closed subscheme of Projective Space of dimension 1 over Rational Field - defined by: - x^2 - y^2 + defined by: x^2 - y^2 :: @@ -1707,13 +1694,13 @@ def _number_field_from_algebraics(self): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: P. = ProjectiveSpace(QQbar,1) - sage: H = End(P) - sage: f = H([QQbar(3^(1/3))*x^2 + QQbar(sqrt(-2))*y^2, y^2]) - sage: f._number_field_from_algebraics() + sage: P. = ProjectiveSpace(QQbar, 1) # optional - sage.rings.number_field + sage: H = End(P) # optional - sage.rings.number_field + sage: f = H([QQbar(3^(1/3))*x^2 + QQbar(sqrt(-2))*y^2, y^2]) # optional - sage.rings.number_field + sage: f._number_field_from_algebraics() # optional - sage.rings.number_field Scheme endomorphism of Projective Space of dimension 1 over Number - Field in a with defining polynomial y^6 + 6*y^4 - 6*y^3 + 12*y^2 + 36*y + 17 - with a = 1.442249570307409? + 1.414213562373095?*I + Field in a with defining polynomial y^6 + 6*y^4 - 6*y^3 + 12*y^2 + 36*y + 17 + with a = 1.442249570307409? + 1.414213562373095?*I Defn: Defined on coordinates by sending (x : y) to ((-48/269*a^5 + 27/269*a^4 - 320/269*a^3 + 468/269*a^2 - 772/269*a - 1092/269)*x^2 + (48/269*a^5 - 27/269*a^4 + 320/269*a^3 - 468/269*a^2 @@ -1721,32 +1708,34 @@ def _number_field_from_algebraics(self): :: - sage: P. = ProjectiveSpace(QQbar,1) - sage: P2. = ProjectiveSpace(QQbar,2) - sage: H = Hom(P, P2) - sage: f = H([x^2 + QQbar(I)*x*y + 3*y^2, y^2, QQbar(sqrt(5))*x*y]) - sage: f._number_field_from_algebraics() + sage: P. = ProjectiveSpace(QQbar, 1) # optional - sage.rings.number_field + sage: P2. = ProjectiveSpace(QQbar, 2) # optional - sage.rings.number_field + sage: H = Hom(P, P2) # optional - sage.rings.number_field + sage: f = H([x^2 + QQbar(I)*x*y + 3*y^2, y^2, QQbar(sqrt(5))*x*y]) # optional - sage.rings.number_field + sage: f._number_field_from_algebraics() # optional - sage.rings.number_field Scheme morphism: - From: Projective Space of dimension 1 over Number Field in a with - defining polynomial y^4 + 3*y^2 + 1 with a = 0.?e-113 + 0.618033988749895?*I - To: Projective Space of dimension 2 over Number Field in a with - defining polynomial y^4 + 3*y^2 + 1 with a = 0.?e-113 + 0.618033988749895?*I + From: Projective Space of dimension 1 over Number Field in a + with defining polynomial y^4 + 3*y^2 + 1 + with a = 0.?e-113 + 0.618033988749895?*I + To: Projective Space of dimension 2 over Number Field in a + with defining polynomial y^4 + 3*y^2 + 1 + with a = 0.?e-113 + 0.618033988749895?*I Defn: Defined on coordinates by sending (x : y) to (x^2 + (a^3 + 2*a)*x*y + 3*y^2 : y^2 : (2*a^2 + 3)*x*y) The following was fixed in :trac:`23808`:: - sage: R.=PolynomialRing(QQ) - sage: s = (t^3+t+1).roots(QQbar)[0][0] - sage: P.=ProjectiveSpace(QQbar,1) - sage: H = Hom(P,P) - sage: f = H([s*x^3-13*y^3, y^3-15*y^3]) - sage: f + sage: R. = PolynomialRing(QQ) + sage: s = (t^3 + t + 1).roots(QQbar)[0][0] # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(QQbar, 1) # optional - sage.rings.number_field + sage: H = Hom(P, P) # optional - sage.rings.number_field + sage: f = H([s*x^3 - 13*y^3, y^3 - 15*y^3]) # optional - sage.rings.number_field + sage: f # optional - sage.rings.number_field Scheme endomorphism of Projective Space of dimension 1 over Algebraic Field Defn: Defined on coordinates by sending (x : y) to ((-0.6823278038280193?)*x^3 + (-13)*y^3 : (-14)*y^3) - sage: f_alg = f._number_field_from_algebraics() - sage: f_alg.change_ring(QQbar) # Used to fail + sage: f_alg = f._number_field_from_algebraics() # optional - sage.rings.number_field + sage: f_alg.change_ring(QQbar) # Used to fail # optional - sage.rings.number_field Scheme endomorphism of Projective Space of dimension 1 over Algebraic Field Defn: Defined on coordinates by sending (x : y) to ((-0.6823278038280193?)*x^3 + (-13)*y^3 : (-14)*y^3) @@ -1806,36 +1795,36 @@ def base_indeterminacy_locus(self): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,2) + sage: P. = ProjectiveSpace(QQ, 2) sage: H = End(P) - sage: f = H([x*z-y*z, x^2-y^2, z^2]) + sage: f = H([x*z - y*z, x^2 - y^2, z^2]) sage: f.base_indeterminacy_locus() Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x*z - y*z, - x^2 - y^2, - z^2 + x*z - y*z, + x^2 - y^2, + z^2 :: - sage: P. = ProjectiveSpace(QQ,2) + sage: P. = ProjectiveSpace(QQ, 2) sage: H = End(P) sage: f = H([x^2, y^2, z^2]) sage: f.base_indeterminacy_locus() Closed subscheme of Projective Space of dimension 2 over Rational Field - defined by: - x^2, - y^2, - z^2 + defined by: + x^2, + y^2, + z^2 :: - sage: P1. = ProjectiveSpace(RR,2) - sage: P2. = ProjectiveSpace(RR,3) - sage: H = Hom(P1,P2) + sage: P1. = ProjectiveSpace(RR, 2) + sage: P2. = ProjectiveSpace(RR, 3) + sage: H = Hom(P1, P2) sage: h = H([y^3*z^3, x^3*z^3, y^3*z^3, x^2*y^2*z^2]) sage: h.base_indeterminacy_locus() - Closed subscheme of Projective Space of dimension 2 over Real Field with - 53 bits of precision defined by: + Closed subscheme of Projective Space of dimension 2 over + Real Field with 53 bits of precision defined by: y^3*z^3, x^3*z^3, y^3*z^3, @@ -1843,12 +1832,12 @@ def base_indeterminacy_locus(self): If defining polynomials are not normalized, output scheme will not be normalized:: - sage: P.=ProjectiveSpace(QQ,2) - sage: H=End(P) - sage: f=H([x*x^2,x*y^2,x*z^2]) + sage: P. = ProjectiveSpace(QQ,2) + sage: H = End(P) + sage: f = H([x*x^2,x*y^2,x*z^2]) sage: f.base_indeterminacy_locus() Closed subscheme of Projective Space of dimension 2 over Rational Field - defined by: + defined by: x^3, x*y^2, x*z^2 @@ -1868,12 +1857,12 @@ def indeterminacy_locus(self): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,2) + sage: P. = ProjectiveSpace(QQ, 2) sage: H = End(P) sage: f = H([x^2, y^2, z^2]) sage: f.indeterminacy_locus() - ... DeprecationWarning: The meaning of indeterminacy_locus() has changed. Read the docstring. - See https://github.com/sagemath/sage/issues/29145 for details. + ... DeprecationWarning: The meaning of indeterminacy_locus() has changed. + Read the docstring. See https://github.com/sagemath/sage/issues/29145 for details. Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: z, y, @@ -1881,7 +1870,7 @@ def indeterminacy_locus(self): :: - sage: P. = ProjectiveSpace(QQ,2) + sage: P. = ProjectiveSpace(QQ, 2) sage: H = End(P) sage: f = H([x*z - y*z, x^2 - y^2, z^2]) sage: f.indeterminacy_locus() @@ -1893,7 +1882,7 @@ def indeterminacy_locus(self): computes the indeterminacy locus only from the defining polynomials of the map:: - sage: P. = ProjectiveSpace(QQ,2) + sage: P. = ProjectiveSpace(QQ, 2) sage: H = End(P) sage: f = H([x*z - y*z, x^2 - y^2, z^2]) sage: f.base_indeterminacy_locus() @@ -1925,20 +1914,20 @@ def indeterminacy_points(self, F=None, base=False): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,2) + sage: P. = ProjectiveSpace(QQ, 2) sage: H = End(P) - sage: f = H([x*z-y*z, x^2-y^2, z^2]) + sage: f = H([x*z - y*z, x^2 - y^2, z^2]) sage: f.indeterminacy_points() - ... DeprecationWarning: The meaning of indeterminacy_locus() has changed. Read the docstring. - See https://github.com/sagemath/sage/issues/29145 for details. + ... DeprecationWarning: The meaning of indeterminacy_locus() has changed. + Read the docstring. See https://github.com/sagemath/sage/issues/29145 for details. [(-1 : 1 : 0), (1 : 1 : 0)] :: - sage: P1. = ProjectiveSpace(RR,2) - sage: P2. = ProjectiveSpace(RR,3) - sage: H = Hom(P1,P2) - sage: h = H([x+y, y, z+y, y]) + sage: P1. = ProjectiveSpace(RR, 2) + sage: P2. = ProjectiveSpace(RR, 3) + sage: H = Hom(P1, P2) + sage: h = H([x + y, y, z + y, y]) sage: set_verbose(None) sage: h.indeterminacy_points(base=True) [] @@ -1950,17 +1939,17 @@ def indeterminacy_points(self, F=None, base=False): :: - sage: P. = ProjectiveSpace(QQ,2) + sage: P. = ProjectiveSpace(QQ, 2) sage: H = End(P) - sage: f = H([x^2+y^2, x*z, x^2+y^2]) + sage: f = H([x^2 + y^2, x*z, x^2 + y^2]) sage: f.indeterminacy_points() [(0 : 0 : 1)] sage: R. = QQ[] - sage: K. = NumberField(t^2+1) - sage: f.indeterminacy_points(F=K) + sage: K. = NumberField(t^2 + 1) # optional - sage.rings.number_field + sage: f.indeterminacy_points(F=K) # optional - sage.rings.number_field [(-a : 1 : 0), (0 : 0 : 1), (a : 1 : 0)] sage: set_verbose(None) - sage: f.indeterminacy_points(F=QQbar, base=True) + sage: f.indeterminacy_points(F=QQbar, base=True) # optional - sage.rings.number_field [(-1*I : 1 : 0), (0 : 0 : 1), (1*I : 1 : 0)] :: @@ -1976,25 +1965,23 @@ def indeterminacy_points(self, F=None, base=False): :: sage: set_verbose(None) - sage: P. = ProjectiveSpace(Qp(3), 2) - sage: H = End(P) - sage: f = H([x^2 - 7*y^2, y^2 - z^2, x^2 - 7*z^2]) - sage: f.indeterminacy_points(base=True) - [(2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 2*3^6 + 3^8 + 3^9 + 2*3^11 + 3^15 + - 2*3^16 + 3^18 + O(3^20) : 1 + O(3^20) : 1 + O(3^20)), - (2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 2*3^6 + 3^8 + 3^9 + 2*3^11 + 3^15 + - 2*3^16 + 3^18 + O(3^20) : 2 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + - 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11 + 2*3^12 + 2*3^13 + - 2*3^14 + 2*3^15 + 2*3^16 + 2*3^17 + 2*3^18 + 2*3^19 + O(3^20) : 1 + - O(3^20)), - (1 + 3 + 3^2 + 2*3^4 + 2*3^7 + 3^8 + 3^9 + 2*3^10 + 2*3^12 + 2*3^13 + - 2*3^14 + 3^15 + 2*3^17 + 3^18 + 2*3^19 + O(3^20) : 1 + O(3^20) : 1 + - O(3^20)), - (1 + 3 + 3^2 + 2*3^4 + 2*3^7 + 3^8 + 3^9 + 2*3^10 + 2*3^12 + 2*3^13 + - 2*3^14 + 3^15 + 2*3^17 + 3^18 + 2*3^19 + O(3^20) : 2 + 2*3 + 2*3^2 + - 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11 - + 2*3^12 + 2*3^13 + 2*3^14 + 2*3^15 + 2*3^16 + 2*3^17 + 2*3^18 + 2*3^19 - + O(3^20) : 1 + O(3^20))] + sage: P. = ProjectiveSpace(Qp(3), 2) # optional - sage.rings.padics + sage: H = End(P) # optional - sage.rings.padics + sage: f = H([x^2 - 7*y^2, y^2 - z^2, x^2 - 7*z^2]) # optional - sage.rings.padics + sage: f.indeterminacy_points(base=True) # optional - sage.rings.padics + [(2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 2*3^6 + 3^8 + + 3^9 + 2*3^11 + 3^15 + 2*3^16 + 3^18 + O(3^20) : 1 + O(3^20) : 1 + O(3^20)), + (2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 2*3^6 + 3^8 + 3^9 + 2*3^11 + 3^15 + + 2*3^16 + 3^18 + O(3^20) : 2 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11 + 2*3^12 + 2*3^13 + + 2*3^14 + 2*3^15 + 2*3^16 + 2*3^17 + 2*3^18 + 2*3^19 + O(3^20) : 1 + O(3^20)), + (1 + 3 + 3^2 + 2*3^4 + 2*3^7 + 3^8 + 3^9 + 2*3^10 + 2*3^12 + 2*3^13 + + 2*3^14 + 3^15 + 2*3^17 + 3^18 + 2*3^19 + O(3^20) : 1 + O(3^20) : 1 + O(3^20)), + (1 + 3 + 3^2 + 2*3^4 + 2*3^7 + 3^8 + 3^9 + 2*3^10 + 2*3^12 + 2*3^13 + + 2*3^14 + 3^15 + 2*3^17 + 3^18 + 2*3^19 + O(3^20) : 2 + 2*3 + 2*3^2 + + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11 + + 2*3^12 + 2*3^13 + 2*3^14 + 2*3^15 + 2*3^16 + 2*3^17 + 2*3^18 + 2*3^19 + + O(3^20) : 1 + O(3^20))] """ if F is None: fcn = self @@ -2026,67 +2013,67 @@ def reduce_base_field(self): EXAMPLES:: - sage: K. = GF(3^4) - sage: P. = ProjectiveSpace(K, 1) - sage: P2. = ProjectiveSpace(K, 2) - sage: H = End(P) - sage: H2 = Hom(P,P2) - sage: H3 = Hom(P2,P) - sage: f = H([x^2 + (2*t^3 + 2*t^2 + 1)*y^2, y^2]) - sage: f.reduce_base_field() - Scheme endomorphism of Projective Space of dimension 1 over Finite Field in t2 of size 3^2 - Defn: Defined on coordinates by sending (x : y) to - (x^2 + t2*y^2 : y^2) - sage: f2 = H2([x^2 + 5*y^2,y^2, 2*x*y]) - sage: f2.reduce_base_field() + sage: K. = GF(3^4) # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.finite_rings + sage: P2. = ProjectiveSpace(K, 2) # optional - sage.rings.finite_rings + sage: H = End(P) # optional - sage.rings.finite_rings + sage: H2 = Hom(P, P2) # optional - sage.rings.finite_rings + sage: H3 = Hom(P2, P) # optional - sage.rings.finite_rings + sage: f = H([x^2 + (2*t^3 + 2*t^2 + 1)*y^2, y^2]) # optional - sage.rings.finite_rings + sage: f.reduce_base_field() # optional - sage.rings.finite_rings + Scheme endomorphism of Projective Space of dimension 1 + over Finite Field in t2 of size 3^2 + Defn: Defined on coordinates by sending (x : y) to (x^2 + t2*y^2 : y^2) + sage: f2 = H2([x^2 + 5*y^2, y^2, 2*x*y]) # optional - sage.rings.finite_rings + sage: f2.reduce_base_field() # optional - sage.rings.finite_rings Scheme morphism: From: Projective Space of dimension 1 over Finite Field of size 3 To: Projective Space of dimension 2 over Finite Field of size 3 - Defn: Defined on coordinates by sending (x : y) to - (x^2 - y^2 : y^2 : -x*y) - sage: f3 = H3([a^2 + t*b^2, c^2]) - sage: f3.reduce_base_field() + Defn: Defined on coordinates by sending (x : y) to (x^2 - y^2 : y^2 : -x*y) + sage: f3 = H3([a^2 + t*b^2, c^2]) # optional - sage.rings.finite_rings + sage: f3.reduce_base_field() # optional - sage.rings.finite_rings Scheme morphism: From: Projective Space of dimension 2 over Finite Field in t of size 3^4 To: Projective Space of dimension 1 over Finite Field in t of size 3^4 - Defn: Defined on coordinates by sending (a : b : c) to - (a^2 + t*b^2 : c^2) + Defn: Defined on coordinates by sending (a : b : c) to (a^2 + t*b^2 : c^2) :: - sage: K. = CyclotomicField(4) - sage: P. = ProjectiveSpace(K, 1) - sage: H = End(P) - sage: f = H([x^2 + 2*y^2, y^2]) - sage: f.reduce_base_field() + sage: K. = CyclotomicField(4) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: H = End(P) # optional - sage.rings.number_field + sage: f = H([x^2 + 2*y^2, y^2]) # optional - sage.rings.number_field + sage: f.reduce_base_field() # optional - sage.rings.number_field Scheme endomorphism of Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y) to - (x^2 + 2*y^2 : y^2) + Defn: Defined on coordinates by sending (x : y) to (x^2 + 2*y^2 : y^2) :: - sage: K. = GF(5) - sage: L = K.algebraic_closure() - sage: P. = ProjectiveSpace(L, 1) - sage: H = End(P) - sage: f = H([(L.gen(2))*x^2 + L.gen(4)*y^2, x*y]) - sage: f.reduce_base_field() - Scheme endomorphism of Projective Space of dimension 1 over Finite Field in z4 of size 5^4 + sage: K. = GF(5) # optional - sage.rings.finite_rings + sage: L = K.algebraic_closure() # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(L, 1) # optional - sage.rings.finite_rings + sage: H = End(P) # optional - sage.rings.finite_rings + sage: f = H([(L.gen(2))*x^2 + L.gen(4)*y^2, x*y]) # optional - sage.rings.finite_rings + sage: f.reduce_base_field() # optional - sage.rings.finite_rings + Scheme endomorphism of Projective Space of dimension 1 + over Finite Field in z4 of size 5^4 Defn: Defined on coordinates by sending (x : y) to ((z4^3 + z4^2 + z4 - 2)*x^2 + z4*y^2 : x*y) - sage: f=DynamicalSystem_projective([L.gen(3)*x^2 + L.gen(2)*y^2, x*y]) - sage: f.reduce_base_field() - Dynamical System of Projective Space of dimension 1 over Finite Field in z6 of size 5^6 + sage: f = DynamicalSystem_projective([L.gen(3)*x^2 + L.gen(2)*y^2, x*y]) # optional - sage.rings.finite_rings + sage: f.reduce_base_field() # optional - sage.rings.finite_rings + Dynamical System of Projective Space of dimension 1 + over Finite Field in z6 of size 5^6 Defn: Defined on coordinates by sending (x : y) to - ((-z6^5 + z6^4 - z6^3 - z6^2 - 2*z6 - 2)*x^2 + (z6^5 - 2*z6^4 + z6^2 - z6 + 1)*y^2 : x*y) + ((-z6^5 + z6^4 - z6^3 - z6^2 - 2*z6 - 2)*x^2 + + (z6^5 - 2*z6^4 + z6^2 - z6 + 1)*y^2 : x*y) TESTS:: - sage: F = GF(3).algebraic_closure() - sage: P. = ProjectiveSpace(F, 1) - sage: H = Hom(P, P) - sage: f = H([x^2 + y^2, y^2]) - sage: f.reduce_base_field() + sage: F = GF(3).algebraic_closure() # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(F, 1) # optional - sage.rings.finite_rings + sage: H = Hom(P, P) # optional - sage.rings.finite_rings + sage: f = H([x^2 + y^2, y^2]) # optional - sage.rings.finite_rings + sage: f.reduce_base_field() # optional - sage.rings.finite_rings Scheme endomorphism of Projective Space of dimension 1 over Finite Field of size 3 Defn: Defined on coordinates by sending (x : y) to (x^2 + y^2 : y^2) @@ -2209,7 +2196,7 @@ def image(self): sage: P2. = ProjectiveSpace(QQ, 2) sage: A2. = AffineSpace(QQ, 2) - sage: f = P2.hom([1,x0/x1], A2) + sage: f = P2.hom([1, x0/x1], A2) sage: f.image() Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: -x + 1 @@ -2227,10 +2214,10 @@ def _fast_eval(self, x): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(7),2) - sage: H = Hom(P,P) - sage: f = H([x^2+y^2, y^2, z^2 + y*z]) - sage: f._fast_eval([1,1,1]) + sage: P. = ProjectiveSpace(GF(7), 2) # optional - sage.rings.finite_rings + sage: H = Hom(P, P) # optional - sage.rings.finite_rings + sage: f = H([x^2 + y^2, y^2, z^2 + y*z]) # optional - sage.rings.finite_rings + sage: f._fast_eval([1,1,1]) # optional - sage.rings.finite_rings [2, 1, 2] """ if self._is_prime_finite_field: @@ -2324,86 +2311,77 @@ def representatives(self): EXAMPLES:: - sage: P2. = ProjectiveSpace(QQ,2) + sage: P2. = ProjectiveSpace(QQ, 2) sage: X = P2.subscheme(0) sage: f = X.hom([x^2*y, x^2*z, x*y*z], P2) sage: f.representatives() [Scheme morphism: - From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - 0 + From: Closed subscheme of Projective Space of dimension 2 + over Rational Field defined by: 0 To: Projective Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x : y : z) to - (x*y : x*z : y*z)] + Defn: Defined on coordinates by sending (x : y : z) to (x*y : x*z : y*z)] :: - sage: P2. = ProjectiveSpace(QQ,2) - sage: P1. = ProjectiveSpace(QQ,1) + sage: P2. = ProjectiveSpace(QQ, 2) + sage: P1. = ProjectiveSpace(QQ, 1) sage: X = P2.subscheme([x^2 - y^2 - y*z]) sage: f = X.hom([x, y], P1) sage: f.representatives() [Scheme morphism: - From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y*z + From: Closed subscheme of Projective Space of dimension 2 + over Rational Field defined by: x^2 - y^2 - y*z To: Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y : z) to - (y + z : x), - Scheme morphism: - From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y*z + Defn: Defined on coordinates by sending (x : y : z) to (y + z : x), + Scheme morphism: + From: Closed subscheme of Projective Space of dimension 2 + over Rational Field defined by: x^2 - y^2 - y*z To: Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y : z) to - (x : y)] + Defn: Defined on coordinates by sending (x : y : z) to (x : y)] sage: g = _[0] sage: g.representatives() [Scheme morphism: - From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y*z + From: Closed subscheme of Projective Space of dimension 2 + over Rational Field defined by: x^2 - y^2 - y*z To: Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y : z) to - (y + z : x), - Scheme morphism: - From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y*z + Defn: Defined on coordinates by sending (x : y : z) to (y + z : x), + Scheme morphism: + From: Closed subscheme of Projective Space of dimension 2 + over Rational Field defined by: x^2 - y^2 - y*z To: Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y : z) to - (x : y)] + Defn: Defined on coordinates by sending (x : y : z) to (x : y)] :: - sage: P2. = ProjectiveSpace(QQ,2) + sage: P2. = ProjectiveSpace(QQ, 2) sage: X = P2.subscheme([x^2 - y^2 - y*z]) - sage: A1. = AffineSpace(QQ,1) + sage: A1. = AffineSpace(QQ, 1) sage: g = X.hom([y/x], A1) sage: g.representatives() [Scheme morphism: - From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y*z + From: Closed subscheme of Projective Space of dimension 2 + over Rational Field defined by: x^2 - y^2 - y*z To: Affine Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y : z) to - (x/(y + z)), - Scheme morphism: - From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y*z + Defn: Defined on coordinates by sending (x : y : z) to (x/(y + z)), + Scheme morphism: + From: Closed subscheme of Projective Space of dimension 2 + over Rational Field defined by: x^2 - y^2 - y*z To: Affine Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y : z) to - (y/x)] + Defn: Defined on coordinates by sending (x : y : z) to (y/x)] sage: g0, g1 = _ sage: emb = A1.projective_embedding(0) sage: emb*g0 Scheme morphism: - From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y*z + From: Closed subscheme of Projective Space of dimension 2 + over Rational Field defined by: x^2 - y^2 - y*z To: Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y : z) to - (y + z : x) + Defn: Defined on coordinates by sending (x : y : z) to (y + z : x) sage: emb*g1 Scheme morphism: - From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x^2 - y^2 - y*z + From: Closed subscheme of Projective Space of dimension 2 + over Rational Field defined by: x^2 - y^2 - y*z To: Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y : z) to - (x : y) + Defn: Defined on coordinates by sending (x : y : z) to (x : y) ALGORITHM: @@ -2490,7 +2468,7 @@ def indeterminacy_locus(self): :: sage: P2. = ProjectiveSpace(QQ, 2) - sage: P1. = ProjectiveSpace(QQ,1) + sage: P1. = ProjectiveSpace(QQ, 1) sage: X = P2.subscheme([x^2 - y^2 - y*z]) sage: f = X.hom([x,y], P1) sage: f.indeterminacy_locus() @@ -2572,7 +2550,7 @@ def is_morphism(self): EXAMPLES:: sage: P2. = ProjectiveSpace(QQ,2) - sage: P1. = ProjectiveSpace(QQ,1) + sage: P1. = ProjectiveSpace(QQ, 1) sage: X = P2.subscheme([x^2 - y^2 - y*z]) sage: f = X.hom([x,y], P1) sage: f.is_morphism() @@ -2653,11 +2631,11 @@ def graph(self): sage: phi = X.hom([x^2], A1) sage: mor = phi.homogenize(0) sage: G = mor.graph(); G - Closed subscheme of Product of projective spaces P^1 x P^1 over Rational Field defined by: - x1^2*x2 - x0^2*x3 + Closed subscheme of Product of projective spaces P^1 x P^1 + over Rational Field defined by: x1^2*x2 - x0^2*x3 sage: G.affine_patch([0, 0]) - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x0^2 - x1 + Closed subscheme of Affine Space of dimension 2 + over Rational Field defined by: x0^2 - x1 """ X = self.domain() Y = self.codomain() @@ -2703,12 +2681,12 @@ def projective_degrees(self): EXAMPLES:: - sage: k = GF(11) - sage: E = EllipticCurve(k,[1,1]) - sage: Q = E(6,5) - sage: phi = E.scalar_multiplication(2) - sage: mor = phi.as_morphism() - sage: mor.projective_degrees() + sage: k = GF(11) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(k, [1,1]) # optional - sage.rings.finite_rings + sage: Q = E(6, 5) # optional - sage.rings.finite_rings + sage: phi = E.scalar_multiplication(2) # optional - sage.rings.finite_rings + sage: mor = phi.as_morphism() # optional - sage.rings.finite_rings + sage: mor.projective_degrees() # optional - sage.rings.finite_rings (12, 3) """ X = self.domain() @@ -2745,12 +2723,12 @@ def degree(self): EXAMPLES:: - sage: k = GF(11) - sage: E = EllipticCurve(k,[1,1]) - sage: Q = E(6,5) - sage: phi = E.scalar_multiplication(2) - sage: mor = phi.as_morphism() - sage: mor.degree() + sage: k = GF(11) # optional - sage.rings.finite_rings + sage: E = EllipticCurve(k, [1,1]) # optional - sage.rings.finite_rings + sage: Q = E(6, 5) # optional - sage.rings.finite_rings + sage: phi = E.scalar_multiplication(2) # optional - sage.rings.finite_rings + sage: mor = phi.as_morphism() # optional - sage.rings.finite_rings + sage: mor.degree() # optional - sage.rings.finite_rings 4 """ return self.projective_degrees()[0] // self.image().degree() diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index d7441f0f463..5844592b1ed 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -105,7 +105,8 @@ def __init__(self, X, v, check=True): sage: P(0,0,0,0) Traceback (most recent call last): ... - ValueError: [0, 0, 0, 0] does not define a point in Projective Space of dimension 3 over Integer Ring since all entries are zero + ValueError: [0, 0, 0, 0] does not define a point in Projective Space of dimension 3 + over Integer Ring since all entries are zero :: @@ -119,7 +120,8 @@ def __init__(self, X, v, check=True): sage: P(0,5,10,15) Traceback (most recent call last): ... - ValueError: [0, 5, 10, 0] does not define a point in Projective Space of dimension 3 over Ring of integers modulo 15 since it is a multiple of a zero divisor + ValueError: [0, 5, 10, 0] does not define a point in Projective Space of dimension 3 + over Ring of integers modulo 15 since it is a multiple of a zero divisor It is possible to avoid the possibly time-consuming checks, but be careful!! :: @@ -130,20 +132,20 @@ def __init__(self, X, v, check=True): :: sage: P. = ProjectiveSpace(2, ZZ) - sage: X = P.subscheme([x^2-y*z]) + sage: X = P.subscheme([x^2 - y*z]) sage: X([2, 2, 2]) (2 : 2 : 2) :: sage: R. = PolynomialRing(ZZ) - sage: P = ProjectiveSpace(1, R.quo(t^2+1)) + sage: P = ProjectiveSpace(1, R.quo(t^2 + 1)) sage: P([2*t, 1]) (2*tbar : 1) :: - sage: P = ProjectiveSpace(ZZ,1) + sage: P = ProjectiveSpace(ZZ, 1) sage: P.point(Infinity) (1 : 0) sage: P(infinity) @@ -151,7 +153,7 @@ def __init__(self, X, v, check=True): :: - sage: P = ProjectiveSpace(ZZ,2) + sage: P = ProjectiveSpace(ZZ, 2) sage: P(Infinity) Traceback (most recent call last): ... @@ -234,17 +236,17 @@ def _richcmp_(self, right, op): :: - sage: PS = ProjectiveSpace(Zp(5), 1, 'x') - sage: P = PS([0, 1]) - sage: P == PS(0) + sage: PS = ProjectiveSpace(Zp(5), 1, 'x') # optional - sage.rings.padics + sage: P = PS([0, 1]) # optional - sage.rings.padics + sage: P == PS(0) # optional - sage.rings.padics True :: sage: R. = PolynomialRing(QQ) sage: PS = ProjectiveSpace(R, 1, 'x') - sage: P = PS([t, 1+t^2]) - sage: Q = PS([t^2, t+t^3]) + sage: P = PS([t, 1 + t^2]) + sage: Q = PS([t^2, t + t^3]) sage: P == Q True @@ -259,9 +261,9 @@ def _richcmp_(self, right, op): sage: PS = ProjectiveSpace(ZZ, 1, 'x') sage: P = PS([2, 1]) - sage: PS2 = ProjectiveSpace(Zp(7), 1, 'x') - sage: Q = PS2([2, 1]) - sage: P == Q + sage: PS2 = ProjectiveSpace(Zp(7), 1, 'x') # optional - sage.rings.padics + sage: Q = PS2([2, 1]) # optional - sage.rings.padics + sage: P == Q # optional - sage.rings.padics True :: @@ -283,23 +285,23 @@ def _richcmp_(self, right, op): :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(z^2+5) - sage: OK = K.ring_of_integers() - sage: t = OK.gen(1) - sage: PS. = ProjectiveSpace(OK,1) - sage: P = PS(2, 1+t) - sage: Q = PS(1-t, 3) - sage: P == Q + sage: K. = NumberField(z^2 + 5) # optional - sage.rings.number_field + sage: OK = K.ring_of_integers() # optional - sage.rings.number_field + sage: t = OK.gen(1) # optional - sage.rings.number_field + sage: PS. = ProjectiveSpace(OK, 1) # optional - sage.rings.number_field + sage: P = PS(2, 1 + t) # optional - sage.rings.number_field + sage: Q = PS(1 - t, 3) # optional - sage.rings.number_field + sage: P == Q # optional - sage.rings.number_field True Check that :trac:`17429` is fixed:: sage: R. = PolynomialRing(QQ) - sage: r = (x^2-x-3).polynomial(x).roots(ComplexIntervalField(), multiplicities=False) + sage: r = (x^2 - x - 3).polynomial(x).roots(ComplexIntervalField(), multiplicities=False) sage: P. = ProjectiveSpace(ComplexIntervalField(), 1) sage: P1 = P(r[0], 1) sage: H = End(P) - sage: f = H([x^2-3*y^2, y^2]) + sage: f = H([x^2 - 3*y^2, y^2]) sage: Q1 = f(P1) sage: Q1 == P1 False @@ -322,17 +324,17 @@ def _richcmp_(self, right, op): :: - sage: PS = ProjectiveSpace(Zp(5), 1, 'x') - sage: P = PS([0, 1]) - sage: P != PS(0) + sage: PS = ProjectiveSpace(Zp(5), 1, 'x') # optional - sage.rings.padics + sage: P = PS([0, 1]) # optional - sage.rings.padics + sage: P != PS(0) # optional - sage.rings.padics False :: sage: R. = PolynomialRing(QQ) sage: PS = ProjectiveSpace(R, 1, 'x') - sage: P = PS([t, 1+t^2]) - sage: Q = PS([t^2, t+t^3]) + sage: P = PS([t, 1 + t^2]) + sage: Q = PS([t^2, t + t^3]) sage: P != Q False @@ -347,9 +349,9 @@ def _richcmp_(self, right, op): sage: PS = ProjectiveSpace(ZZ, 1, 'x') sage: P = PS([2, 1]) - sage: PS2 = ProjectiveSpace(Zp(7), 1, 'x') - sage: Q = PS2([2, 1]) - sage: P != Q + sage: PS2 = ProjectiveSpace(Zp(7), 1, 'x') # optional - sage.rings.padics + sage: Q = PS2([2, 1]) # optional - sage.rings.padics + sage: P != Q # optional - sage.rings.padics False :: @@ -395,10 +397,10 @@ def __hash__(self): :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2 + 3) - sage: O = K.maximal_order() - sage: P. = ProjectiveSpace(O, 1) - sage: hash(P([1+w, 2])) == hash(P([2, 1-w])) + sage: K. = NumberField(x^2 + 3) # optional - sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(O, 1) # optional - sage.rings.number_field + sage: hash(P([1 + w, 2])) == hash(P([2, 1 - w])) # optional - sage.rings.number_field True TESTS:: @@ -407,9 +409,9 @@ def __hash__(self): sage: Q. = ProjectiveSpace(Zmod(10), 1) sage: hash(P([2, 5])) == hash(Q([2, 5])) True - sage: hash(P([2, 5])) == hash(P([2,5])) + sage: hash(P([2, 5])) == hash(P([2, 5])) True - sage: hash(P([3, 7])) == hash(P([2,5])) + sage: hash(P([3, 7])) == hash(P([2, 5])) True """ R = self.codomain().base_ring() @@ -437,35 +439,35 @@ def _matrix_times_point_(self, mat, dom): EXAMPLES:: - sage: P = ProjectiveSpace(QQ,1) + sage: P = ProjectiveSpace(QQ, 1) sage: Q = P(1,1) - sage: m = matrix(QQ, 2, 2, [1,1,0,1]) + sage: m = matrix(QQ, 2, 2, [1,1, 0,1]) sage: m*Q (2 : 1) :: - sage: P. = ProjectiveSpace(QQ,2) - sage: X = P.subscheme(x-y) + sage: P. = ProjectiveSpace(QQ, 2) + sage: X = P.subscheme(x - y) sage: Q = X(1,1) - sage: m = matrix(CC, 3, 3, [1,CC.0,0,CC.0,1,0,1,1,1]) + sage: m = matrix(CC, 3, 3, [1,CC.0,0, CC.0,1,0, 1,1,1]) sage: m*Q (0.333333333333333 + 0.333333333333333*I : 0.333333333333333 + 0.333333333333333*I : 1.00000000000000) :: - sage: P = ProjectiveSpace(QQbar,1) - sage: Q = P(QQbar(sqrt(2)),1) - sage: m = matrix(ZZ, 2, 2, [1,-1,0,1]) - sage: m*Q + sage: P = ProjectiveSpace(QQbar, 1) # optional - sage.rings.number_field + sage: Q = P(QQbar(sqrt(2)),1) # optional - sage.rings.number_field sage.symbolic + sage: m = matrix(ZZ, 2, 2, [1,-1, 0,1]) # optional - sage.rings.number_field sage.symbolic + sage: m*Q # optional - sage.rings.number_field sage.symbolic (0.4142135623730951? : 1) :: - sage: P = ProjectiveSpace(QQ,1) + sage: P = ProjectiveSpace(QQ, 1) sage: Q = P(1,1) - sage: m = matrix(QQ, 3, 2, [1,1,0,1,1,1]) + sage: m = matrix(QQ, 3, 2, [1,1, 0,1, 1,1]) sage: m*Q Traceback (most recent call last): ... @@ -537,29 +539,29 @@ def normalize_coordinates(self): EXAMPLES:: - sage: P = ProjectiveSpace(ZZ,2,'x') + sage: P = ProjectiveSpace(ZZ, 2, 'x') sage: p = P([-5, -15, -20]) sage: p.normalize_coordinates(); p (1 : 3 : 4) :: - sage: P = ProjectiveSpace(Zp(7),2,'x') - sage: p = P([-5, -15, -2]) - sage: p.normalize_coordinates(); p + sage: P = ProjectiveSpace(Zp(7), 2, 'x') # optional - sage.rings.padics + sage: p = P([-5, -15, -2]) # optional - sage.rings.padics + sage: p.normalize_coordinates(); p # optional - sage.rings.padics (5 + O(7^20) : 1 + 2*7 + O(7^20) : 2 + O(7^20)) :: sage: R. = PolynomialRing(QQ) - sage: P = ProjectiveSpace(R,2,'x') + sage: P = ProjectiveSpace(R, 2, 'x') sage: p = P([3/5*t^3, 6*t, t]) sage: p.normalize_coordinates(); p (3/5*t^2 : 6 : 1) :: - sage: P. = ProjectiveSpace(Zmod(20),1) + sage: P. = ProjectiveSpace(Zmod(20), 1) sage: Q = P(3, 6) sage: Q.normalize_coordinates() sage: Q @@ -569,7 +571,7 @@ def normalize_coordinates(self): gcd `c` is removed. :: sage: R. = PolynomialRing(QQ) - sage: P = ProjectiveSpace(R,1) + sage: P = ProjectiveSpace(R, 1) sage: Q = P(2*c, 4*c) sage: Q.normalize_coordinates();Q (2 : 4) @@ -577,17 +579,17 @@ def normalize_coordinates(self): A polynomial ring over a ring gives the more intuitive result. :: sage: R. = PolynomialRing(ZZ) - sage: P = ProjectiveSpace(R,1) + sage: P = ProjectiveSpace(R, 1) sage: Q = P(2*c, 4*c) sage: Q.normalize_coordinates();Q (1 : 2) :: - sage: R. = PolynomialRing(QQ,1) + sage: R. = PolynomialRing(QQ, 1) sage: S = R.quotient_ring(R.ideal(t^3)) - sage: P. = ProjectiveSpace(S,1) - sage: Q = P(t+1, t^2+t) + sage: P. = ProjectiveSpace(S, 1) + sage: Q = P(t + 1, t^2 + t) sage: Q.normalize_coordinates() sage: Q (1 : tbar) @@ -636,8 +638,8 @@ def dehomogenize(self,n): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,2) - sage: X = P.subscheme(x^2-y^2); + sage: P. = ProjectiveSpace(QQ, 2) + sage: X = P.subscheme(x^2 - y^2) sage: Q = X(23, 23, 46) sage: Q.dehomogenize(2) (1/2, 1/2) @@ -646,23 +648,23 @@ def dehomogenize(self,n): sage: R. = PolynomialRing(QQ) sage: S = R.quo(R.ideal(t^3)) - sage: P. = ProjectiveSpace(S,2) + sage: P. = ProjectiveSpace(S, 2) sage: Q = P(t, 1, 1) sage: Q.dehomogenize(1) (tbar, 1) :: - sage: P. = ProjectiveSpace(GF(5),2) - sage: Q = P(1, 3, 1) - sage: Q.dehomogenize(0) + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: Q = P(1, 3, 1) # optional - sage.rings.finite_rings + sage: Q.dehomogenize(0) # optional - sage.rings.finite_rings (3, 1) :: - sage: P.= ProjectiveSpace(GF(5),2) - sage: Q = P(1, 3, 0) - sage: Q.dehomogenize(2) + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: Q = P(1, 3, 0) # optional - sage.rings.finite_rings + sage: Q.dehomogenize(2) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: can...t dehomogenize at 0 coordinate @@ -692,14 +694,14 @@ def global_height(self, prec=None): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,2) + sage: P. = ProjectiveSpace(QQ, 2) sage: Q = P.point([4, 4, 1/30]) sage: Q.global_height() 4.78749174278205 :: - sage: P. = ProjectiveSpace(ZZ,2) + sage: P. = ProjectiveSpace(ZZ, 2) sage: Q = P([4, 1, 30]) sage: Q.global_height() 3.40119738166216 @@ -707,36 +709,36 @@ def global_height(self, prec=None): :: sage: R. = PolynomialRing(QQ) - sage: k. = NumberField(x^2+5) - sage: A = ProjectiveSpace(k, 2, 'z') - sage: A([3, 5*w+1, 1]).global_height(prec=100) + sage: k. = NumberField(x^2 + 5) # optional - sage.rings.number_field + sage: A = ProjectiveSpace(k, 2, 'z') # optional - sage.rings.number_field + sage: A([3, 5*w + 1, 1]).global_height(prec=100) # optional - sage.rings.number_field 2.4181409534757389986565376694 :: - sage: P. = ProjectiveSpace(QQbar,2) - sage: Q = P([QQbar(sqrt(3)), QQbar(sqrt(-2)), 1]) - sage: Q.global_height() + sage: P. = ProjectiveSpace(QQbar, 2) # optional - sage.rings.number_field + sage: Q = P([QQbar(sqrt(3)), QQbar(sqrt(-2)), 1]) # optional - sage.rings.number_field + sage: Q.global_height() # optional - sage.rings.number_field 0.549306144334055 :: - sage: K = UniversalCyclotomicField() - sage: P. = ProjectiveSpace(K,2) - sage: Q = P.point([K(4/3), K.gen(7), K.gen(5)]) - sage: Q.global_height() + sage: K = UniversalCyclotomicField() # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: Q = P.point([K(4/3), K.gen(7), K.gen(5)]) # optional - sage.rings.number_field + sage: Q.global_height() # optional - sage.rings.number_field 1.38629436111989 TESTS:: sage: P = ProjectiveSpace(QQ, 2) - sage: P(1/1,2/3,5/8).global_height() + sage: P(1/1, 2/3, 5/8).global_height() 3.17805383034795 sage: x = polygen(QQ, 'x') - sage: F. = NumberField(x^3 - 5) - sage: P = ProjectiveSpace(F, 2) - sage: P(u,u^2/5,1).global_height() + sage: F. = NumberField(x^3 - 5) # optional - sage.rings.number_field + sage: P = ProjectiveSpace(F, 2) # optional - sage.rings.number_field + sage: P(u, u^2/5, 1).global_height() # optional - sage.rings.number_field 1.07295860828940 """ if prec is None: @@ -784,14 +786,14 @@ def local_height(self, v, prec=None): EXAMPLES:: - sage: P.= ProjectiveSpace(QQ,2) - sage: Q = P.point([4,4,1/150], False) + sage: P. = ProjectiveSpace(QQ, 2) + sage: Q = P.point([4, 4, 1/150], False) sage: Q.local_height(5) 3.21887582486820 :: - sage: P. = ProjectiveSpace(QQ,2) + sage: P. = ProjectiveSpace(QQ, 2) sage: Q = P([4, 1, 30]) sage: Q.local_height(2) 0.693147180559945 @@ -818,16 +820,16 @@ def local_height_arch(self, i, prec=None): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,2) + sage: P. = ProjectiveSpace(QQ, 2) sage: Q = P.point([4, 4, 1/150], False) sage: Q.local_height_arch(0) 1.38629436111989 :: - sage: P. = ProjectiveSpace(QuadraticField(5, 'w'), 2) - sage: Q = P.point([4, 1, 30], False) - sage: Q.local_height_arch(1) + sage: P. = ProjectiveSpace(QuadraticField(5, 'w'), 2) # optional - sage.rings.number_field + sage: Q = P.point([4, 1, 30], False) # optional - sage.rings.number_field + sage: Q.local_height_arch(1) # optional - sage.rings.number_field 3.401197381662155375413236691607 """ K = FractionField(self.domain().base_ring()) @@ -859,9 +861,9 @@ def multiplier(self, f, n, check=True): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,3) + sage: P. = ProjectiveSpace(QQ, 3) sage: f = DynamicalSystem_projective([x^2, y^2, 4*w^2, 4*z^2], domain=P) - sage: Q = P.point([4, 4, 1, 1], False); + sage: Q = P.point([4, 4, 1, 1], False) sage: Q.multiplier(f, 1) [ 2 0 -8] [ 0 2 -8] @@ -911,21 +913,21 @@ def is_preperiodic(self, f, err=0.1, return_period=False): - boolean -- ``True`` if preperiodic. - - if return_period is ``True``, then ``(0,0)`` if wandering, and ``(m,n)`` - if preperiod ``m`` and period ``n``. + - if ``return_period`` is ``True``, then ``(0,0)`` if wandering, and ``(m,n)`` + if preperiod ``m`` and period ``n``. EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^3-3*x*y^2, y^3], domain=P) + sage: P. = ProjectiveSpace(QQ, 1) + sage: f = DynamicalSystem_projective([x^3 - 3*x*y^2, y^3], domain=P) sage: Q = P(-1, 1) sage: Q.is_preperiodic(f) True :: - sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2-29/16*y^2, y^2], domain=P) + sage: P. = ProjectiveSpace(QQ, 1) + sage: f = DynamicalSystem_projective([x^2 - 29/16*y^2, y^2], domain=P) sage: Q = P(1, 4) sage: Q.is_preperiodic(f, return_period=True) (1, 3) @@ -936,30 +938,37 @@ def is_preperiodic(self, f, err=0.1, return_period=False): :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2+1) - sage: P. = ProjectiveSpace(K, 1) - sage: f = DynamicalSystem_projective([x^5 + 5/4*x*y^4, y^5], domain=P) - sage: Q = P([-1/2*a+1/2, 1]) - sage: Q.is_preperiodic(f) + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: f = DynamicalSystem_projective([x^5 + 5/4*x*y^4, y^5], domain=P) # optional - sage.rings.number_field + sage: Q = P([-1/2*a + 1/2, 1]) # optional - sage.rings.number_field + sage: Q.is_preperiodic(f) # optional - sage.rings.number_field True - sage: Q = P([a, 1]) - sage: Q.is_preperiodic(f) + sage: Q = P([a, 1]) # optional - sage.rings.number_field + sage: Q.is_preperiodic(f) # optional - sage.rings.number_field False :: - sage: P. = ProjectiveSpace(QQ,2) - sage: f = DynamicalSystem_projective([-38/45*x^2 + (2*y - 7/45*z)*x + (-1/2*y^2 - 1/2*y*z + z^2),\ - -67/90*x^2 + (2*y + z*157/90)*x - y*z, z^2], domain=P) + sage: P. = ProjectiveSpace(QQ, 2) + sage: f = DynamicalSystem_projective([ + ....: -38/45*x^2 + (2*y - 7/45*z)*x + (-1/2*y^2 - 1/2*y*z + z^2), + ....: -67/90*x^2 + (2*y + z*157/90)*x - y*z, + ....: z^2 + ....: ], domain=P) sage: Q = P([1, 3, 1]) sage: Q.is_preperiodic(f, return_period=True) (0, 9) :: - sage: P. = ProjectiveSpace(QQ,3) - sage: f = DynamicalSystem_projective([(-y - w)*x + (-13/30*y^2 + 13/30*w*y + w^2),\ - -1/2*x^2 + (-y + 3/2*w)*x + (-1/3*y^2 + 4/3*w*y),-3/2*z^2 + 5/2*z*w + w^2,w^2], domain=P) + sage: P. = ProjectiveSpace(QQ, 3) + sage: f = DynamicalSystem_projective([ + ....: (-y - w)*x + (-13/30*y^2 + 13/30*w*y + w^2), + ....: -1/2*x^2 + (-y + 3/2*w)*x + (-1/3*y^2 + 4/3*w*y), + ....: -3/2*z^2 + 5/2*z*w + w^2, + ....: w^2 + ....: ], domain=P) sage: Q = P([3,0,4/3,1]) sage: Q.is_preperiodic(f, return_period=True) (2, 24) @@ -968,42 +977,43 @@ def is_preperiodic(self, f, err=0.1, return_period=False): sage: from sage.misc.verbose import set_verbose sage: set_verbose(-1) - sage: P. = ProjectiveSpace(QQbar,2) - sage: f = DynamicalSystem_projective([x^2, QQbar(sqrt(-1))*y^2, z^2], domain=P) - sage: Q = P([1, 1, 1]) - sage: Q.is_preperiodic(f) + sage: P. = ProjectiveSpace(QQbar, 2) # optional - sage.rings.number_field + sage: f = DynamicalSystem_projective([x^2, QQbar(sqrt(-1))*y^2, z^2], # optional - sage.rings.number_field sage.symbolic + ....: domain=P) + sage: Q = P([1, 1, 1]) # optional - sage.rings.number_field sage.symbolic + sage: Q.is_preperiodic(f) # optional - sage.rings.number_field sage.symbolic True :: sage: set_verbose(-1) - sage: P. = ProjectiveSpace(QQbar,2) - sage: f = DynamicalSystem_projective([x^2, y^2, z^2], domain=P) - sage: Q = P([QQbar(sqrt(-1)), 1, 1]) - sage: Q.is_preperiodic(f) + sage: P. = ProjectiveSpace(QQbar, 2) # optional - sage.rings.number_field + sage: f = DynamicalSystem_projective([x^2, y^2, z^2], domain=P) # optional - sage.rings.number_field + sage: Q = P([QQbar(sqrt(-1)), 1, 1]) # optional - sage.rings.number_field sage.symbolic + sage: Q.is_preperiodic(f) # optional - sage.rings.number_field sage.symbolic True :: sage: P. = ProjectiveSpace(QQ, 1) - sage: f = DynamicalSystem_projective([16*x^2-29*y^2, 16*y^2], domain=P) + sage: f = DynamicalSystem_projective([16*x^2 - 29*y^2, 16*y^2], domain=P) sage: Q = P(-1,4) sage: Q.is_preperiodic(f) True :: - sage: P. =ProjectiveSpace(GF(3), 2) - sage: F = DynamicalSystem([x^2 - 2*y^2, y^2, z^2]) - sage: Q = P(1, 1, 1) - sage: Q.is_preperiodic(F, return_period=True) + sage: P. = ProjectiveSpace(GF(3), 2) # optional - sage.rings.finite_rings + sage: F = DynamicalSystem([x^2 - 2*y^2, y^2, z^2]) # optional - sage.rings.finite_rings + sage: Q = P(1, 1, 1) # optional - sage.rings.finite_rings + sage: Q.is_preperiodic(F, return_period=True) # optional - sage.rings.finite_rings (1, 1) TESTS:: sage: P. = ProjectiveSpace(QQ, 1) sage: H = End(P) - sage: f = H([16*x^2-29*y^2, 16*y^2]) + sage: f = H([16*x^2 - 29*y^2, 16*y^2]) sage: Q = P(-1,4) sage: Q.is_preperiodic(f) Traceback (most recent call last): @@ -1013,7 +1023,7 @@ def is_preperiodic(self, f, err=0.1, return_period=False): :: sage: P. = ProjectiveSpace(QQ, 1) - sage: f = DynamicalSystem_projective([16*x^2-29*y^2, 16*y^2]) + sage: f = DynamicalSystem_projective([16*x^2 - 29*y^2, 16*y^2]) sage: Q = P(11,4) sage: Q.is_preperiodic(f, err=2) False @@ -1067,25 +1077,26 @@ def __init__(self, X, v, check=True): sage: P(0, 0, 0, 0) Traceback (most recent call last): ... - ValueError: [0, 0, 0, 0] does not define a point in Projective Space of dimension 3 over Rational Field since all entries are zero + ValueError: [0, 0, 0, 0] does not define a point in Projective Space of dimension 3 + over Rational Field since all entries are zero :: sage: P. = ProjectiveSpace(2, QQ) - sage: X = P.subscheme([x^2-y*z]) + sage: X = P.subscheme([x^2 - y*z]) sage: X([2, 2, 2]) (1 : 1 : 1) :: - sage: P = ProjectiveSpace(1, GF(7)) - sage: Q=P([2, 1]) - sage: Q[0].parent() + sage: P = ProjectiveSpace(1, GF(7)) # optional - sage.rings.finite_rings + sage: Q = P([2, 1]) # optional - sage.rings.finite_rings + sage: Q[0].parent() # optional - sage.rings.finite_rings Finite Field of size 7 :: - sage: P = ProjectiveSpace(QQ,1) + sage: P = ProjectiveSpace(QQ, 1) sage: P.point(Infinity) (1 : 0) sage: P(infinity) @@ -1093,7 +1104,7 @@ def __init__(self, X, v, check=True): :: - sage: P = ProjectiveSpace(QQ,2) + sage: P = ProjectiveSpace(QQ, 2) sage: P(infinity) Traceback (most recent call last): ... @@ -1172,16 +1183,16 @@ def normalize_coordinates(self): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(5),2) - sage: Q = P.point([GF(5)(1), GF(5)(3), GF(5)(0)], False); Q + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: Q = P.point([GF(5)(1), GF(5)(3), GF(5)(0)], False); Q # optional - sage.rings.finite_rings (1 : 3 : 0) - sage: Q.normalize_coordinates(); Q + sage: Q.normalize_coordinates(); Q # optional - sage.rings.finite_rings (2 : 1 : 0) :: sage: P. = ProjectiveSpace(QQ, 2) - sage: X = P.subscheme(x^2-y^2); + sage: X = P.subscheme(x^2 - y^2); sage: Q = X.point([23, 23, 46], False); Q (23 : 23 : 46) sage: Q.normalize_coordinates(); Q @@ -1204,25 +1215,26 @@ def _number_field_from_algebraics(self): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: P. = ProjectiveSpace(QQbar,1) - sage: Q = P([-1/2*QQbar(sqrt(2)) + QQbar(I), 1]) - sage: S = Q._number_field_from_algebraics(); S + sage: P. = ProjectiveSpace(QQbar, 1) # optional - sage.rings.number_field + sage: Q = P([-1/2*QQbar(sqrt(2)) + QQbar(I), 1]) # optional - sage.rings.number_field sage.symbolic + sage: S = Q._number_field_from_algebraics(); S # optional - sage.rings.number_field sage.symbolic (1/2*a^3 + a^2 - 1/2*a : 1) - sage: S.codomain() - Projective Space of dimension 1 over Number Field in a with defining polynomial y^4 + 1 with a = 0.7071067811865475? + 0.7071067811865475?*I + sage: S.codomain() # optional - sage.rings.number_field sage.symbolic + Projective Space of dimension 1 over Number Field in a with defining + polynomial y^4 + 1 with a = 0.7071067811865475? + 0.7071067811865475?*I The following was fixed in :trac:`23808`:: sage: R. = PolynomialRing(QQ) - sage: P. = ProjectiveSpace(QQbar,1) - sage: Q = P([-1/2*QQbar(sqrt(2)) + QQbar(I), 1]);Q + sage: P. = ProjectiveSpace(QQbar, 1) # optional - sage.rings.number_field + sage: Q = P([-1/2*QQbar(sqrt(2)) + QQbar(I), 1]);Q # optional - sage.rings.number_field sage.symbolic (-0.7071067811865475? + 1*I : 1) - sage: S = Q._number_field_from_algebraics(); S + sage: S = Q._number_field_from_algebraics(); S # optional - sage.rings.number_field sage.symbolic (1/2*a^3 + a^2 - 1/2*a : 1) - sage: T = S.change_ring(QQbar) # Used to fail - sage: T + sage: T = S.change_ring(QQbar) # Used to fail # optional - sage.rings.number_field sage.symbolic + sage: T # optional - sage.rings.number_field sage.symbolic (-0.7071067811865475? + 1.000000000000000?*I : 1) - sage: Q[0] == T[0] + sage: Q[0] == T[0] # optional - sage.rings.number_field sage.symbolic True """ from sage.schemes.projective.projective_space import is_ProjectiveSpace @@ -1261,17 +1273,17 @@ def clear_denominators(self): :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2 - 3) - sage: P. = ProjectiveSpace(K, 2) - sage: Q = P([1/w, 3, 0]) - sage: Q.clear_denominators(); Q + sage: K. = NumberField(x^2 - 3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: Q = P([1/w, 3, 0]) # optional - sage.rings.number_field + sage: Q.clear_denominators(); Q # optional - sage.rings.number_field (w : 9 : 0) :: sage: P. = ProjectiveSpace(QQ, 2) - sage: X = P.subscheme(x^2 - y^2); - sage: Q = X([1/2, 1/2, 1]); + sage: X = P.subscheme(x^2 - y^2) + sage: Q = X([1/2, 1/2, 1]) sage: Q.clear_denominators(); Q (1 : 1 : 2) @@ -1363,27 +1375,27 @@ def __hash__(self): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: hash(P(2, 1, 2)) + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: hash(P(2, 1, 2)) # optional - sage.rings.finite_rings 41 :: - sage: P. = ProjectiveSpace(GF(7), 2) - sage: X = P.subscheme(x^2 - y^2) - sage: hash(X(1, 1, 2)) + sage: P. = ProjectiveSpace(GF(7), 2) # optional - sage.rings.finite_rings + sage: X = P.subscheme(x^2 - y^2) # optional - sage.rings.finite_rings + sage: hash(X(1, 1, 2)) # optional - sage.rings.finite_rings 81 :: - sage: P. = ProjectiveSpace(GF(13), 1) - sage: hash(P(3, 4)) + sage: P. = ProjectiveSpace(GF(13), 1) # optional - sage.rings.finite_rings + sage: hash(P(3, 4)) # optional - sage.rings.finite_rings 17 :: - sage: P. = ProjectiveSpace(GF(13^3,'t'), 1) - sage: hash(P(3, 4)) + sage: P. = ProjectiveSpace(GF(13^3,'t'), 1) # optional - sage.rings.finite_rings + sage: hash(P(3, 4)) # optional - sage.rings.finite_rings 2201 """ p = self.codomain().base_ring().order() diff --git a/src/sage/schemes/projective/projective_rational_point.py b/src/sage/schemes/projective/projective_rational_point.py index 738f28cb993..07de1170f66 100644 --- a/src/sage/schemes/projective/projective_rational_point.py +++ b/src/sage/schemes/projective/projective_rational_point.py @@ -15,8 +15,8 @@ Projective, over `\QQ`:: sage: from sage.schemes.projective.projective_rational_point import enum_projective_rational_field - sage: P. = ProjectiveSpace(2,QQ) - sage: C = P.subscheme([X+Y-Z]) + sage: P. = ProjectiveSpace(2, QQ) + sage: C = P.subscheme([X + Y - Z]) sage: enum_projective_rational_field(C, 3) [(-2 : 3 : 1), (-1 : 1 : 0), (-1 : 2 : 1), (-1/2 : 3/2 : 1), (0 : 1 : 1), (1/3 : 2/3 : 1), (1/2 : 1/2 : 1), (2/3 : 1/3 : 1), @@ -26,8 +26,8 @@ Projective over a finite field:: sage: from sage.schemes.projective.projective_rational_point import enum_projective_finite_field - sage: E = EllipticCurve('72').change_ring(GF(19)) - sage: enum_projective_finite_field(E) + sage: E = EllipticCurve('72').change_ring(GF(19)) # optional - sage.rings.finite_rings + sage: enum_projective_finite_field(E) # optional - sage.rings.finite_rings [(0 : 1 : 0), (1 : 0 : 1), (3 : 0 : 1), (4 : 9 : 1), (4 : 10 : 1), (6 : 6 : 1), (6 : 13 : 1), (7 : 6 : 1), (7 : 13 : 1), (9 : 4 : 1), (9 : 15 : 1), (12 : 8 : 1), (12 : 11 : 1), (13 : 8 : 1), (13 : 11 : 1), @@ -89,7 +89,7 @@ def enum_projective_rational_field(X, B): EXAMPLES:: sage: P. = ProjectiveSpace(2, QQ) - sage: C = P.subscheme([X+Y-Z]) + sage: C = P.subscheme([X + Y - Z]) sage: from sage.schemes.projective.projective_rational_point import enum_projective_rational_field sage: enum_projective_rational_field(C(QQ), 6) [(-5 : 6 : 1), (-4 : 5 : 1), (-3 : 4 : 1), (-2 : 3 : 1), @@ -110,15 +110,15 @@ def enum_projective_rational_field(X, B): sage: P3. = ProjectiveSpace(3, QQ) sage: enum_projective_rational_field(P3, 1) [(-1 : -1 : -1 : 1), (-1 : -1 : 0 : 1), (-1 : -1 : 1 : 0), (-1 : -1 : 1 : 1), - (-1 : 0 : -1 : 1), (-1 : 0 : 0 : 1), (-1 : 0 : 1 : 0), (-1 : 0 : 1 : 1), - (-1 : 1 : -1 : 1), (-1 : 1 : 0 : 0), (-1 : 1 : 0 : 1), (-1 : 1 : 1 : 0), - (-1 : 1 : 1 : 1), (0 : -1 : -1 : 1), (0 : -1 : 0 : 1), (0 : -1 : 1 : 0), - (0 : -1 : 1 : 1), (0 : 0 : -1 : 1), (0 : 0 : 0 : 1), (0 : 0 : 1 : 0), - (0 : 0 : 1 : 1), (0 : 1 : -1 : 1), (0 : 1 : 0 : 0), (0 : 1 : 0 : 1), - (0 : 1 : 1 : 0), (0 : 1 : 1 : 1), (1 : -1 : -1 : 1), (1 : -1 : 0 : 1), - (1 : -1 : 1 : 0), (1 : -1 : 1 : 1), (1 : 0 : -1 : 1), (1 : 0 : 0 : 0), - (1 : 0 : 0 : 1), (1 : 0 : 1 : 0), (1 : 0 : 1 : 1), (1 : 1 : -1 : 1), - (1 : 1 : 0 : 0), (1 : 1 : 0 : 1), (1 : 1 : 1 : 0), (1 : 1 : 1 : 1)] + (-1 : 0 : -1 : 1), (-1 : 0 : 0 : 1), (-1 : 0 : 1 : 0), (-1 : 0 : 1 : 1), + (-1 : 1 : -1 : 1), (-1 : 1 : 0 : 0), (-1 : 1 : 0 : 1), (-1 : 1 : 1 : 0), + (-1 : 1 : 1 : 1), (0 : -1 : -1 : 1), (0 : -1 : 0 : 1), (0 : -1 : 1 : 0), + (0 : -1 : 1 : 1), (0 : 0 : -1 : 1), (0 : 0 : 0 : 1), (0 : 0 : 1 : 0), + (0 : 0 : 1 : 1), (0 : 1 : -1 : 1), (0 : 1 : 0 : 0), (0 : 1 : 0 : 1), + (0 : 1 : 1 : 0), (0 : 1 : 1 : 1), (1 : -1 : -1 : 1), (1 : -1 : 0 : 1), + (1 : -1 : 1 : 0), (1 : -1 : 1 : 1), (1 : 0 : -1 : 1), (1 : 0 : 0 : 0), + (1 : 0 : 0 : 1), (1 : 0 : 1 : 0), (1 : 0 : 1 : 1), (1 : 1 : -1 : 1), + (1 : 1 : 0 : 0), (1 : 1 : 0 : 1), (1 : 1 : 1 : 0), (1 : 1 : 1 : 1)] ALGORITHM: @@ -187,20 +187,20 @@ def enum_projective_number_field(X, **kwds): sage: from sage.schemes.projective.projective_rational_point import enum_projective_number_field sage: u = QQ['u'].0 - sage: K = NumberField(u^3 - 5,'v') - 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) + sage: K = NumberField(u^3 - 5, 'v') # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: X = P.subscheme([x - y]) # optional - sage.rings.number_field + sage: enum_projective_number_field(X(K), bound=RR(5^(1/3)), prec=2^10) # optional - sage.rings.number_field [(0 : 0 : 1), (1 : 1 : 0), (-1 : -1 : 1), (1 : 1 : 1)] :: sage: u = QQ['u'].0 - sage: K = NumberField(u^2 + 3, 'v') - sage: A. = ProjectiveSpace(K,1) - sage: X = A.subscheme(x-y) + sage: K = NumberField(u^2 + 3, 'v') # optional - sage.rings.number_field + sage: A. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: X = A.subscheme(x - y) # optional - sage.rings.number_field sage: from sage.schemes.projective.projective_rational_point import enum_projective_number_field - sage: enum_projective_number_field(X, bound=2) + sage: enum_projective_number_field(X, bound=2) # optional - sage.rings.number_field [(1 : 1)] """ B = kwds.pop('bound') @@ -244,35 +244,35 @@ def enum_projective_finite_field(X): EXAMPLES:: - sage: F = GF(53) - sage: P. = ProjectiveSpace(2,F) + sage: F = GF(53) # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(2, F) # optional - sage.rings.finite_rings sage: from sage.schemes.projective.projective_rational_point import enum_projective_finite_field - sage: len(enum_projective_finite_field(P(F))) + sage: len(enum_projective_finite_field(P(F))) # optional - sage.rings.finite_rings 2863 - sage: 53^2+53+1 + sage: 53^2 + 53 + 1 2863 :: - sage: F = GF(9,'a') - sage: P. = ProjectiveSpace(2,F) - sage: C = Curve(X^3-Y^3+Z^2*Y) - sage: enum_projective_finite_field(C(F)) + sage: F = GF(9, 'a') # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(2,F) # optional - sage.rings.finite_rings + sage: C = Curve(X^3 - Y^3 + Z^2*Y) # optional - sage.rings.finite_rings + sage: enum_projective_finite_field(C(F)) # optional - sage.rings.finite_rings [(0 : 0 : 1), (0 : 1 : 1), (0 : 2 : 1), (1 : 1 : 0), (a + 1 : 2*a : 1), - (a + 1 : 2*a + 1 : 1), (a + 1 : 2*a + 2 : 1), (2*a + 2 : a : 1), - (2*a + 2 : a + 1 : 1), (2*a + 2 : a + 2 : 1)] + (a + 1 : 2*a + 1 : 1), (a + 1 : 2*a + 2 : 1), (2*a + 2 : a : 1), + (2*a + 2 : a + 1 : 1), (2*a + 2 : a + 2 : 1)] :: - sage: F = GF(5) - sage: P2F. = ProjectiveSpace(2,F) - sage: enum_projective_finite_field(P2F) + sage: F = GF(5) # optional - sage.rings.finite_rings + sage: P2F. = ProjectiveSpace(2, F) # optional - sage.rings.finite_rings + sage: enum_projective_finite_field(P2F) # optional - sage.rings.finite_rings [(0 : 0 : 1), (0 : 1 : 0), (0 : 1 : 1), (0 : 2 : 1), (0 : 3 : 1), (0 : 4 : 1), - (1 : 0 : 0), (1 : 0 : 1), (1 : 1 : 0), (1 : 1 : 1), (1 : 2 : 1), (1 : 3 : 1), - (1 : 4 : 1), (2 : 0 : 1), (2 : 1 : 0), (2 : 1 : 1), (2 : 2 : 1), (2 : 3 : 1), - (2 : 4 : 1), (3 : 0 : 1), (3 : 1 : 0), (3 : 1 : 1), (3 : 2 : 1), (3 : 3 : 1), - (3 : 4 : 1), (4 : 0 : 1), (4 : 1 : 0), (4 : 1 : 1), (4 : 2 : 1), (4 : 3 : 1), - (4 : 4 : 1)] + (1 : 0 : 0), (1 : 0 : 1), (1 : 1 : 0), (1 : 1 : 1), (1 : 2 : 1), (1 : 3 : 1), + (1 : 4 : 1), (2 : 0 : 1), (2 : 1 : 0), (2 : 1 : 1), (2 : 2 : 1), (2 : 3 : 1), + (2 : 4 : 1), (3 : 0 : 1), (3 : 1 : 0), (3 : 1 : 1), (3 : 2 : 1), (3 : 3 : 1), + (3 : 4 : 1), (4 : 0 : 1), (4 : 1 : 0), (4 : 1 : 1), (4 : 2 : 1), (4 : 3 : 1), + (4 : 4 : 1)] ALGORITHM: @@ -313,10 +313,10 @@ def sieve(X, bound): Returns the list of all projective, rational points on scheme ``X`` of height up to ``bound``. - Height of a projective point X = (x_1, x_2,..., x_n) is given by - H_X = max(y_1, y_2,..., y_n), where H_X is height of point X and y_i's - are the normalized coordinates such that all y_i are integers and - gcd(y_1, y_2,..., y_n) = 1. + Height of a projective point `X = (x_1, x_2,\dots, x_n)` is given by + `H_X = \max(y_1, y_2,\dots, y_n)`, where the values `y_i` + are the normalized coordinates such that all `y_i` are integers and + `\gcd(y_1, y_2,\dots, y_n) = 1`. ALGORITHM: @@ -343,8 +343,8 @@ def sieve(X, bound): EXAMPLES:: sage: from sage.schemes.projective.projective_rational_point import sieve - sage: P.=ProjectiveSpace(QQ,3) - sage: Y=P.subscheme([x^2-3^2*y^2+z*q,x+z+4*q]) + sage: P. = ProjectiveSpace(QQ, 3) + sage: Y = P.subscheme([x^2 - 3^2*y^2 + z*q, x + z + 4*q]) sage: sorted(sieve(Y, 12)) # long time [(-4 : -4/3 : 0 : 1), (-4 : 4/3 : 0 : 1), (-1 : -1/3 : 1 : 0), (-1 : 1/3 : 1 : 0)] @@ -364,7 +364,7 @@ def sieve(X, bound): Algorithm works even if coefficients are fraction:: sage: from sage.schemes.projective.projective_rational_point import sieve - sage: P. = ProjectiveSpace(2,QQ) + sage: P. = ProjectiveSpace(2, QQ) sage: X = P.subscheme(3*x - 3/2*y) sage: sieve(X, 3) [(-1 : -2 : 1), (-1/2 : -1 : 1), (-1/3 : -2/3 : 1), (0 : 0 : 1), diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index e215da942e1..221dca45981 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -28,7 +28,7 @@ Projective Space of dimension 5 over Complex Field with 53 bits of precision The third argument specifies the printing names of the generators of the -homogeneous coordinate ring. Using the method `.objgens()` you can obtain both +homogeneous coordinate ring. Using the method :meth:`objgens` you can obtain both the space and the generators as ready to use variables. :: sage: P2, vars = ProjectiveSpace(10, QQ, 't').objgens() @@ -55,10 +55,10 @@ :: - sage: V = P2.subscheme([x+y+z, x+y-z]); V + sage: V = P2.subscheme([x + y + z, x + y - z]); V Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x + y + z, - x + y - z + x + y + z, + x + y - z sage: V.dimension() 0 @@ -139,7 +139,7 @@ def is_ProjectiveSpace(x): sage: from sage.schemes.projective.projective_space import is_ProjectiveSpace sage: is_ProjectiveSpace(ProjectiveSpace(5, names='x')) True - sage: is_ProjectiveSpace(ProjectiveSpace(5, GF(9,'alpha'), names='x')) + sage: is_ProjectiveSpace(ProjectiveSpace(5, GF(9, 'alpha'), names='x')) # optional - sage.rings.finite_rings True sage: is_ProjectiveSpace(Spec(ZZ)) False @@ -168,7 +168,7 @@ def ProjectiveSpace(n, R=None, names=None): :: - sage: ProjectiveSpace(5)/GF(17) + sage: ProjectiveSpace(5)/GF(17) # optional - sage.rings.finite_rings Projective Space of dimension 5 over Finite Field of size 17 The default base ring is `\ZZ`. @@ -182,27 +182,27 @@ def ProjectiveSpace(n, R=None, names=None): :: - sage: R = GF(7)['x,y,z'] - sage: P = ProjectiveSpace(R); P + sage: R = GF(7)['x,y,z'] # optional - sage.rings.finite_rings + sage: P = ProjectiveSpace(R); P # optional - sage.rings.finite_rings Projective Space of dimension 2 over Finite Field of size 7 - sage: P.coordinate_ring() + sage: P.coordinate_ring() # optional - sage.rings.finite_rings Multivariate Polynomial Ring in x, y, z over Finite Field of size 7 - sage: P.coordinate_ring() is R + sage: P.coordinate_ring() is R # optional - sage.rings.finite_rings True :: - sage: ProjectiveSpace(3, Zp(5), 'y') + sage: ProjectiveSpace(3, Zp(5), 'y') # optional - sage.rings.padics Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20 :: - sage: ProjectiveSpace(2,QQ,'x,y,z') + sage: ProjectiveSpace(2, QQ, 'x,y,z') Projective Space of dimension 2 over Rational Field :: - sage: PS.=ProjectiveSpace(1,CC) + sage: PS. = ProjectiveSpace(1, CC) sage: PS Projective Space of dimension 1 over Complex Field with 53 bits of precision @@ -224,7 +224,7 @@ def ProjectiveSpace(n, R=None, names=None): TESTS:: - sage: R.=QQ[] + sage: R. = QQ[] sage: P. = ProjectiveSpace(R) Traceback (most recent call last): ... @@ -232,7 +232,7 @@ def ProjectiveSpace(n, R=None, names=None): :: - sage: R.=QQ[] + sage: R. = QQ[] sage: P. = ProjectiveSpace(R) sage: P.gens() == R.gens() True @@ -335,7 +335,7 @@ def __init__(self, n, R=ZZ, names=None): EXAMPLES:: - sage: ProjectiveSpace(3, Zp(5), 'y') + sage: ProjectiveSpace(3, Zp(5), 'y') # optional - sage.rings.padics Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20 """ AmbientSpace.__init__(self, n, R) @@ -345,7 +345,7 @@ def ngens(self): """ Return the number of generators of this projective space. - This is the number of variables in the coordinate ring of self. + This is the number of variables in the coordinate ring of ``self``. EXAMPLES:: @@ -417,7 +417,7 @@ def coordinate_ring(self): EXAMPLES:: - sage: ProjectiveSpace(3, GF(19^2,'alpha'), 'abcd').coordinate_ring() + sage: ProjectiveSpace(3, GF(19^2,'alpha'), 'abcd').coordinate_ring() # optional - sage.rings.finite_rings Multivariate Polynomial Ring in a, b, c, d over Finite Field in alpha of size 19^2 :: @@ -588,7 +588,7 @@ def _latex_(self): TESTS:: - sage: ProjectiveSpace(3, Zp(5), 'y')._latex_() + sage: ProjectiveSpace(3, Zp(5), 'y')._latex_() # optional - sage.rings.padics '{\\mathbf P}_{\\Bold{Z}_{5}}^3' """ return "{\\mathbf P}_{%s}^%s" % (latex(self.base_ring()), @@ -604,7 +604,7 @@ def _linear_system_as_kernel(self, d, pt, m): - ``d`` -- a nonnegative integer. - - ``pt`` -- a point of self (possibly represented by a list with at \ + - ``pt`` -- a point of ``self`` (possibly represented by a list with at \ least one component equal to 1). - ``m`` -- a nonnegative integer. @@ -612,17 +612,17 @@ def _linear_system_as_kernel(self, d, pt, m): OUTPUT: A matrix of size `\binom{m-1+n}{n}` x `\binom{d+n}{n}` where n is the - relative dimension of self. The base ring of the matrix is a ring that - contains the base ring of self and the coefficients of the given point. + relative dimension of ``self``. The base ring of the matrix is a ring that + contains the base ring of ``self`` and the coefficients of the given point. EXAMPLES: If the degree `d` is 0, then a matrix consisting of the first unit vector is returned:: - sage: P = ProjectiveSpace(GF(5), 2, names='x') - sage: pt = P([1, 1, 1]) - sage: P._linear_system_as_kernel(0, pt, 3) + sage: P = ProjectiveSpace(GF(5), 2, names='x') # optional - sage.rings.finite_rings + sage: pt = P([1, 1, 1]) # optional - sage.rings.finite_rings + sage: P._linear_system_as_kernel(0, pt, 3) # optional - sage.rings.finite_rings [1] [0] [0] @@ -633,10 +633,10 @@ def _linear_system_as_kernel(self, d, pt, m): If the multiplicity `m` is 0, then a matrix with zero rows is returned:: - sage: P = ProjectiveSpace(GF(5), 2, names='x') - sage: pt = P([1, 1, 1]) - sage: M = P._linear_system_as_kernel(2, pt, 0) - sage: [M.nrows(), M.ncols()] + sage: P = ProjectiveSpace(GF(5), 2, names='x') # optional - sage.rings.finite_rings + sage: pt = P([1, 1, 1]) # optional - sage.rings.finite_rings + sage: M = P._linear_system_as_kernel(2, pt, 0) # optional - sage.rings.finite_rings + sage: [M.nrows(), M.ncols()] # optional - sage.rings.finite_rings [0, 6] The base ring does not need to be a field or even an integral domain. @@ -654,14 +654,13 @@ def _linear_system_as_kernel(self, d, pt, m): (even when the base ring is a field and the list gives a well-defined point in projective space):: - sage: R = GF(5) - sage: P = ProjectiveSpace(R, 2, names='x') - sage: pt = [R(3), R(3), R(0)] - sage: P._linear_system_as_kernel(3, pt, 2) + sage: R = GF(5) # optional - sage.rings.finite_rings + sage: P = ProjectiveSpace(R, 2, names='x') # optional - sage.rings.finite_rings + sage: pt = [R(3), R(3), R(0)] # optional - sage.rings.finite_rings + sage: P._linear_system_as_kernel(3, pt, 2) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: at least one component of pt=[3, 3, 0] must be equal - to 1 + TypeError: at least one component of pt=[3, 3, 0] must be equal to 1 The components of the list do not have to be elements of the base ring of the projective space. It suffices if there exists a common parent. @@ -669,10 +668,10 @@ def _linear_system_as_kernel(self, d, pt, m): hypersurfaces of degree 2 in 3-space with multiplicity at least 2 at a general point in the third affine patch:: - sage: P = ProjectiveSpace(QQ,3,names='x') - sage: RPol. = PolynomialRing(QQ,4) + sage: P = ProjectiveSpace(QQ, 3, names='x') + sage: RPol. = PolynomialRing(QQ, 4) sage: pt = [t0,t1,1,t3] - sage: P._linear_system_as_kernel(2,pt,2) + sage: P._linear_system_as_kernel(2, pt, 2) [ 2*t0 t1 1 t3 0 0 0 0 0 0] [ 0 t0 0 0 2*t1 1 t3 0 0 0] [ t0^2 t0*t1 t0 t0*t3 t1^2 t1 t1*t3 1 t3 t3^2] @@ -734,8 +733,8 @@ def _morphism(self, *args, **kwds): TESTS:: - sage: P2. = ProjectiveSpace(2, GF(3)) - sage: P2._morphism(P2.Hom(P2), [x,y,z]) + sage: P2. = ProjectiveSpace(2, GF(3)) # optional - sage.rings.finite_rings + sage: P2._morphism(P2.Hom(P2), [x,y,z]) # optional - sage.rings.finite_rings Scheme endomorphism of Projective Space of dimension 2 over Finite Field of size 3 Defn: Defined on coordinates by sending (x : y : z) to (x : y : z) @@ -764,8 +763,8 @@ def _point_homset(self, *args, **kwds): TESTS:: - sage: P2. = ProjectiveSpace(2, GF(3)) - sage: P2._point_homset(Spec(GF(3)), P2) + sage: P2. = ProjectiveSpace(2, GF(3)) # optional - sage.rings.finite_rings + sage: P2._point_homset(Spec(GF(3)), P2) # optional - sage.rings.finite_rings Set of rational points of Projective Space of dimension 2 over Finite Field of size 3 """ return SchemeHomset_points_projective_ring(*args, **kwds) @@ -828,9 +827,9 @@ def _point(self, *args, **kwds): TESTS:: - sage: P2. = ProjectiveSpace(2, GF(3)) - sage: point_homset = P2._point_homset(Spec(GF(3)), P2) - sage: P2._point(point_homset, [1,2,3]) + sage: P2. = ProjectiveSpace(2, GF(3)) # optional - sage.rings.finite_rings + sage: point_homset = P2._point_homset(Spec(GF(3)), P2) # optional - sage.rings.finite_rings + sage: P2._point(point_homset, [1,2,3]) # optional - sage.rings.finite_rings (2 : 1 : 0) """ return SchemeMorphism_point_projective_ring(*args, **kwds) @@ -846,7 +845,7 @@ def _repr_(self): TESTS:: - sage: ProjectiveSpace(3, Zp(5), 'y')._repr_() + sage: ProjectiveSpace(3, Zp(5), 'y')._repr_() # optional - sage.rings.padics 'Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20' """ return "Projective Space of dimension %s over %s" % (self.dimension_relative(), self.base_ring()) @@ -862,7 +861,7 @@ def _repr_generic_point(self, v=None): EXAMPLES:: sage: P. = ProjectiveSpace(2, ZZ) - sage: P._repr_generic_point([z*y-x^2]) + sage: P._repr_generic_point([z*y - x^2]) '(-x^2 + y*z)' sage: P._repr_generic_point() '(x : y : z)' @@ -882,7 +881,7 @@ def _latex_generic_point(self, v=None): EXAMPLES:: sage: P. = ProjectiveSpace(2, ZZ) - sage: P._latex_generic_point([z*y-x^2]) + sage: P._latex_generic_point([z*y - x^2]) '\\left(-x^{2} + y z\\right)' sage: P._latex_generic_point() '\\left(x : y : z\\right)' @@ -914,14 +913,14 @@ def change_ring(self, R): sage: P. = ProjectiveSpace(2, ZZ) sage: PQ = P.change_ring(QQ); PQ Projective Space of dimension 2 over Rational Field - sage: PQ.change_ring(GF(5)) + sage: PQ.change_ring(GF(5)) # optional - sage.rings.finite_rings Projective Space of dimension 2 over Finite Field of size 5 :: - sage: K. = QuadraticField(2) - sage: P = ProjectiveSpace(K,2,'t') - sage: P.change_ring(K.embeddings(QQbar)[0]) + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: P = ProjectiveSpace(K, 2, 't') # optional - sage.rings.number_field + sage: P.change_ring(K.embeddings(QQbar)[0]) # optional - sage.rings.number_field Projective Space of dimension 2 over Algebraic Field """ if isinstance(R, Map): @@ -961,7 +960,8 @@ def subscheme(self, X): sage: X.defining_polynomials () (x*z^2, y^2*z, x*y^2) sage: I = X.defining_ideal(); I - Ideal (x*z^2, y^2*z, x*y^2) of Multivariate Polynomial Ring in x, y, z over Rational Field + Ideal (x*z^2, y^2*z, x*y^2) of Multivariate Polynomial Ring in x, y, z + over Rational Field sage: I.groebner_basis() [x*y^2, y^2*z, x*z^2] sage: X.dimension() @@ -972,13 +972,13 @@ def subscheme(self, X): Spectrum of Rational Field sage: X.structure_morphism() Scheme morphism: - From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x*z^2, - y^2*z, - x*y^2 + From: Closed subscheme of Projective Space of dimension 2 + over Rational Field defined by: x*z^2, y^2*z, x*y^2 To: Spectrum of Rational Field Defn: Structure map + TESTS:: + sage: TestSuite(X).run(skip=["_test_an_element", "_test_elements",\ "_test_elements_eq", "_test_some_elements", "_test_elements_eq_reflexive",\ "_test_elements_eq_symmetric", "_test_elements_eq_transitive",\ @@ -997,15 +997,15 @@ def affine_patch(self, i, AA=None): Return the `i^{th}` affine patch of this projective space. This is an ambient affine space `\mathbb{A}^n_R,` where - `R` is the base ring of self, whose "projective embedding" + `R` is the base ring of ``self``, whose "projective embedding" map is `1` in the `i^{th}` factor. INPUT: - - ``i`` -- integer between 0 and dimension of self, inclusive. + - ``i`` -- integer between 0 and dimension of ``self``, inclusive. - ``AA`` -- (default: None) ambient affine space, this is constructed - if it is not given. + if it is not given. OUTPUT: @@ -1032,7 +1032,7 @@ def affine_patch(self, i, AA=None): :: - sage: P. = ProjectiveSpace(QQ,1) + sage: P. = ProjectiveSpace(QQ, 1) sage: P.affine_patch(0).projective_embedding(0).codomain() == P True """ @@ -1101,7 +1101,7 @@ def Lattes_map(self, E, m): EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,1) + sage: P. = ProjectiveSpace(QQ, 1) sage: E = EllipticCurve(QQ,[-1, 0]) sage: P.Lattes_map(E, 2) Dynamical System of Projective Space of dimension 1 over Rational Field @@ -1110,9 +1110,9 @@ def Lattes_map(self, E, m): TESTS:: - sage: P. = ProjectiveSpace(GF(37), 1) - sage: E = EllipticCurve([1, 1]) - sage: f = P.Lattes_map(E, 2); f + sage: P. = ProjectiveSpace(GF(37), 1) # optional - sage.rings.finite_rings + sage: E = EllipticCurve([1, 1]) # optional - sage.rings.finite_rings + sage: f = P.Lattes_map(E, 2); f # optional - sage.rings.finite_rings Dynamical System of Projective Space of dimension 1 over Finite Field of size 37 Defn: Defined on coordinates by sending (x : y) to (-9*x^4 + 18*x^2*y^2 - 2*x*y^3 - 9*y^4 : x^3*y + x*y^3 + y^4) @@ -1183,16 +1183,16 @@ def chebyshev_polynomial(self, n, kind='first', monic=False): sage: P. = ProjectiveSpace(QQ, 1) sage: P.chebyshev_polynomial(5, 'first') Dynamical System of Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y) to - (16*x^5 - 20*x^3*y^2 + 5*x*y^4 : y^5) + Defn: Defined on coordinates by sending (x : y) to + (16*x^5 - 20*x^3*y^2 + 5*x*y^4 : y^5) :: sage: P. = ProjectiveSpace(QQ, 1) sage: P.chebyshev_polynomial(3, 'second') Dynamical System of Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y) to - (8*x^3 - 4*x*y^2 : y^3) + Defn: Defined on coordinates by sending (x : y) to + (8*x^3 - 4*x*y^2 : y^3) :: @@ -1220,7 +1220,7 @@ def chebyshev_polynomial(self, n, kind='first', monic=False): :: - sage: P. = ProjectiveSpace(QQ,1) + sage: P. = ProjectiveSpace(QQ, 1) sage: P.chebyshev_polynomial(3, monic=True) Dynamical System of Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x : y) to @@ -1229,9 +1229,10 @@ def chebyshev_polynomial(self, n, kind='first', monic=False): :: sage: F. = FunctionField(QQ) - sage: P. = ProjectiveSpace(F,1) - sage: P.chebyshev_polynomial(4,monic=True) - Dynamical System of Projective Space of dimension 1 over Rational function field in t over Rational Field + sage: P. = ProjectiveSpace(F, 1) + sage: P.chebyshev_polynomial(4, monic=True) + Dynamical System of Projective Space of dimension 1 + over Rational function field in t over Rational Field Defn: Defined on coordinates by sending (y : z) to (y^4 + (-4)*y^2*z^2 + 2*z^4 : z^4) """ @@ -1291,7 +1292,7 @@ def veronese_embedding(self, d, CS=None, order='lex'): (x^2 : x*y : x*z : y^2 : y*z : z^2) sage: vd(P.subscheme([])) Closed subscheme of Projective Space of dimension 5 over Rational Field - defined by: + defined by: -u^2 + t*v, -s*u + r*v, -s*t + r*u, @@ -1332,14 +1333,14 @@ def point_transformation_matrix(self, points_source, points_target, normalize=Tr INPUT: - - ``points_source`` -- points in source projective space. + - ``points_source`` -- points in source projective space. - - ``points_target`` -- points in target projective space. + - ``points_target`` -- points in target projective space. - - ``normalize`` -- (default: `True`) If the returned matrix should be normalized. - Only works over exact rings. If the base ring is a field, the matrix is normalized so - that the last nonzero entry in the last row is 1. If the base ring is a ring, then - the matrix is normalized so that the entries are elements of the base ring. + - ``normalize`` -- (default: ``True``) If the returned matrix should be normalized. + Only works over exact rings. If the base ring is a field, the matrix is normalized so + that the last nonzero entry in the last row is 1. If the base ring is a ring, then + the matrix is normalized so that the entries are elements of the base ring. OUTPUT: Transformation matrix - element of PGL. @@ -1349,9 +1350,9 @@ def point_transformation_matrix(self, points_source, points_target, normalize=Tr EXAMPLES:: - sage: P1.=ProjectiveSpace(QQ, 2) - sage: points_source=[P1([1, 4, 1]), P1([1, 2, 2]), P1([3, 5, 1]), P1([1, -1, 1])] - sage: points_target=[P1([5, -2, 7]), P1([3, -2, 3]), P1([6, -5, 9]), P1([3, 6, 7])] + sage: P1. = ProjectiveSpace(QQ, 2) + sage: points_source = [P1([1, 4, 1]), P1([1, 2, 2]), P1([3, 5, 1]), P1([1, -1, 1])] + sage: points_target = [P1([5, -2, 7]), P1([3, -2, 3]), P1([6, -5, 9]), P1([3, 6, 7])] sage: m = P1.point_transformation_matrix(points_source, points_target); m [ -13/59 -128/59 -25/59] [538/177 8/59 26/177] @@ -1361,10 +1362,10 @@ def point_transformation_matrix(self, points_source, points_target, normalize=Tr :: - sage: P. = ProjectiveSpace(GF(13), 1) - sage: points_source = [P([-6, 7]), P([1, 4]), P([3, 2])] - sage: points_target = [P([-1, 2]), P([0, 2]), P([-1, 6])] - sage: P.point_transformation_matrix(points_source, points_target) + sage: P. = ProjectiveSpace(GF(13), 1) # optional - sage.rings.finite_rings + sage: points_source = [P([-6, 7]), P([1, 4]), P([3, 2])] # optional - sage.rings.finite_rings + sage: points_target = [P([-1, 2]), P([0, 2]), P([-1, 6])] # optional - sage.rings.finite_rings + sage: P.point_transformation_matrix(points_source, points_target) # optional - sage.rings.finite_rings [10 4] [10 1] @@ -1385,14 +1386,14 @@ def point_transformation_matrix(self, points_source, points_target, normalize=Tr sage: points_source = [P([-6*t, 7]), P([1, 4]), P([3, 2])] sage: points_target = [P([-1, 2*t]), P([0, 2]), P([-1, 6])] sage: P.point_transformation_matrix(points_source, points_target) - [ (1/3*t + 7/12)/(t^2 - 53/24*t) (-1/12*t - 7/48)/(t^2 - 53/24*t)] - [(-2/3*t^2 - 7/36*t - 35/12)/(t^2 - 53/24*t) 1] + [ (1/3*t + 7/12)/(t^2 - 53/24*t) (-1/12*t - 7/48)/(t^2 - 53/24*t)] + [(-2/3*t^2 - 7/36*t - 35/12)/(t^2 - 53/24*t) 1] :: - sage: P1.=ProjectiveSpace(RR, 2) - sage: points_source=[P1([1, 4, 1]), P1([1, 2, 2]), P1([3, 5, 1]), P1([1, -1, 1])] - sage: points_target=[P1([5, -2, 7]), P1([3, -2, 3]), P1([6, -5, 9]), P1([3, 6, 7])] + sage: P1. = ProjectiveSpace(RR, 2) + sage: points_source = [P1([1, 4, 1]), P1([1, 2, 2]), P1([3, 5, 1]), P1([1, -1, 1])] + sage: points_target = [P1([5, -2, 7]), P1([3, -2, 3]), P1([6, -5, 9]), P1([3, 6, 7])] sage: P1.point_transformation_matrix(points_source, points_target) # abs tol 1e-13 [-0.0619047619047597 -0.609523809523810 -0.119047619047621] [ 0.853968253968253 0.0380952380952380 0.0412698412698421] @@ -1400,9 +1401,9 @@ def point_transformation_matrix(self, points_source, points_target, normalize=Tr :: - sage: P1.=ProjectiveSpace(ZZ, 2) - sage: points_source=[P1([1, 4, 1]), P1([1, 2, 2]), P1([3, 5, 1]), P1([1, -1, 1])] - sage: points_target=[P1([5, -2, 7]), P1([3, -2, 3]), P1([6, -5, 9]), P1([3, 6, 7])] + sage: P1. = ProjectiveSpace(ZZ, 2) + sage: points_source = [P1([1, 4, 1]), P1([1, 2, 2]), P1([3, 5, 1]), P1([1, -1, 1])] + sage: points_target = [P1([5, -2, 7]), P1([3, -2, 3]), P1([6, -5, 9]), P1([3, 6, 7])] sage: P1.point_transformation_matrix(points_source, points_target) [ -39 -384 -75] [ 538 24 26] @@ -1410,9 +1411,9 @@ def point_transformation_matrix(self, points_source, points_target, normalize=Tr :: - sage: P1.=ProjectiveSpace(ZZ, 2) - sage: points_source=[P1([1, 4, 1]), P1([1, 2, 2]), P1([3, 5, 1]), P1([1, -1, 1])] - sage: points_target=[P1([5, -2, 7]), P1([3, -2, 3]), P1([6, -5, 9]), P1([3, 6, 7])] + sage: P1. = ProjectiveSpace(ZZ, 2) + sage: points_source = [P1([1, 4, 1]), P1([1, 2, 2]), P1([3, 5, 1]), P1([1, -1, 1])] + sage: points_target = [P1([5, -2, 7]), P1([3, -2, 3]), P1([6, -5, 9]), P1([3, 6, 7])] sage: P1.point_transformation_matrix(points_source, points_target, normalize=False) [-13/30 -64/15 -5/6] [269/45 4/15 13/45] @@ -1440,9 +1441,9 @@ def point_transformation_matrix(self, points_source, points_target, normalize=Tr :: - sage: P.=ProjectiveSpace(QQ, 2) - sage: points_source=[P([1, 4, 1]), P([2, -7, 9]), P([3, 5, 1])] - sage: points_target=[P([5, -2, 7]), P([3, -2, 3]), P([6, -5, 9]), P([6, -1, 1])] + sage: P. = ProjectiveSpace(QQ, 2) + sage: points_source = [P([1, 4, 1]), P([2, -7, 9]), P([3, 5, 1])] + sage: points_target = [P([5, -2, 7]), P([3, -2, 3]), P([6, -5, 9]), P([6, -1, 1])] sage: P.point_transformation_matrix(points_source, points_target) Traceback (most recent call last): ... @@ -1450,9 +1451,9 @@ def point_transformation_matrix(self, points_source, points_target, normalize=Tr :: - sage: P.=ProjectiveSpace(QQ, 2) - sage: points_source=[P([1, 4, 1]), P([2, -7, 9]), P([3, 5, 1]), P([1, -1, 1])] - sage: points_target=[P([5, -2, 7]), P([3, -2, 3]), P([6, -5, 9]), P([6, -1, 1]),P([7, 8, -9])] + sage: P. = ProjectiveSpace(QQ, 2) + sage: points_source = [P([1, 4, 1]), P([2, -7, 9]), P([3, 5, 1]), P([1, -1, 1])] + sage: points_target = [P([5, -2, 7]), P([3, -2, 3]), P([6, -5, 9]), P([6, -1, 1]), P([7, 8, -9])] sage: P.point_transformation_matrix(points_source, points_target) Traceback (most recent call last): ... @@ -1460,9 +1461,9 @@ def point_transformation_matrix(self, points_source, points_target, normalize=Tr :: - sage: P.=ProjectiveSpace(QQ, 2) - sage: P1.=ProjectiveSpace(QQ, 2) - sage: points_source=[P([1, 4, 1]), P([2, -7, 9]), P([3, 5, 1]), P1([1, -1, 1])] + sage: P. = ProjectiveSpace(QQ, 2) + sage: P1. = ProjectiveSpace(QQ, 2) + sage: points_source = [P([1, 4, 1]), P([2, -7, 9]), P([3, 5, 1]), P1([1, -1, 1])] sage: points_target=[P([5, -2, 7]), P([3, -2, 3]), P([6, -5, 9]), P([6, -1, 1])] sage: P.point_transformation_matrix(points_source, points_target) Traceback (most recent call last): @@ -1471,10 +1472,10 @@ def point_transformation_matrix(self, points_source, points_target, normalize=Tr :: - sage: P.=ProjectiveSpace(QQ, 2) - sage: P1.=ProjectiveSpace(QQ, 2) - sage: points_source=[P([1, 4, 1]), P([2, -7, 9]), P([3, 5, 1]), P([1, -1, 1])] - sage: points_target=[P([5, -2, 7]), P([3, -2, 3]), P([6, -5, 9]), P1([6, -1, 1])] + sage: P. = ProjectiveSpace(QQ, 2) + sage: P1. = ProjectiveSpace(QQ, 2) + sage: points_source = [P([1, 4, 1]), P([2, -7, 9]), P([3, 5, 1]), P([1, -1, 1])] + sage: points_target = [P([5, -2, 7]), P([3, -2, 3]), P([6, -5, 9]), P1([6, -1, 1])] sage: P.point_transformation_matrix(points_source, points_target) Traceback (most recent call last): ... @@ -1482,10 +1483,10 @@ def point_transformation_matrix(self, points_source, points_target, normalize=Tr :: - sage: P.=ProjectiveSpace(ZZ,2) + sage: P. = ProjectiveSpace(ZZ, 2) sage: points_source = [P(1, 0, 0), P(0, 1, 0), P(0, 0, 1), P(1, -1, -1)] sage: points_target = [P(0, 1, 0), P(-2, 0, 1), P(0, 0, 1), P(1, -1, -1)] - sage: P.point_transformation_matrix(points_source,points_target,normalize=True) + sage: P.point_transformation_matrix(points_source, points_target, normalize=True) [ 0 -2 0] [-2 0 0] [ 0 1 1] @@ -1589,12 +1590,12 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): :: - sage: K. = CyclotomicField(3) - sage: P. = ProjectiveSpace(K, 2) - sage: plane1 = P.subscheme(x - 2*v*y + z) - sage: plane2 = P.subscheme(x + v*y + v*z) - sage: m = P.hyperplane_transformation_matrix(plane1, plane2) - sage: m + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: plane1 = P.subscheme(x - 2*v*y + z) # optional - sage.rings.number_field + sage: plane2 = P.subscheme(x + v*y + v*z) # optional - sage.rings.number_field + sage: m = P.hyperplane_transformation_matrix(plane1, plane2) # optional - sage.rings.number_field + sage: m # optional - sage.rings.number_field [ v 0 0] [ 0 -2*v 0] [ 0 0 1] @@ -1602,11 +1603,11 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): :: sage: R. = QQ[] - sage: K. = NumberField(x^2+1) - sage: P. = ProjectiveSpace(K, 3) - 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 + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 3) # optional - sage.rings.number_field + sage: plane1 = P.subscheme(k*x + 2*k*y + z) # optional - sage.rings.number_field + sage: plane2 = P.subscheme(7*k*x + y + 9*z) # optional - sage.rings.number_field + sage: m = P.hyperplane_transformation_matrix(plane1, plane2); m # optional - sage.rings.number_field [ 1 0 0 0] [ 0 14*k 0 0] [ 0 0 7/9 0] @@ -1614,23 +1615,23 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): :: - sage: K. = CyclotomicField(3) - sage: R. = K[] - sage: F. = K.extension(t^5 + 2) - sage: G. = F.absolute_field() - sage: P. = ProjectiveSpace(G, 2) - sage: plane1 = P.subscheme(x - 2*u*y + z) - sage: plane2 = P.subscheme(x + u*y + z) - sage: m = P.hyperplane_transformation_matrix(plane1, plane2) - sage: plane2(m*P((2*u, 1, 0))) + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: F. = K.extension(t^5 + 2) # optional - sage.rings.number_field + sage: G. = F.absolute_field() # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(G, 2) # optional - sage.rings.number_field + sage: plane1 = P.subscheme(x - 2*u*y + z) # optional - sage.rings.number_field + sage: plane2 = P.subscheme(x + u*y + z) # optional - sage.rings.number_field + sage: m = P.hyperplane_transformation_matrix(plane1, plane2) # optional - sage.rings.number_field + sage: plane2(m*P((2*u, 1, 0))) # optional - sage.rings.number_field (-u : 1 : 0) :: - sage: P. = ProjectiveSpace(FiniteField(2), 2) - sage: plane1 = P.subscheme(x + y + z) - sage: plane2 = P.subscheme(z) - sage: P.hyperplane_transformation_matrix(plane1, plane2) + sage: P. = ProjectiveSpace(FiniteField(2), 2) # optional - sage.rings.finite_rings + sage: plane1 = P.subscheme(x + y + z) # optional - sage.rings.finite_rings + sage: plane2 = P.subscheme(z) # optional - sage.rings.finite_rings + sage: P.hyperplane_transformation_matrix(plane1, plane2) # optional - sage.rings.finite_rings [1 0 0] [1 1 0] [1 1 1] @@ -1751,16 +1752,16 @@ def is_linearly_independent(self, points, n=None): :: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: points = [P((1, 0, 1)), P((1, 2, 1)), P((1, 3, 4)), P((0, 0 ,1))] - sage: P.is_linearly_independent(points, 2) + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: points = [P((1, 0, 1)), P((1, 2, 1)), P((1, 3, 4)), P((0, 0, 1))] # optional - sage.rings.finite_rings + sage: P.is_linearly_independent(points, 2) # optional - sage.rings.finite_rings True :: sage: R. = QQ[] sage: P. = ProjectiveSpace(R, 2) - sage: points = [P((c, 0, 1)), P((0, c, 1)), P((1, 0, 4)), P((0, 0 ,1))] + sage: points = [P((c, 0, 1)), P((0, c, 1)), P((1, 0, 4)), P((0, 0, 1))] sage: P.is_linearly_independent(points, 3) False @@ -1768,16 +1769,16 @@ def is_linearly_independent(self, points, n=None): sage: R. = QQ[] sage: P. = ProjectiveSpace(FractionField(R), 2) - sage: points = [P((c, 0, 1)), P((0, c, 1)), P((1, 3, 4)), P((0, 0 ,1))] + sage: points = [P((c, 0, 1)), P((0, c, 1)), P((1, 3, 4)), P((0, 0, 1))] sage: P.is_linearly_independent(points, 3) True :: - sage: K. = CyclotomicField(3) - sage: P. = ProjectiveSpace(K, 2) - sage: points = [P((k, k^2, 1)), P((0, k, 1)), P((1, 0, 4)), P((0, 0 ,1))] - sage: P.is_linearly_independent(points, 3) + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: points = [P((k, k^2, 1)), P((0, k, 1)), P((1, 0, 4)), P((0, 0, 1))] # optional - sage.rings.number_field + sage: P.is_linearly_independent(points, 3) # optional - sage.rings.number_field True :: @@ -1829,8 +1830,8 @@ def _point_homset(self, *args, **kwds): TESTS:: - sage: P2. = ProjectiveSpace(2, GF(3)) - sage: P2._point_homset(Spec(GF(3)), P2) + sage: P2. = ProjectiveSpace(2, GF(3)) # optional - sage.rings.finite_rings + sage: P2._point_homset(Spec(GF(3)), P2) # optional - sage.rings.finite_rings Set of rational points of Projective Space of dimension 2 over Finite Field of size 3 """ return SchemeHomset_points_projective_field(*args, **kwds) @@ -1843,9 +1844,9 @@ def _point(self, *args, **kwds): TESTS:: - sage: P2. = ProjectiveSpace(2, GF(3)) - sage: point_homset = P2._point_homset(Spec(GF(3)), P2) - sage: P2._point(point_homset, [1,2,3]) + sage: P2. = ProjectiveSpace(2, GF(3)) # optional - sage.rings.finite_rings + sage: point_homset = P2._point_homset(Spec(GF(3)), P2) # optional - sage.rings.finite_rings + sage: P2._point(point_homset, [1,2,3]) # optional - sage.rings.finite_rings (2 : 1 : 0) """ return SchemeMorphism_point_projective_field(*args, **kwds) @@ -1858,8 +1859,8 @@ def _morphism(self, *args, **kwds): TESTS:: - sage: P2. = ProjectiveSpace(2, GF(3)) - sage: P2._morphism(P2.Hom(P2), [x,y,z]) + sage: P2. = ProjectiveSpace(2, GF(3)) # optional - sage.rings.finite_rings + sage: P2._morphism(P2.Hom(P2), [x,y,z]) # optional - sage.rings.finite_rings Scheme endomorphism of Projective Space of dimension 2 over Finite Field of size 3 Defn: Defined on coordinates by sending (x : y : z) to (x : y : z) @@ -1897,58 +1898,59 @@ 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))) + sage: P. = ProjectiveSpace(NumberField(u^2 - 2, 'v'), 2) # optional - sage.rings.number_field + sage: len(list(P.points_of_bounded_height(bound=2))) # optional - sage.rings.number_field 265 :: - sage: CF. = CyclotomicField(3) - sage: R. = CF[] - sage: L. = CF.extension(x^3 + 2) - sage: Q. = ProjectiveSpace(L, 1) - sage: sorted(list(Q.points_of_bounded_height(bound=1))) + sage: CF. = CyclotomicField(3) # optional - sage.rings.number_field + sage: R. = CF[] # optional - sage.rings.number_field + sage: L. = CF.extension(x^3 + 2) # optional - sage.rings.number_field + sage: Q. = ProjectiveSpace(L, 1) # optional - sage.rings.number_field + sage: sorted(list(Q.points_of_bounded_height(bound=1))) # optional - sage.rings.number_field [(0 : 1), (1 : 0), (a + 1 : 1), (a : 1), (-1 : 1), (-a - 1 : 1), (-a : 1), (1 : 1)] :: 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)]) + sage: F. = NumberField(x^4 - 8*x^2 + 3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(F, 2) # optional - sage.rings.number_field + sage: all(exp(p.global_height()) <= 1 # optional - sage.rings.number_field + ....: for p in P.points_of_bounded_height(bound=1)) True :: - sage: K. = CyclotomicField(3) - sage: P. = ProjectiveSpace(K, 2) - sage: len(list(P.points_of_bounded_height(bound=1))) + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: len(list(P.points_of_bounded_height(bound=1))) # optional - sage.rings.number_field 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))) + sage: K. = NumberField(u^2 - 2) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: len(list(P.points_of_bounded_height(bound=2))) # optional - sage.rings.number_field 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))) + sage: K. = NumberField(x^4 - 8*x^2 + 3) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 1) # optional - sage.rings.number_field + sage: len(list(P.points_of_bounded_height(bound=2))) # optional - sage.rings.number_field 108 :: 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)) + sage: K. = NumberField(x^5 + x^3 + 1) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 2) # optional - sage.rings.number_field + sage: L = P.points_of_bounded_height(bound=1.2) # optional - sage.rings.number_field + sage: len(list(L)) # optional - sage.rings.number_field 109 """ from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, IQ_points_of_bounded_height, points_of_bounded_height @@ -2017,7 +2019,7 @@ def subscheme_from_Chow_form(self, Ch, dim): sage: P = ProjectiveSpace(QQ, 4, 'z') sage: R. = PolynomialRing(QQ) sage: H = x1^2 + x2^2 + 5*x3*x4 - sage: P.subscheme_from_Chow_form(H,3) + sage: P.subscheme_from_Chow_form(H, 3) Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: -5*z0*z1 + z2^2 + z3^2 @@ -2025,7 +2027,7 @@ def subscheme_from_Chow_form(self, Ch, dim): sage: P = ProjectiveSpace(QQ, 3, 'z') sage: R. = PolynomialRing(QQ) - sage: H = x1-x2-x3+x5+2*x0 + sage: H = x1 - x2 - x3 + x5 + 2*x0 sage: P.subscheme_from_Chow_form(H, 1) Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: @@ -2036,13 +2038,13 @@ def subscheme_from_Chow_form(self, Ch, dim): :: - sage: P. = ProjectiveSpace(GF(7), 3) - sage: X = P.subscheme([x3^2+x1*x2,x2-x0]) - sage: Ch = X.Chow_form();Ch + sage: P. = ProjectiveSpace(GF(7), 3) # optional - sage.rings.finite_rings + sage: X = P.subscheme([x3^2 + x1*x2, x2 - x0]) # optional - sage.rings.finite_rings + sage: Ch = X.Chow_form(); Ch # optional - sage.rings.finite_rings t0^2 - 2*t0*t3 + t3^2 - t2*t4 - t4*t5 - sage: Y = P.subscheme_from_Chow_form(Ch, 1); Y - Closed subscheme of Projective Space of dimension 3 over Finite Field of - size 7 defined by: + sage: Y = P.subscheme_from_Chow_form(Ch, 1); Y # optional - sage.rings.finite_rings + Closed subscheme of Projective Space of dimension 3 + over Finite Field of size 7 defined by: x1*x2 + x3^2, -x0*x2 + x2^2, -x0*x1 - x1*x2 - 2*x3^2, @@ -2051,10 +2053,10 @@ def subscheme_from_Chow_form(self, Ch, dim): -2*x0*x3 + 2*x2*x3, 2*x0*x3 - 2*x2*x3, x0^2 - 2*x0*x2 + x2^2 - sage: I = Y.defining_ideal() - sage: I.saturation(I.ring().ideal(list(I.ring().gens())))[0] - Ideal (x0 - x2, x1*x2 + x3^2) of Multivariate Polynomial Ring in x0, x1, - x2, x3 over Finite Field of size 7 + sage: I = Y.defining_ideal() # optional - sage.rings.finite_rings + sage: I.saturation(I.ring().ideal(list(I.ring().gens())))[0] # optional - sage.rings.finite_rings + Ideal (x0 - x2, x1*x2 + x3^2) of Multivariate Polynomial Ring + in x0, x1, x2, x3 over Finite Field of size 7 """ if not Ch.is_homogeneous(): raise ValueError("Chow form must be a homogeneous polynomial") @@ -2132,8 +2134,9 @@ def line_through(self, p, q): sage: p1 = P3(1, 2, 3, 4) sage: p2 = P3(4, 3, 2, 1) sage: P3.line_through(p1, p2) - Projective Curve over Rational Field defined by -5/4*x0 + 5/2*x1 - 5/4*x2, - -5/2*x0 + 15/4*x1 - 5/4*x3, -5/4*x0 + 15/4*x2 - 5/2*x3, -5/4*x1 + 5/2*x2 - 5/4*x3 + Projective Curve over Rational Field defined by + -5/4*x0 + 5/2*x1 - 5/4*x2, -5/2*x0 + 15/4*x1 - 5/4*x3, + -5/4*x0 + 15/4*x2 - 5/2*x3, -5/4*x1 + 5/2*x2 - 5/4*x3 sage: p3 = P3(2,4,6,8) sage: P3.line_through(p1, p3) Traceback (most recent call last): @@ -2159,9 +2162,9 @@ def _point(self, *args, **kwds): TESTS:: - sage: P2. = ProjectiveSpace(2, GF(3)) - sage: point_homset = P2._point_homset(Spec(GF(3)), P2) - sage: P2._point(point_homset, [1,2,3]) + sage: P2. = ProjectiveSpace(2, GF(3)) # optional - sage.rings.finite_rings + sage: point_homset = P2._point_homset(Spec(GF(3)), P2) # optional - sage.rings.finite_rings + sage: P2._point(point_homset, [1,2,3]) # optional - sage.rings.finite_rings (2 : 1 : 0) """ return SchemeMorphism_point_projective_finite_field(*args, **kwds) @@ -2174,8 +2177,8 @@ def _morphism(self, *args, **kwds): TESTS:: - sage: P2. = ProjectiveSpace(2, GF(3)) - sage: P2._morphism(P2.Hom(P2), [x,y,z]) + sage: P2. = ProjectiveSpace(2, GF(3)) # optional - sage.rings.finite_rings + sage: P2._morphism(P2.Hom(P2), [x,y,z]) # optional - sage.rings.finite_rings Scheme endomorphism of Projective Space of dimension 2 over Finite Field of size 3 Defn: Defined on coordinates by sending (x : y : z) to (x : y : z) @@ -2194,28 +2197,28 @@ def __iter__(self): EXAMPLES:: - sage: FF = FiniteField(3) - sage: PP = ProjectiveSpace(0,FF) - sage: [ x for x in PP ] + sage: FF = FiniteField(3) # optional - sage.rings.finite_rings + sage: PP = ProjectiveSpace(0, FF) # optional - sage.rings.finite_rings + sage: [ x for x in PP ] # optional - sage.rings.finite_rings [(1)] - sage: PP = ProjectiveSpace(1,FF) - sage: [ x for x in PP ] + sage: PP = ProjectiveSpace(1, FF) # optional - sage.rings.finite_rings + sage: [ x for x in PP ] # optional - sage.rings.finite_rings [(0 : 1), (1 : 1), (2 : 1), (1 : 0)] - sage: PP = ProjectiveSpace(2,FF) - sage: [ x for x in PP ] + sage: PP = ProjectiveSpace(2, FF) # optional - sage.rings.finite_rings + sage: [ x for x in PP ] # optional - sage.rings.finite_rings [(0 : 0 : 1), - (0 : 1 : 1), - (0 : 2 : 1), - (1 : 0 : 1), - (1 : 1 : 1), - (1 : 2 : 1), - (2 : 0 : 1), - (2 : 1 : 1), - (2 : 2 : 1), - (0 : 1 : 0), - (1 : 1 : 0), - (2 : 1 : 0), - (1 : 0 : 0)] + (0 : 1 : 1), + (0 : 2 : 1), + (1 : 0 : 1), + (1 : 1 : 1), + (1 : 2 : 1), + (2 : 0 : 1), + (2 : 1 : 1), + (2 : 2 : 1), + (0 : 1 : 0), + (1 : 1 : 0), + (2 : 1 : 0), + (1 : 0 : 0)] AUTHORS: @@ -2245,11 +2248,12 @@ def rational_points(self, F=None): EXAMPLES:: - sage: P = ProjectiveSpace(1, GF(3)) - sage: P.rational_points() + sage: P = ProjectiveSpace(1, GF(3)) # optional - sage.rings.finite_rings + sage: P.rational_points() # optional - sage.rings.finite_rings [(0 : 1), (1 : 1), (2 : 1), (1 : 0)] - sage: P.rational_points(GF(3^2, 'b')) - [(0 : 1), (b : 1), (b + 1 : 1), (2*b + 1 : 1), (2 : 1), (2*b : 1), (2*b + 2 : 1), (b + 2 : 1), (1 : 1), (1 : 0)] + sage: P.rational_points(GF(3^2, 'b')) # optional - sage.rings.finite_rings + [(0 : 1), (b : 1), (b + 1 : 1), (2*b + 1 : 1), (2 : 1), (2*b : 1), + (2*b + 2 : 1), (b + 2 : 1), (1 : 1), (1 : 0)] """ if F is None: return [P for P in self] @@ -2267,8 +2271,8 @@ def rational_points_dictionary(self): EXAMPLES:: - sage: P1 = ProjectiveSpace(GF(7),1,'x') - sage: P1.rational_points_dictionary() + sage: P1 = ProjectiveSpace(GF(7), 1, 'x') # optional - sage.rings.finite_rings + sage: P1.rational_points_dictionary() # optional - sage.rings.finite_rings {(0 : 1): 0, (1 : 0): 7, (1 : 1): 1, @@ -2314,16 +2318,16 @@ def rational_points(self, bound=0): Returns the projective points `(x_0:\cdots:x_n)` over `\QQ` with `|x_i| \leq` bound. - ALGORITHM: + ALGORITHM: - The very simple algorithm works as follows: every point - `(x_0:\cdots:x_n)` in projective space has a unique - largest index `i` for which `x_i` is not - zero. The algorithm then iterates downward on this - index. We normalize by choosing `x_i` positive. Then, - the points `x_0,\ldots,x_{i-1}` are the points of - affine `i`-space that are relatively prime to - `x_i`. We access these by using the Tuples method. + The very simple algorithm works as follows: every point + `(x_0:\cdots:x_n)` in projective space has a unique + largest index `i` for which `x_i` is not + zero. The algorithm then iterates downward on this + index. We normalize by choosing `x_i` positive. Then, + the points `x_0,\ldots,x_{i-1}` are the points of + affine `i`-space that are relatively prime to + `x_i`. We access these by using the Tuples method. INPUT: @@ -2340,16 +2344,15 @@ def rational_points(self, bound=0): sage: PP = ProjectiveSpace(2, QQ) sage: PP.rational_points(2) [(-2 : -2 : 1), (-1 : -2 : 1), (0 : -2 : 1), (1 : -2 : 1), (2 : -2 : 1), - (-2 : -1 : 1), (-1 : -1 : 1), (0 : -1 : 1), (1 : -1 : 1), (2 : -1 : 1), - (-2 : 0 : 1), (-1 : 0 : 1), (0 : 0 : 1), (1 : 0 : 1), (2 : 0 : 1), (-2 : - 1 : 1), (-1 : 1 : 1), (0 : 1 : 1), (1 : 1 : 1), (2 : 1 : 1), (-2 : 2 : - 1), (-1 : 2 : 1), (0 : 2 : 1), (1 : 2 : 1), (2 : 2 : 1), (-1/2 : -1 : - 1), (1/2 : -1 : 1), (-1 : -1/2 : 1), (-1/2 : -1/2 : 1), (0 : -1/2 : 1), - (1/2 : -1/2 : 1), (1 : -1/2 : 1), (-1/2 : 0 : 1), (1/2 : 0 : 1), (-1 : - 1/2 : 1), (-1/2 : 1/2 : 1), (0 : 1/2 : 1), (1/2 : 1/2 : 1), (1 : 1/2 : - 1), (-1/2 : 1 : 1), (1/2 : 1 : 1), (-2 : 1 : 0), (-1 : 1 : 0), (0 : 1 : - 0), (1 : 1 : 0), (2 : 1 : 0), (-1/2 : 1 : 0), (1/2 : 1 : 0), (1 : 0 : - 0)] + (-2 : -1 : 1), (-1 : -1 : 1), (0 : -1 : 1), (1 : -1 : 1), (2 : -1 : 1), + (-2 : 0 : 1), (-1 : 0 : 1), (0 : 0 : 1), (1 : 0 : 1), (2 : 0 : 1), (-2 : 1 : 1), + (-1 : 1 : 1), (0 : 1 : 1), (1 : 1 : 1), (2 : 1 : 1), (-2 : 2 : 1), + (-1 : 2 : 1), (0 : 2 : 1), (1 : 2 : 1), (2 : 2 : 1), (-1/2 : -1 : 1), + (1/2 : -1 : 1), (-1 : -1/2 : 1), (-1/2 : -1/2 : 1), (0 : -1/2 : 1), + (1/2 : -1/2 : 1), (1 : -1/2 : 1), (-1/2 : 0 : 1), (1/2 : 0 : 1), (-1 : 1/2 : 1), + (-1/2 : 1/2 : 1), (0 : 1/2 : 1), (1/2 : 1/2 : 1), (1 : 1/2 : 1), (-1/2 : 1 : 1), + (1/2 : 1 : 1), (-2 : 1 : 0), (-1 : 1 : 0), (0 : 1 : 0), (1 : 1 : 0), + (2 : 1 : 0), (-1/2 : 1 : 0), (1/2 : 1 : 0), (1 : 0 : 0)] AUTHORS: diff --git a/src/sage/schemes/projective/projective_subscheme.py b/src/sage/schemes/projective/projective_subscheme.py index 4a178c53766..e6caf19ba74 100644 --- a/src/sage/schemes/projective/projective_subscheme.py +++ b/src/sage/schemes/projective/projective_subscheme.py @@ -60,7 +60,7 @@ class AlgebraicScheme_subscheme_projective(AlgebraicScheme_subscheme): EXAMPLES:: sage: P. = ProjectiveSpace(2, QQ) - sage: P.subscheme([x^2-y*z]) + sage: P.subscheme([x^2 - y*z]) Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: x^2 - y*z @@ -87,7 +87,7 @@ def point(self, v, check=True): EXAMPLES:: sage: P2. = ProjectiveSpace(QQ, 2) - sage: X = P2.subscheme([x-y,y-z]) + sage: X = P2.subscheme([x - y, y - z]) sage: X.point([1,1,1]) (1 : 1 : 1) @@ -101,7 +101,7 @@ def point(self, v, check=True): :: sage: P. = ProjectiveSpace(QQ, 1) - sage: X = P.subscheme(x^2+2*y^2) + sage: X = P.subscheme(x^2 + 2*y^2) sage: X.point(infinity) Traceback (most recent call last): ... @@ -142,21 +142,19 @@ def _morphism(self, *args, **kwds): TESTS:: - sage: P1. = ProjectiveSpace(1,QQ) - sage: P2 = ProjectiveSpace(2,QQ) + sage: P1. = ProjectiveSpace(1, QQ) + sage: P2 = ProjectiveSpace(2, QQ) sage: H12 = P1.Hom(P2) - sage: H12([x^2,x*y, y^2]) # indirect doctest + sage: H12([x^2, x*y, y^2]) # indirect doctest Scheme morphism: From: Projective Space of dimension 1 over Rational Field To: Projective Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x : y) to - (x^2 : x*y : y^2) - sage: P1._morphism(H12, [x^2,x*y, y^2]) + Defn: Defined on coordinates by sending (x : y) to (x^2 : x*y : y^2) + sage: P1._morphism(H12, [x^2, x*y, y^2]) Scheme morphism: From: Projective Space of dimension 1 over Rational Field To: Projective Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x : y) to - (x^2 : x*y : y^2) + Defn: Defined on coordinates by sending (x : y) to (x^2 : x*y : y^2) """ return self.ambient_space()._morphism(*args, **kwds) @@ -232,31 +230,29 @@ def affine_patch(self, i, AA=None): Y^3*Z + Z^3 + Y sage: U.embedding_morphism() Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - Y^3*Z + Z^3 + Y - To: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - X^3*Y + Y^3*Z + X*Z^3 - Defn: Defined on coordinates by sending (Y, Z) to - (1 : Y : Z) + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: Y^3*Z + Z^3 + Y + To: Closed subscheme of Projective Space of dimension 2 over Rational Field + defined by: X^3*Y + Y^3*Z + X*Z^3 + Defn: Defined on coordinates by sending (Y, Z) to (1 : Y : Z) sage: U.projective_embedding() is U.embedding_morphism() True :: - sage: A. = AffineSpace(QQ,3) - sage: X = A.subscheme([x-y*z]) + sage: A. = AffineSpace(QQ, 3) + sage: X = A.subscheme([x - y*z]) sage: Y = X.projective_embedding(1).codomain() - sage: Y.affine_patch(1,A).ambient_space() == A + sage: Y.affine_patch(1, A).ambient_space() == A True :: - sage: P. = ProjectiveSpace(2,ZZ) - sage: S = P.subscheme([u^2-v*w]) + sage: P. = ProjectiveSpace(2, ZZ) + sage: S = P.subscheme([u^2 - v*w]) sage: A. = AffineSpace(2, ZZ) sage: S.affine_patch(1, A) - Closed subscheme of Affine Space of dimension 2 over Integer Ring - defined by: + Closed subscheme of Affine Space of dimension 2 over Integer Ring defined by: x^2 - y """ i = int(i) # implicit type checking @@ -305,8 +301,8 @@ def _best_affine_patch(self, point): EXAMPLES:: - sage: P.= ProjectiveSpace(QQ,2) - sage: S = P.subscheme(x+2*y+3*z) + sage: P. = ProjectiveSpace(QQ, 2) + sage: S = P.subscheme(x + 2*y + 3*z) sage: S._best_affine_patch(P.point([0,-3,2])) 1 sage: S._best_affine_patch([0,-3,2]) @@ -314,9 +310,9 @@ def _best_affine_patch(self, point): TESTS:: - sage: F = GF(3) - sage: P.= ProjectiveSpace(F,2) - sage: S._best_affine_patch([0,1,2]) + sage: F = GF(3) # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(F, 2) # optional - sage.rings.finite_rings + sage: S._best_affine_patch([0,1,2]) # optional - sage.rings.finite_rings 2 """ point = list(point) @@ -357,8 +353,8 @@ def neighborhood(self, point): EXAMPLES:: - sage: P.= ProjectiveSpace(QQ,2) - sage: S = P.subscheme(x+2*y+3*z) + sage: P.= ProjectiveSpace(QQ, 2) + sage: S = P.subscheme(x + 2*y + 3*z) sage: s = S.point([0,-3,2]); s (0 : -3/2 : 1) sage: patch = S.neighborhood(s); patch @@ -366,12 +362,11 @@ def neighborhood(self, point): x + 3*z sage: patch.embedding_morphism() Scheme morphism: - From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x + 3*z - To: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - x + 2*y + 3*z - Defn: Defined on coordinates by sending (x, z) to - (x : -3/2 : z + 1) + From: Closed subscheme of Affine Space of dimension 2 over Rational Field + defined by: x + 3*z + To: Closed subscheme of Projective Space of dimension 2 over Rational Field + defined by: x + 2*y + 3*z + Defn: Defined on coordinates by sending (x, z) to (x : -3/2 : z + 1) sage: patch.embedding_center() (0, 0) sage: patch.embedding_morphism()([0,0]) @@ -415,8 +410,8 @@ def is_smooth(self, point=None): EXAMPLES:: - sage: P2. = ProjectiveSpace(2,QQ) - sage: cuspidal_curve = P2.subscheme([y^2*z-x^3]) + sage: P2. = ProjectiveSpace(2, QQ) + sage: cuspidal_curve = P2.subscheme([y^2*z - x^3]) sage: cuspidal_curve Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: -x^3 + y^2*z @@ -426,7 +421,7 @@ def is_smooth(self, point=None): False sage: cuspidal_curve.is_smooth() False - sage: P2.subscheme([y^2*z-x^3+z^3+1/10*x*y*z]).is_smooth() + sage: P2.subscheme([y^2*z - x^3 + z^3 + 1/10*x*y*z]).is_smooth() True TESTS:: @@ -473,26 +468,20 @@ def orbit(self, f, N): EXAMPLES:: sage: P. = ProjectiveSpace(QQ, 3) - sage: f = DynamicalSystem_projective([(x-2*y)^2,(x-2*z)^2,(x-2*w)^2,x^2]) - sage: f.orbit(P.subscheme([x]),5) + sage: f = DynamicalSystem_projective([(x-2*y)^2, (x-2*z)^2, (x-2*w)^2, x^2]) + sage: f.orbit(P.subscheme([x]), 5) [Closed subscheme of Projective Space of dimension 3 over Rational Field - defined by: - x, + defined by: x, Closed subscheme of Projective Space of dimension 3 over Rational Field - defined by: - w, + defined by: w, Closed subscheme of Projective Space of dimension 3 over Rational Field - defined by: - z - w, + defined by: z - w, Closed subscheme of Projective Space of dimension 3 over Rational Field - defined by: - y - z, + defined by: y - z, Closed subscheme of Projective Space of dimension 3 over Rational Field - defined by: - x - y, + defined by: x - y, Closed subscheme of Projective Space of dimension 3 over Rational Field - defined by: - x - w] + defined by: x - w] :: @@ -500,8 +489,8 @@ def orbit(self, f, N): sage: P1. = ProjectiveSpace(QQ, 1) sage: H = Hom(PS, P1) sage: f = H([x^2, y^2]) - sage: X = PS.subscheme([x-y]) - sage: X.orbit(f,2) + sage: X = PS.subscheme([x - y]) + sage: X.orbit(f, 2) Traceback (most recent call last): ... TypeError: map must be a dynamical system for iteration @@ -510,8 +499,8 @@ def orbit(self, f, N): sage: PS. = ProjectiveSpace(QQ, 2) sage: f = DynamicalSystem_projective([x^2, y^2, z^2]) - sage: X = PS.subscheme([x-y]) - sage: X.orbit(f,[-1,2]) + sage: X = PS.subscheme([x - y]) + sage: X.orbit(f, [-1,2]) Traceback (most recent call last): ... TypeError: orbit bounds must be non-negative @@ -556,9 +545,9 @@ def nth_iterate(self, f, n): sage: P. = ProjectiveSpace(QQ, 3) sage: f = DynamicalSystem_projective([y^2, z^2, x^2, w^2]) - sage: f.nth_iterate(P.subscheme([x-w,y-z]), 3) + sage: f.nth_iterate(P.subscheme([x - w, y - z]), 3) Closed subscheme of Projective Space of dimension 3 over Rational Field - defined by: + defined by: y - z, x - w @@ -566,8 +555,8 @@ def nth_iterate(self, f, n): sage: PS. = ProjectiveSpace(ZZ, 2) sage: f = DynamicalSystem_projective([x^2, y^2, z^2]) - sage: X = PS.subscheme([x-y]) - sage: X.nth_iterate(f,-2) + sage: X = PS.subscheme([x - y]) + sage: X.nth_iterate(f, -2) Traceback (most recent call last): ... TypeError: must be a forward orbit @@ -575,11 +564,11 @@ def nth_iterate(self, f, n): :: sage: PS. = ProjectiveSpace(ZZ, 2) - sage: P2.=ProjectiveSpace(QQ, 2) + sage: P2. = ProjectiveSpace(QQ, 2) sage: H = Hom(PS, P2) sage: f = H([x^2, y^2, z^2]) - sage: X = PS.subscheme([x-y]) - sage: X.nth_iterate(f,2) + sage: X = PS.subscheme([x - y]) + sage: X.nth_iterate(f, 2) Traceback (most recent call last): ... TypeError: map must be a dynamical system for iteration @@ -588,8 +577,8 @@ def nth_iterate(self, f, n): sage: PS. = ProjectiveSpace(QQ, 2) sage: f = DynamicalSystem_projective([x^2, y^2, z^2]) - sage: X = PS.subscheme([x-y]) - sage: X.nth_iterate(f,2.5) + sage: X = PS.subscheme([x - y]) + sage: X.nth_iterate(f, 2.5) Traceback (most recent call last): ... TypeError: Attempt to coerce non-integral RealNumber to Integer @@ -624,11 +613,11 @@ def _forward_image(self, f, check=True): sage: PS. = ProjectiveSpace(QQ, 2) sage: H = End(PS) - sage: f = H([x^2, y^2-2*z^2, z^2]) - sage: X = PS.subscheme(y-2*z) + sage: f = H([x^2, y^2 - 2*z^2, z^2]) + sage: X = PS.subscheme(y - 2*z) sage: X._forward_image(f) Closed subscheme of Projective Space of dimension 2 over Rational Field - defined by: + defined by: y - 2*z :: @@ -637,10 +626,10 @@ def _forward_image(self, f, check=True): sage: PS. = ProjectiveSpace(ZZ, 3) sage: H = End(PS) sage: f = H([y^2, x^2, w^2, z^2]) - sage: X = PS.subscheme([z^2+y*w, x-w]) + sage: X = PS.subscheme([z^2 + y*w, x - w]) sage: f(X) Closed subscheme of Projective Space of dimension 3 over Integer Ring - defined by: + defined by: y - z, x*z - w^2 @@ -649,10 +638,10 @@ def _forward_image(self, f, check=True): sage: PS. = ProjectiveSpace(CC, 3) sage: H = End(PS) sage: f = H([x^2 + y^2, y^2, z^2-y^2, w^2]) - sage: X = PS.subscheme([z-2*w]) + sage: X = PS.subscheme([z - 2*w]) sage: f(X) Closed subscheme of Projective Space of dimension 3 over Complex Field - with 53 bits of precision defined by: + with 53 bits of precision defined by: y + z + (-4.00000000000000)*w :: @@ -661,36 +650,35 @@ def _forward_image(self, f, check=True): sage: P. = ProjectiveSpace(FractionField(R), 2) sage: H = End(P) sage: f = H([x^2 + 2*y*z, t^2*y^2, z^2]) - sage: f([t^2*y-z]) + sage: f([t^2*y - z]) Closed subscheme of Projective Space of dimension 2 over Fraction Field - of Univariate Polynomial Ring in t over Rational Field defined by: + of Univariate Polynomial Ring in t over Rational Field defined by: y - 1/(t^2)*z :: sage: set_verbose(-1) - sage: PS. = ProjectiveSpace(Qp(3), 2) - sage: H = End(PS) - sage: f = H([x^2,2*y^2,z^2]) - sage: X = PS.subscheme([2*x-y,z]) - sage: f(X) + sage: PS. = ProjectiveSpace(Qp(3), 2) # optional - sage.rings.padics + sage: H = End(PS) # optional - sage.rings.padics + sage: f = H([x^2, 2*y^2, z^2]) # optional - sage.rings.padics + sage: X = PS.subscheme([2*x - y, z]) # optional - sage.rings.padics + sage: f(X) # optional - sage.rings.padics Closed subscheme of Projective Space of dimension 2 over 3-adic Field - with capped relative precision 20 defined by: + with capped relative precision 20 defined by: z, - x + (1 + 3^2 + 3^4 + 3^6 + 3^8 + 3^10 + 3^12 + 3^14 + 3^16 + 3^18 + - O(3^20))*y + x + (1 + 3^2 + 3^4 + 3^6 + 3^8 + 3^10 + 3^12 + 3^14 + 3^16 + 3^18 + O(3^20))*y :: sage: R. = PolynomialRing(QQ) sage: P. = ProjectiveSpace(FractionField(R), 2) sage: H = End(P) - sage: f = H([y0*x^2+y1*z^2, y2*y^2+y3*z^2, z^2]) + sage: f = H([y0*x^2 + y1*z^2, y2*y^2 + y3*z^2, z^2]) sage: X = P.subscheme(x*z) sage: X._forward_image(f) Closed subscheme of Projective Space of dimension 2 over Fraction Field - of Multivariate Polynomial Ring in y0, y1, y2, y3 over Rational Field - defined by: + of Multivariate Polynomial Ring in y0, y1, y2, y3 over Rational Field + defined by: x*z + (-y1)*z^2 :: @@ -698,11 +686,11 @@ def _forward_image(self, f, check=True): sage: P2. = ProjectiveSpace(QQ, 2) sage: P5. = ProjectiveSpace(QQ, 5) sage: H = Hom(P2, P5) - sage: f = H([x^2,x*y,x*z,y^2,y*z,z^2]) #Veronese map + sage: f = H([x^2, x*y, x*z, y^2, y*z, z^2]) # Veronese map sage: X = P2.subscheme([]) sage: f(X) Closed subscheme of Projective Space of dimension 5 over Rational Field - defined by: + defined by: -z4^2 + z3*z5, -z2*z4 + z1*z5, -z2*z3 + z1*z4, @@ -712,14 +700,14 @@ def _forward_image(self, f, check=True): :: - sage: P2.=ProjectiveSpace(QQ, 2) - sage: P3.=ProjectiveSpace(QQ, 3) + sage: P2. = ProjectiveSpace(QQ, 2) + sage: P3. = ProjectiveSpace(QQ, 3) sage: H = Hom(P2, P3) - sage: X = P2.subscheme([x-y,x-z]) - sage: f = H([x^2,y^2,z^2,x*y]) + sage: X = P2.subscheme([x - y, x - z]) + sage: f = H([x^2, y^2, z^2, x*y]) sage: f(X) Closed subscheme of Projective Space of dimension 3 over Rational Field - defined by: + defined by: w - t, v - t, u - t @@ -728,9 +716,9 @@ def _forward_image(self, f, check=True): sage: P1. = ProjectiveSpace(QQ, 1) sage: P2. = ProjectiveSpace(QQ, 2) - sage: H = Hom(P2,P1) - sage: f = H([x^2,y*z]) - sage: X = P2.subscheme([x-y]) + sage: H = Hom(P2, P1) + sage: f = H([x^2, y*z]) + sage: X = P2.subscheme([x - y]) sage: f(X) Traceback (most recent call last): ... @@ -741,7 +729,7 @@ def _forward_image(self, f, check=True): sage: PS. = ProjectiveSpace(ZZ, 2) sage: H = End(PS) sage: f = H([x^3, x*y^2, x*z^2]) - sage: X = PS.subscheme([x-y]) + sage: X = PS.subscheme([x - y]) sage: X._forward_image(f) Traceback (most recent call last): ... @@ -751,7 +739,7 @@ def _forward_image(self, f, check=True): sage: PS. = ProjectiveSpace(QQ, 2) sage: P1. = ProjectiveSpace(QQ, 1) - sage: Y = P1.subscheme([u-v]) + sage: Y = P1.subscheme([u - v]) sage: H = End(PS) sage: f = H([x^2, y^2, z^2]) sage: Y._forward_image(f) @@ -812,20 +800,20 @@ def preimage(self, f, k=1, check=True): sage: PS. = ProjectiveSpace(ZZ, 2) sage: H = End(PS) sage: f = H([y^2, x^2, z^2]) - sage: X = PS.subscheme([x-y]) + sage: X = PS.subscheme([x - y]) sage: X.preimage(f) Closed subscheme of Projective Space of dimension 2 over Integer Ring - defined by: + defined by: -x^2 + y^2 :: sage: P. = ProjectiveSpace(QQ, 4) sage: H = End(P) - sage: f = H([x^2-y^2, y^2, z^2, w^2, t^2+w^2]) - sage: f.rational_preimages(P.subscheme([x-z, t^2, w-t])) + sage: f = H([x^2 - y^2, y^2, z^2, w^2, t^2 + w^2]) + sage: f.rational_preimages(P.subscheme([x - z, t^2, w - t])) Closed subscheme of Projective Space of dimension 4 over Rational Field - defined by: + defined by: x^2 - y^2 - z^2, w^4 + 2*w^2*t^2 + t^4, -t^2 @@ -835,11 +823,11 @@ def preimage(self, f, k=1, check=True): sage: P1. = ProjectiveSpace(QQ, 1) sage: P3. = ProjectiveSpace(QQ, 3) sage: H = Hom(P1, P3) - sage: X = P3.subscheme([u-v, 2*u-w, u+t]) - sage: f = H([x^2,y^2, x^2+y^2, x*y]) + sage: X = P3.subscheme([u - v, 2*u - w, u + t]) + sage: f = H([x^2, y^2, x^2 + y^2, x*y]) sage: X.preimage(f) Closed subscheme of Projective Space of dimension 1 over Rational Field - defined by: + defined by: x^2 - y^2, x^2 - y^2, x^2 + x*y @@ -849,7 +837,7 @@ def preimage(self, f, k=1, check=True): sage: P1. = ProjectiveSpace(QQ, 1) sage: P3. = ProjectiveSpace(QQ, 3) sage: H = Hom(P3, P1) - sage: X = P1.subscheme([x-y]) + sage: X = P1.subscheme([x - y]) sage: f = H([u^2, v^2]) sage: X.preimage(f) Traceback (most recent call last): @@ -861,7 +849,7 @@ def preimage(self, f, k=1, check=True): sage: PS. = ProjectiveSpace(ZZ, 2) sage: H = End(PS) sage: f = H([x^2, x^2, x^2]) - sage: X = PS.subscheme([x-y]) + sage: X = PS.subscheme([x - y]) sage: X.preimage(f) Traceback (most recent call last): ... @@ -871,7 +859,7 @@ def preimage(self, f, k=1, check=True): sage: PS. = ProjectiveSpace(ZZ, 2) sage: P1. = ProjectiveSpace(ZZ, 1) - sage: Y = P1.subscheme([u^2-v^2]) + sage: Y = P1.subscheme([u^2 - v^2]) sage: H = End(PS) sage: f = H([x^2, y^2, z^2]) sage: Y.preimage(f) @@ -882,12 +870,12 @@ def preimage(self, f, k=1, check=True): :: sage: P. = ProjectiveSpace(QQ, 2) - sage: Y = P.subscheme([x-y]) + sage: Y = P.subscheme([x - y]) sage: H = End(P) sage: f = H([x^2, y^2, z^2]) sage: Y.preimage(f, k=2) Closed subscheme of Projective Space of dimension 2 over Rational Field - defined by: + defined by: x^4 - y^4 """ dom = f.domain() @@ -933,7 +921,8 @@ def dual(self): sage: I = R.ideal(x^2 + y^2 + z^2) sage: X = P.subscheme(I) sage: X.dual() - Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: + Closed subscheme of Projective Space of dimension 2 over Rational Field + defined by: y0^2 + y1^2 + y2^2 The dual of the twisted cubic curve in projective 3-space is a singular @@ -947,7 +936,7 @@ def dual(self): sage: X = P.subscheme(I) sage: X.dual() Closed subscheme of Projective Space of dimension 3 over - Rational Field defined by: + Rational Field defined by: y2^2 - y1*y3, y1*y2 - y0*y3, y1^2 - y0*y2 @@ -961,20 +950,20 @@ def dual(self): An example over a finite field:: - sage: R = PolynomialRing(GF(61), 'a,b,c') - sage: P. = ProjectiveSpace(2, R.base_ring()) - sage: X = P.subscheme(R.ideal(a*a+2*b*b+3*c*c)) - sage: X.dual() + sage: R = PolynomialRing(GF(61), 'a,b,c') # optional - sage.rings.finite_rings + sage: P. = ProjectiveSpace(2, R.base_ring()) # optional - sage.rings.finite_rings + sage: X = P.subscheme(R.ideal(a*a + 2*b*b + 3*c*c)) # optional - sage.rings.finite_rings + sage: X.dual() # optional - sage.rings.finite_rings Closed subscheme of Projective Space of dimension 2 over - Finite Field of size 61 defined by: - y0^2 - 30*y1^2 - 20*y2^2 + Finite Field of size 61 defined by: + y0^2 - 30*y1^2 - 20*y2^2 TESTS:: - sage: R = PolynomialRing(Qp(3), 'a,b,c') - sage: P. = ProjectiveSpace(2, R.base_ring()) - sage: X = P.subscheme(R.ideal(a*a+2*b*b+3*c*c)) - sage: X.dual() + sage: R = PolynomialRing(Qp(3), 'a,b,c') # optional - sage.rings.padics + sage: P. = ProjectiveSpace(2, R.base_ring()) # optional - sage.rings.padics + sage: X = P.subscheme(R.ideal(a*a + 2*b*b + 3*c*c)) # optional - sage.rings.padics + sage: X.dual() # optional - sage.rings.padics Traceback (most recent call last): ... NotImplementedError: base ring must be QQ or a finite field @@ -1036,9 +1025,9 @@ def degree(self): sage: X.degree() 7 - sage: P. = ProjectiveSpace(GF(13), 3) - sage: X = P.subscheme([y^3 - w^3, x + 7*z]) - sage: X.degree() + sage: P. = ProjectiveSpace(GF(13), 3) # optional - sage.rings.finite_rings + sage: X = P.subscheme([y^3 - w^3, x + 7*z]) # optional - sage.rings.finite_rings + sage: X.degree() # optional - sage.rings.finite_rings 3 sage: P. = ProjectiveSpace(QQ, 4) @@ -1066,28 +1055,28 @@ def intersection_multiplicity(self, X, P): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(5), 2) - sage: C = Curve([x^4 - z^2*y^2], P) - sage: D = Curve([y^4*z - x^5 - x^3*z^2], P) - sage: Q1 = P([0,1,0]) - sage: C.intersection_multiplicity(D, Q1) + sage: P. = ProjectiveSpace(GF(5), 2) # optional - sage.rings.finite_rings + sage: C = Curve([x^4 - z^2*y^2], P) # optional - sage.rings.finite_rings + sage: D = Curve([y^4*z - x^5 - x^3*z^2], P) # optional - sage.rings.finite_rings + sage: Q1 = P([0,1,0]) # optional - sage.rings.finite_rings + sage: C.intersection_multiplicity(D, Q1) # optional - sage.rings.finite_rings 4 - sage: Q2 = P([0,0,1]) - sage: C.intersection_multiplicity(D, Q2) + sage: Q2 = P([0,0,1]) # optional - sage.rings.finite_rings + sage: C.intersection_multiplicity(D, Q2) # optional - sage.rings.finite_rings 6 :: sage: R. = QQ[] - sage: K. = NumberField(a^4 + 1) - sage: P. = ProjectiveSpace(K, 3) - sage: X = P.subscheme([x^2 + y^2 - z*w]) - sage: Y = P.subscheme([y*z - x*w, z - w]) - sage: Q1 = P([b^2,1,0,0]) - sage: X.intersection_multiplicity(Y, Q1) + sage: K. = NumberField(a^4 + 1) # optional - sage.rings.number_field + sage: P. = ProjectiveSpace(K, 3) # optional - sage.rings.number_field + sage: X = P.subscheme([x^2 + y^2 - z*w]) # optional - sage.rings.number_field + sage: Y = P.subscheme([y*z - x*w, z - w]) # optional - sage.rings.number_field + sage: Q1 = P([b^2,1,0,0]) # optional - sage.rings.number_field + sage: X.intersection_multiplicity(Y, Q1) # optional - sage.rings.number_field 1 - sage: Q2 = P([1/2*b^3-1/2*b,1/2*b^3-1/2*b,1,1]) - sage: X.intersection_multiplicity(Y, Q2) + sage: Q2 = P([1/2*b^3 - 1/2*b, 1/2*b^3 - 1/2*b, 1, 1]) # optional - sage.rings.number_field + sage: X.intersection_multiplicity(Y, Q2) # optional - sage.rings.number_field 1 :: @@ -1100,9 +1089,8 @@ def intersection_multiplicity(self, X, P): Traceback (most recent call last): ... TypeError: the intersection of this subscheme and (=Closed subscheme of Affine Space of dimension 3 - over Rational Field defined by: - z^2 + w^2 - 2*y, - y^2 - w^2) must be proper and finite + over Rational Field defined by: z^2 + w^2 - 2*y, y^2 - w^2) + must be proper and finite """ try: self.ambient_space()(P) @@ -1157,10 +1145,10 @@ def multiplicity(self, P): :: - sage: P. = ProjectiveSpace(GF(29), 3) - sage: C = Curve([y^17 - x^5*w^4*z^8, x*y - z^2], P) - sage: Q = P([3,0,0,1]) - sage: C.multiplicity(Q) + sage: P. = ProjectiveSpace(GF(29), 3) # optional - sage.rings.finite_rings + sage: C = Curve([y^17 - x^5*w^4*z^8, x*y - z^2], P) # optional - sage.rings.finite_rings + sage: Q = P([3,0,0,1]) # optional - sage.rings.finite_rings + sage: C.multiplicity(Q) # optional - sage.rings.finite_rings 8 """ if self.base_ring() not in Fields(): @@ -1205,15 +1193,14 @@ def veronese_embedding(self, d, CS=None, order='lex'): sage: v = L.veronese_embedding(2) sage: v Scheme morphism: - From: Closed subscheme of Projective Space of dimension 2 over - Rational Field defined by: - -x + y - To: Closed subscheme of Projective Space of dimension 5 over - Rational Field defined by: - -x4^2 + x3*x5, - x2 - x4, - x1 - x3, - x0 - x3 + From: Closed subscheme of Projective Space of dimension 2 + over Rational Field defined by: -x + y + To: Closed subscheme of Projective Space of dimension 5 + over Rational Field defined by: + -x4^2 + x3*x5, + x2 - x4, + x1 - x3, + x0 - x3 Defn: Defined on coordinates by sending (x : y : z) to (x^2 : x*y : x*z : y^2 : y*z : z^2) sage: v.codomain().degree() @@ -1228,14 +1215,13 @@ def veronese_embedding(self, d, CS=None, order='lex'): sage: Q. = ProjectiveSpace(QQ, 3) sage: P.subscheme([]).veronese_embedding(3, Q) Scheme morphism: - From: Closed subscheme of Projective Space of dimension 1 over - Rational Field defined by: - (no polynomials) - To: Closed subscheme of Projective Space of dimension 3 over - Rational Field defined by: - -s^2 + v*t, - -v*s + u*t, - -v^2 + u*s + From: Closed subscheme of Projective Space of dimension 1 + over Rational Field defined by: (no polynomials) + To: Closed subscheme of Projective Space of dimension 3 + over Rational Field defined by: + -s^2 + v*t, + -v*s + u*t, + -v^2 + u*s Defn: Defined on coordinates by sending (x : y) to (x^3 : x^2*y : x*y^2 : y^3) """ @@ -1266,21 +1252,19 @@ def _morphism(self, *args, **kwds): TESTS:: - sage: P1. = ProjectiveSpace(1,QQ) - sage: P2 = ProjectiveSpace(2,QQ) + sage: P1. = ProjectiveSpace(1, QQ) + sage: P2 = ProjectiveSpace(2, QQ) sage: H12 = P1.Hom(P2) - sage: H12([x^2,x*y, y^2]) # indirect doctest + sage: H12([x^2, x*y, y^2]) # indirect doctest Scheme morphism: From: Projective Space of dimension 1 over Rational Field To: Projective Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x : y) to - (x^2 : x*y : y^2) - sage: P1._morphism(H12, [x^2,x*y, y^2]) + Defn: Defined on coordinates by sending (x : y) to (x^2 : x*y : y^2) + sage: P1._morphism(H12, [x^2, x*y, y^2]) Scheme morphism: From: Projective Space of dimension 1 over Rational Field To: Projective Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending (x : y) to - (x^2 : x*y : y^2) + Defn: Defined on coordinates by sending (x : y) to (x^2 : x*y : y^2) """ return SchemeMorphism_polynomial_projective_subscheme_field(*args, **kwds) @@ -1311,47 +1295,39 @@ def Chow_form(self): EXAMPLES:: - sage: P. = ProjectiveSpace(GF(17), 3) - sage: X = P.subscheme([x3+x1,x2-x0,x2-x3]) - sage: X.Chow_form() + sage: P. = ProjectiveSpace(GF(17), 3) # optional - sage.rings.finite_rings + sage: X = P.subscheme([x3 + x1, x2 - x0, x2 - x3]) # optional - sage.rings.finite_rings + sage: X.Chow_form() # optional - sage.rings.finite_rings t0 - t1 + t2 + t3 :: - sage: P. = ProjectiveSpace(QQ,3) - sage: X = P.subscheme([x3^2 -101*x1^2 - 3*x2*x0]) + sage: P. = ProjectiveSpace(QQ, 3) + sage: X = P.subscheme([x3^2 - 101*x1^2 - 3*x2*x0]) sage: X.Chow_form() t0^2 - 101*t2^2 - 3*t1*t3 :: - sage: P.=ProjectiveSpace(QQ,3) - sage: X = P.subscheme([x0*x2-x1^2, x0*x3-x1*x2, x1*x3-x2^2]) + sage: P. = ProjectiveSpace(QQ, 3) + sage: X = P.subscheme([x0*x2 - x1^2, x0*x3 - x1*x2, x1*x3 - x2^2]) sage: Ch = X.Chow_form(); Ch t2^3 + 2*t2^2*t3 + t2*t3^2 - 3*t1*t2*t4 - t1*t3*t4 + t0*t4^2 + t1^2*t5 sage: Y = P.subscheme_from_Chow_form(Ch, 1); Y Closed subscheme of Projective Space of dimension 3 over Rational Field - defined by: - x2^2*x3 - x1*x3^2, - -x2^3 + x0*x3^2, - -x2^2*x3 + x1*x3^2, - x1*x2*x3 - x0*x3^2, - 3*x1*x2^2 - 3*x0*x2*x3, - -2*x1^2*x3 + 2*x0*x2*x3, - -3*x1^2*x2 + 3*x0*x1*x3, - x1^3 - x0^2*x3, - x2^3 - x1*x2*x3, - -3*x1*x2^2 + 2*x1^2*x3 + x0*x2*x3, - 2*x0*x2^2 - 2*x0*x1*x3, - 3*x1^2*x2 - 2*x0*x2^2 - x0*x1*x3, - -x0*x1*x2 + x0^2*x3, - -x0*x1^2 + x0^2*x2, - -x1^3 + x0*x1*x2, - x0*x1^2 - x0^2*x2 + defined by: + x2^2*x3 - x1*x3^2, -x2^3 + x0*x3^2, + -x2^2*x3 + x1*x3^2, x1*x2*x3 - x0*x3^2, + 3*x1*x2^2 - 3*x0*x2*x3, -2*x1^2*x3 + 2*x0*x2*x3, + -3*x1^2*x2 + 3*x0*x1*x3, x1^3 - x0^2*x3, + x2^3 - x1*x2*x3, -3*x1*x2^2 + 2*x1^2*x3 + x0*x2*x3, + 2*x0*x2^2 - 2*x0*x1*x3, 3*x1^2*x2 - 2*x0*x2^2 - x0*x1*x3, + -x0*x1*x2 + x0^2*x3, -x0*x1^2 + x0^2*x2, + -x1^3 + x0*x1*x2, x0*x1^2 - x0^2*x2 sage: I = Y.defining_ideal() sage: I.saturation(I.ring().ideal(list(I.ring().gens())))[0] - Ideal (x2^2 - x1*x3, x1*x2 - x0*x3, x1^2 - x0*x2) of Multivariate - Polynomial Ring in x0, x1, x2, x3 over Rational Field + Ideal (x2^2 - x1*x3, x1*x2 - x0*x3, x1^2 - x0*x2) + of Multivariate Polynomial Ring in x0, x1, x2, x3 over Rational Field """ I = self.defining_ideal() P = self.ambient_space() diff --git a/src/sage/schemes/riemann_surfaces/riemann_surface.py b/src/sage/schemes/riemann_surfaces/riemann_surface.py index e7c401cd07b..917de00d7b0 100644 --- a/src/sage/schemes/riemann_surfaces/riemann_surface.py +++ b/src/sage/schemes/riemann_surfaces/riemann_surface.py @@ -258,15 +258,15 @@ def numerical_inverse(C): EXAMPLES:: - sage: C = matrix(CC,3,3,[-4.5606e-31 + 1.2326e-31*I, - ....: -0.21313 + 0.24166*I, - ....: -3.4513e-31 + 0.16111*I, - ....: -1.0175 + 9.8608e-32*I, - ....: 0.30912 + 0.19962*I, - ....: -4.9304e-32 + 0.39923*I, - ....: 0.96793 - 3.4513e-31*I, - ....: -0.091587 + 0.19276*I, - ....: 3.9443e-31 + 0.38552*I]) + sage: C = matrix(CC, 3, 3, [-4.5606e-31 + 1.2326e-31*I, + ....: -0.21313 + 0.24166*I, + ....: -3.4513e-31 + 0.16111*I, + ....: -1.0175 + 9.8608e-32*I, + ....: 0.30912 + 0.19962*I, + ....: -4.9304e-32 + 0.39923*I, + ....: 0.96793 - 3.4513e-31*I, + ....: -0.091587 + 0.19276*I, + ....: 3.9443e-31 + 0.38552*I]) sage: from sage.schemes.riemann_surfaces.riemann_surface import numerical_inverse sage: 3e-16 < (C^-1*C-C^0).norm() < 1e-15 True @@ -416,8 +416,8 @@ def reparameterize_differential_minpoly(minpoly, z0): INPUT: - - ``minpoly`` -- a polynomial in two variables, where the first variables - corresponds to the base coordinate on the Riemann surface + - ``minpoly`` -- a polynomial in two variables, where the first variable + corresponds to the base coordinate on the Riemann surface - ``z0`` -- complex number or infinity; the point about which to reparameterize @@ -434,7 +434,7 @@ def reparameterize_differential_minpoly(minpoly, z0): .. MATH:: - `\frac{-\bar{z}^{-2} d\bar{z}}{2\sqrt{\bar{z}^{-3}-1}} = \frac{-d\bar{z}}{2\sqrt{\bar{z}(1-\bar{z}^3)}}`. + \frac{-\bar{z}^{-2} d\bar{z}}{2\sqrt{\bar{z}^{-3}-1}} = \frac{-d\bar{z}}{2\sqrt{\bar{z}(1-\bar{z}^3)}}. Hence the transformed differential should have minimal polynomial `\bar{g}^2 \bar{z} (1 - \bar{z}^3) - 1/4 = 0`, and we can check this:: @@ -529,7 +529,7 @@ class RiemannSurface(): We can also work with Riemann surfaces that are defined over fields with a complex embedding, but since the current interface for computing genus and regular differentials in Singular presently does not support extensions of - QQ, we need to specify a description of the differentials ourselves. We give + `\QQ`, we need to specify a description of the differentials ourselves. We give an example of a CM elliptic curve:: sage: Qt. = QQ[] @@ -2294,7 +2294,7 @@ def matrix_of_integral_values(self, differentials, integration_method="heuristic .. NOTE:: If ``differentials is self.cohomology_basis()``, the calculations - of the integrals along the edges are written to `self._integral_dict``. + of the integrals along the edges are written to ``self._integral_dict``. This is as this data will be required when computing the Abel-Jacobi map, and so it is helpful to have is stored rather than recomputing. @@ -2562,12 +2562,12 @@ def homomorphism_basis(self, other, b=None, r=None): Given another complex torus (given as the analytic Jacobian of a Riemann surface), numerically compute a basis for the homomorphism module. The - answer is returned as a list of 2g x 2g integer matrices T=(D, B; C, A) - such that if the columns of (I|M1) generate the lattice defining the - Jacobian of the Riemann surface and the columns of (I|M2) do this for - the codomain, then approximately we have (I|M2)T=(D+M2C)(I|M1), i.e., up + answer is returned as a list of `2g \times 2g` integer matrices `T=(D, B; C, A)` + such that if the columns of `(I|M_1)` generate the lattice defining the + Jacobian of the Riemann surface and the columns of `(I|M_2)` do this for + the codomain, then approximately we have `(I|M_2)T=(D+M_2C)(I|M_1)`, i.e., up to a choice of basis for `\CC^g` as a complex vector space, we we - realize (I|M1) as a sublattice of (I|M2). + realize `(I|M_1)` as a sublattice of `(I|M_2)`. INPUT: @@ -3265,9 +3265,7 @@ def _aj_based(self, P): we are using the convention that the `w` value over `\infty` is given by the limit as ``z`` tends to `\infty` of ``self.w_values(z)[branch]``. - OUTPUT: - - A vector of length ``self.genus``. + OUTPUT: A vector of length ``self.genus``. EXAMPLES: @@ -3497,9 +3495,7 @@ def abel_jacobi(self, divisor, verbose=False): of the computation, in terms of how many elements of the list ``divisor`` have been completed. - OUTPUT: - - A vector of length ``self.genus``. + OUTPUT: A vector of length ``self.genus``. EXAMPLES: @@ -3666,9 +3662,7 @@ def curve(self): For others, the curve is constructed and cached, so that an identical curve is returned upon subsequent calls. - OUTPUT: - - Curve from which Riemann surface is obtained. + OUTPUT: Curve from which Riemann surface is obtained. EXAMPLES:: diff --git a/src/sage/schemes/toric/chow_group.py b/src/sage/schemes/toric/chow_group.py index 2384d342656..8c835df37d2 100644 --- a/src/sage/schemes/toric/chow_group.py +++ b/src/sage/schemes/toric/chow_group.py @@ -274,8 +274,7 @@ def project_to_degree(self, degree): EXAMPLES:: sage: A = toric_varieties.P2().Chow_group() - sage: cycle = 10*A.gen(0) + 11*A.gen(1) + 12*A.gen(2) - sage: cycle + sage: cycle = 10*A.gen(0) + 11*A.gen(1) + 12*A.gen(2); cycle ( 12 | 11 | 10 ) sage: cycle.project_to_degree(2) ( 0 | 0 | 10 ) @@ -657,9 +656,7 @@ def scheme(self): r""" Return the underlying toric variety. - OUTPUT: - - A :class:`ToricVariety + OUTPUT: A :class:`ToricVariety `. EXAMPLES:: @@ -787,9 +784,9 @@ def _repr_(self) -> str: sage: P2 = toric_varieties.P2() sage: from sage.schemes.toric.chow_group import ChowGroup - sage: ChowGroup(P2,ZZ)._repr_() + sage: ChowGroup(P2, ZZ)._repr_() 'Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches' - sage: ChowGroup(P2,QQ)._repr_() + sage: ChowGroup(P2, QQ)._repr_() 'QQ-Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches' """ if self.base_ring() == QQ: @@ -855,15 +852,15 @@ def degree(self, k=None): Four exercises from page 65 of [Ful1993]_. First, an example with `A_1(X)=\ZZ\oplus\ZZ/3\ZZ`:: - sage: X = ToricVariety(Fan(cones=[[0,1],[1,2],[2,0]], - ....: rays=[[2,-1],[-1,2],[-1,-1]])) + sage: X = ToricVariety(Fan(cones=[[0,1], [1,2], [2,0]], + ....: rays=[[2,-1], [-1,2], [-1,-1]])) sage: A = X.Chow_group() sage: A.degree(1) C3 x Z Second, an example with `A_2(X)=\ZZ^2`:: - sage: points = [[1,0,0],[0,1,0],[0,0,1],[1,-1,1],[-1,0,-1]] + sage: points = [[1,0,0], [0,1,0], [0,0,1], [1,-1,1], [-1,0,-1]] sage: l = LatticePolytope(points) sage: l.show3d() sage: X = ToricVariety(FaceFan(l)) @@ -873,8 +870,8 @@ def degree(self, k=None): Third, an example with `A_2(X)=\ZZ^5`:: - sage: cube = [[ 1,0,0],[0, 1,0],[0,0, 1],[-1, 1, 1], - ....: [-1,0,0],[0,-1,0],[0,0,-1],[ 1,-1,-1]] + sage: cube = [[ 1,0,0], [0, 1,0], [0,0, 1], [-1, 1, 1], + ....: [-1,0,0], [0,-1,0], [0,0,-1], [ 1,-1,-1]] sage: lat_cube = LatticePolytope(cube) sage: X = ToricVariety(FaceFan((LatticePolytope(lat_cube)))) sage: X.Chow_group().degree(2) @@ -887,23 +884,25 @@ def degree(self, k=None): cube, so the variety is "more singular". Its Chow group has torsion, `A_2(X)=\ZZ^5 \oplus \ZZ/2`:: - sage: rays = [[ 1, 2, 3],[ 1,-1, 1],[-1, 1, 1],[-1,-1, 1], - ....: [-1,-1,-1],[-1, 1,-1],[ 1,-1,-1],[ 1, 1,-1]] - sage: cones = [[0,1,2,3],[4,5,6,7],[0,1,7,6], - ....: [4,5,3,2],[0,2,5,7],[4,6,1,3]] + sage: rays = [[ 1, 2, 3], [ 1,-1, 1], [-1, 1, 1], [-1,-1, 1], + ....: [-1,-1,-1], [-1, 1,-1], [ 1,-1,-1], [ 1, 1,-1]] + sage: cones = [[0,1,2,3], [4,5,6,7], [0,1,7,6], + ....: [4,5,3,2], [0,2,5,7], [4,6,1,3]] sage: X = ToricVariety(Fan(cones, rays)) sage: X.Chow_group().degree(2) # long time (2s on sage.math, 2011) C2 x Z^5 Finally, Example 1.3 of [FS1994]_:: - sage: points_mod = lambda k: matrix([[ 1, 1, 2*k+1],[ 1,-1, 1], - ....: [-1, 1, 1],[-1,-1, 1],[-1,-1,-1], - ....: [-1, 1,-1],[ 1,-1,-1],[ 1, 1,-1]]) - sage: rays = lambda k: matrix([[1,1,1],[1,-1,1],[-1,1,1]] - ....: ).solve_left(points_mod(k)).rows() - sage: cones = [[0,1,2,3],[4,5,6,7],[0,1,7,6], - ....: [4,5,3,2],[0,2,5,7],[4,6,1,3]] + sage: def points_mod(k): + ....: return matrix([[ 1, 1, 2*k+1], [ 1,-1, 1], + ....: [-1, 1, 1], [-1,-1, 1], [-1,-1,-1], + ....: [-1, 1,-1], [ 1,-1,-1], [ 1, 1,-1]]) + sage: def rays(k): + ....: return matrix([[ 1, 1, 1], + ....: [ 1, -1, 1], + ....: [-1, 1, 1]]).solve_left(points_mod(k)).rows() + sage: cones = [[0,1,2,3], [4,5,6,7], [0,1,7,6], [4,5,3,2], [0,2,5,7], [4,6,1,3]] sage: X_Delta = lambda k: ToricVariety(Fan(cones=cones, rays=rays(k))) sage: X_Delta(0).Chow_group().degree() # long time (3s on sage.math, 2011) (Z, Z, Z^5, Z) @@ -1027,8 +1026,7 @@ def relation_gens(self): sage: P2 = toric_varieties.P2() sage: A = P2.Chow_group() - sage: first = A.relation_gens()[0] - sage: first + sage: first = A.relation_gens()[0]; first ( 0 | 0 | 0 ) sage: first.is_zero() True @@ -1051,8 +1049,7 @@ class ChowGroup_degree_class(SageObject): EXAMPLES:: sage: P2 = toric_varieties.P2() - sage: A = P2.Chow_group() - sage: A + sage: A = P2.Chow_group(); A Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches sage: A.degree() (Z, Z, Z) @@ -1102,9 +1099,7 @@ def _repr_(self) -> str: """ Return a string representation. - OUTPUT: - - String. + OUTPUT: A string. EXAMPLES:: @@ -1141,9 +1136,7 @@ def module(self): """ Return the submodule of the toric Chow group generated. - OUTPUT: - - A :class:`sage.modules.fg_pid.fgp_module.FGP_Module_class` + OUTPUT: A :class:`sage.modules.fg_pid.fgp_module.FGP_Module_class`. EXAMPLES:: @@ -1158,9 +1151,7 @@ def ngens(self) -> int: """ Return the number of generators. - OUTPUT: - - An integer. + OUTPUT: An integer. EXAMPLES:: @@ -1173,17 +1164,13 @@ def ngens(self) -> int: def gen(self, i): """ - Return the ``i``-th generator of the Chow group of fixed - degree. + Return the ``i``-th generator of the Chow group of fixed degree. INPUT: - ``i`` -- integer. The index of the generator to be returned. - OUTPUT: - - A tuple of Chow cycles of fixed degree generating - :meth:`module`. + OUTPUT: A Chow cycle. EXAMPLES:: @@ -1198,9 +1185,7 @@ def gens(self): """ Return the generators of the Chow group of fixed degree. - OUTPUT: - - A tuple of Chow cycles of fixed degree generating + OUTPUT: A tuple of Chow cycles of fixed degree generating :meth:`module`. EXAMPLES:: @@ -1215,15 +1200,13 @@ def gens(self): def is_ChowGroup(x) -> bool: r""" - Return whether ``x`` is a :class:`ChowGroup_class` + Return whether ``x`` is a :class:`ChowGroup_class`. INPUT: - ``x`` -- anything. - OUTPUT: - - ``True`` or ``False``. + OUTPUT: ``True`` or ``False``. EXAMPLES:: @@ -1240,15 +1223,13 @@ def is_ChowGroup(x) -> bool: def is_ChowCycle(x) -> bool: r""" - Return whether ``x`` is a :class:`ChowGroup_class` + Return whether ``x`` is a :class:`ChowCycle`. INPUT: - ``x`` -- anything. - OUTPUT: - - ``True`` or ``False``. + OUTPUT: ``True`` or ``False``. EXAMPLES:: diff --git a/src/sage/schemes/toric/divisor.py b/src/sage/schemes/toric/divisor.py index 8647225c77b..c71ca05eede 100644 --- a/src/sage/schemes/toric/divisor.py +++ b/src/sage/schemes/toric/divisor.py @@ -45,7 +45,7 @@ types:: sage: F = Fan(cones=[(0,1,2,3), (0,1,4)], - ....: rays=[(1,1,1), (1,-1,1), (1,-1,-1), (1,1,-1), (0,0,1)]) + ....: rays=[(1,1,1), (1,-1,1), (1,-1,-1), (1,1,-1), (0,0,1)]) sage: X = ToricVariety(F) sage: QQ_Cartier = X.divisor([2,2,1,1,1]) sage: Cartier = 2 * QQ_Cartier @@ -93,7 +93,7 @@ Divisor class [1, 0, 0, 0] sage: Dx.divisor_class() in Cl True - sage: (-Dw+Dv+Dy).divisor_class() + sage: (-Dw + Dv + Dy).divisor_class() Divisor class [1, 0, 0, 0] sage: c0 Divisor class [1, 0, 0, 0] @@ -257,9 +257,7 @@ def ToricDivisor(toric_variety, arg=None, ring=None, check=True, reduce=True): ``reduce=False`` it is your responsibility to pass valid input data ``arg``. - OUTPUT: - - - A :class:`sage.schemes.toric.divisor.ToricDivisor_generic` + OUTPUT: A :class:`sage.schemes.toric.divisor.ToricDivisor_generic`. EXAMPLES:: @@ -271,7 +269,7 @@ def ToricDivisor(toric_variety, arg=None, ring=None, check=True, reduce=True): V(u) + V(y) sage: dP6.inject_variables() Defining x, u, y, v, z, w - sage: ToricDivisor(dP6, u+y) + sage: ToricDivisor(dP6, u + y) Traceback (most recent call last): ... ValueError: u + y is not a monomial @@ -384,10 +382,10 @@ class ToricDivisor_generic(Divisor_generic): - ``parent`` -- :class:`ToricDivisorGroup`. The parent divisor group. - ``check`` -- boolean. Type-check the entries of ``v``, see - :meth:`sage.schemes.generic.divisor_group.DivisorGroup_generic.__init__`. + :class:`~sage.schemes.generic.divisor_group.DivisorGroup_generic`. - ``reduce`` -- boolean. Combine coefficients in ``v``, see - :meth:`sage.schemes.generic.divisor_group.DivisorGroup_generic.__init__`. + :class:`~sage.schemes.generic.divisor_group.DivisorGroup_generic`. .. WARNING:: @@ -518,9 +516,7 @@ def function_value(self, point): - ``point`` -- either an integer, interpreted as the index of a ray of `\Sigma`, or a point of the lattice `N`. - OUTPUT: - - - an integer or a rational number. + OUTPUT: An integer or a rational number. EXAMPLES:: @@ -575,7 +571,7 @@ def m(self, cone): EXAMPLES:: sage: F = Fan(cones=[(0,1,2,3), (0,1,4)], - ....: rays=[(1,1,1), (1,-1,1), (1,-1,-1), (1,1,-1), (0,0,1)]) + ....: rays=[(1,1,1), (1,-1,1), (1,-1,-1), (1,1,-1), (0,0,1)]) sage: X = ToricVariety(F) sage: square_cone = X.fan().cone_containing(0,1,2,3) sage: triangle_cone = X.fan().cone_containing(0,1,4) @@ -781,7 +777,7 @@ def move_away_from(self, cone): EXAMPLES:: sage: F = Fan(cones=[(0,1,2,3), (0,1,4)], - ....: rays=[(1,1,1), (1,-1,1), (1,-1,-1), (1,1,-1), (0,0,1)]) + ....: rays=[(1,1,1), (1,-1,1), (1,-1,-1), (1,1,-1), (0,0,1)]) sage: X = ToricVariety(F) sage: square_cone = X.fan().cone_containing(0,1,2,3) sage: triangle_cone = X.fan().cone_containing(0,1,4) @@ -812,7 +808,7 @@ def cohomology_class(self): OUTPUT: - Returns the corresponding cohomology class as an instance of + The corresponding cohomology class as an instance of :class:`~sage.schemes.toric.variety.CohomologyClass`. The cohomology class is the first Chern class of the associated line bundle `\mathcal{O}(D)`. @@ -820,7 +816,7 @@ def cohomology_class(self): EXAMPLES:: sage: dP6 = toric_varieties.dP6() - sage: D = dP6.divisor(dP6.fan().ray(0) ) + sage: D = dP6.divisor(dP6.fan().ray(0)) sage: D.cohomology_class() [y + v - w] """ @@ -859,7 +855,7 @@ def divisor_class(self): OUTPUT: - Returns the class of the divisor in `\mathop{Cl}(X) + The class of the divisor in `\mathop{Cl}(X) \otimes_\ZZ \QQ` as an instance of :class:`ToricRationalDivisorClassGroup`. @@ -915,7 +911,7 @@ def is_ample(self): .. NOTE:: - * For a QQ-Cartier divisor, some positive integral + * For a `\QQ`-Cartier divisor, some positive integral multiple is Cartier. We return whether this associated divisor is ample, i.e. corresponds to an ample line bundle. @@ -959,8 +955,7 @@ def is_ample(self): [(1, 1), (1, 2), (2, 1), (2, 2)] sage: [ (a,b) for a,b in product(range(-3,3), repeat=2) ....: if D(a,b).is_nef() ] - [(0, 0), (0, 1), (0, 2), (1, 0), - (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] + [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] A (worse than orbifold) singular Fano threefold:: @@ -1037,8 +1032,7 @@ def is_nef(self): [(1, 1), (1, 2), (2, 1), (2, 2)] sage: [ (a,b) for a,b in product(range(-3,3), repeat=2) ....: if D(a,b).is_nef() ] - [(0, 0), (0, 1), (0, 2), (1, 0), - (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] + [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] """ try: return self._is_nef @@ -1140,9 +1134,7 @@ def sections(self): the line bundle (or reflexive sheaf) associated to the divisor. - OUTPUT: - - - :class:`tuple` of points of lattice `M`. + OUTPUT: A :class:`tuple` of points of lattice `M`. EXAMPLES:: @@ -1160,7 +1152,7 @@ def sections(self): sage: rays = [(1,0,0),(0,1,0),(0,0,1),(-2,0,-1),(-2,-1,0),(-3,-1,-1),(1,1,1),(-1,0,0)] sage: cones = [[0,1,3],[0,1,6],[0,2,4],[0,2,6],[0,3,5],[0,4,5],[1,3,7],[1,6,7],[2,4,7],[2,6,7],[3,5,7],[4,5,7]] - sage: X = ToricVariety(Fan(rays=rays,cones=cones)) + sage: X = ToricVariety(Fan(rays=rays, cones=cones)) sage: D = X.divisor(2); D V(z2) sage: D.is_nef() @@ -1206,10 +1198,10 @@ def sections_monomials(self): From [Cox]_ page 38:: - sage: lp = LatticePolytope([(1,0),(1,1),(0,1),(-1,0),(0,-1)]) + sage: lp = LatticePolytope([(1,0), (1,1), (0,1), (-1,0), (0,-1)]) sage: lp 2-d reflexive polytope #5 in 2-d lattice M - sage: dP7 = ToricVariety( FaceFan(lp), 'x1, x2, x3, x4, x5') + sage: dP7 = ToricVariety(FaceFan(lp), 'x1, x2, x3, x4, x5') sage: AK = -dP7.K() sage: AK.sections() (N(-1, 0), N(-1, 1), N(0, -1), N(0, 0), @@ -1278,10 +1270,8 @@ def Kodaira_map(self, names='z'): Scheme morphism: From: 1-d CPR-Fano toric variety covered by 2 affine patches To: Closed subscheme of Projective Space of dimension 2 - over Rational Field defined by: - -z1^2 + z0*z2 - Defn: Defined on coordinates by sending [u : v] to - (v^2 : u*v : u^2) + over Rational Field defined by: -z1^2 + z0*z2 + Defn: Defined on coordinates by sending [u : v] to (v^2 : u*v : u^2) sage: dP6 = toric_varieties.dP6() sage: D = -dP6.K() @@ -1290,17 +1280,10 @@ def Kodaira_map(self, names='z'): From: 2-d CPR-Fano toric variety covered by 6 affine patches To: Closed subscheme of Projective Space of dimension 6 over Rational Field defined by: - -x1*x5 + x0*x6, - -x2*x3 + x0*x5, - -x1*x3 + x0*x4, - x4*x5 - x3*x6, - -x1*x2 + x0*x3, - x3*x5 - x2*x6, - x3*x4 - x1*x6, - x3^2 - x1*x5, - x2*x4 - x1*x5, - -x1*x5^2 + x2*x3*x6, - -x1*x5^3 + x2^2*x6^2 + -x1*x5 + x0*x6, -x2*x3 + x0*x5, -x1*x3 + x0*x4, + x4*x5 - x3*x6, -x1*x2 + x0*x3, x3*x5 - x2*x6, + x3*x4 - x1*x6, x3^2 - x1*x5, x2*x4 - x1*x5, + -x1*x5^2 + x2*x3*x6, -x1*x5^3 + x2^2*x6^2 Defn: Defined on coordinates by sending [x : u : y : v : z : w] to (x*u^2*y^2*v : x^2*u^2*y*w : u*y^2*v^2*z : x*u*y*v*z*w : x^2*u*z*w^2 : y*v^2*z^2*w : x*v*z^2*w^2) @@ -1329,9 +1312,7 @@ def _sheaf_complex(self, m): - `m` -- a point in ``self.scheme().fan().dual_lattice()``. - OUTPUT: - - - :class:`simplicial complex `. + OUTPUT: A :class:`simplicial complex `. EXAMPLES:: @@ -1367,9 +1348,7 @@ def _sheaf_cohomology(self, cplx): - ``cplx`` -- simplicial complex. - OUTPUT: - - - integer vector. + OUTPUT: An integer vector. EXAMPLES:: @@ -1704,7 +1683,7 @@ def __init__(self, toric_variety, base_ring): parent classes even if the schemes are the same:: sage: from sage.schemes.generic.divisor_group import DivisorGroup - sage: DivisorGroup(P2,ZZ) is ToricDivisorGroup(P2,ZZ) + sage: DivisorGroup(P2, ZZ) is ToricDivisorGroup(P2, ZZ) False """ assert is_ToricVariety(toric_variety), str(toric_variety) + ' is not a toric variety!' @@ -1714,9 +1693,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - string. + OUTPUT: A string. TESTS:: diff --git a/src/sage/schemes/toric/divisor_class.pyx b/src/sage/schemes/toric/divisor_class.pyx index 50e23646087..63f21d55b5c 100644 --- a/src/sage/schemes/toric/divisor_class.pyx +++ b/src/sage/schemes/toric/divisor_class.pyx @@ -80,13 +80,11 @@ def is_ToricRationalDivisorClass(x): EXAMPLES:: - sage: from sage.schemes.toric.divisor_class import ( - ....: is_ToricRationalDivisorClass) + sage: from sage.schemes.toric.divisor_class import is_ToricRationalDivisorClass sage: is_ToricRationalDivisorClass(1) False sage: dP6 = toric_varieties.dP6() - sage: D = dP6.rational_class_group().gen(0) - sage: D + sage: D = dP6.rational_class_group().gen(0); D Divisor class [1, 0, 0, 0] sage: is_ToricRationalDivisorClass(D) True diff --git a/src/sage/schemes/toric/fano_variety.py b/src/sage/schemes/toric/fano_variety.py index 1bf2b79ad36..c7d05455d97 100644 --- a/src/sage/schemes/toric/fano_variety.py +++ b/src/sage/schemes/toric/fano_variety.py @@ -53,49 +53,35 @@ Its anticanonical "hypersurface" is a one-dimensional Calabi-Yau manifold:: - sage: P2.anticanonical_hypersurface( - ....: monomial_points="all") - Closed subscheme of 2-d CPR-Fano toric variety - covered by 3 affine patches defined by: - a0*z0^3 + a9*z0^2*z1 + a7*z0*z1^2 - + a1*z1^3 + a8*z0^2*z2 + a6*z0*z1*z2 - + a4*z1^2*z2 + a5*z0*z2^2 - + a3*z1*z2^2 + a2*z2^3 + sage: P2.anticanonical_hypersurface(monomial_points="all") + Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: + a0*z0^3 + a9*z0^2*z1 + a7*z0*z1^2 + a1*z1^3 + a8*z0^2*z2 + a6*z0*z1*z2 + + a4*z1^2*z2 + a5*z0*z2^2 + a3*z1*z2^2 + a2*z2^3 In many cases it is sufficient to work with the "simplified polynomial moduli space" of anticanonical hypersurfaces:: - sage: P2.anticanonical_hypersurface( - ....: monomial_points="simplified") - Closed subscheme of 2-d CPR-Fano toric variety - covered by 3 affine patches defined by: + sage: P2.anticanonical_hypersurface(monomial_points="simplified") + Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: a0*z0^3 + a1*z1^3 + a6*z0*z1*z2 + a2*z2^3 The mirror family to these hypersurfaces lives inside the Fano toric variety obtained using ``simplex`` as ``Delta`` instead of ``Delta_polar``:: - sage: FTV = CPRFanoToricVariety(Delta=simplex, - ....: coordinate_points="all") - sage: FTV.anticanonical_hypersurface( - ....: monomial_points="simplified") - Closed subscheme of 2-d CPR-Fano toric variety - covered by 9 affine patches defined by: - a2*z2^3*z3^2*z4*z5^2*z8 - + a1*z1^3*z3*z4^2*z7^2*z9 - + a3*z0*z1*z2*z3*z4*z5*z7*z8*z9 - + a0*z0^3*z5*z7*z8^2*z9^2 + sage: FTV = CPRFanoToricVariety(Delta=simplex, coordinate_points="all") + sage: FTV.anticanonical_hypersurface(monomial_points="simplified") + Closed subscheme of 2-d CPR-Fano toric variety covered by 9 affine patches defined by: + a2*z2^3*z3^2*z4*z5^2*z8 + a1*z1^3*z3*z4^2*z7^2*z9 + + a3*z0*z1*z2*z3*z4*z5*z7*z8*z9 + a0*z0^3*z5*z7*z8^2*z9^2 Here we have taken the resolved version of the ambient space for the mirror family, but in fact we don't have to resolve singularities corresponding to the interior points of facets - they are singular points which do not lie on a generic anticanonical hypersurface:: - sage: FTV = CPRFanoToricVariety(Delta=simplex, - ....: coordinate_points="all but facets") - sage: FTV.anticanonical_hypersurface( - ....: monomial_points="simplified") - Closed subscheme of 2-d CPR-Fano toric variety - covered by 3 affine patches defined by: + sage: FTV = CPRFanoToricVariety(Delta=simplex, coordinate_points="all but facets") + sage: FTV.anticanonical_hypersurface(monomial_points="simplified") + Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: a0*z0^3 + a1*z1^3 + a3*z0*z1*z2 + a2*z2^3 This looks very similar to our second version of the anticanonical @@ -108,10 +94,8 @@ sage: p4318 = ReflexivePolytope(3, 4318) sage: FTV = CPRFanoToricVariety(Delta_polar=p4318) sage: FTV.anticanonical_hypersurface() - Closed subscheme of 3-d CPR-Fano toric variety - covered by 4 affine patches defined by: - a0*z2^12 + a4*z2^6*z3^6 + a3*z3^12 - + a8*z0*z1*z2*z3 + a2*z1^3 + a1*z0^2 + Closed subscheme of 3-d CPR-Fano toric variety covered by 4 affine patches defined by: + a0*z2^12 + a4*z2^6*z3^6 + a3*z3^12 + a8*z0*z1*z2*z3 + a2*z1^3 + a1*z0^2 Below you will find detailed descriptions of available functions. Current functionality of this module is very basic, but it is under active @@ -181,8 +165,7 @@ def is_CPRFanoToricVariety(x): EXAMPLES:: - sage: from sage.schemes.toric.fano_variety import ( - ....: is_CPRFanoToricVariety) + sage: from sage.schemes.toric.fano_variety import is_CPRFanoToricVariety sage: is_CPRFanoToricVariety(1) False sage: FTV = toric_varieties.P2() @@ -281,9 +264,7 @@ def CPRFanoToricVariety(Delta=None, ``Delta``). If you know for sure that the input is valid, you may significantly decrease construction time using ``check=False`` option. - OUTPUT: - - - :class:`CPR-Fano toric variety `. + OUTPUT: :class:`CPR-Fano toric variety `. EXAMPLES: @@ -291,10 +272,8 @@ def CPRFanoToricVariety(Delta=None, sage: diamond = lattice_polytope.cross_polytope(2) sage: diamond.vertices() - M( 1, 0), - M( 0, 1), - M(-1, 0), - M( 0, -1) + M( 1, 0), M( 0, 1), + M(-1, 0), M( 0, -1) in 2-d lattice M sage: P1xP1 = CPRFanoToricVariety(Delta_polar=diamond) sage: P1xP1 @@ -302,10 +281,8 @@ def CPRFanoToricVariety(Delta=None, sage: P1xP1.fan() Rational polyhedral fan in 2-d lattice M sage: P1xP1.fan().rays() - M( 1, 0), - M( 0, 1), - M(-1, 0), - M( 0, -1) + M( 1, 0), M( 0, 1), + M(-1, 0), M( 0, -1) in 2-d lattice M "Unfortunately," this variety is smooth to start with and we cannot @@ -315,72 +292,50 @@ def CPRFanoToricVariety(Delta=None, sage: square = diamond.polar() sage: square.vertices() - N( 1, 1), - N( 1, -1), - N(-1, -1), - N(-1, 1) + N( 1, 1), N( 1, -1), + N(-1, -1), N(-1, 1) in 2-d lattice N sage: square.points() - N( 1, 1), - N( 1, -1), - N(-1, -1), - N(-1, 1), - N(-1, 0), - N( 0, -1), - N( 0, 0), - N( 0, 1), - N( 1, 0) + N( 1, 1), N( 1, -1), N(-1, -1), + N(-1, 1), N(-1, 0), N( 0, -1), + N( 0, 0), N( 0, 1), N( 1, 0) in 2-d lattice N We will construct several varieties associated to it:: sage: FTV = CPRFanoToricVariety(Delta_polar=square) sage: FTV.fan().rays() - N( 1, 1), - N( 1, -1), - N(-1, -1), - N(-1, 1) + N( 1, 1), N( 1, -1), + N(-1, -1), N(-1, 1) in 2-d lattice N sage: FTV.gens() (z0, z1, z2, z3) sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points=[0,1,2,3,8]) + ....: coordinate_points=[0,1,2,3,8]) sage: FTV.fan().rays() - N( 1, 1), - N( 1, -1), - N(-1, -1), - N(-1, 1), - N( 1, 0) + N( 1, 1), N( 1, -1), N(-1, -1), + N(-1, 1), N( 1, 0) in 2-d lattice N sage: FTV.gens() (z0, z1, z2, z3, z8) sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points=[8,0,2,1,3], - ....: coordinate_names="x+") + ....: coordinate_points=[8,0,2,1,3], + ....: coordinate_names="x+") sage: FTV.fan().rays() - N( 1, 0), - N( 1, 1), - N(-1, -1), - N( 1, -1), - N(-1, 1) + N( 1, 0), N( 1, 1), N(-1, -1), + N( 1, -1), N(-1, 1) in 2-d lattice N sage: FTV.gens() (x8, x0, x2, x1, x3) sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points="all", - ....: coordinate_names="x y Z+") + ....: coordinate_points="all", + ....: coordinate_names="x y Z+") sage: FTV.fan().rays() - N( 1, 1), - N( 1, -1), - N(-1, -1), - N(-1, 1), - N(-1, 0), - N( 0, -1), - N( 0, 1), - N( 1, 0) + N( 1, 1), N( 1, -1), N(-1, -1), N(-1, 1), + N(-1, 0), N( 0, -1), N( 0, 1), N( 1, 0) in 2-d lattice N sage: FTV.gens() (x, y, Z2, Z3, Z4, Z5, Z7, Z8) @@ -394,9 +349,9 @@ def CPRFanoToricVariety(Delta=None, you want:: sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points="all", - ....: coordinate_names="x y Z+", - ....: coordinate_name_indices=list(range(8))) + ....: coordinate_points="all", + ....: coordinate_names="x y Z+", + ....: coordinate_name_indices=list(range(8))) sage: FTV.gens() (x, y, Z2, Z3, Z4, Z5, Z6, Z7) @@ -406,9 +361,9 @@ def CPRFanoToricVariety(Delta=None, much "automatic" ones:: sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points="all", - ....: coordinate_names="x Z+", - ....: coordinate_name_indices=list(range(8))) + ....: coordinate_points="all", + ....: coordinate_names="x Z+", + ....: coordinate_name_indices=list(range(8))) sage: FTV.gens() (x, Z1, Z2, Z3, Z4, Z5, Z6, Z7) @@ -416,16 +371,16 @@ def CPRFanoToricVariety(Delta=None, accordingly:: sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points="all", - ....: coordinate_names="x Z+", - ....: coordinate_name_indices=[0] + list(range(7))) + ....: coordinate_points="all", + ....: coordinate_names="x Z+", + ....: coordinate_name_indices=[0] + list(range(7))) sage: FTV.gens() (x, Z0, Z1, Z2, Z3, Z4, Z5, Z6) sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points="all", - ....: coordinate_names="x y Z+", - ....: coordinate_name_indices=[0]*2 + list(range(6))) + ....: coordinate_points="all", + ....: coordinate_names="x y Z+", + ....: coordinate_name_indices=[0]*2 + list(range(6))) sage: FTV.gens() (x, y, Z0, Z1, Z2, Z3, Z4, Z5) @@ -440,14 +395,11 @@ def CPRFanoToricVariety(Delta=None, (these charts actually form exactly the face fan of our square) :: sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points=[0,1,2,3,4], - ....: charts=charts) + ....: coordinate_points=[0,1,2,3,4], + ....: charts=charts) sage: FTV.fan().rays() - N( 1, 1), - N( 1, -1), - N(-1, -1), - N(-1, 1), - N(-1, 0) + N( 1, 1), N( 1, -1), N(-1, -1), + N(-1, 1), N(-1, 0) in 2-d lattice N sage: [cone.ambient_ray_indices() for cone in FTV.fan()] [(0, 1), (1, 2), (2, 4), (3, 4), (0, 3)] @@ -456,22 +408,21 @@ def CPRFanoToricVariety(Delta=None, sage: bad_charts = charts + [(3,0)] sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points=[0,1,2,3,4], - ....: charts=bad_charts) + ....: coordinate_points=[0,1,2,3,4], + ....: charts=bad_charts) Traceback (most recent call last): ... ValueError: you have provided 5 cones, but only 4 of them are maximal! - Use discard_faces=True if you indeed need to construct a fan from - these cones. + Use discard_faces=True if you indeed need to construct a fan from these cones. These charts are technically correct, they just happened to list one of them twice, but it is assumed that such a situation will not happen. It is especially important when you try to speed up your code:: sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points=[0,1,2,3,4], - ....: charts=bad_charts, - ....: check=False) + ....: coordinate_points=[0,1,2,3,4], + ....: charts=bad_charts, + ....: check=False) Traceback (most recent call last): ... IndexError: list assignment index out of range @@ -485,8 +436,8 @@ def CPRFanoToricVariety(Delta=None, sage: bad_charts = charts + [(0,2)] sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points=[0,1,2,3,4], - ....: charts=bad_charts) + ....: coordinate_points=[0,1,2,3,4], + ....: charts=bad_charts) Traceback (most recent call last): ... ValueError: (0, 2) does not form a chart of a subdivision of @@ -494,34 +445,31 @@ def CPRFanoToricVariety(Delta=None, sage: bad_charts = charts[:-1] sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points=[0,1,2,3,4], - ....: charts=bad_charts) + ....: coordinate_points=[0,1,2,3,4], + ....: charts=bad_charts) Traceback (most recent call last): ... ValueError: given charts do not form a complete fan! sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points=[1,2,3,4]) + ....: coordinate_points=[1,2,3,4]) Traceback (most recent call last): ... - ValueError: all 4 vertices of Delta_polar - must be used for coordinates! + ValueError: all 4 vertices of Delta_polar must be used for coordinates! Got: [1, 2, 3, 4] sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points=[0,0,1,2,3,4]) + ....: coordinate_points=[0,0,1,2,3,4]) Traceback (most recent call last): ... - ValueError: no repetitions are - allowed for coordinate points! + ValueError: no repetitions are allowed for coordinate points! Got: [0, 0, 1, 2, 3, 4] sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points=[0,1,2,3,6]) + ....: coordinate_points=[0,1,2,3,6]) Traceback (most recent call last): ... - ValueError: the origin (point #6) - cannot be used for a coordinate! + ValueError: the origin (point #6) cannot be used for a coordinate! Got: [0, 1, 2, 3, 6] Here is a shorthand for defining the toric variety and homogeneous @@ -676,9 +624,7 @@ class CPRFanoToricVariety_field(ToricVariety_field): - ``base_field`` -- base field of the CPR-Fano toric variety. - OUTPUT: - - - :class:`CPR-Fano toric variety `. + OUTPUT: :class:`CPR-Fano toric variety `. TESTS:: @@ -804,22 +750,18 @@ def anticanonical_hypersurface(self, **kwds): Its anticanonical "hypersurface" is a one-dimensional Calabi-Yau manifold:: - sage: P2.anticanonical_hypersurface( - ....: monomial_points="all") + sage: P2.anticanonical_hypersurface(monomial_points="all") Closed subscheme of 2-d CPR-Fano toric variety - covered by 3 affine patches defined by: - a0*z0^3 + a9*z0^2*z1 + a7*z0*z1^2 - + a1*z1^3 + a8*z0^2*z2 + a6*z0*z1*z2 - + a4*z1^2*z2 + a5*z0*z2^2 - + a3*z1*z2^2 + a2*z2^3 + covered by 3 affine patches defined by: + a0*z0^3 + a9*z0^2*z1 + a7*z0*z1^2 + a1*z1^3 + a8*z0^2*z2 + a6*z0*z1*z2 + + a4*z1^2*z2 + a5*z0*z2^2 + a3*z1*z2^2 + a2*z2^3 In many cases it is sufficient to work with the "simplified polynomial moduli space" of anticanonical hypersurfaces:: - sage: P2.anticanonical_hypersurface( - ....: monomial_points="simplified") + sage: P2.anticanonical_hypersurface(monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety - covered by 3 affine patches defined by: + covered by 3 affine patches defined by: a0*z0^3 + a1*z1^3 + a6*z0*z1*z2 + a2*z2^3 The mirror family to these hypersurfaces lives inside the Fano toric @@ -827,15 +769,12 @@ def anticanonical_hypersurface(self, **kwds): ``Delta_polar``:: sage: FTV = CPRFanoToricVariety(Delta=simplex, - ....: coordinate_points="all") - sage: FTV.anticanonical_hypersurface( - ....: monomial_points="simplified") + ....: coordinate_points="all") + sage: FTV.anticanonical_hypersurface(monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety - covered by 9 affine patches defined by: - a2*z2^3*z3^2*z4*z5^2*z8 - + a1*z1^3*z3*z4^2*z7^2*z9 - + a3*z0*z1*z2*z3*z4*z5*z7*z8*z9 - + a0*z0^3*z5*z7*z8^2*z9^2 + covered by 9 affine patches defined by: + a2*z2^3*z3^2*z4*z5^2*z8 + a1*z1^3*z3*z4^2*z7^2*z9 + + a3*z0*z1*z2*z3*z4*z5*z7*z8*z9 + a0*z0^3*z5*z7*z8^2*z9^2 Here we have taken the resolved version of the ambient space for the mirror family, but in fact we don't have to resolve singularities @@ -843,11 +782,10 @@ def anticanonical_hypersurface(self, **kwds): points which do not lie on a generic anticanonical hypersurface:: sage: FTV = CPRFanoToricVariety(Delta=simplex, - ....: coordinate_points="all but facets") - sage: FTV.anticanonical_hypersurface( - ....: monomial_points="simplified") + ....: coordinate_points="all but facets") + sage: FTV.anticanonical_hypersurface(monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety - covered by 3 affine patches defined by: + covered by 3 affine patches defined by: a0*z0^3 + a1*z1^3 + a3*z0*z1*z2 + a2*z2^3 This looks very similar to our second anticanonical @@ -858,18 +796,16 @@ def anticanonical_hypersurface(self, **kwds): automatically generated coefficients. If you want, you can specify your own names :: - sage: FTV.anticanonical_hypersurface( - ....: coefficient_names="a b c d") + sage: FTV.anticanonical_hypersurface(coefficient_names="a b c d") Closed subscheme of 2-d CPR-Fano toric variety - covered by 3 affine patches defined by: + covered by 3 affine patches defined by: a*z0^3 + b*z1^3 + d*z0*z1*z2 + c*z2^3 or give concrete coefficients :: - sage: FTV.anticanonical_hypersurface( - ....: coefficients=[1, 2, 3, 4]) + sage: FTV.anticanonical_hypersurface(coefficients=[1, 2, 3, 4]) Closed subscheme of 2-d CPR-Fano toric variety - covered by 3 affine patches defined by: + covered by 3 affine patches defined by: z0^3 + 2*z1^3 + 4*z0*z1*z2 + 3*z2^3 or even mix numerical coefficients with some expressions :: @@ -878,13 +814,12 @@ def anticanonical_hypersurface(self, **kwds): ....: coefficients=[0, "t", "1/t", "psi/(psi^2 + phi)"]) sage: H Closed subscheme of 2-d CPR-Fano toric variety - covered by 3 affine patches defined by: + covered by 3 affine patches defined by: t*z1^3 + psi/(phi + psi^2)*z0*z1*z2 + 1/t*z2^3 sage: R = H.ambient_space().base_ring() sage: R Fraction Field of - Multivariate Polynomial Ring in phi, psi, t - over Rational Field + Multivariate Polynomial Ring in phi, psi, t over Rational Field """ # The example above is also copied to the tutorial section in the # main documentation of the module. @@ -899,10 +834,7 @@ def change_ring(self, F): - ``F`` -- field. - OUTPUT: - - - :class:`CPR-Fano toric variety ` over - ``F``. + OUTPUT: :class:`CPR-Fano toric variety ` over ``F``. .. NOTE:: @@ -925,14 +857,13 @@ def change_ring(self, F): Traceback (most recent call last): ... ValueError: no natural map from the base ring - (=Real Field with 53 bits of precision) - to R (=Rational Field)! + (=Real Field with 53 bits of precision) to R (=Rational Field)! sage: R = PolynomialRing(QQ, 2, 'a') sage: P1xP1.change_ring(R) Traceback (most recent call last): ... TypeError: need a field to construct a Fano toric variety! - Got Multivariate Polynomial Ring in a0, a1 over Rational Field + Got Multivariate Polynomial Ring in a0, a1 over Rational Field """ if self.base_ring() == F: return self @@ -961,8 +892,7 @@ def coordinate_point_to_coordinate(self, point): EXAMPLES:: sage: diamond = lattice_polytope.cross_polytope(2) - sage: FTV = CPRFanoToricVariety(diamond, - ....: coordinate_points=[0,1,2,3,8]) + sage: FTV = CPRFanoToricVariety(diamond, coordinate_points=[0,1,2,3,8]) sage: FTV.coordinate_points() (0, 1, 2, 3, 8) sage: FTV.gens() @@ -976,23 +906,21 @@ def coordinate_points(self): r""" Return indices of points of :meth:`Delta_polar` used for coordinates. - OUTPUT: - - - :class:`tuple` of integers. + OUTPUT: :class:`tuple` of integers. EXAMPLES:: sage: diamond = lattice_polytope.cross_polytope(2) sage: square = diamond.polar() sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points=[0,1,2,3,8]) + ....: coordinate_points=[0,1,2,3,8]) sage: FTV.coordinate_points() (0, 1, 2, 3, 8) sage: FTV.gens() (z0, z1, z2, z3, z8) sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points="all") + ....: coordinate_points="all") sage: FTV.coordinate_points() (0, 1, 2, 3, 4, 5, 7, 8) sage: FTV.gens() @@ -1119,13 +1047,12 @@ def nef_complete_intersection(self, nef_partition, **kwds): nef-partition of the 3-dimensional reflexive polytope #2254:: sage: p = ReflexivePolytope(3, 2254) - sage: np = p.nef_partitions()[1] - sage: np + sage: np = p.nef_partitions()[1]; np Nef-partition {2, 3, 4, 7, 8} ⊔ {0, 1, 5, 6} sage: X = CPRFanoToricVariety(Delta_polar=p) sage: X.nef_complete_intersection(np) Closed subscheme of 3-d CPR-Fano toric variety - covered by 10 affine patches defined by: + covered by 10 affine patches defined by: a0*z1*z4^2*z5^2*z7^3 + a2*z2*z4*z5*z6*z7^2*z8^2 + a3*z2*z3*z4*z7*z8 + a1*z0*z2, b3*z1*z4*z5^2*z6^2*z7^2*z8^2 + b0*z2*z5*z6^3*z7*z8^4 @@ -1136,7 +1063,7 @@ def nef_complete_intersection(self, nef_partition, **kwds): sage: X.nef_complete_intersection(np, monomial_points="vertices") Closed subscheme of 3-d CPR-Fano toric variety - covered by 10 affine patches defined by: + covered by 10 affine patches defined by: a0*z1*z4^2*z5^2*z7^3 + a2*z2*z4*z5*z6*z7^2*z8^2 + a3*z2*z3*z4*z7*z8 + a1*z0*z2, b3*z1*z4*z5^2*z6^2*z7^2*z8^2 + b0*z2*z5*z6^3*z7*z8^4 @@ -1149,7 +1076,7 @@ def nef_complete_intersection(self, nef_partition, **kwds): ....: monomial_points="vertices", ....: coefficients=[("a", "a^2", "a/e", "c_i"), list(range(1,6))]) Closed subscheme of 3-d CPR-Fano toric variety - covered by 10 affine patches defined by: + covered by 10 affine patches defined by: a*z1*z4^2*z5^2*z7^3 + a/e*z2*z4*z5*z6*z7^2*z8^2 + (c_i)*z2*z3*z4*z7*z8 + (a^2)*z0*z2, 4*z1*z4*z5^2*z6^2*z7^2*z8^2 + z2*z5*z6^3*z7*z8^4 @@ -1159,10 +1086,10 @@ def nef_complete_intersection(self, nef_partition, **kwds): intersections in a completely resolved ambient toric variety:: sage: X = CPRFanoToricVariety(Delta_polar=p, - ....: coordinate_points="all") + ....: coordinate_points="all") sage: X.nef_complete_intersection(np) Closed subscheme of 3-d CPR-Fano toric variety - covered by 22 affine patches defined by: + covered by 22 affine patches defined by: a2*z2*z4*z5*z6*z7^2*z8^2*z9^2*z10^2*z11*z12*z13 + a0*z1*z4^2*z5^2*z7^3*z9*z10^2*z12*z13 + a3*z2*z3*z4*z7*z8*z9*z10*z11*z12 + a1*z0*z2, @@ -1206,11 +1133,8 @@ def cartesian_product(self, other, sage: P1xP2 = P1.cartesian_product(P2); P1xP2 3-d CPR-Fano toric variety covered by 6 affine patches sage: P1xP2.fan().rays() - N+N( 1, 0, 0), - N+N(-1, 0, 0), - N+N( 0, 1, 0), - N+N( 0, 0, 1), - N+N( 0, -1, -1) + N+N( 1, 0, 0), N+N(-1, 0, 0), N+N( 0, 1, 0), + N+N( 0, 0, 1), N+N( 0, -1, -1) in 3-d lattice N+N sage: P1xP2.Delta_polar() 3-d reflexive polytope in 3-d lattice N+N @@ -1270,16 +1194,14 @@ def resolve(self, **kwds): ... ValueError: the origin (point #6) cannot be used for subdivision! - sage: FTV_res = FTV.resolve(new_points=[8,5]) - sage: FTV_res + sage: FTV_res = FTV.resolve(new_points=[8,5]); FTV_res 2-d CPR-Fano toric variety covered by 6 affine patches sage: FTV_res.coordinate_points() (0, 1, 2, 3, 8, 5) sage: FTV_res.gens() (z0, z1, z2, z3, z8, z5) - sage: TV_res = FTV.resolve(new_rays=[(1,2)]) - sage: TV_res + sage: TV_res = FTV.resolve(new_rays=[(1,2)]); TV_res 2-d toric variety covered by 5 affine patches sage: TV_res.gens() (z0, z1, z2, z3, z4) @@ -1357,7 +1279,7 @@ class AnticanonicalHypersurface(AlgebraicScheme_subscheme_toric): sage: import sage.schemes.toric.fano_variety as ftv sage: ftv.AnticanonicalHypersurface(P1xP1) Closed subscheme of 2-d CPR-Fano toric variety - covered by 4 affine patches defined by: + covered by 4 affine patches defined by: a0*s^2*x^2 + a3*t^2*x^2 + a6*s*t*x*y + a1*s^2*y^2 + a2*t^2*y^2 See :meth:`~CPRFanoToricVariety_field.anticanonical_hypersurface()` for a @@ -1375,19 +1297,19 @@ def __init__(self, P_Delta, monomial_points=None, coefficient_names=None, sage: import sage.schemes.toric.fano_variety as ftv sage: ftv.AnticanonicalHypersurface(P1xP1) Closed subscheme of 2-d CPR-Fano toric variety - covered by 4 affine patches defined by: + covered by 4 affine patches defined by: a0*s^2*x^2 + a3*t^2*x^2 + a6*s*t*x*y + a1*s^2*y^2 + a2*t^2*y^2 Check that finite fields are handled correctly :trac:`14899`:: - sage: F = GF(5^2, "a") - sage: X = P1xP1.change_ring(F) - sage: X.anticanonical_hypersurface(monomial_points="all", + sage: F = GF(5^2, "a") # optional - sage.rings.finite_rings + sage: X = P1xP1.change_ring(F) # optional - sage.rings.finite_rings + sage: X.anticanonical_hypersurface(monomial_points="all", # optional - sage.rings.finite_rings ....: coefficients=[1]*X.Delta().npoints()) Closed subscheme of 2-d CPR-Fano toric variety - covered by 4 affine patches defined by: + covered by 4 affine patches defined by: s^2*x^2 + s*t*x^2 + t^2*x^2 + s^2*x*y + s*t*x*y - + t^2*x*y + s^2*y^2 + s*t*y^2 + t^2*y^2 + + t^2*x*y + s^2*y^2 + s*t*y^2 + t^2*y^2 """ if not is_CPRFanoToricVariety(P_Delta): raise TypeError("anticanonical hypersurfaces can only be " @@ -1468,17 +1390,14 @@ class NefCompleteIntersection(AlgebraicScheme_subscheme_toric): EXAMPLES:: sage: o = lattice_polytope.cross_polytope(3) - sage: np = o.nef_partitions()[0] - sage: np + sage: np = o.nef_partitions()[0]; np Nef-partition {0, 1, 3} ⊔ {2, 4, 5} sage: X = CPRFanoToricVariety(Delta_polar=o) sage: X.nef_complete_intersection(np) Closed subscheme of 3-d CPR-Fano toric variety - covered by 8 affine patches defined by: - a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 - + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, - b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 - + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 + covered by 8 affine patches defined by: + a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, + b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 See :meth:`CPRFanoToricVariety_field.nef_complete_intersection` for a more elaborate example. @@ -1500,7 +1419,7 @@ def __init__(self, P_Delta, nef_partition, sage: from sage.schemes.toric.fano_variety import * sage: NefCompleteIntersection(X, np) Closed subscheme of 3-d CPR-Fano toric variety - covered by 8 affine patches defined by: + covered by 8 affine patches defined by: a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 @@ -1583,26 +1502,19 @@ def cohomology_class(self): r""" Return the class of ``self`` in the ambient space cohomology ring. - OUTPUT: - - - a :class:`cohomology class - `. + OUTPUT: A :class:`cohomology class `. EXAMPLES:: sage: o = lattice_polytope.cross_polytope(3) - sage: np = o.nef_partitions()[0] - sage: np + sage: np = o.nef_partitions()[0]; np Nef-partition {0, 1, 3} ⊔ {2, 4, 5} sage: X = CPRFanoToricVariety(Delta_polar=o) - sage: CI = X.nef_complete_intersection(np) - sage: CI + sage: CI = X.nef_complete_intersection(np); CI Closed subscheme of 3-d CPR-Fano toric variety - covered by 8 affine patches defined by: - a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 - + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, - b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 - + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 + covered by 8 affine patches defined by: + a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, + b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 sage: CI.cohomology_class() [2*z3*z4 + 4*z3*z5 + 2*z4*z5] """ @@ -1616,26 +1528,19 @@ def nef_partition(self): r""" Return the nef-partition associated to ``self``. - OUTPUT: - - - a :class:`nef-partition - `. + OUTPUT: A :class:`nef-partition `. EXAMPLES:: sage: o = lattice_polytope.cross_polytope(3) - sage: np = o.nef_partitions()[0] - sage: np + sage: np = o.nef_partitions()[0]; np Nef-partition {0, 1, 3} ⊔ {2, 4, 5} sage: X = CPRFanoToricVariety(Delta_polar=o) - sage: CI = X.nef_complete_intersection(np) - sage: CI + sage: CI = X.nef_complete_intersection(np); CI Closed subscheme of 3-d CPR-Fano toric variety - covered by 8 affine patches defined by: - a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 - + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, - b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 - + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 + covered by 8 affine patches defined by: + a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, + b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 sage: CI.nef_partition() Nef-partition {0, 1, 3} ⊔ {2, 4, 5} sage: CI.nef_partition() is np @@ -1667,17 +1572,13 @@ def add_variables(field, variables): sage: F = add_variables(QQ, []); F # No extension Rational Field sage: F = add_variables(QQ, ["a"]); F - Fraction Field of Univariate Polynomial Ring - in a over Rational Field + Fraction Field of Univariate Polynomial Ring in a over Rational Field sage: F = add_variables(F, ["a"]); F - Fraction Field of Univariate Polynomial Ring - in a over Rational Field + Fraction Field of Univariate Polynomial Ring in a over Rational Field sage: F = add_variables(F, ["b", "c"]); F - Fraction Field of Multivariate Polynomial Ring - in a, b, c over Rational Field + Fraction Field of Multivariate Polynomial Ring in a, b, c over Rational Field sage: F = add_variables(F, ["c", "d", "b", "c", "d"]); F - Fraction Field of Multivariate Polynomial Ring - in a, b, c, d over Rational Field + Fraction Field of Multivariate Polynomial Ring in a, b, c, d over Rational Field """ if not variables: return field diff --git a/src/sage/schemes/toric/homset.py b/src/sage/schemes/toric/homset.py index a057ecdf1ab..4470303d8d4 100644 --- a/src/sage/schemes/toric/homset.py +++ b/src/sage/schemes/toric/homset.py @@ -48,8 +48,7 @@ Scheme morphism: From: 2-d CPR-Fano toric variety covered by 4 affine patches To: 1-d CPR-Fano toric variety covered by 2 affine patches - Defn: Defined on coordinates by sending [s : t : x : y] to - [s : t] + Defn: Defined on coordinates by sending [s : t : x : y] to [s : t] In the case of toric algebraic schemes (defined by polynomials in toric varieties), this module defines the underlying morphism of the @@ -57,7 +56,7 @@ sage: P1xP1.inject_variables() Defining s, t, x, y - sage: S = P1xP1.subscheme([s*x-t*y]) + sage: S = P1xP1.subscheme([s*x - t*y]) sage: type(S.Hom(S)) @@ -76,8 +75,7 @@ Scheme morphism: From: 2-d CPR-Fano toric variety covered by 3 affine patches To: Projective Space of dimension 2 over Rational Field - Defn: Defined on coordinates by sending [x : y : z] to - (x^2 : y^2 : z^2) + Defn: Defined on coordinates by sending [x : y : z] to (x^2 : y^2 : z^2) sage: native_to_toric = P2_native.Hom(P2_toric); native_to_toric Set of morphisms @@ -89,8 +87,7 @@ Scheme morphism: From: Projective Space of dimension 2 over Rational Field To: 2-d CPR-Fano toric variety covered by 3 affine patches - Defn: Defined on coordinates by sending (u : v : w) to - [u^2 : v^2 : w^2] + Defn: Defined on coordinates by sending (u : v : w) to [u^2 : v^2 : w^2] """ # **************************************************************************** @@ -294,16 +291,13 @@ def _an_element_(self): class SchemeHomset_points_toric_base(SchemeHomset_points): """ - Base class for homsets with toric ambient spaces + Base class for homsets with toric ambient spaces. INPUT: - same as for :class:`SchemeHomset_points`. - OUTPUT: - - A scheme morphism of type - :class:`SchemeHomset_points_toric_base`. + OUTPUT: A scheme morphism of type :class:`SchemeHomset_points_toric_base`. EXAMPLES:: @@ -323,16 +317,14 @@ def is_finite(self): """ Return whether there are finitely many points. - OUTPUT: - - Boolean. + OUTPUT: A boolean. EXAMPLES:: sage: P2 = toric_varieties.P2() sage: P2.point_set().is_finite() False - sage: P2.change_ring(GF(7)).point_set().is_finite() + sage: P2.change_ring(GF(7)).point_set().is_finite() # optional - sage.rings.finite_rings True """ variety = self.codomain() @@ -355,11 +347,11 @@ def _naive_enumerator(self, ring=None): EXAMPLES:: - sage: P123 = toric_varieties.P2_123(base_ring=GF(3)) - sage: point_set = P123.point_set() - sage: next(iter(point_set._naive_enumerator())) + sage: P123 = toric_varieties.P2_123(base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: point_set = P123.point_set() # optional - sage.rings.finite_rings + sage: next(iter(point_set._naive_enumerator())) # optional - sage.rings.finite_rings (0, 0, 1) - sage: next(iter(point_set)) + sage: next(iter(point_set)) # optional - sage.rings.finite_rings [0 : 0 : 1] """ from sage.schemes.toric.points import NaiveFinitePointEnumerator @@ -386,11 +378,11 @@ def _finite_field_enumerator(self, finite_field=None): EXAMPLES:: - sage: P123 = toric_varieties.P2_123(base_ring=GF(3)) - sage: point_set = P123.point_set() - sage: next(iter(point_set._finite_field_enumerator())) + sage: P123 = toric_varieties.P2_123(base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: point_set = P123.point_set() # optional - sage.rings.finite_rings + sage: next(iter(point_set._finite_field_enumerator())) # optional - sage.rings.finite_rings (0, 0, 1) - sage: next(iter(point_set)) + sage: next(iter(point_set)) # optional - sage.rings.finite_rings [0 : 0 : 1] """ from sage.schemes.toric.points import FiniteFieldPointEnumerator @@ -412,9 +404,9 @@ def _enumerator(self): EXAMPLES:: - sage: P123 = toric_varieties.P2_123(base_ring=GF(3)) - sage: point_set = P123.point_set() - sage: point_set._enumerator() + sage: P123 = toric_varieties.P2_123(base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: point_set = P123.point_set() # optional - sage.rings.finite_rings + sage: point_set._enumerator() # optional - sage.rings.finite_rings """ ring = self.domain().base_ring() @@ -439,10 +431,7 @@ class SchemeHomset_points_toric_field(SchemeHomset_points_toric_base): - same as for :class:`~sage.schemes.generic.homset.SchemeHomset_points`. - OUTPUT: - - A scheme morphism of type - :class:`SchemeHomset_points_toric_field`. + OUTPUT: A scheme morphism of type :class:`SchemeHomset_points_toric_field`. EXAMPLES:: @@ -459,11 +448,11 @@ class SchemeHomset_points_toric_field(SchemeHomset_points_toric_base): unity:: sage: fan = NormalFan(ReflexivePolytope(2, 0)) - sage: X = ToricVariety(fan, base_field=GF(7)) - sage: point_set = X.point_set() - sage: point_set.cardinality() + sage: X = ToricVariety(fan, base_field=GF(7)) # optional - sage.rings.finite_rings + sage: point_set = X.point_set() # optional - sage.rings.finite_rings + sage: point_set.cardinality() # optional - sage.rings.finite_rings 21 - sage: sorted(X.point_set().list()) + sage: sorted(X.point_set().list()) # optional - sage.rings.finite_rings [[0 : 0 : 1], [0 : 1 : 0], [0 : 1 : 1], [0 : 1 : 3], [1 : 0 : 0], [1 : 0 : 1], [1 : 0 : 3], [1 : 1 : 0], [1 : 1 : 1], [1 : 1 : 2], [1 : 1 : 3], [1 : 1 : 4], @@ -477,9 +466,9 @@ class SchemeHomset_points_toric_field(SchemeHomset_points_toric_base): on the fiber:: sage: fan = Fan([Cone([(1,0), (1,1)]), Cone([(1,1), (0,1)])]) - sage: blowup_plane = ToricVariety(fan, base_ring=GF(3)) - sage: point_set = blowup_plane.point_set() - sage: sorted(point_set.list()) + sage: blowup_plane = ToricVariety(fan, base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: point_set = blowup_plane.point_set() # optional - sage.rings.finite_rings + sage: sorted(point_set.list()) # optional - sage.rings.finite_rings [[0 : 1 : 0], [0 : 1 : 1], [0 : 1 : 2], [1 : 0 : 0], [1 : 0 : 1], [1 : 0 : 2], [1 : 1 : 0], [1 : 1 : 1], [1 : 1 : 2], @@ -488,8 +477,8 @@ class SchemeHomset_points_toric_field(SchemeHomset_points_toric_base): Toric varieties with torus factors (that is, where the fan is not full-dimensional) also work:: - sage: F_times_Fstar = ToricVariety(Fan([Cone([(1,0)])]), base_field=GF(3)) - sage: sorted(F_times_Fstar.point_set().list()) + sage: F_times_Fstar = ToricVariety(Fan([Cone([(1,0)])]), base_field=GF(3)) # optional - sage.rings.finite_rings + sage: sorted(F_times_Fstar.point_set().list()) # optional - sage.rings.finite_rings [[0 : 1], [0 : 2], [1 : 1], [1 : 2], [2 : 1], [2 : 2]] TESTS:: @@ -511,29 +500,29 @@ def cardinality(self): sage: o = lattice_polytope.cross_polytope(3) sage: V = ToricVariety(FaceFan(o)) - sage: V.change_ring(GF(2)).point_set().cardinality() + sage: V.change_ring(GF(2)).point_set().cardinality() # optional - sage.rings.finite_rings 27 - sage: V.change_ring(GF(8, "a")).point_set().cardinality() + sage: V.change_ring(GF(8, "a")).point_set().cardinality() # optional - sage.rings.finite_rings 729 - sage: V.change_ring(GF(101)).point_set().cardinality() + sage: V.change_ring(GF(101)).point_set().cardinality() # optional - sage.rings.finite_rings 1061208 For non-smooth varieties over finite fields, the homogeneous rescalings are solved. This is somewhat slower:: sage: fan = NormalFan(ReflexivePolytope(2, 0)) - sage: X = ToricVariety(fan, base_field=GF(7)) - sage: X.point_set().cardinality() + sage: X = ToricVariety(fan, base_field=GF(7)) # optional - sage.rings.finite_rings + sage: X.point_set().cardinality() # optional - sage.rings.finite_rings 21 Fulton's formula does not apply since the variety is not smooth. And, indeed, naive application gives a different result:: - sage: q = X.base_ring().order() - sage: n = X.dimension() - sage: d = map(len, fan().cones()) - sage: sum(dk * (q-1)**(n-k) for k, dk in enumerate(d)) + sage: q = X.base_ring().order() # optional - sage.rings.finite_rings + sage: n = X.dimension() # optional - sage.rings.finite_rings + sage: d = map(len, fan().cones()) # optional - sage.rings.finite_rings + sage: sum(dk * (q-1)**(n-k) for k, dk in enumerate(d)) # optional - sage.rings.finite_rings 57 Over infinite fields the number of points is not very tricky:: @@ -578,17 +567,15 @@ def __iter__(self): """ Iterate over the points of the variety. - OUTPUT: - - Iterator over points. + OUTPUT: Iterator over points. EXAMPLES:: - sage: P123 = toric_varieties.P2_123(base_ring=GF(3)) - sage: point_set = P123.point_set() - sage: next(iter(point_set.__iter__())) + sage: P123 = toric_varieties.P2_123(base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: point_set = P123.point_set() # optional - sage.rings.finite_rings + sage: next(iter(point_set.__iter__())) # optional - sage.rings.finite_rings [0 : 0 : 1] - sage: next(iter(point_set)) # syntactic sugar + sage: next(iter(point_set)) # syntactic sugar # optional - sage.rings.finite_rings [0 : 0 : 1] """ for pt in self._enumerator(): @@ -608,9 +595,9 @@ def _enumerator(self): EXAMPLES:: - sage: P123 = toric_varieties.P2_123(base_ring=GF(3)) - sage: point_set = P123.point_set() - sage: point_set._enumerator() + sage: P123 = toric_varieties.P2_123(base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: point_set = P123.point_set() # optional - sage.rings.finite_rings + sage: point_set._enumerator() # optional - sage.rings.finite_rings """ ambient = super()._enumerator() @@ -633,11 +620,11 @@ def __iter__(self): EXAMPLES:: - sage: P2. = toric_varieties.P2(base_ring=GF(5)) - sage: cubic = P2.subscheme([x^3 + y^3 + z^3]) - sage: list(cubic.point_set()) + sage: P2. = toric_varieties.P2(base_ring=GF(5)) # optional - sage.rings.finite_rings + sage: cubic = P2.subscheme([x^3 + y^3 + z^3]) # optional - sage.rings.finite_rings + sage: list(cubic.point_set()) # optional - sage.rings.finite_rings [[0 : 1 : 4], [1 : 0 : 4], [1 : 4 : 0], [1 : 1 : 2], [1 : 2 : 1], [1 : 3 : 3]] - sage: cubic.point_set().cardinality() + sage: cubic.point_set().cardinality() # optional - sage.rings.finite_rings 6 """ for p in self._enumerator(): @@ -653,11 +640,11 @@ def cardinality(self): EXAMPLES:: - sage: P2. = toric_varieties.P2(base_ring=GF(5)) - sage: cubic = P2.subscheme([x^3 + y^3 + z^3]) - sage: list(cubic.point_set()) + sage: P2. = toric_varieties.P2(base_ring=GF(5)) # optional - sage.rings.finite_rings + sage: cubic = P2.subscheme([x^3 + y^3 + z^3]) # optional - sage.rings.finite_rings + sage: list(cubic.point_set()) # optional - sage.rings.finite_rings [[0 : 1 : 4], [1 : 0 : 4], [1 : 4 : 0], [1 : 1 : 2], [1 : 2 : 1], [1 : 3 : 3]] - sage: cubic.point_set().cardinality() + sage: cubic.point_set().cardinality() # optional - sage.rings.finite_rings 6 """ try: diff --git a/src/sage/schemes/toric/ideal.py b/src/sage/schemes/toric/ideal.py index e5902d83ffd..c598d05f3ed 100644 --- a/src/sage/schemes/toric/ideal.py +++ b/src/sage/schemes/toric/ideal.py @@ -19,7 +19,7 @@ EXAMPLES:: - sage: A = matrix([[1,1,1],[0,1,2]]) + sage: A = matrix([[1,1,1], [0,1,2]]) sage: IA = ToricIdeal(A) sage: IA.ker() Free module of degree 3 and rank 1 over Integer Ring @@ -34,7 +34,7 @@ this toric ideal ([Stu1997]_, Example 1.2) is the twisted cubic and cannot be generated by `2=\dim \ker(A)` polynomials:: - sage: A = matrix([[3,2,1,0],[0,1,2,3]]) + sage: A = matrix([[3,2,1,0], [0,1,2,3]]) sage: IA = ToricIdeal(A) sage: IA.ker() Free module of degree 4 and rank 2 over Integer Ring @@ -49,7 +49,8 @@ [Stu1997]_. One can show that `I_d` is generated by one quadric and `d` binomials of degree `d`:: - sage: I = lambda d: ToricIdeal(matrix([[1,1,1,1,1],[0,1,1,0,0],[0,0,1,1,d]])) + sage: def I(d): + ....: return ToricIdeal(matrix([[1,1,1,1,1], [0,1,1,0,0], [0,0,1,1,d]])) sage: I(2) Ideal (-z3^2 + z0*z4, z0*z2 - z1*z3, @@ -168,7 +169,7 @@ class ToricIdeal(MPolynomialIdeal): EXAMPLES:: - sage: A = matrix([[1,1,1],[0,1,2]]) + sage: A = matrix([[1,1,1], [0,1,2]]) sage: ToricIdeal(A) Ideal (-z1^2 + z0*z2) of Multivariate Polynomial Ring in z0, z1, z2 over Rational Field @@ -212,16 +213,17 @@ def __init__(self, A, EXAMPLES:: - sage: A = matrix([[1,1,1],[0,1,2]]) + sage: A = matrix([[1,1,1], [0,1,2]]) sage: ToricIdeal(A) Ideal (-z1^2 + z0*z2) of Multivariate Polynomial Ring in z0, z1, z2 over Rational Field - sage: ToricIdeal(A, names='x', base_ring=GF(101)) + sage: ToricIdeal(A, names='x', base_ring=GF(101)) # optional - sage.rings.finite_rings Ideal (-x1^2 + x0*x2) of Multivariate Polynomial Ring in x0, x1, x2 over Finite Field of size 101 sage: ToricIdeal(A, names='x', base_ring=FractionField(QQ['t'])) - Ideal (-x1^2 + x0*x2) of Multivariate Polynomial Ring - in x0, x1, x2 over Fraction Field of Univariate Polynomial Ring in t over Rational Field + Ideal (-x1^2 + x0*x2) of + Multivariate Polynomial Ring in x0, x1, x2 over + Fraction Field of Univariate Polynomial Ring in t over Rational Field """ self._A = matrix(ZZ, A) if polynomial_ring: @@ -247,13 +249,11 @@ def A(self): """ Return the defining matrix. - OUTPUT: - - An integer matrix. + OUTPUT: An integer matrix. EXAMPLES:: - sage: A = matrix([[1,1,1],[0,1,2]]) + sage: A = matrix([[1,1,1], [0,1,2]]) sage: IA = ToricIdeal(A) sage: IA.A() [1 1 1] @@ -265,18 +265,15 @@ def ker(self): """ Return the kernel of the defining matrix. - OUTPUT: - - The kernel of ``self.A()``. + OUTPUT: The kernel of ``self.A()``. EXAMPLES:: - sage: A = matrix([[1,1,1],[0,1,2]]) + sage: A = matrix([[1,1,1], [0,1,2]]) sage: IA = ToricIdeal(A) sage: IA.ker() Free module of degree 3 and rank 1 over Integer Ring - User basis matrix: - [-1 2 -1] + User basis matrix: [-1 2 -1] """ if '_ker' in self.__dict__: @@ -288,14 +285,12 @@ def nvariables(self): r""" Return the number of variables of the ambient polynomial ring. - OUTPUT: - - Integer. The number of columns of the defining matrix + OUTPUT: An integer. The number of columns of the defining matrix :meth:`A`. EXAMPLES:: - sage: A = matrix([[1,1,1],[0,1,2]]) + sage: A = matrix([[1,1,1], [0,1,2]]) sage: IA = ToricIdeal(A) sage: IA.nvariables() 3 @@ -324,7 +319,7 @@ def _init_ring(self, term_order): EXAMPLES:: - sage: A = matrix([[1,1,1],[0,1,2]]) + sage: A = matrix([[1,1,1], [0,1,2]]) sage: IA = ToricIdeal(A) sage: R = IA._init_ring('neglex'); R Multivariate Polynomial Ring in z0, z1, z2 over Rational Field @@ -352,12 +347,11 @@ def _naive_ideal(self, ring): EXAMPLES:: - sage: A = matrix([[1,1,1],[0,1,2]]) + sage: A = matrix([[1,1,1], [0,1,2]]) sage: IA = ToricIdeal(A) sage: IA.ker() Free module of degree 3 and rank 1 over Integer Ring - User basis matrix: - [-1 2 -1] + User basis matrix: [-1 2 -1] sage: IA._naive_ideal(IA.ring()) Ideal (z1^2 - z0*z2) of Multivariate Polynomial Ring in z0, z1, z2 over Rational Field """ @@ -398,7 +392,7 @@ def _ideal_quotient_by_variable(self, ring, ideal, n): sage: IA._ideal_quotient_by_variable(R, J0, 0) Ideal (z2*z3^2 - z0*z1*z4, z1*z3 - z0*z2, z2^2*z3 - z1^2*z4, z1^3*z4 - z0*z2^3) - of Multivariate Polynomial Ring in z0, z1, z2, z3, z4 over Rational Field + of Multivariate Polynomial Ring in z0, z1, z2, z3, z4 over Rational Field """ N = self.nvariables() y = list(ring.gens()) @@ -439,17 +433,17 @@ def _ideal_HostenSturmfels(self): EXAMPLES:: - sage: A = matrix([[3,2,1,0],[0,1,2,3]]) + sage: A = matrix([[3,2,1,0], [0,1,2,3]]) sage: IA = ToricIdeal(A); IA Ideal (-z1*z2 + z0*z3, -z1^2 + z0*z2, z2^2 - z1*z3) - of Multivariate Polynomial Ring in z0, z1, z2, z3 over Rational Field + of Multivariate Polynomial Ring in z0, z1, z2, z3 over Rational Field sage: R = IA.ring() sage: IA == IA._ideal_HostenSturmfels() True TESTS:: - sage: I_2x2 = identity_matrix(ZZ,2) + sage: I_2x2 = identity_matrix(ZZ, 2) sage: ToricIdeal(I_2x2) Ideal (0) of Multivariate Polynomial Ring in z0, z1 over Rational Field """ diff --git a/src/sage/schemes/toric/library.py b/src/sage/schemes/toric/library.py index 6f3617f22b6..c12c8e2c75e 100644 --- a/src/sage/schemes/toric/library.py +++ b/src/sage/schemes/toric/library.py @@ -203,9 +203,7 @@ def _make_ToricVariety(self, name, coordinate_names, base_ring): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`toric variety + OUTPUT: A :class:`toric variety `. EXAMPLES:: @@ -244,9 +242,7 @@ def _make_CPRFanoToricVariety(self, name, coordinate_names, base_ring): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -290,23 +286,16 @@ def dP6(self, names='x u y v z w', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: dP6 = toric_varieties.dP6() - sage: dP6 + sage: dP6 = toric_varieties.dP6(); dP6 2-d CPR-Fano toric variety covered by 6 affine patches sage: dP6.fan().rays() - N( 0, 1), - N(-1, 0), - N(-1, -1), - N( 0, -1), - N( 1, 0), - N( 1, 1) + N( 0, 1), N(-1, 0), N(-1, -1), + N( 0, -1), N( 1, 0), N( 1, 1) in 2-d lattice N sage: dP6.gens() (x, u, y, v, z, w) @@ -328,22 +317,16 @@ def dP7(self, names='x u y v z', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: dP7 = toric_varieties.dP7() - sage: dP7 + sage: dP7 = toric_varieties.dP7(); dP7 2-d CPR-Fano toric variety covered by 5 affine patches sage: dP7.fan().rays() - N( 0, 1), - N(-1, 0), - N(-1, -1), - N( 0, -1), - N( 1, 0) + N( 0, 1), N(-1, 0), N(-1, -1), + N( 0, -1), N( 1, 0) in 2-d lattice N sage: dP7.gens() (x, u, y, v, z) @@ -365,21 +348,16 @@ def dP8(self, names='t x y z', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: dP8 = toric_varieties.dP8() - sage: dP8 + sage: dP8 = toric_varieties.dP8(); dP8 2-d CPR-Fano toric variety covered by 4 affine patches sage: dP8.fan().rays() - N( 1, 1), - N( 0, 1), - N(-1, -1), - N( 1, 0) + N( 1, 1), N( 0, 1), + N(-1, -1), N( 1, 0) in 2-d lattice N sage: dP8.gens() (t, x, y, z) @@ -401,21 +379,16 @@ def P1xP1(self, names='s t x y', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: P1xP1 = toric_varieties.P1xP1() - sage: P1xP1 + sage: P1xP1 = toric_varieties.P1xP1(); P1xP1 2-d CPR-Fano toric variety covered by 4 affine patches sage: P1xP1.fan().rays() - N( 1, 0), - N(-1, 0), - N( 0, 1), - N( 0, -1) + N( 1, 0), N(-1, 0), + N( 0, 1), N( 0, -1) in 2-d lattice N sage: P1xP1.gens() (s, t, x, y) @@ -437,21 +410,16 @@ def P1xP1_Z2(self, names='s t x y', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: P1xP1_Z2 = toric_varieties.P1xP1_Z2() - sage: P1xP1_Z2 + sage: P1xP1_Z2 = toric_varieties.P1xP1_Z2(); P1xP1_Z2 2-d CPR-Fano toric variety covered by 4 affine patches sage: P1xP1_Z2.fan().rays() - N( 1, 1), - N(-1, -1), - N(-1, 1), - N( 1, -1) + N( 1, 1), N(-1, -1), + N(-1, 1), N( 1, -1) in 2-d lattice N sage: P1xP1_Z2.gens() (s, t, x, y) @@ -475,15 +443,12 @@ def P1(self, names='s t', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: P1 = toric_varieties.P1() - sage: P1 + sage: P1 = toric_varieties.P1(); P1 1-d CPR-Fano toric variety covered by 2 affine patches sage: P1.fan().rays() N( 1), @@ -509,15 +474,12 @@ def P2(self, names='x y z', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: P2 = toric_varieties.P2() - sage: P2 + sage: P2 = toric_varieties.P2(); P2 2-d CPR-Fano toric variety covered by 3 affine patches sage: P2.fan().rays() N( 1, 0), @@ -545,15 +507,12 @@ def P(self, n, names='z+', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: P3 = toric_varieties.P(3) - sage: P3 + sage: P3 = toric_varieties.P(3); P3 3-d CPR-Fano toric variety covered by 4 affine patches sage: P3.fan().rays() N( 1, 0, 0), @@ -596,15 +555,12 @@ def A1(self, names='z', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`toric variety + OUTPUT: A :class:`toric variety `. EXAMPLES:: - sage: A1 = toric_varieties.A1() - sage: A1 + sage: A1 = toric_varieties.A1(); A1 1-d affine toric variety sage: A1.fan().rays() N(1) @@ -628,15 +584,12 @@ def A2(self, names='x y', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`toric variety + OUTPUT: A :class:`toric variety `. EXAMPLES:: - sage: A2 = toric_varieties.A2() - sage: A2 + sage: A2 = toric_varieties.A2(); A2 2-d affine toric variety sage: A2.fan().rays() N(1, 0), @@ -663,15 +616,12 @@ def A(self, n, names='z+', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`toric variety + OUTPUT: A :class:`toric variety `. EXAMPLES:: - sage: A3 = toric_varieties.A(3) - sage: A3 + sage: A3 = toric_varieties.A(3); A3 3-d affine toric variety sage: A3.fan().rays() N(1, 0, 0), @@ -711,15 +661,12 @@ def A2_Z2(self, names='x y', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`toric variety + OUTPUT: A :class:`toric variety `. EXAMPLES:: - sage: A2_Z2 = toric_varieties.A2_Z2() - sage: A2_Z2 + sage: A2_Z2 = toric_varieties.A2_Z2(); A2_Z2 2-d affine toric variety sage: A2_Z2.fan().rays() N(1, 0), @@ -745,15 +692,12 @@ def P1xA1(self, names='s t z', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`toric variety + OUTPUT: A :class:`toric variety `. EXAMPLES:: - sage: P1xA1 = toric_varieties.P1xA1() - sage: P1xA1 + sage: P1xA1 = toric_varieties.P1xA1(); P1xA1 2-d toric variety covered by 2 affine patches sage: P1xA1.fan().rays() N( 1, 0), @@ -779,21 +723,16 @@ def Conifold(self, names='u x y v', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`toric variety + OUTPUT: A :class:`toric variety `. EXAMPLES:: - sage: Conifold = toric_varieties.Conifold() - sage: Conifold + sage: Conifold = toric_varieties.Conifold(); Conifold 3-d affine toric variety sage: Conifold.fan().rays() - N(0, 0, 1), - N(0, 1, 1), - N(1, 0, 1), - N(1, 1, 1) + N(0, 0, 1), N(0, 1, 1), + N(1, 0, 1), N(1, 1, 1) in 3-d lattice N sage: Conifold.gens() (u, x, y, v) @@ -815,29 +754,18 @@ def dP6xdP6(self, names='x0 x1 x2 x3 x4 x5 y0 y1 y2 y3 y4 y5', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: dP6xdP6 = toric_varieties.dP6xdP6() - sage: dP6xdP6 + sage: dP6xdP6 = toric_varieties.dP6xdP6(); dP6xdP6 4-d CPR-Fano toric variety covered by 36 affine patches sage: dP6xdP6.fan().rays() - N( 0, 1, 0, 0), - N(-1, 0, 0, 0), - N(-1, -1, 0, 0), - N( 0, -1, 0, 0), - N( 1, 0, 0, 0), - N( 1, 1, 0, 0), - N( 0, 0, 0, 1), - N( 0, 0, -1, 0), - N( 0, 0, -1, -1), - N( 0, 0, 0, -1), - N( 0, 0, 1, 0), - N( 0, 0, 1, 1) + N( 0, 1, 0, 0), N(-1, 0, 0, 0), N(-1, -1, 0, 0), + N( 0, -1, 0, 0), N( 1, 0, 0, 0), N( 1, 1, 0, 0), + N( 0, 0, 0, 1), N( 0, 0, -1, 0), N( 0, 0, -1, -1), + N( 0, 0, 0, -1), N( 0, 0, 1, 0), N( 0, 0, 1, 1) in 4-d lattice N sage: dP6xdP6.gens() (x0, x1, x2, x3, x4, x5, y0, y1, y2, y3, y4, y5) @@ -862,25 +790,16 @@ def Cube_face_fan(self, names='z+', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: Cube_face_fan = toric_varieties.Cube_face_fan() - sage: Cube_face_fan + sage: Cube_face_fan = toric_varieties.Cube_face_fan(); Cube_face_fan 3-d CPR-Fano toric variety covered by 6 affine patches sage: Cube_face_fan.fan().rays() - N( 1, 1, 1), - N( 1, -1, 1), - N(-1, 1, 1), - N(-1, -1, 1), - N(-1, -1, -1), - N(-1, 1, -1), - N( 1, -1, -1), - N( 1, 1, -1) + N( 1, 1, 1), N( 1, -1, 1), N(-1, 1, 1), N(-1, -1, 1), + N(-1, -1, -1), N(-1, 1, -1), N( 1, -1, -1), N( 1, 1, -1) in 3-d lattice N sage: Cube_face_fan.gens() (z0, z1, z2, z3, z4, z5, z6, z7) @@ -906,25 +825,16 @@ def Cube_sublattice(self, names='z+', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: Cube_sublattice = toric_varieties.Cube_sublattice() - sage: Cube_sublattice + sage: Cube_sublattice = toric_varieties.Cube_sublattice(); Cube_sublattice 3-d CPR-Fano toric variety covered by 6 affine patches sage: Cube_sublattice.fan().rays() - N( 1, 0, 0), - N( 0, 1, 0), - N( 0, 0, 1), - N(-1, 1, 1), - N(-1, 0, 0), - N( 0, -1, 0), - N( 0, 0, -1), - N( 1, -1, -1) + N( 1, 0, 0), N( 0, 1, 0), N( 0, 0, 1), N(-1, 1, 1), + N(-1, 0, 0), N( 0, -1, 0), N( 0, 0, -1), N( 1, -1, -1) in 3-d lattice N sage: Cube_sublattice.gens() (z0, z1, z2, z3, z4, z5, z6, z7) @@ -950,9 +860,7 @@ def Cube_nonpolyhedral(self, names='z+', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`toric variety + OUTPUT: A :class:`toric variety `. .. NOTE:: @@ -967,14 +875,8 @@ def Cube_nonpolyhedral(self, names='z+', base_ring=QQ): sage: Cube_nonpolyhedral 3-d toric variety covered by 6 affine patches sage: Cube_nonpolyhedral.fan().rays() - N( 1, 2, 3), - N( 1, -1, 1), - N(-1, 1, 1), - N(-1, -1, 1), - N(-1, -1, -1), - N(-1, 1, -1), - N( 1, -1, -1), - N( 1, 1, -1) + N( 1, 2, 3), N( 1, -1, 1), N(-1, 1, 1), N(-1, -1, 1), + N(-1, -1, -1), N(-1, 1, -1), N( 1, -1, -1), N( 1, 1, -1) in 3-d lattice N sage: Cube_nonpolyhedral.gens() (z0, z1, z2, z3, z4, z5, z6, z7) @@ -1012,18 +914,11 @@ def Cube_deformation(self,k, names=None, base_ring=QQ): EXAMPLES:: - sage: X_2 = toric_varieties.Cube_deformation(2) - sage: X_2 + sage: X_2 = toric_varieties.Cube_deformation(2); X_2 3-d toric variety covered by 6 affine patches sage: X_2.fan().rays() - N( 1, 1, 5), - N( 1, -1, 1), - N(-1, 1, 1), - N(-1, -1, 1), - N(-1, -1, -1), - N(-1, 1, -1), - N( 1, -1, -1), - N( 1, 1, -1) + N( 1, 1, 5), N( 1, -1, 1), N(-1, 1, 1), N(-1, -1, 1), + N(-1, -1, -1), N(-1, 1, -1), N( 1, -1, -1), N( 1, 1, -1) in 3-d lattice N sage: X_2.gens() (z0, z1, z2, z3, z4, z5, z6, z7) @@ -1059,29 +954,20 @@ def BCdlOG(self, names='v1 v2 c1 c2 v4 v5 b e1 e2 e3 f g v6', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: X = toric_varieties.BCdlOG() - sage: X + sage: X = toric_varieties.BCdlOG(); X 5-d CPR-Fano toric variety covered by 54 affine patches sage: X.fan().rays() - N(-1, 0, 0, 2, 3), - N( 0, -1, 0, 2, 3), - N( 0, 0, -1, 2, 3), - N( 0, 0, -1, 1, 2), - N( 0, 0, 0, -1, 0), - N( 0, 0, 0, 0, -1), - N( 0, 0, 0, 2, 3), - N( 0, 0, 1, 2, 3), - N( 0, 0, 2, 2, 3), - N( 0, 0, 1, 1, 1), - N( 0, 1, 2, 2, 3), - N( 0, 1, 3, 2, 3), + N(-1, 0, 0, 2, 3), N( 0, -1, 0, 2, 3), + N( 0, 0, -1, 2, 3), N( 0, 0, -1, 1, 2), + N( 0, 0, 0, -1, 0), N( 0, 0, 0, 0, -1), + N( 0, 0, 0, 2, 3), N( 0, 0, 1, 2, 3), + N( 0, 0, 2, 2, 3), N( 0, 0, 1, 1, 1), + N( 0, 1, 2, 2, 3), N( 0, 1, 3, 2, 3), N( 1, 0, 4, 2, 3) in 5-d lattice N sage: X.gens() @@ -1104,24 +990,16 @@ def BCdlOG_base(self, names='d4 d3 r2 r1 d2 u d1', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`toric variety + OUTPUT: A :class:`toric variety `. EXAMPLES:: - sage: base = toric_varieties.BCdlOG_base() - sage: base + sage: base = toric_varieties.BCdlOG_base(); base 3-d toric variety covered by 10 affine patches sage: base.fan().rays() - N(-1, 0, 0), - N( 0, -1, 0), - N( 0, 0, -1), - N( 0, 0, 1), - N( 0, 1, 2), - N( 0, 1, 3), - N( 1, 0, 4) + N(-1, 0, 0), N( 0, -1, 0), N( 0, 0, -1), N( 0, 0, 1), + N( 0, 1, 2), N( 0, 1, 3), N( 1, 0, 4) in 3-d lattice N sage: base.gens() (d4, d3, r2, r1, d2, u, d1) @@ -1143,15 +1021,12 @@ def P2_112(self, names='z+', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: P2_112 = toric_varieties.P2_112() - sage: P2_112 + sage: P2_112 = toric_varieties.P2_112(); P2_112 2-d CPR-Fano toric variety covered by 3 affine patches sage: P2_112.fan().rays() N( 1, 0), @@ -1178,15 +1053,12 @@ def P2_123(self, names='z+', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: P2_123 = toric_varieties.P2_123() - sage: P2_123 + sage: P2_123 = toric_varieties.P2_123(); P2_123 2-d CPR-Fano toric variety covered by 3 affine patches sage: P2_123.fan().rays() N( 1, 0), @@ -1213,22 +1085,16 @@ def P4_11169(self, names='z+', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: P4_11169 = toric_varieties.P4_11169() - sage: P4_11169 + sage: P4_11169 = toric_varieties.P4_11169(); P4_11169 4-d CPR-Fano toric variety covered by 5 affine patches sage: P4_11169.fan().rays() - N( 1, 0, 0, 0), - N( 0, 1, 0, 0), - N( 0, 0, 1, 0), - N( 0, 0, 0, 1), - N(-9, -6, -1, -1) + N( 1, 0, 0, 0), N( 0, 1, 0, 0), N( 0, 0, 1, 0), + N( 0, 0, 0, 1), N(-9, -6, -1, -1) in 4-d lattice N sage: P4_11169.gens() (z0, z1, z2, z3, z4) @@ -1251,9 +1117,7 @@ def P4_11169_resolved(self, names='z+', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -1262,12 +1126,8 @@ def P4_11169_resolved(self, names='z+', base_ring=QQ): sage: P4_11169_resolved 4-d CPR-Fano toric variety covered by 9 affine patches sage: P4_11169_resolved.fan().rays() - N( 1, 0, 0, 0), - N( 0, 1, 0, 0), - N( 0, 0, 1, 0), - N( 0, 0, 0, 1), - N(-9, -6, -1, -1), - N(-3, -2, 0, 0) + N( 1, 0, 0, 0), N( 0, 1, 0, 0), N( 0, 0, 1, 0), + N( 0, 0, 0, 1), N(-9, -6, -1, -1), N(-3, -2, 0, 0) in 4-d lattice N sage: P4_11169_resolved.gens() (z0, z1, z2, z3, z4, z5) @@ -1289,22 +1149,16 @@ def P4_11133(self, names='z+', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: - sage: P4_11133 = toric_varieties.P4_11133() - sage: P4_11133 + sage: P4_11133 = toric_varieties.P4_11133(); P4_11133 4-d CPR-Fano toric variety covered by 5 affine patches sage: P4_11133.fan().rays() - N( 1, 0, 0, 0), - N( 0, 1, 0, 0), - N( 0, 0, 1, 0), - N( 0, 0, 0, 1), - N(-3, -3, -1, -1) + N( 1, 0, 0, 0), N( 0, 1, 0, 0), N( 0, 0, 1, 0), + N( 0, 0, 0, 1), N(-3, -3, -1, -1) in 4-d lattice N sage: P4_11133.gens() (z0, z1, z2, z3, z4) @@ -1326,9 +1180,7 @@ def P4_11133_resolved(self, names='z+', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`CPR-Fano toric variety + OUTPUT: A :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -1337,12 +1189,8 @@ def P4_11133_resolved(self, names='z+', base_ring=QQ): sage: P4_11133_resolved 4-d CPR-Fano toric variety covered by 9 affine patches sage: P4_11133_resolved.fan().rays() - N( 1, 0, 0, 0), - N( 0, 1, 0, 0), - N( 0, 0, 1, 0), - N( 0, 0, 0, 1), - N(-3, -3, -1, -1), - N(-1, -1, 0, 0) + N( 1, 0, 0, 0), N( 0, 1, 0, 0), N( 0, 0, 1, 0), + N( 0, 0, 0, 1), N(-3, -3, -1, -1), N(-1, -1, 0, 0) in 4-d lattice N sage: P4_11133_resolved.gens() (z0, z1, z2, z3, z4, z5) @@ -1387,7 +1235,7 @@ def WP(self, *q, **kw): sage: X = toric_varieties.WP([1,3,1], names='x y z') sage: X.inject_variables() Defining x, y, z - sage: g = y^2-(x^6-z^6) + sage: g = y^2 - (x^6-z^6) sage: C = X.subscheme([g]); C Closed subscheme of 2-d toric variety covered by 3 affine patches defined by: -x^6 + z^6 + y^2 @@ -1457,9 +1305,7 @@ def torus(self, n, names='z+', base_ring=QQ): - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. - OUTPUT: - - A :class:`toric variety + OUTPUT: A :class:`toric variety `. EXAMPLES:: @@ -1476,7 +1322,7 @@ def torus(self, n, names='z+', base_ring=QQ): in 3-d lattice N sage: T3.gens() (z0, z1, z2) - sage: sorted(T3.change_ring(GF(3)).point_set().list()) + sage: sorted(T3.change_ring(GF(3)).point_set().list()) # optional - sage.rings.finite_rings [[1 : 1 : 1], [1 : 1 : 2], [1 : 2 : 1], [1 : 2 : 2], [2 : 1 : 1], [2 : 1 : 2], [2 : 2 : 1], [2 : 2 : 2]] """ diff --git a/src/sage/schemes/toric/morphism.py b/src/sage/schemes/toric/morphism.py index d41c35c5a7b..e8013196778 100644 --- a/src/sage/schemes/toric/morphism.py +++ b/src/sage/schemes/toric/morphism.py @@ -48,12 +48,11 @@ sage: P2. = toric_varieties.P2() sage: P1. = toric_varieties.P1() - sage: P1.hom([0,u^2+v^2,u*v], P2) + sage: P1.hom([0, u^2 + v^2, u*v], P2) Scheme morphism: From: 1-d CPR-Fano toric variety covered by 2 affine patches To: 2-d CPR-Fano toric variety covered by 3 affine patches - Defn: Defined on coordinates by sending [u : v] to - [0 : u^2 + v^2 : u*v] + Defn: Defined on coordinates by sending [u : v] to [0 : u^2 + v^2 : u*v] This is a well-defined morphism of algebraic varieties because homogeneously rescaled coordinates of a point of `\mathbb{P}^1` map to the same @@ -78,8 +77,7 @@ Scheme morphism: From: 1-d CPR-Fano toric variety covered by 2 affine patches To: 2-d CPR-Fano toric variety covered by 3 affine patches - Defn: Defined on coordinates by sending [u : v] to - [0 : u : v] + Defn: Defined on coordinates by sending [u : v] to [0 : u : v] This map is actually the embedding of the :meth:`~sage.schemes.toric.variety.ToricVariety_field.orbit_closure` @@ -93,7 +91,7 @@ Consider instead the following morphism of fans:: - sage: fm = FanMorphism( matrix(ZZ,[[1,0]]), P1.fan(), P2.fan() ); fm + sage: fm = FanMorphism(matrix(ZZ, [[1,0]]), P1.fan(), P2.fan()); fm Fan morphism defined by the matrix [1 0] Domain fan: Rational polyhedral fan in 1-d lattice N @@ -114,8 +112,7 @@ Scheme morphism: From: 1-d CPR-Fano toric variety covered by 2 affine patches To: 2-d CPR-Fano toric variety covered by 3 affine patches - Defn: Defined on coordinates by sending [u : v] to - [u : v : v] + Defn: Defined on coordinates by sending [u : v] to [u : v : v] Finally, here is an example of a fan morphism that cannot be written using homogeneous polynomials. Consider the blowup `O_{\mathbb{P}^1}(2) @@ -174,8 +171,7 @@ Scheme morphism: From: 0-d affine toric variety To: 2-d affine toric variety - Defn: Defined on coordinates by sending [] to - [1 : 1] + Defn: Defined on coordinates by sending [] to [1 : 1] The fibers are labeled by torus orbits in the base, that is, cones of the codomain fan. In this case, the fibers over lower-dimensional @@ -217,7 +213,8 @@ 2-dimensional cone, which represents the exceptional set of the blow-up in this single coordinate chart. Lets investigate further:: - sage: exceptional_cones = single_chart.fan_morphism().primitive_preimage_cones(A2_Z2.fan(2)[0]) + sage: fm = single_chart.fan_morphism() + sage: exceptional_cones = fm.primitive_preimage_cones(A2_Z2.fan(2)[0]) sage: exceptional_set = single_chart.fiber_component(exceptional_cones[0]) sage: exceptional_set 1-d affine toric variety @@ -225,8 +222,7 @@ Scheme morphism: From: 1-d affine toric variety To: 2-d affine toric variety - Defn: Defined on coordinates by sending [z0] to - [z0 : 0] + Defn: Defined on coordinates by sending [z0] to [z0 : 0] So we see that the fiber over this point is an affine line. Together with another affine line in the other coordinate patch, this covers @@ -237,7 +233,7 @@ sage: A3 = toric_varieties.A(3) sage: P3 = toric_varieties.P(3) - sage: m = matrix([(2,0,0), (1,1,0), (3, 1, 0)]) + sage: m = matrix([(2,0,0), (1,1,0), (3,1,0)]) sage: phi = A3.hom(m, P3) sage: phi.as_polynomial_map() Scheme morphism: @@ -407,9 +403,7 @@ class SchemeMorphism_point_toric_field(SchemeMorphism_point, Morphism): - ``check`` -- if ``True`` (default), the input will be checked for correctness. - OUTPUT: - - A :class:`SchemeMorphism_point_toric_field`. + OUTPUT: A :class:`SchemeMorphism_point_toric_field`. TESTS:: @@ -470,16 +464,14 @@ class SchemeMorphism_polynomial_toric_variety(SchemeMorphism_polynomial, Morphis Same as for :class:`~sage.schemes.toric.morphism.SchemeMorphism_polynomial`. - OUTPUT: - - A :class:`~sage.schemes.toric.morphism.SchemeMorphism_polynomial_toric_variety`. + OUTPUT: A :class:`~sage.schemes.toric.morphism.SchemeMorphism_polynomial_toric_variety`. TESTS:: sage: P1xP1 = toric_varieties.P1xP1() sage: P1xP1.inject_variables() Defining s, t, x, y - sage: P1 = P1xP1.subscheme(s-t) + sage: P1 = P1xP1.subscheme(s - t) sage: H = P1xP1.Hom(P1) sage: import sage.schemes.toric.morphism as MOR sage: MOR.SchemeMorphism_polynomial_toric_variety(H, [s, s, x, y]) @@ -501,7 +493,7 @@ def __init__(self, parent, polynomials, check=True): sage: P1xP1 = toric_varieties.P1xP1() sage: P1xP1.inject_variables() Defining s, t, x, y - sage: P1 = P1xP1.subscheme(s-t) + sage: P1 = P1xP1.subscheme(s - t) sage: H = P1xP1.Hom(P1) sage: import sage.schemes.toric.morphism as MOR sage: MOR.SchemeMorphism_polynomial_toric_variety(H, [s, s, x, y]) @@ -525,10 +517,9 @@ def as_fan_morphism(self): """ Express the morphism as a map defined by a fan morphism. - OUTPUT: + OUTPUT: A :class:`SchemeMorphism_polynomial_toric_variety`. - A :class:`SchemeMorphism_polynomial_toric_variety`. Raises a - ``TypeError`` if the morphism cannot be written in such a way. + Raises a ``TypeError`` if the morphism cannot be written in such a way. EXAMPLES:: @@ -611,9 +602,7 @@ def defining_cone(self): r""" Return the cone corresponding to the torus orbit. - OUTPUT: - - A cone of the fan of the ambient toric variety. + OUTPUT: A cone of the fan of the ambient toric variety. EXAMPLES:: @@ -634,8 +623,8 @@ def _reverse_ray_map(self): OUTPUT: - Return a dictionary `{orbit ray generator : preimage ray - index}`. Note that the orbit ray generator need not be + A dictionary ``{orbit ray generator: preimage ray + index}``. Note that the orbit ray generator need not be primitive. Also, the preimage ray is not necessarily unique. EXAMPLES:: @@ -710,8 +699,7 @@ def as_polynomial_map(self): Scheme morphism: From: 1-d toric variety covered by 2 affine patches To: 2-d CPR-Fano toric variety covered by 3 affine patches - Defn: Defined on coordinates by sending [z0 : z1] to - [0 : z1 : z0] + Defn: Defined on coordinates by sending [z0 : z1] to [0 : z1 : z0] If the toric variety is singular, then some orbit closure embeddings cannot be written with homogeneous polynomials:: @@ -744,7 +732,7 @@ def pullback_divisor(self, divisor): INPUT: - - ``divisor`` -- a torus-invariant QQ-Cartier divisor on the + - ``divisor`` -- a torus-invariant `\QQ`-Cartier divisor on the codomain of the embedding map. OUTPUT: @@ -811,9 +799,7 @@ class SchemeMorphism_fan_toric_variety(SchemeMorphism, Morphism): :class:`SchemeMorphism_fan_toric_variety_dominant` for additional functionality for fibrations. - OUTPUT: - - A :class:`~sage.schemes.toric.morphism.SchemeMorphism_fan_toric_variety`. + OUTPUT: A :class:`~sage.schemes.toric.morphism.SchemeMorphism_fan_toric_variety`. EXAMPLES:: @@ -833,13 +819,13 @@ class SchemeMorphism_fan_toric_variety(SchemeMorphism, Morphism): sage: P1xP1 = toric_varieties.P1xP1() sage: P1 = toric_varieties.P1() sage: hom_set = P1xP1.Hom(P1) - sage: fm = FanMorphism( matrix(ZZ,[[1],[0]]), P1xP1.fan(), P1.fan() ) + sage: fm = FanMorphism(matrix(ZZ, [[1],[0]]), P1xP1.fan(), P1.fan()) sage: hom_set(fm) Scheme morphism: From: 2-d CPR-Fano toric variety covered by 4 affine patches To: 1-d CPR-Fano toric variety covered by 2 affine patches Defn: Defined by sending Rational polyhedral fan in 2-d lattice N - to Rational polyhedral fan in 1-d lattice N. + to Rational polyhedral fan in 1-d lattice N. sage: P1xP1.hom(fm, P1) Scheme morphism: @@ -858,7 +844,7 @@ def __init__(self, parent, fan_morphism, check=True): sage: P1xP1 = toric_varieties.P1xP1() sage: P1 = toric_varieties.P1() sage: hom_set = P1xP1.Hom(P1) - sage: fan_morphism = FanMorphism( matrix(ZZ,[[1],[0]]), P1xP1.fan(), P1.fan() ) + sage: fan_morphism = FanMorphism(matrix(ZZ, [[1],[0]]), P1xP1.fan(), P1.fan()) sage: from sage.schemes.toric.morphism import SchemeMorphism_fan_toric_variety sage: SchemeMorphism_fan_toric_variety(hom_set, fan_morphism) Scheme morphism: @@ -882,9 +868,7 @@ def _richcmp_(self, right, op): - ``right`` -- another toric morphism - OUTPUT: - - - boolean + OUTPUT: A boolean. Comparison is done first by domain, then by codomain, then by fan morphism. @@ -925,9 +909,7 @@ def _composition_(self, right, homset): - ``right`` -- a toric morphism defined by a fan morphism. - OUTPUT: - - - a toric morphism. + OUTPUT: A toric morphism. EXAMPLES:: @@ -1034,8 +1016,7 @@ def factor(self): Scheme morphism: From: 2-d affine toric variety To: 2-d affine toric variety - Defn: Defined on coordinates by sending [x : y] to - [x^2 : y] + Defn: Defined on coordinates by sending [x : y] to [x^2 : y] Blowup chart (birational):: @@ -1043,8 +1024,7 @@ def factor(self): Scheme morphism: From: 2-d affine toric variety To: 2-d toric variety covered by 3 affine patches - Defn: Defined on coordinates by sending [z0 : z1] to - [1 : z1 : z0*z1] + Defn: Defined on coordinates by sending [z0 : z1] to [1 : z1 : z0*z1] Coordinate plane inclusion (injective):: @@ -1052,8 +1032,7 @@ def factor(self): Scheme morphism: From: 2-d toric variety covered by 3 affine patches To: 3-d CPR-Fano toric variety covered by 4 affine patches - Defn: Defined on coordinates by sending [z0 : z1 : z2] to - [z2 : z1 : z0 : z0] + Defn: Defined on coordinates by sending [z0 : z1 : z2] to [z2 : z1 : z0 : z0] """ phi_i, phi_b, phi_s = self.fan_morphism().factor() from sage.schemes.toric.all import ToricVariety @@ -1067,9 +1046,7 @@ def fan_morphism(self): """ Return the defining fan morphism. - OUTPUT: - - A :class:`~sage.geometry.fan_morphism.FanMorphism`. + OUTPUT: A :class:`~sage.geometry.fan_morphism.FanMorphism`. EXAMPLES:: @@ -1089,10 +1066,9 @@ def as_polynomial_map(self): """ Express the morphism via homogeneous polynomials. - OUTPUT: + OUTPUT: A :class:`SchemeMorphism_polynomial_toric_variety`. - A :class:`SchemeMorphism_polynomial_toric_variety`. Raises a - ``TypeError`` if the morphism cannot be written in terms of + Raises a ``TypeError`` if the morphism cannot be written in terms of homogeneous polynomials. EXAMPLES:: @@ -1101,8 +1077,7 @@ def as_polynomial_map(self): sage: square = A1.hom(matrix([[2]]), A1) sage: square.as_polynomial_map() Scheme endomorphism of 1-d affine toric variety - Defn: Defined on coordinates by sending [z] to - [z^2] + Defn: Defined on coordinates by sending [z] to [z^2] sage: P1 = toric_varieties.P1() sage: patch = A1.hom(matrix([[1]]), P1) @@ -1110,8 +1085,7 @@ def as_polynomial_map(self): Scheme morphism: From: 1-d affine toric variety To: 1-d CPR-Fano toric variety covered by 2 affine patches - Defn: Defined on coordinates by sending [z] to - [z : 1] + Defn: Defined on coordinates by sending [z] to [z : 1] """ R = self.domain().coordinate_ring() phi = self.fan_morphism() @@ -1300,7 +1274,7 @@ def pullback_divisor(self, divisor): INPUT: - - ``divisor`` -- a torus-invariant QQ-Cartier divisor on the + - ``divisor`` -- a torus-invariant `\QQ`-Cartier divisor on the codomain of ``self``. OUTPUT: @@ -1311,7 +1285,7 @@ def pullback_divisor(self, divisor): sage: A2_Z2 = toric_varieties.A2_Z2() sage: A2 = toric_varieties.A2() - sage: f = A2.hom( matrix([[1,0],[1,2]]), A2_Z2) + sage: f = A2.hom(matrix([[1,0], [1,2]]), A2_Z2) sage: f.pullback_divisor(A2_Z2.divisor(0)) V(x) @@ -1357,9 +1331,7 @@ class SchemeMorphism_fan_toric_variety_dominant(SchemeMorphism_fan_toric_variety morphism :meth:`must be dominant `. - OUTPUT: - - A :class:`~sage.schemes.toric.morphism.SchemeMorphism_fan_toric_variety_dominant`. + OUTPUT: A :class:`~sage.schemes.toric.morphism.SchemeMorphism_fan_toric_variety_dominant`. EXAMPLES:: @@ -1419,11 +1391,10 @@ def fiber_generic(self): Scheme morphism: From: 1-d toric variety covered by 2 affine patches To: 2-d CPR-Fano toric variety covered by 4 affine patches - Defn: Defined on coordinates by sending [z0 : z1] to - [1 : 1 : z0 : z1] + Defn: Defined on coordinates by sending [z0 : z1] to [1 : 1 : z0 : z1] sage: A1 = toric_varieties.A1() - sage: fan = Fan([(0,1,2)], [(1,1,0),(1,0,1),(1,-1,-1)]) + sage: fan = Fan([(0,1,2)], [(1,1,0), (1,0,1), (1,-1,-1)]) sage: fan = fan.subdivide(new_rays=[(1,0,0)]) sage: f = ToricVariety(fan).hom(matrix([[1],[0],[0]]), A1) sage: f.fiber_generic() @@ -1478,10 +1449,11 @@ def fiber_component(self, domain_cone, multiplicity=False): ....: (0,1,0,0),(0,2,-1,-1),(1,0,0,0),(2,0,-1,-1)]) sage: coarse_fan = FaceFan(polytope) sage: P2 = toric_varieties.P2() - sage: proj24 = matrix([[0,0],[1,0],[0,0],[0,1]]) + sage: proj24 = matrix([[0,0], [1,0], [0,0], [0,1]]) sage: fm = FanMorphism(proj24, coarse_fan, P2.fan(), subdivide=True) sage: fibration = ToricVariety(fm.domain_fan()).hom(fm, P2) - sage: primitive_cones = fibration.fan_morphism().primitive_preimage_cones(P2.fan(1)[0]) + sage: ffm = fibration.fan_morphism() + sage: primitive_cones = ffm.primitive_preimage_cones(P2.fan(1)[0]) sage: primitive_cone = primitive_cones[0] sage: fibration.fiber_component(primitive_cone) 2-d toric variety covered by 4 affine patches @@ -1597,11 +1569,12 @@ def fiber_graph(self, codomain_cone): sage: coarse_fan = FaceFan(polytope, lattice=ToricLattice(4)) sage: P2 = toric_varieties.P2() - sage: proj34 = block_matrix(2,1,[zero_matrix(2,2), identity_matrix(2)]) + sage: proj34 = block_matrix(2, 1, [zero_matrix(2,2), + ....: identity_matrix(2)]) sage: fm = FanMorphism(proj34, coarse_fan, P2.fan(), subdivide=True) sage: fibration = ToricVariety(fm.domain_fan()).hom(fm, P2) - sage: fibration.fiber_graph( P2.fan(0)[0] ) + sage: fibration.fiber_graph(P2.fan(0)[0]) Graph on 1 vertex sage: for c1 in P2.fan(1): ....: fibration.fiber_graph(c1) @@ -1674,7 +1647,8 @@ class SchemeMorphism_fan_fiber_component_toric_variety(SchemeMorphism): sage: proj24 = matrix([[0,0],[1,0],[0,0],[0,1]]) sage: fm = FanMorphism(proj24, coarse_fan, P2.fan(), subdivide=True) sage: fibration = ToricVariety(fm.domain_fan()).hom(fm, P2) - sage: primitive_cones = fibration.fan_morphism().primitive_preimage_cones(P2.fan(1)[0]) + sage: ffm = fibration.fan_morphism() + sage: primitive_cones = ffm.primitive_preimage_cones(P2.fan(1)[0]) sage: primitive_cone = primitive_cones[0] sage: fiber_component = fibration.fiber_component(primitive_cone) sage: fiber_component @@ -1706,7 +1680,7 @@ def __init__(self, toric_morphism, defining_cone): ....: (0,1,0,0),(0,2,-1,-1),(1,0,0,0),(2,0,-1,-1)]) sage: coarse_fan = FaceFan(polytope, lattice=ToricLattice(4)) sage: P2 = toric_varieties.P2() - sage: proj24 = matrix([[0,0],[1,0],[0,0],[0,1]]) + sage: proj24 = matrix([[0,0], [1,0], [0,0], [0,1]]) sage: fm = FanMorphism(proj24, coarse_fan, P2.fan(), subdivide=True) sage: fibration = ToricVariety(fm.domain_fan()).hom(fm, P2) sage: primitive_cone = Cone([(-1, 2, -1, 0)]) @@ -1762,7 +1736,7 @@ def as_polynomial_map(self): ....: (0,1,0,0),(0,2,-1,-1),(1,0,0,0),(2,0,-1,-1)]) sage: coarse_fan = FaceFan(polytope, lattice=ToricLattice(4)) sage: P2 = toric_varieties.P2() - sage: proj24 = matrix([[0,0],[1,0],[0,0],[0,1]]) + sage: proj24 = matrix([[0,0], [1,0], [0,0], [0,1]]) sage: fm = FanMorphism(proj24, coarse_fan, P2.fan(), subdivide=True) sage: fibration = ToricVariety(fm.domain_fan()).hom(fm, P2) @@ -1939,7 +1913,7 @@ def _image_ray_multiplicity(self, fiber_ray): ....: (0,1,0,0),(0,2,-1,-1),(1,0,0,0),(2,0,-1,-1)]) sage: coarse_fan = FaceFan(polytope, lattice=ToricLattice(4)) sage: P2 = toric_varieties.P2() - sage: proj24 = matrix([[0,0],[1,0],[0,0],[0,1]]) + sage: proj24 = matrix([[0,0], [1,0], [0,0], [0,1]]) sage: fm = FanMorphism(proj24, coarse_fan, P2.fan(), subdivide=True) sage: fibration = ToricVariety(fm.domain_fan()).hom(fm, P2) sage: primitive_cone = Cone([(-1, 2, -1, 0)]) @@ -1976,7 +1950,7 @@ def pullback_divisor(self, divisor): INPUT: - - ``divisor`` -- a torus-invariant QQ-Cartier divisor on the + - ``divisor`` -- a torus-invariant `\QQ`-Cartier divisor on the codomain of the embedding map. OUTPUT: diff --git a/src/sage/schemes/toric/points.py b/src/sage/schemes/toric/points.py index a0e0d586563..f72bd2eb3ba 100644 --- a/src/sage/schemes/toric/points.py +++ b/src/sage/schemes/toric/points.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Enumerate points of a toric variety @@ -14,13 +13,13 @@ EXAMPLES:: - sage: P2 = toric_varieties.P2(base_ring=GF(3)) - sage: point_set = P2.point_set() - sage: point_set.cardinality() + sage: P2 = toric_varieties.P2(base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: point_set = P2.point_set() # optional - sage.rings.finite_rings + sage: point_set.cardinality() # optional - sage.rings.finite_rings 13 - sage: next(iter(point_set)) + sage: next(iter(point_set)) # optional - sage.rings.finite_rings [0 : 0 : 1] - sage: list(point_set)[0:5] + sage: list(point_set)[0:5] # optional - sage.rings.finite_rings [[0 : 0 : 1], [1 : 0 : 0], [0 : 1 : 0], [0 : 1 : 1], [0 : 1 : 2]] """ @@ -82,9 +81,7 @@ def __iter__(self): """ Iterate over the points. - OUTPUT: - - Iterator over points. + OUTPUT: Iterator over points. EXAMPLES:: @@ -125,8 +122,8 @@ def __init__(self, fan, ring): sage: from sage.schemes.toric.points import NaiveFinitePointEnumerator sage: fan = toric_varieties.P2().fan() - sage: n = NaiveFinitePointEnumerator(fan, GF(3)) - sage: next(iter(n)) + sage: n = NaiveFinitePointEnumerator(fan, GF(3)) # optional - sage.rings.finite_rings + sage: next(iter(n)) # optional - sage.rings.finite_rings (0, 0, 1) """ assert ring.is_finite() @@ -138,9 +135,7 @@ def rays(self): """ Return all rays (real and virtual). - OUTPUT: - - Tuple of rays of the fan. + OUTPUT: Tuple of rays of the fan. EXAMPLES:: @@ -149,8 +144,8 @@ def rays(self): sage: fan.rays() Empty collection in 2-d lattice N - sage: n = NaiveFinitePointEnumerator(fan, GF(3)) - sage: n.rays() + sage: n = NaiveFinitePointEnumerator(fan, GF(3)) # optional - sage.rings.finite_rings + sage: n.rays() # optional - sage.rings.finite_rings N(1, 0), N(0, 1) in 2-d lattice N @@ -164,8 +159,9 @@ def units(self): EXAMPLES:: - sage: ne = toric_varieties.P2(base_ring=GF(5)).point_set()._naive_enumerator() - sage: ne.units() + sage: P2 = toric_varieties.P2(base_ring=GF(5)) # optional - sage.rings.finite_rings + sage: ne = P2.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: ne.units() # optional - sage.rings.finite_rings (1, 2, 3, 4) """ return tuple(x for x in self.ring if x != 0) @@ -186,12 +182,13 @@ def roots(self, n): EXAMPLES:: - sage: ne = toric_varieties.P2(base_ring=GF(5)).point_set()._naive_enumerator() - sage: ne.roots(2) + sage: P2 = toric_varieties.P2(base_ring=GF(5)) # optional - sage.rings.finite_rings + sage: ne = P2.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: ne.roots(2) # optional - sage.rings.finite_rings (1, 4) - sage: ne.roots(3) + sage: ne.roots(3) # optional - sage.rings.finite_rings (1,) - sage: ne.roots(4) + sage: ne.roots(4) # optional - sage.rings.finite_rings (1, 2, 3, 4) """ return tuple(x for x in self.ring if x**n == self.ring.one()) @@ -208,11 +205,11 @@ def _Chow_group_free(self): EXAMPLES:: sage: fan = NormalFan(ReflexivePolytope(2, 0)) - sage: X = ToricVariety(fan, base_ring=GF(7)) - sage: X.Chow_group().degree(1) + sage: X = ToricVariety(fan, base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: X.Chow_group().degree(1) # optional - sage.rings.finite_rings C3 x Z - sage: enum = X.point_set()._naive_enumerator() - sage: enum._Chow_group_free() + sage: enum = X.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: enum._Chow_group_free() # optional - sage.rings.finite_rings ((1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5), (6, 6, 6)) """ units = self.units() @@ -236,11 +233,11 @@ def _Chow_group_torsion(self): EXAMPLES:: sage: fan = NormalFan(ReflexivePolytope(2, 0)) - sage: X = ToricVariety(fan, base_ring=GF(7)) - sage: X.Chow_group().degree(1) + sage: X = ToricVariety(fan, base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: X.Chow_group().degree(1) # optional - sage.rings.finite_rings C3 x Z - sage: enum = X.point_set()._naive_enumerator() - sage: enum._Chow_group_torsion() + sage: enum = X.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: enum._Chow_group_torsion() # optional - sage.rings.finite_rings ((1, 2, 4), (1, 4, 2)) """ if self.fan.is_smooth(): @@ -269,16 +266,19 @@ def rescalings(self): EXAMPLES:: - sage: ni = toric_varieties.P2_123(base_ring=GF(5)).point_set()._naive_enumerator() - sage: ni.rescalings() + sage: P2_123 = toric_varieties.P2_123(base_ring=GF(5)) # optional - sage.rings.finite_rings + sage: ni = P2_123.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: ni.rescalings() # optional - sage.rings.finite_rings ((1, 1, 1), (1, 4, 4), (4, 2, 3), (4, 3, 2)) - sage: ni = toric_varieties.dP8(base_ring=GF(3)).point_set()._naive_enumerator() - sage: ni.rescalings() + sage: dP8 = toric_varieties.dP8(base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: ni = dP8.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: ni.rescalings() # optional - sage.rings.finite_rings ((1, 1, 1, 1), (1, 2, 2, 2), (2, 1, 2, 1), (2, 2, 1, 2)) - sage: ni = toric_varieties.P1xP1(base_ring=GF(3)).point_set()._naive_enumerator() - sage: ni.rescalings() + sage: P1xP1 = toric_varieties.P1xP1(base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: ni = P1xP1.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: ni.rescalings() # optional - sage.rings.finite_rings ((1, 1, 1, 1), (1, 1, 2, 2), (2, 2, 1, 1), (2, 2, 2, 2)) """ free = self._Chow_group_free() @@ -302,14 +302,15 @@ def orbit(self, point): EXAMPLES:: - sage: ne = toric_varieties.P2_123(base_ring=GF(7)).point_set()._naive_enumerator() - sage: sorted(ne.orbit([1, 0, 0])) + sage: P2_123 = toric_varieties.P2_123(base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: ne = P2_123.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: sorted(ne.orbit([1, 0, 0])) # optional - sage.rings.finite_rings [(1, 0, 0), (2, 0, 0), (4, 0, 0)] - sage: sorted(ne.orbit([0, 1, 0])) + sage: sorted(ne.orbit([0, 1, 0])) # optional - sage.rings.finite_rings [(0, 1, 0), (0, 6, 0)] - sage: sorted(ne.orbit([0, 0, 1])) + sage: sorted(ne.orbit([0, 0, 1])) # optional - sage.rings.finite_rings [(0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 0, 4), (0, 0, 5), (0, 0, 6)] - sage: sorted(ne.orbit([1, 1, 0])) + sage: sorted(ne.orbit([1, 1, 0])) # optional - sage.rings.finite_rings [(1, 1, 0), (1, 6, 0), (2, 1, 0), (2, 6, 0), (4, 1, 0), (4, 6, 0)] """ result = set() @@ -329,8 +330,9 @@ def cone_iter(self): EXAMPLES:: - sage: ne = toric_varieties.dP6(base_ring=GF(11)).point_set()._naive_enumerator() - sage: for cone in ne.cone_iter(): + sage: dP6 = toric_varieties.dP6(base_ring=GF(11)) # optional - sage.rings.finite_rings + sage: ne = dP6.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: for cone in ne.cone_iter(): # optional - sage.rings.finite_rings ....: print(cone.ambient_ray_indices()) (0, 1) (1, 2) @@ -358,28 +360,28 @@ def coordinate_iter(self): This method does NOT identify homogeneous coordinates that are equivalent by a homogeneous rescaling. - OUTPUT: - - An iterator over the points. + OUTPUT: An iterator over the points. EXAMPLES:: - sage: F2 = GF(2) - sage: ni = toric_varieties.P2(base_ring=F2).point_set()._naive_enumerator() - sage: list(ni.coordinate_iter()) - [(0, 0, 1), (1, 0, 0), (0, 1, 0), (0, 1, 1), (1, 0, 1), (1, 1, 0), (1, 1, 1)] + sage: P2 = toric_varieties.P2(base_ring=GF(2)) # optional - sage.rings.finite_rings + sage: ni = P2.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: list(ni.coordinate_iter()) # optional - sage.rings.finite_rings + [(0, 0, 1), (1, 0, 0), (0, 1, 0), (0, 1, 1), + (1, 0, 1), (1, 1, 0), (1, 1, 1)] - sage: ni = toric_varieties.P1xP1(base_ring=F2).point_set()._naive_enumerator() - sage: list(ni.coordinate_iter()) + sage: P1xP1 = toric_varieties.P1xP1(base_ring=GF(2)) # optional - sage.rings.finite_rings + sage: ni = P1xP1.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: list(ni.coordinate_iter()) # optional - sage.rings.finite_rings [(0, 1, 0, 1), (1, 0, 0, 1), (1, 0, 1, 0), (0, 1, 1, 0), (0, 1, 1, 1), (1, 0, 1, 1), (1, 1, 0, 1), (1, 1, 1, 0), (1, 1, 1, 1)] TESTS:: - sage: V = ToricVariety(Fan([Cone([(1,1)])]), base_ring=GF(3)) - sage: ni = V.point_set()._naive_enumerator() - sage: list(ni.coordinate_iter()) + sage: V = ToricVariety(Fan([Cone([(1,1)])]), base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: ni = V.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: list(ni.coordinate_iter()) # optional - sage.rings.finite_rings [(0, 1), (0, 2), (1, 1), (1, 2), (2, 1), (2, 2)] """ units = [x for x in self.ring if x != 0] @@ -400,18 +402,19 @@ def __iter__(self): rescalings, and returns precisely one representative per orbit. - OUTPUT: - - Iterator over points. + OUTPUT: An iterator over points. EXAMPLES:: - sage: ni = toric_varieties.P2(base_ring=GF(2)).point_set()._naive_enumerator() - sage: list(ni) - [(0, 0, 1), (1, 0, 0), (0, 1, 0), (0, 1, 1), (1, 0, 1), (1, 1, 0), (1, 1, 1)] + sage: P2 = toric_varieties.P2(base_ring=GF(2)) # optional - sage.rings.finite_rings + sage: ni = P2.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: list(ni) # optional - sage.rings.finite_rings + [(0, 0, 1), (1, 0, 0), (0, 1, 0), (0, 1, 1), + (1, 0, 1), (1, 1, 0), (1, 1, 1)] - sage: ni = toric_varieties.P1xP1(base_ring=GF(3)).point_set()._naive_enumerator() - sage: list(ni) + sage: P1xP1 = toric_varieties.P1xP1(base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: ni = P1xP1.point_set()._naive_enumerator() # optional - sage.rings.finite_rings + sage: list(ni) # optional - sage.rings.finite_rings [(0, 1, 0, 1), (1, 0, 0, 1), (1, 0, 1, 0), (0, 1, 1, 0), (0, 1, 1, 1), (0, 1, 1, 2), (1, 0, 1, 1), (1, 0, 1, 2), (1, 1, 0, 1), (1, 2, 0, 1), (1, 1, 1, 0), (1, 2, 1, 0), @@ -432,15 +435,13 @@ def multiplicative_generator(self): """ Return the multiplicative generator of the finite field. - OUTPUT: - - A finite field element. + OUTPUT: A finite field element. EXAMPLES:: - sage: point_set = toric_varieties.P2(base_ring=GF(5^2, 'a')).point_set() - sage: ffe = point_set._finite_field_enumerator() - sage: ffe.multiplicative_generator() + sage: point_set = toric_varieties.P2(base_ring=GF(5^2, 'a')).point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._finite_field_enumerator() # optional - sage.rings.finite_rings + sage: ffe.multiplicative_generator() # optional - sage.rings.finite_rings a """ return self.ring.multiplicative_generator() @@ -458,25 +459,23 @@ def root_generator(self, n): - ``n`` integer. - OUTPUT: - - A multiplicative generator for :meth:`roots`. + OUTPUT: A multiplicative generator for :meth:`roots`. EXAMPLES:: - sage: point_set = toric_varieties.P2(base_ring=GF(5)).point_set() - sage: ffe = point_set._finite_field_enumerator() - sage: ffe.root_generator(2) + sage: point_set = toric_varieties.P2(base_ring=GF(5)).point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._finite_field_enumerator() # optional - sage.rings.finite_rings + sage: ffe.root_generator(2) # optional - sage.rings.finite_rings 4 - sage: ffe.root_generator(3) + sage: ffe.root_generator(3) # optional - sage.rings.finite_rings 1 - sage: ffe.root_generator(4) + sage: ffe.root_generator(4) # optional - sage.rings.finite_rings 2 TESTS:: - sage: for p in primes(10): - ....: for k in range(1,5): + sage: for p in primes(10): # optional - sage.rings.finite_rings + ....: for k in range(1, 5): ....: F = GF(p^k, 'a') ....: N = F.cardinality() - 1 ....: ffe = point_set._finite_field_enumerator(F) @@ -501,13 +500,13 @@ def _Chow_group_free_generators(self): EXAMPLES:: sage: fan = NormalFan(ReflexivePolytope(2, 0)) - sage: X = ToricVariety(fan, base_ring=GF(7)) - sage: X.Chow_group().degree(1) + sage: X = ToricVariety(fan, base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: X.Chow_group().degree(1) # optional - sage.rings.finite_rings C3 x Z - sage: enum = X.point_set()._finite_field_enumerator() - sage: enum._Chow_group_free() + sage: enum = X.point_set()._finite_field_enumerator() # optional - sage.rings.finite_rings + sage: enum._Chow_group_free() # optional - sage.rings.finite_rings ((1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5), (6, 6, 6)) - sage: enum._Chow_group_free_generators() + sage: enum._Chow_group_free_generators() # optional - sage.rings.finite_rings ((3, 3, 3),) """ result = [] @@ -530,13 +529,13 @@ def _Chow_group_torsion_generators(self): EXAMPLES:: sage: fan = NormalFan(ReflexivePolytope(2, 0)) - sage: X = ToricVariety(fan, base_ring=GF(7)) - sage: X.Chow_group().degree(1) + sage: X = ToricVariety(fan, base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: X.Chow_group().degree(1) # optional - sage.rings.finite_rings C3 x Z - sage: enum = X.point_set()._finite_field_enumerator() - sage: enum._Chow_group_torsion() + sage: enum = X.point_set()._finite_field_enumerator() # optional - sage.rings.finite_rings + sage: enum._Chow_group_torsion() # optional - sage.rings.finite_rings ((1, 2, 4), (1, 4, 2)) - sage: enum._Chow_group_torsion_generators() + sage: enum._Chow_group_torsion_generators() # optional - sage.rings.finite_rings ((1, 2, 4),) """ if self.fan.is_smooth(): @@ -570,19 +569,19 @@ def log(self, z): EXAMPLES:: - sage: F. = GF(5^2) - sage: point_set = toric_varieties.P2_123(base_ring=F).point_set() - sage: ffe = point_set._finite_field_enumerator() - sage: z = tuple(a^i for i in range(25)); z + sage: F. = GF(5^2) # optional - sage.rings.finite_rings + sage: point_set = toric_varieties.P2_123(base_ring=F).point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._finite_field_enumerator() # optional - sage.rings.finite_rings + sage: z = tuple(a^i for i in range(25)); z # optional - sage.rings.finite_rings (1, a, a + 3, 4*a + 3, 2*a + 2, 4*a + 1, 2, 2*a, 2*a + 1, 3*a + 1, 4*a + 4, 3*a + 2, 4, 4*a, 4*a + 2, a + 2, 3*a + 3, a + 4, 3, 3*a, 3*a + 4, 2*a + 4, a + 1, 2*a + 3, 1) - sage: ffe.log(z) + sage: ffe.log(z) # optional - sage.rings.finite_rings (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0) - sage: ffe.exp(ffe.log(z)) == z + sage: ffe.exp(ffe.log(z)) == z # optional - sage.rings.finite_rings True - sage: ffe.log(ffe.exp(range(24))) == tuple(range(24)) + sage: ffe.log(ffe.exp(range(24))) == tuple(range(24)) # optional - sage.rings.finite_rings True """ base = self.multiplicative_generator() @@ -603,15 +602,15 @@ def exp(self, powers): EXAMPLES:: - sage: F. = GF(5^2) - sage: point_set = toric_varieties.P2_123(base_ring=F).point_set() - sage: ffe = point_set._finite_field_enumerator() - sage: powers = list(range(24)) - sage: ffe.exp(powers) + sage: F. = GF(5^2) # optional - sage.rings.finite_rings + sage: point_set = toric_varieties.P2_123(base_ring=F).point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._finite_field_enumerator() # optional - sage.rings.finite_rings + sage: powers = list(range(24)) # optional - sage.rings.finite_rings + sage: ffe.exp(powers) # optional - sage.rings.finite_rings (1, a, a + 3, 4*a + 3, 2*a + 2, 4*a + 1, 2, 2*a, 2*a + 1, 3*a + 1, 4*a + 4, 3*a + 2, 4, 4*a, 4*a + 2, a + 2, 3*a + 3, a + 4, 3, 3*a, 3*a + 4, 2*a + 4, a + 1, 2*a + 3) - sage: ffe.log(ffe.exp(powers)) == tuple(powers) + sage: ffe.log(ffe.exp(powers)) == tuple(powers) # optional - sage.rings.finite_rings True """ base = self.multiplicative_generator() @@ -629,13 +628,13 @@ def rescaling_log_generators(self): EXAMPLES:: - sage: point_set = toric_varieties.P2_123(base_ring=GF(5)).point_set() - sage: ffe = point_set._finite_field_enumerator() - sage: ffe.rescalings() + sage: point_set = toric_varieties.P2_123(base_ring=GF(5)).point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._finite_field_enumerator() # optional - sage.rings.finite_rings + sage: ffe.rescalings() # optional - sage.rings.finite_rings ((1, 1, 1), (1, 4, 4), (4, 2, 3), (4, 3, 2)) - sage: list(map(ffe.log, ffe.rescalings())) + sage: list(map(ffe.log, ffe.rescalings())) # optional - sage.rings.finite_rings [(0, 0, 0), (0, 2, 2), (2, 1, 3), (2, 3, 1)] - sage: ffe.rescaling_log_generators() + sage: ffe.rescaling_log_generators() # optional - sage.rings.finite_rings ((2, 3, 1),) """ free = self._Chow_group_free_generators() @@ -657,22 +656,22 @@ def cone_points_iter(self): EXAMPLES:: sage: fan = NormalFan(ReflexivePolytope(2, 0)) - sage: X = ToricVariety(fan, base_ring=GF(7)) - sage: point_set = X.point_set() - sage: ffe = point_set._finite_field_enumerator() - sage: cpi = ffe.cone_points_iter() - sage: cone, nonzero_points, cokernel = list(cpi)[5] - sage: cone + sage: X = ToricVariety(fan, base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: point_set = X.point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._finite_field_enumerator() # optional - sage.rings.finite_rings + sage: cpi = ffe.cone_points_iter() # optional - sage.rings.finite_rings + sage: cone, nonzero_points, cokernel = list(cpi)[5] # optional - sage.rings.finite_rings + sage: cone # optional - sage.rings.finite_rings 1-d cone of Rational polyhedral fan in 2-d lattice N - sage: cone.ambient_ray_indices() + sage: cone.ambient_ray_indices() # optional - sage.rings.finite_rings (2,) - sage: nonzero_points + sage: nonzero_points # optional - sage.rings.finite_rings [0, 1] - sage: cokernel + sage: cokernel # optional - sage.rings.finite_rings Finitely generated module V/W over Integer Ring with invariants (2) - sage: list(cokernel) + sage: list(cokernel) # optional - sage.rings.finite_rings [(0), (1)] - sage: [p.lift() for p in cokernel] + sage: [p.lift() for p in cokernel] # optional - sage.rings.finite_rings [(0, 0), (0, 1)] """ from sage.matrix.constructor import matrix, block_matrix, identity_matrix @@ -702,27 +701,26 @@ def __iter__(self): rescalings, and returns precisely one representative per orbit. - OUTPUT: - - Iterator over points. + OUTPUT: Iterator over points. EXAMPLES:: - sage: point_set = toric_varieties.P2(base_ring=GF(2)).point_set() - sage: ffe = point_set._finite_field_enumerator() - sage: list(ffe) - [(0, 0, 1), (1, 0, 0), (0, 1, 0), (0, 1, 1), (1, 0, 1), (1, 1, 0), (1, 1, 1)] + sage: point_set = toric_varieties.P2(base_ring=GF(2)).point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._finite_field_enumerator() # optional - sage.rings.finite_rings + sage: list(ffe) # optional - sage.rings.finite_rings + [(0, 0, 1), (1, 0, 0), (0, 1, 0), (0, 1, 1), + (1, 0, 1), (1, 1, 0), (1, 1, 1)] sage: fan = NormalFan(ReflexivePolytope(2, 0)) - sage: X = ToricVariety(fan, base_ring=GF(7)) - sage: point_set = X.point_set() - sage: ffe = point_set._finite_field_enumerator() - sage: list(ffe) + sage: X = ToricVariety(fan, base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: point_set = X.point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._finite_field_enumerator() # optional - sage.rings.finite_rings + sage: list(ffe) # optional - sage.rings.finite_rings [(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 1, 1), (0, 1, 3), (1, 0, 1), (1, 0, 3), (1, 1, 0), (1, 3, 0), (1, 1, 1), (1, 1, 3), (1, 1, 2), (1, 1, 6), (1, 1, 4), (1, 1, 5), (1, 3, 2), (1, 3, 6), (1, 3, 4), (1, 3, 5), (1, 3, 1), (1, 3, 3)] - sage: set(point_set._naive_enumerator()) == set(ffe) + sage: set(point_set._naive_enumerator()) == set(ffe) # optional - sage.rings.finite_rings True """ nrays = len(self.rays()) @@ -739,17 +737,15 @@ def cardinality(self): """ Return the cardinality of the point set. - OUTPUT: - - Integer. The number of points. + OUTPUT: An integer. The number of points. EXAMPLES:: sage: fan = NormalFan(ReflexivePolytope(2, 0)) - sage: X = ToricVariety(fan, base_ring=GF(7)) - sage: point_set = X.point_set() - sage: ffe = point_set._finite_field_enumerator() - sage: ffe.cardinality() + sage: X = ToricVariety(fan, base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: point_set = X.point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._finite_field_enumerator() # optional - sage.rings.finite_rings + sage: ffe.cardinality() # optional - sage.rings.finite_rings 21 """ n = 0 @@ -776,7 +772,7 @@ def __init__(self, polynomials, ambient): sage: P2. = toric_varieties.P2() sage: from sage.schemes.toric.points import NaiveSubschemePointEnumerator sage: ne = NaiveSubschemePointEnumerator( - ....: [x^2+y^2-2*z^2], P2.point_set()._enumerator()) + ....: [x^2 + y^2 - 2*z^2], P2.point_set()._enumerator()) sage: next(iter(ne)) (1, 1, 1) """ @@ -801,7 +797,7 @@ def __iter__(self): sage: P2. = toric_varieties.P2() sage: from sage.schemes.toric.points import NaiveSubschemePointEnumerator sage: ne = NaiveSubschemePointEnumerator( - ....: [x^2+y^2-2*z^2], P2.point_set()._enumerator()) + ....: [x^2 + y^2 - 2*z^2], P2.point_set()._enumerator()) sage: next(iter(ne)) (1, 1, 1) """ @@ -831,14 +827,14 @@ def inhomogeneous_equations(self, ring, nonzero_coordinates, cokernel): EXAMPLES:: sage: R. = QQ[] - sage: P2. = toric_varieties.P2(base_ring=GF(7)) - sage: X = P2.subscheme([x^3 + 2*y^3 + 3*z^3, x*y*z + x*y^2]) - sage: point_set = X.point_set() - sage: ffe = point_set._enumerator() - sage: cone, nonzero_coordinates, cokernel = list(ffe.ambient.cone_points_iter())[5] - sage: cone.ambient_ray_indices(), nonzero_coordinates + sage: P2. = toric_varieties.P2(base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: X = P2.subscheme([x^3 + 2*y^3 + 3*z^3, x*y*z + x*y^2]) # optional - sage.rings.finite_rings + sage: point_set = X.point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._enumerator() # optional - sage.rings.finite_rings + sage: cone, nonzero_coordinates, cokernel = list(ffe.ambient.cone_points_iter())[5] # optional - sage.rings.finite_rings + sage: cone.ambient_ray_indices(), nonzero_coordinates # optional - sage.rings.finite_rings ((2,), [0, 1]) - sage: ffe.inhomogeneous_equations(R, nonzero_coordinates, cokernel) + sage: ffe.inhomogeneous_equations(R, nonzero_coordinates, cokernel) # optional - sage.rings.finite_rings [2*s^3 + 1, s^2] """ nrays = len(self.ambient.rays()) @@ -872,14 +868,14 @@ def solutions_serial(self, inhomogeneous_equations, log_range): EXAMPLES:: - sage: R. = GF(7)[] - sage: P2. = toric_varieties.P2(base_ring=GF(7)) - sage: X = P2.subscheme(1) - sage: point_set = X.point_set() - sage: ffe = point_set._enumerator() - sage: ffe.solutions_serial([s^2-1, s^6-s^2], [range(6)]) + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: P2. = toric_varieties.P2(base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: X = P2.subscheme(1) # optional - sage.rings.finite_rings + sage: point_set = X.point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._enumerator() # optional - sage.rings.finite_rings + sage: ffe.solutions_serial([s^2 - 1, s^6 - s^2], [range(6)]) # optional - sage.rings.finite_rings - sage: list(_) + sage: list(_) # optional - sage.rings.finite_rings [(0,), (3,)] """ from itertools import product @@ -900,14 +896,14 @@ def solutions(self, inhomogeneous_equations, log_range): EXAMPLES:: - sage: R. = GF(7)[] - sage: P2. = toric_varieties.P2(base_ring=GF(7)) - sage: X = P2.subscheme(1) - sage: point_set = X.point_set() - sage: ffe = point_set._enumerator() - sage: ffe.solutions([s^2-1, s^6-s^2], [range(6)]) + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: P2. = toric_varieties.P2(base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: X = P2.subscheme(1) # optional - sage.rings.finite_rings + sage: point_set = X.point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._enumerator() # optional - sage.rings.finite_rings + sage: ffe.solutions([s^2 - 1, s^6 - s^2], [range(6)]) # optional - sage.rings.finite_rings - sage: sorted(_) + sage: sorted(_) # optional - sage.rings.finite_rings [(0,), (3,)] """ # Do simple cases in one process (this includes most doctests) @@ -946,18 +942,18 @@ def homogeneous_coordinates(self, log_t, nonzero_coordinates, cokernel): EXAMPLES:: - sage: P2. = toric_varieties.P2(base_ring=GF(7)) - sage: X = P2.subscheme([x^3 + 2*y^3 + 3*z^3, x*y*z + x*y^2]) - sage: point_set = X.point_set() - sage: ffe = point_set._enumerator() - sage: cone, nonzero_coordinates, cokernel = list(ffe.ambient.cone_points_iter())[5] - sage: cone.ambient_ray_indices(), nonzero_coordinates + sage: P2. = toric_varieties.P2(base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: X = P2.subscheme([x^3 + 2*y^3 + 3*z^3, x*y*z + x*y^2]) # optional - sage.rings.finite_rings + sage: point_set = X.point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._enumerator() # optional - sage.rings.finite_rings + sage: cone, nonzero_coordinates, cokernel = list(ffe.ambient.cone_points_iter())[5] # optional - sage.rings.finite_rings + sage: cone.ambient_ray_indices(), nonzero_coordinates # optional - sage.rings.finite_rings ((2,), [0, 1]) - sage: ffe.homogeneous_coordinates([0], nonzero_coordinates, cokernel) + sage: ffe.homogeneous_coordinates([0], nonzero_coordinates, cokernel) # optional - sage.rings.finite_rings (1, 1, 0) - sage: ffe.homogeneous_coordinates([1], nonzero_coordinates, cokernel) + sage: ffe.homogeneous_coordinates([1], nonzero_coordinates, cokernel) # optional - sage.rings.finite_rings (1, 3, 0) - sage: ffe.homogeneous_coordinates([2], nonzero_coordinates, cokernel) + sage: ffe.homogeneous_coordinates([2], nonzero_coordinates, cokernel) # optional - sage.rings.finite_rings (1, 2, 0) """ z = [self.ambient.ring.zero()] * len(self.ambient.rays()) @@ -982,11 +978,11 @@ def __iter__(self): EXAMPLES:: - sage: P2. = toric_varieties.P2(base_ring=GF(7)) - sage: X = P2.subscheme([x^3 + 2*y^3 + 3*z^3, x*y*z + x*y^2]) - sage: point_set = X.point_set() - sage: ffe = point_set._enumerator() - sage: list(ffe) # indirect doctest + sage: P2. = toric_varieties.P2(base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: X = P2.subscheme([x^3 + 2*y^3 + 3*z^3, x*y*z + x*y^2]) # optional - sage.rings.finite_rings + sage: point_set = X.point_set() # optional - sage.rings.finite_rings + sage: ffe = point_set._enumerator() # optional - sage.rings.finite_rings + sage: list(ffe) # indirect doctest # optional - sage.rings.finite_rings [(1, 1, 6), (1, 2, 5), (1, 4, 3)] """ for cone, nonzero_coordinates, cokernel in self.ambient.cone_points_iter(): @@ -1001,17 +997,15 @@ def cardinality(self): """ Return the cardinality of the point set. - OUTPUT: - - Integer. The number of points. + OUTPUT: An integer. The number of points. EXAMPLES:: sage: fan = NormalFan(ReflexivePolytope(2, 0)) - sage: X. = ToricVariety(fan, base_ring=GF(7)) - sage: Y = X.subscheme(u^3 + v^3 + w^3 + u*v*w) - sage: point_set = Y.point_set() - sage: list(point_set) + sage: X. = ToricVariety(fan, base_ring=GF(7)) # optional - sage.rings.finite_rings + sage: Y = X.subscheme(u^3 + v^3 + w^3 + u*v*w) # optional - sage.rings.finite_rings + sage: point_set = Y.point_set() # optional - sage.rings.finite_rings + sage: list(point_set) # optional - sage.rings.finite_rings [[0 : 1 : 3], [1 : 0 : 3], [1 : 3 : 0], @@ -1019,8 +1013,8 @@ def cardinality(self): [1 : 1 : 4], [1 : 3 : 2], [1 : 3 : 5]] - sage: ffe = point_set._enumerator() - sage: ffe.cardinality() + sage: ffe = point_set._enumerator() # optional - sage.rings.finite_rings + sage: ffe.cardinality() # optional - sage.rings.finite_rings 7 """ n = 0 diff --git a/src/sage/schemes/toric/sheaf/constructor.py b/src/sage/schemes/toric/sheaf/constructor.py index 74aa578d422..11a189adbf3 100644 --- a/src/sage/schemes/toric/sheaf/constructor.py +++ b/src/sage/schemes/toric/sheaf/constructor.py @@ -272,9 +272,9 @@ def Klyachko(self, multi_filtration): EXAMPLES:: sage: P1 = toric_varieties.P1() - sage: v1, v2, v3 = [(1,0,0),(0,1,0),(0,0,1)] - sage: F1 = FilteredVectorSpace({1:[v1, v2, v3], 3:[v1]}) - sage: F2 = FilteredVectorSpace({0:[v1, v2, v3], 2:[v2, v3]}) + sage: v1, v2, v3 = [(1,0,0), (0,1,0), (0,0,1)] + sage: F1 = FilteredVectorSpace({1: [v1, v2, v3], 3: [v1]}) + sage: F2 = FilteredVectorSpace({0: [v1, v2, v3], 2: [v2, v3]}) sage: P1 = toric_varieties.P1() sage: r1, r2 = P1.fan().rays() sage: F = MultiFilteredVectorSpace({r1:F1, r2:F2}); F diff --git a/src/sage/schemes/toric/sheaf/klyachko.py b/src/sage/schemes/toric/sheaf/klyachko.py index 77fae4b7545..5112420b54f 100644 --- a/src/sage/schemes/toric/sheaf/klyachko.py +++ b/src/sage/schemes/toric/sheaf/klyachko.py @@ -62,9 +62,7 @@ def is_KlyachkoBundle(X): - ``X`` -- anything. - OUTPUT: - - Boolean. + OUTPUT: A boolean. EXAMPLES:: @@ -93,12 +91,12 @@ def Bundle(toric_variety, multi_filtration, check=True): EXAMPLES:: sage: P1 = toric_varieties.P1() - sage: v1, v2, v3 = [(1,0,0),(0,1,0),(0,0,1)] - sage: F1 = FilteredVectorSpace({1:[v1, v2, v3], 3:[v1]}) - sage: F2 = FilteredVectorSpace({0:[v1, v2, v3], 2:[v2, v3]}) + sage: v1, v2, v3 = [(1,0,0), (0,1,0), (0,0,1)] + sage: F1 = FilteredVectorSpace({1: [v1, v2, v3], 3: [v1]}) + sage: F2 = FilteredVectorSpace({0: [v1, v2, v3], 2: [v2, v3]}) sage: P1 = toric_varieties.P1() sage: r1, r2 = P1.fan().rays() - sage: F = MultiFilteredVectorSpace({r1:F1, r2:F2}); F + sage: F = MultiFilteredVectorSpace({r1: F1, r2: F2}); F Filtrations N(-1): QQ^3 >= QQ^2 >= QQ^2 >= 0 >= 0 N(1): QQ^3 >= QQ^3 >= QQ^1 >= QQ^1 >= 0 @@ -110,7 +108,7 @@ def Bundle(toric_variety, multi_filtration, check=True): sage: P1.sheaves.Klyachko(F) Rank 3 bundle on 1-d CPR-Fano toric variety covered by 2 affine patches. - sage: P1.sheaves.Klyachko({r1:F1, r2:F2}) # alternative + sage: P1.sheaves.Klyachko({r1: F1, r2: F2}) # alternative Rank 3 bundle on 1-d CPR-Fano toric variety covered by 2 affine patches. The above is just a shorthand for:: @@ -157,8 +155,8 @@ def __init__(self, toric_variety, multi_filtration, check=True): sage: P1 = toric_varieties.P1() sage: r1, r2 = P1.fan().rays() sage: F = MultiFilteredVectorSpace({ - ....: r1:FilteredVectorSpace(3,1), - ....: r2:FilteredVectorSpace(3,0)}); F + ....: r1: FilteredVectorSpace(3,1), + ....: r2: FilteredVectorSpace(3,0)}); F Filtrations N(-1): QQ^3 >= 0 >= 0 N(1): QQ^3 >= QQ^3 >= 0 @@ -183,9 +181,7 @@ def variety(self): r""" Return the base toric variety. - OUTPUT: - - A toric variety. + OUTPUT: A toric variety. EXAMPLES:: @@ -201,9 +197,7 @@ def base_ring(self): r""" Return the base field. - OUTPUT: - - A field. + OUTPUT: A field. EXAMPLES:: @@ -217,9 +211,7 @@ def fiber(self): r""" Return the generic fiber of the vector bundle. - OUTPUT: - - A vector space over :meth:`base_ring`. + OUTPUT: A vector space over :meth:`base_ring`. EXAMPLES:: @@ -234,9 +226,7 @@ def rank(self): r""" Return the rank of the vector bundle. - OUTPUT: - - Integer. + OUTPUT: An integer. EXAMPLES:: @@ -250,9 +240,7 @@ def _repr_(self): r""" Return a string representation. - OUTPUT: - - String. + OUTPUT: A string. EXAMPLES:: @@ -331,8 +319,7 @@ def get_degree(self, ray, i): sage: TX = toric_varieties.dP6().sheaves.tangent_bundle() sage: TX.get_degree(0, 1) Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [0 1] + Basis matrix: [0 1] """ return self.get_filtration(ray).get_degree(i) @@ -363,12 +350,10 @@ def filtration_intersection(self, sigma, i): sage: V = X.sheaves.tangent_bundle() sage: V.filtration_intersection(fan(1)[0], 1) Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 0] + Basis matrix: [1 0] sage: V.filtration_intersection(fan(2)[0], 1) Vector space of degree 2 and dimension 0 over Rational Field - Basis matrix: - [] + Basis matrix: [] """ sigma = self._variety.fan().embed(sigma) V = self.fiber() @@ -401,16 +386,13 @@ def E_degree(self, alpha, m): sage: V = X.sheaves.tangent_bundle() sage: V.E_degree(X.fan().ray(0), (1,0)) Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 0] + Basis matrix: [1 0] sage: V.E_degree(X.fan(1)[0], (1,0)) Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 0] + Basis matrix: [1 0] sage: V.E_degree(0, (1,0)) Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 0] + Basis matrix: [1 0] """ fan = self.variety().fan() N = fan.lattice() @@ -430,7 +412,7 @@ def E_degree(self, alpha, m): @cached_method def E_intersection(self, sigma, m): r""" - Return the vector subspace ``E^\sigma(m)``. + Return the vector subspace `E^\sigma(m)`. See [Kly1990]_, equation 4.1. @@ -441,9 +423,7 @@ def E_intersection(self, sigma, m): - ``m`` -- tuple of integers or `M`-lattice point. A point in the dual lattice of the fan. Must be immutable. - OUTPUT: - - The subspace `E^\sigma(m)` + OUTPUT: The subspace `E^\sigma(m)`. EXAMPLES:: @@ -452,12 +432,10 @@ def E_intersection(self, sigma, m): sage: V = X.sheaves.tangent_bundle() sage: V.E_intersection(fan(1)[0], (1,0)) Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 0] + Basis matrix: [1 0] sage: V.E_intersection(fan(2)[0], (-1,1)) Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [0 1] + Basis matrix: [0 1] For the empty cone, this is always the whole vector space:: @@ -484,9 +462,7 @@ def E_quotient(self, sigma, m): - ``m`` -- tuple of integers or `M`-lattice point. A point in the dual lattice of the fan. Must be immutable. - OUTPUT: - - The subspace `E_\sigma(m)` + OUTPUT: The subspace `E_\sigma(m)`. EXAMPLES:: @@ -499,17 +475,16 @@ def E_quotient(self, sigma, m): sage: m.set_immutable() sage: V.E_quotient(cone, m) Vector space quotient V/W of dimension 1 over Rational Field where - V: Vector space of dimension 2 over Rational Field - W: Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 0] + V: Vector space of dimension 2 over Rational Field + W: Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: [1 0] sage: V.E_quotient(fan(2)[0], (-1,1)) Vector space quotient V/W of dimension 0 over Rational Field where - V: Vector space of dimension 2 over Rational Field - W: Vector space of degree 2 and dimension 2 over Rational Field - Basis matrix: - [1 0] - [0 1] + V: Vector space of dimension 2 over Rational Field + W: Vector space of degree 2 and dimension 2 over Rational Field + Basis matrix: + [1 0] + [0 1] """ sigma = self._variety.fan().embed(sigma) V = self.fiber() @@ -545,10 +520,10 @@ def E_quotient_projection(self, sigma, tau, m): sage: P3 = toric_varieties.P(3) sage: rays = [(1,0,0), (0,1,0), (0,0,1)] - sage: F1 = FilteredVectorSpace(rays, {0:[0], 1:[2], 2:[1]}) + sage: F1 = FilteredVectorSpace(rays, {0: [0], 1: [2], 2: [1]}) sage: F2 = FilteredVectorSpace(3, 0) sage: r = P3.fan().rays() - sage: V = P3.sheaves.Klyachko({r[0]:F1, r[1]:F2, r[2]:F2, r[3]:F2}) + sage: V = P3.sheaves.Klyachko({r[0]: F1, r[1]: F2, r[2]: F2, r[3]: F2}) sage: tau = Cone([(1,0,0), (0,1,0)]) sage: sigma = Cone([(1,0,0)]) sage: M = P3.fan().dual_lattice() @@ -556,30 +531,26 @@ def E_quotient_projection(self, sigma, tau, m): sage: m.set_immutable() sage: V.E_quotient(sigma, m) Vector space quotient V/W of dimension 2 over Rational Field where - V: Vector space of dimension 3 over Rational Field - W: Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [0 1 0] + V: Vector space of dimension 3 over Rational Field + W: Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: [0 1 0] sage: V.E_quotient(tau, m) Vector space quotient V/W of dimension 2 over Rational Field where - V: Vector space of dimension 3 over Rational Field - W: Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [0 1 0] + V: Vector space of dimension 3 over Rational Field + W: Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: [0 1 0] sage: V.E_quotient_projection(sigma, tau, m) Vector space morphism represented by the matrix: - [1 0] - [0 1] - Domain: Vector space quotient V/W of dimension 2 over Rational Field where - V: Vector space of dimension 3 over Rational Field - W: Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [0 1 0] - Codomain: Vector space quotient V/W of dimension 2 over Rational Field where - V: Vector space of dimension 3 over Rational Field - W: Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [0 1 0] + [1 0] + [0 1] + Domain: Vector space quotient V/W of dimension 2 over Rational Field where + V: Vector space of dimension 3 over Rational Field + W: Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: [0 1 0] + Codomain: Vector space quotient V/W of dimension 2 over Rational Field where + V: Vector space of dimension 3 over Rational Field + W: Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: [0 1 0] """ if not sigma.is_face_of(tau): raise ValueError('the cone sigma is not a face of the cone tau') @@ -608,10 +579,10 @@ def cohomology_complex(self, m): sage: P3 = toric_varieties.P(3) sage: rays = [(1,0,0), (0,1,0), (0,0,1)] - sage: F1 = FilteredVectorSpace(rays, {0:[0], 1:[2], 2:[1]}) - sage: F2 = FilteredVectorSpace(rays, {0:[1,2], 1:[0]}) + sage: F1 = FilteredVectorSpace(rays, {0: [0], 1: [2], 2: [1]}) + sage: F2 = FilteredVectorSpace(rays, {0: [1,2], 1: [0]}) sage: r = P3.fan().rays() - sage: V = P3.sheaves.Klyachko({r[0]:F1, r[1]:F2, r[2]:F2, r[3]:F2}) + sage: V = P3.sheaves.Klyachko({r[0]: F1, r[1]: F2, r[2]: F2, r[3]: F2}) sage: tau = Cone([(1,0,0), (0,1,0)]) sage: sigma = Cone([(1, 0, 0)]) sage: M = P3.fan().dual_lattice() @@ -621,7 +592,7 @@ def cohomology_complex(self, m): sage: F = CyclotomicField(3) sage: P3 = toric_varieties.P(3).change_ring(F) - sage: V = P3.sheaves.Klyachko({r[0]:F1, r[1]:F2, r[2]:F2, r[3]:F2}) + sage: V = P3.sheaves.Klyachko({r[0]: F1, r[1]: F2, r[2]: F2, r[3]: F2}) sage: V.cohomology_complex(m) Chain complex with at most 2 nonzero terms over Cyclotomic Field of order 3 and degree 2 @@ -737,9 +708,7 @@ def __richcmp__(self, other, op): - ``other`` -- anything. - OUTPUT: - - Boolean. + OUTPUT: A boolean. EXAMPLES:: @@ -748,7 +717,7 @@ def __richcmp__(self, other, op): sage: V2 = X.sheaves.trivial_bundle(2) sage: V2 == V1 False - sage: V2 == V1+V1 + sage: V2 == V1 + V1 True sage: T_X = X.sheaves.tangent_bundle() @@ -774,9 +743,7 @@ def is_isomorphic(self, other): - ``other`` -- anything. - OUTPUT: - - Boolean. + OUTPUT: A boolean. EXAMPLES:: @@ -800,9 +767,7 @@ def direct_sum(self, other): - ``other`` -- a Klyachko bundle over the same base. - OUTPUT: - - The direct sum as a new Klyachko bundle. + OUTPUT: The direct sum as a new Klyachko bundle. EXAMPLES:: @@ -832,9 +797,7 @@ def tensor_product(self, other): - ``other`` -- a Klyachko bundle over the same base. - OUTPUT: - - The tensor product as a new Klyachko bundle. + OUTPUT: The tensor product as a new Klyachko bundle. EXAMPLES:: @@ -888,18 +851,16 @@ def symmetric_power(self, n): - ``n`` -- integer. - OUTPUT: - - The `n`-th symmetric power as a new Klyachko bundle. + OUTPUT: The `n`-th symmetric power as a new Klyachko bundle. EXAMPLES:: sage: P1 = toric_varieties.P1() sage: H = P1.divisor(0) sage: L = P1.sheaves.line_bundle(H) - sage: (L+L).symmetric_power(2) + sage: (L + L).symmetric_power(2) Rank 3 bundle on 1-d CPR-Fano toric variety covered by 2 affine patches. - sage: (L+L).symmetric_power(2) == L*L+L*L+L*L + sage: (L + L).symmetric_power(2) == L*L + L*L + L*L True """ filt = self._filt.symmetric_power(n) @@ -909,9 +870,7 @@ def dual(self): """ Return the dual bundle. - OUTPUT: - - The dual bundle as a new Klyachko bundle. + OUTPUT: The dual bundle as a new Klyachko bundle. EXAMPLES:: diff --git a/src/sage/schemes/toric/toric_subscheme.py b/src/sage/schemes/toric/toric_subscheme.py index 76c0b300813..e425ee3d0a8 100644 --- a/src/sage/schemes/toric/toric_subscheme.py +++ b/src/sage/schemes/toric/toric_subscheme.py @@ -44,10 +44,8 @@ class AlgebraicScheme_subscheme_toric(AlgebraicScheme_subscheme): - ``polynomials`` -- single polynomial, list, or ideal of defining polynomials in the coordinate ring of ``toric_variety``. - OUTPUT: - - - :class:`algebraic subscheme of a toric variety - `. + OUTPUT: An :class:`algebraic subscheme of a toric variety + `. TESTS:: @@ -56,7 +54,7 @@ class AlgebraicScheme_subscheme_toric(AlgebraicScheme_subscheme): Defining s, t, x, y sage: import sage.schemes.toric.toric_subscheme as SCM sage: X = SCM.AlgebraicScheme_subscheme_toric( - ....: P1xP1, [x*s + y*t, x^3+y^3]) + ....: P1xP1, [x*s + y*t, x^3 + y^3]) sage: X Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: @@ -65,7 +63,7 @@ class AlgebraicScheme_subscheme_toric(AlgebraicScheme_subscheme): A better way to construct the same scheme as above:: - sage: P1xP1.subscheme([x*s + y*t, x^3+y^3]) + sage: P1xP1.subscheme([x*s + y*t, x^3 + y^3]) Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: s*x + t*y, @@ -87,7 +85,7 @@ def __init__(self, toric_variety, polynomials): Defining s, t, x, y sage: import sage.schemes.toric.toric_subscheme as SCM sage: X = SCM.AlgebraicScheme_subscheme_toric( - ....: P1xP1, [x*s + y*t, x^3+y^3]) + ....: P1xP1, [x*s + y*t, x^3 + y^3]) sage: X Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: @@ -106,9 +104,7 @@ def _morphism(self, *args, **kwds): - same as for :class:`~sage.schemes.toric.morphism.SchemeMorphism_polynomial_toric_variety`. - OUTPUT: - - - :class:`~sage.schemes.toric.morphism.SchemeMorphism_polynomial_toric_variety`. + OUTPUT: A :class:`~sage.schemes.toric.morphism.SchemeMorphism_polynomial_toric_variety`. TESTS:: @@ -148,9 +144,7 @@ def _point_homset(self, *args, **kwds): - same as for :class:`~sage.schemes.toric.homset.SchemeHomset_points_toric_field`. - OUTPUT: - - :class:`~sage.schemes.toric.homset.SchemeHomset_points_subscheme_toric_field`. + OUTPUT: A :class:`~sage.schemes.toric.homset.SchemeHomset_points_subscheme_toric_field`. TESTS:: @@ -170,14 +164,12 @@ def fan(self): """ Return the fan of the ambient space. - OUTPUT: - - A fan. + OUTPUT: A fan. EXAMPLES:: sage: P2. = toric_varieties.P(2) - sage: E = P2.subscheme([x^2+y^2+z^2]) + sage: E = P2.subscheme([x^2 + y^2 + z^2]) sage: E.fan() Rational polyhedral fan in 2-d lattice N """ @@ -214,11 +206,10 @@ def affine_patch(self, i): Scheme morphism: From: 2-d affine toric variety To: 2-d CPR-Fano toric variety covered by 4 affine patches - Defn: Defined on coordinates by sending [t : x] to - [1 : t : x : 1] + Defn: Defined on coordinates by sending [t : x] to [1 : t : x : 1] sage: P1xP1.inject_variables() Defining s, t, x, y - sage: P1 = P1xP1.subscheme(x-y) + sage: P1 = P1xP1.subscheme(x - y) sage: subpatch = P1.affine_patch(1) sage: subpatch Closed subscheme of 2-d affine toric variety defined by: @@ -273,17 +264,17 @@ def affine_algebraic_patch(self, cone=None, names=None): sage: P2. = toric_varieties.P2() sage: cone = P2.fan().generating_cone(0) - sage: V = P2.subscheme(x^3+y^3+z^3) + sage: V = P2.subscheme(x^3 + y^3 + z^3) sage: V.affine_algebraic_patch(cone) Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: z0^3 + z1^3 + 1 - sage: cone = Cone([(0,1),(2,1)]) + sage: cone = Cone([(0,1), (2,1)]) sage: A2Z2. = AffineToricVariety(cone) sage: A2Z2.affine_algebraic_patch() Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: -z0*z1 + z2^2 - sage: V = A2Z2.subscheme(x^2+y^2-1) + sage: V = A2Z2.subscheme(x^2 + y^2 - 1) sage: patch = V.affine_algebraic_patch(); patch Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: -z0*z1 + z2^2, @@ -299,11 +290,11 @@ def affine_algebraic_patch(self, cone=None, names=None): the singularity of the ambient space and the second is the pull-back of `x^2+y^2-1` :: - sage: lp = LatticePolytope([(1,0,0),(1,1,0),(1,1,1),(1,0,1),(-2,-1,-1)], + sage: lp = LatticePolytope([(1,0,0), (1,1,0), (1,1,1), (1,0,1), (-2,-1,-1)], ....: lattice=ToricLattice(3)) sage: X. = CPRFanoToricVariety(Delta_polar=lp) - sage: Y = X.subscheme(x*v+y*u+t) - sage: cone = Cone([(1,0,0),(1,1,0),(1,1,1),(1,0,1)]) + sage: Y = X.subscheme(x*v + y*u + t) + sage: cone = Cone([(1,0,0), (1,1,0), (1,1,1), (1,0,1)]) sage: Y.affine_algebraic_patch(cone) Closed subscheme of Affine Space of dimension 4 over Rational Field defined by: z0*z2 - z1*z3, @@ -398,8 +389,8 @@ def _best_affine_patch(self, point): EXAMPLES:: - sage: P.= toric_varieties.P2() - sage: S = P.subscheme(x+2*y+3*z) + sage: P. = toric_varieties.P2() + sage: S = P.subscheme(x + 2*y + 3*z) sage: S._best_affine_patch(P.point([2,-3,0])) 1 sage: S._best_affine_patch([2,-3,0]) @@ -433,8 +424,8 @@ def neighborhood(self, point): EXAMPLES:: - sage: P.= toric_varieties.P2() - sage: S = P.subscheme(x+2*y+3*z) + sage: P. = toric_varieties.P2() + sage: S = P.subscheme(x + 2*y + 3*z) sage: s = S.point([0,-3,2]); s [0 : -3 : 2] sage: patch = S.neighborhood(s); patch @@ -442,12 +433,10 @@ def neighborhood(self, point): x + 2*y + 6 sage: patch.embedding_morphism() Scheme morphism: - From: Closed subscheme of 2-d affine toric variety defined by: - x + 2*y + 6 - To: Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - x + 2*y + 3*z - Defn: Defined on coordinates by sending [x : y] to - [-2*y - 6 : y : 2] + From: Closed subscheme of 2-d affine toric variety defined by: x + 2*y + 6 + To: Closed subscheme of 2-d CPR-Fano toric variety + covered by 3 affine patches defined by: x + 2*y + 3*z + Defn: Defined on coordinates by sending [x : y] to [-2*y - 6 : y : 2] sage: patch.embedding_center() [0 : -3] sage: patch.embedding_morphism()(patch.embedding_center()) @@ -462,12 +451,10 @@ def neighborhood(self, point): 3*x0 sage: patch.embedding_morphism() Scheme morphism: - From: Closed subscheme of 2-d affine toric variety defined by: - 3*x0 - To: Closed subscheme of 2-d CPR-Fano toric variety covered by 6 affine patches defined by: - x0*x3 - Defn: Defined on coordinates by sending [x0 : x1] to - [0 : x1 : 2 : 3 : 4 : 5] + From: Closed subscheme of 2-d affine toric variety defined by: 3*x0 + To: Closed subscheme of 2-d CPR-Fano toric variety + covered by 6 affine patches defined by: x0*x3 + Defn: Defined on coordinates by sending [x0 : x1] to [0 : x1 : 2 : 3 : 4 : 5] sage: patch.embedding_center() [0 : 1] sage: patch.embedding_morphism()(patch.embedding_center()) @@ -504,19 +491,17 @@ def dimension(self): """ Return the dimension of ``self``. - OUTPUT: - - Integer. If ``self`` is empty, `-1` is returned. + OUTPUT: An integer. If ``self`` is empty, `-1` is returned. EXAMPLES:: sage: P1xP1 = toric_varieties.P1xP1() sage: P1xP1.inject_variables() Defining s, t, x, y - sage: P1 = P1xP1.subscheme(s-t) + sage: P1 = P1xP1.subscheme(s - t) sage: P1.dimension() 1 - sage: P1xP1.subscheme([s-t, (s-t)^2]).dimension() + sage: P1xP1.subscheme([s - t, (s-t)^2]).dimension() 1 sage: P1xP1.subscheme([s, t]).dimension() -1 @@ -546,7 +531,7 @@ def is_smooth(self, point=None): EXAMPLES:: sage: P2. = toric_varieties.P2() - sage: cuspidal_curve = P2.subscheme([y^2*z-x^3]) + sage: cuspidal_curve = P2.subscheme([y^2*z - x^3]) sage: cuspidal_curve Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: -x^3 + y^2*z @@ -574,11 +559,11 @@ def is_smooth(self, point=None): A smooth hypersurface in a compact singular toric variety:: - sage: lp = LatticePolytope([(1,0,0),(1,1,0),(1,1,1),(1,0,1),(-2,-1,-1)], + sage: lp = LatticePolytope([(1,0,0), (1,1,0), (1,1,1), (1,0,1), (-2,-1,-1)], ....: lattice=ToricLattice(3)) sage: X. = CPRFanoToricVariety(Delta_polar=lp) - sage: Y = X.subscheme(x*v+y*u+t) - sage: cone = Cone([(1,0,0),(1,1,0),(1,1,1),(1,0,1)]) + sage: Y = X.subscheme(x*v + y*u + t) + sage: cone = Cone([(1,0,0), (1,1,0), (1,1,1), (1,0,1)]) sage: Y.is_smooth() True """ @@ -621,7 +606,7 @@ def is_nondegenerate(self): sage: fan = FaceFan(diamond) sage: P1xP1xP1 = ToricVariety(fan) sage: z0, z1, z2, z3, z4, z5 = P1xP1xP1.gens() - sage: t = 5; + sage: t = 5 sage: F = z0^2*z1^2*z2^2 + z1^2*z2^2*z3^2 + z0^2*z2^2*z4^2\ ....: + z2^2*z3^2*z4^2 + t*z0*z1*z2*z3*z4*z5 + z0^2*z1^2*z5^2\ ....: + z1^2*z3^2*z5^2 + z0^2*z4^2*z5^2 + z3^2*z4^2*z5^2 @@ -634,23 +619,23 @@ def is_nondegenerate(self): Taking a random change of variables breaks the symmetry, but makes the surface nondegenerate:: - sage: F1 = F.subs(z0 = 1*z0 + 1*z3, z3 = 1*z0 + 2*z3,\ - ....: z1 = -2*z1 + -1*z4, z4 = 1*z1 + 2*z4,\ - ....: z2 = -3*z2 + -1*z5, z5 = -3*z2 + 2*z5 ) + sage: F1 = F.subs(z0=1*z0 + 1*z3, z3=1*z0 + 2*z3, + ....: z1=-2*z1 + -1*z4, z4=1*z1 + 2*z4, + ....: z2=-3*z2 + -1*z5, z5=-3*z2 + 2*z5) sage: Y = P1xP1xP1.subscheme([F1]) sage: Y.is_smooth() True sage: Y.is_nondegenerate() True - This example is from Hamm, :arxiv:`1106.1826v1`. It addresses - an issue raised at :trac:`15239`:: + This example is from Hamm, :arxiv:`1106.1826v1`. It addresses + an issue raised at :trac:`15239`:: sage: X = toric_varieties.WP([1,4,2,3], names='z0 z1 z2 z3') sage: X.inject_variables() Defining z0, z1, z2, z3 - sage: g0 = z1^3 + z2^6 +z3^4 - sage: g = g0-2*z3^2*z0^6+z2*z0^10+z0^12 + sage: g0 = z1^3 + z2^6 + z3^4 + sage: g = g0 - 2*z3^2*z0^6 + z2*z0^10 + z0^12 sage: Y = X.subscheme([g]) sage: Y.is_nondegenerate() False @@ -659,9 +644,9 @@ def is_nondegenerate(self): sage: P2. = toric_varieties.P2() sage: f = x^5 + 2*x*y^4 + y^5 - 2*y^3*z^2 + x*z^4 - 2*z^5 - sage: P2.change_ring(GF(5)).subscheme([f]).is_nondegenerate() + sage: P2.change_ring(GF(5)).subscheme([f]).is_nondegenerate() # optional - sage.rings.finite_rings True - sage: P2.change_ring(GF(7)).subscheme([f]).is_nondegenerate() + sage: P2.change_ring(GF(7)).subscheme([f]).is_nondegenerate() # optional - sage.rings.finite_rings False TESTS: @@ -713,7 +698,7 @@ def is_schon(self): r""" Check if ``self`` is schon (nondegenerate). - See `is_nondegenerate` for further documentation. + See :meth:`is_nondegenerate` for further documentation. EXAMPLES:: @@ -759,7 +744,7 @@ class AlgebraicScheme_subscheme_affine_toric(AlgebraicScheme_subscheme_toric): Defining s, t, x, y sage: import sage.schemes.toric.toric_subscheme as SCM sage: X = SCM.AlgebraicScheme_subscheme_toric( - ....: P1xP1, [x*s + y*t, x^3+y^3]) + ....: P1xP1, [x*s + y*t, x^3 + y^3]) sage: X Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: @@ -768,7 +753,7 @@ class AlgebraicScheme_subscheme_affine_toric(AlgebraicScheme_subscheme_toric): A better way to construct the same scheme as above:: - sage: P1xP1.subscheme([x*s + y*t, x^3+y^3]) + sage: P1xP1.subscheme([x*s + y*t, x^3 + y^3]) Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: s*x + t*y, @@ -786,7 +771,7 @@ def __init__(self, toric_variety, polynomials): Defining s, t, x, y sage: import sage.schemes.toric.toric_subscheme as SCM sage: X = SCM.AlgebraicScheme_subscheme_toric( - ....: P1xP1, [x*s + y*t, x^3+y^3]) + ....: P1xP1, [x*s + y*t, x^3 + y^3]) sage: X Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: @@ -801,14 +786,12 @@ def dimension(self): """ Return the dimension of ``self``. - OUTPUT: - - - integer. + OUTPUT: An integer. EXAMPLES:: sage: P1xP1. = toric_varieties.P1xP1() - sage: P1 = P1xP1.subscheme(s0-s1) + sage: P1 = P1xP1.subscheme(s0 - s1) sage: P1.dimension() 1 @@ -853,7 +836,7 @@ def is_smooth(self, point=None): EXAMPLES:: sage: A2. = toric_varieties.A2() - sage: cuspidal_curve = A2.subscheme([y^2-x^3]) + sage: cuspidal_curve = A2.subscheme([y^2 - x^3]) sage: cuspidal_curve Closed subscheme of 2-d affine toric variety defined by: -x^3 + y^2 @@ -863,7 +846,7 @@ def is_smooth(self, point=None): False sage: cuspidal_curve.is_smooth() False - sage: circle = A2.subscheme(x^2+y^2-1) + sage: circle = A2.subscheme(x^2 + y^2 - 1) sage: circle.is_smooth([1,0]) True sage: circle.is_smooth() diff --git a/src/sage/schemes/toric/variety.py b/src/sage/schemes/toric/variety.py index 9b543e71cdd..c594610f15d 100644 --- a/src/sage/schemes/toric/variety.py +++ b/src/sage/schemes/toric/variety.py @@ -85,20 +85,16 @@ sage: diamond = lattice_polytope.cross_polytope(2) sage: diamond.vertices() - M( 1, 0), - M( 0, 1), - M(-1, 0), - M( 0, -1) + M( 1, 0), M( 0, 1), + M(-1, 0), M( 0, -1) in 2-d lattice M sage: fan = FaceFan(diamond) sage: P1xP1 = ToricVariety(fan) sage: P1xP1 2-d toric variety covered by 4 affine patches sage: P1xP1.fan().rays() - M( 1, 0), - M( 0, 1), - M(-1, 0), - M( 0, -1) + M( 1, 0), M( 0, 1), + M(-1, 0), M( 0, -1) in 2-d lattice M sage: P1xP1.gens() (z0, z1, z2, z3) @@ -117,21 +113,18 @@ sage: P1xP1.inject_variables() Defining x, s, y, t sage: P1xP1.subscheme(x) - Closed subscheme of 2-d toric variety - covered by 4 affine patches defined by: + Closed subscheme of 2-d toric variety covered by 4 affine patches defined by: x sage: P1xP1.subscheme(x^2 + y^2) - Closed subscheme of 2-d toric variety - covered by 4 affine patches defined by: + Closed subscheme of 2-d toric variety covered by 4 affine patches defined by: x^2 + y^2 sage: P1xP1.subscheme(x^2 + s^2) Traceback (most recent call last): ... ValueError: x^2 + s^2 is not homogeneous on 2-d toric variety covered by 4 affine patches - sage: P1xP1.subscheme([x^2*s^2 + x*y*t^2 +y^2*t^2, s^3 + t^3]) - Closed subscheme of 2-d toric variety - covered by 4 affine patches defined by: + sage: P1xP1.subscheme([x^2*s^2 + x*y*t^2 + y^2*t^2, s^3 + t^3]) + Closed subscheme of 2-d toric variety covered by 4 affine patches defined by: x^2*s^2 + x*y*t^2 + y^2*t^2, s^3 + t^3 @@ -149,8 +142,7 @@ Scheme morphism: From: 2-d affine toric variety To: 2-d toric variety covered by 4 affine patches - Defn: Defined on coordinates by sending [x : s] to - [x : s : 1 : 1] + Defn: Defined on coordinates by sending [x : s] to [x : s : 1 : 1] The patch above was specifically chosen to coincide with our representation of the affine plane before, but you can get the other three patches as well. @@ -170,10 +162,8 @@ True sage: TV = ToricVariety(NormalFan(diamond)) sage: TV.fan().rays() - N( 1, 1), - N( 1, -1), - N(-1, -1), - N(-1, 1) + N( 1, 1), N( 1, -1), + N(-1, -1), N(-1, 1) in 2-d lattice N sage: TV.is_orbifold() True @@ -184,14 +174,8 @@ sage: TV3 = ToricVariety(NormalFan(lattice_polytope.cross_polytope(3))) sage: TV3.fan().rays() - N( 1, -1, -1), - N( 1, 1, -1), - N( 1, 1, 1), - N( 1, -1, 1), - N(-1, -1, 1), - N(-1, -1, -1), - N(-1, 1, -1), - N(-1, 1, 1) + N( 1, -1, -1), N( 1, 1, -1), N( 1, 1, 1), N( 1, -1, 1), + N(-1, -1, 1), N(-1, -1, -1), N(-1, 1, -1), N(-1, 1, 1) in 3-d lattice N sage: TV3.is_orbifold() False @@ -267,9 +251,9 @@ sage: D = P4_11133.divisor(0) sage: HH(D) [3*z4] - sage: P4_11133.integrate( HH(D)^4 ) + sage: P4_11133.integrate(HH(D)^4) 9 - sage: P4_11133.integrate( HH(D) * HH(cone) ) + sage: P4_11133.integrate(HH(D) * HH(cone)) 1 Although computationally less efficient, we can do the same @@ -287,13 +271,13 @@ The real advantage of the Chow group is that - * it works just as well over `\ZZ`, so torsion information is also - easily available, and +* it works just as well over `\ZZ`, so torsion information is also + easily available, and - * its combinatorial description also works over worse-than-orbifold - singularities. By contrast, the cohomology groups can become very - complicated to compute in this case, and one usually only has a - spectral sequence but no toric algorithm. +* its combinatorial description also works over worse-than-orbifold + singularities. By contrast, the cohomology groups can become very + complicated to compute in this case, and one usually only has a + spectral sequence but no toric algorithm. Below you will find detailed descriptions of available functions. If you are familiar with toric geometry, you will likely see that many important objects @@ -411,9 +395,7 @@ def ToricVariety(fan, - ``base_field`` -- alias for ``base_ring``. Takes precedence if both are specified. - OUTPUT: - - - :class:`toric variety `. + OUTPUT: A :class:`toric variety `. EXAMPLES: @@ -421,10 +403,8 @@ def ToricVariety(fan, sage: fan = FaceFan(lattice_polytope.cross_polytope(2)) sage: fan.rays() - M( 1, 0), - M( 0, 1), - M(-1, 0), - M( 0, -1) + M( 1, 0), M( 0, 1), + M(-1, 0), M( 0, -1) in 2-d lattice M sage: P1xP1 = ToricVariety(fan) sage: P1xP1.gens() @@ -439,8 +419,7 @@ def ToricVariety(fan, sage: P1xP1(0,1,0,1) Traceback (most recent call last): ... - TypeError: coordinates (0, 1, 0, 1) - are in the exceptional set + TypeError: coordinates (0, 1, 0, 1) are in the exceptional set We cannot set to zero both coordinates of the same projective line! @@ -455,9 +434,8 @@ def ToricVariety(fan, sage: P1xP1.inject_variables() Defining x, s, y, t - sage: P1xP1.subscheme(x*s-y*t) - Closed subscheme of 2-d toric variety - covered by 4 affine patches defined by: + sage: P1xP1.subscheme(x*s - y*t) + Closed subscheme of 2-d toric variety covered by 4 affine patches defined by: x*s - y*t Here is a shorthand for defining the toric variety and homogeneous @@ -493,9 +471,7 @@ def AffineToricVariety(cone, *args, **kwds): `, which will be passed to :func:`ToricVariety` with the rest of positional and keyword arguments. - OUTPUT: - - - :class:`toric variety `. + OUTPUT: A :class:`toric variety `. .. NOTE:: @@ -552,9 +528,7 @@ class ToricVariety_field(AmbientSpace): - ``base_field`` -- base field of the toric variety. - OUTPUT: - - - :class:`toric variety `. + OUTPUT: A :class:`toric variety `. TESTS:: @@ -589,9 +563,7 @@ def __eq__(self, right): - ``right`` -- anything - OUTPUT: - - boolean + OUTPUT: A boolean. ``True`` if and only if ``right`` is of the same type as ``self``, their fans are the same, names of variables are the same and @@ -627,9 +599,7 @@ def __ne__(self, other): - ``other`` -- anything - OUTPUT: - - boolean + OUTPUT: A boolean. ``True`` if and only if ``other`` is of the same type as ``self``, their fans are the same, names of variables are the same and @@ -872,7 +842,7 @@ def _homset(self, *args, **kwds): sage: P1xP1.inject_variables() Defining s, t, x, y - sage: P1 = P1xP1.subscheme(s-t) + sage: P1 = P1xP1.subscheme(s - t) sage: hom_set = P1xP1.Hom(P1) sage: hom_set([s,s,x,y]) Scheme morphism: @@ -1010,15 +980,13 @@ def affine_patch(self, i): Scheme morphism: From: 2-d affine toric variety To: 2-d toric variety covered by 4 affine patches - Defn: Defined on coordinates by sending [y : t] to - [1 : 1 : y : t] + Defn: Defined on coordinates by sending [y : t] to [1 : 1 : y : t] sage: patch1 = P1xP1.affine_patch(1) sage: patch1.embedding_morphism() Scheme morphism: From: 2-d affine toric variety To: 2-d toric variety covered by 4 affine patches - Defn: Defined on coordinates by sending [s : y] to - [1 : s : y : 1] + Defn: Defined on coordinates by sending [s : y] to [1 : s : y : 1] sage: patch1 is P1xP1.affine_patch(1) True """ @@ -1055,9 +1023,7 @@ def change_ring(self, F): - ``F`` -- field. - OUTPUT: - - - :class:`toric variety ` over ``F``. + OUTPUT: :class:`toric variety ` over ``F``. .. NOTE:: @@ -1080,8 +1046,7 @@ def change_ring(self, F): Traceback (most recent call last): ... ValueError: no natural map from the base ring - (=Real Field with 53 bits of precision) - to R (=Rational Field)! + (=Real Field with 53 bits of precision) to R (=Rational Field)! sage: R = PolynomialRing(QQ, 2, 'a') sage: P1xA1.change_ring(R) Traceback (most recent call last): @@ -1105,16 +1070,13 @@ def coordinate_ring(self): For toric varieties this is the homogeneous coordinate ring (a.k.a. Cox's ring and total ring). - OUTPUT: - - - polynomial ring. + OUTPUT: A polynomial ring. EXAMPLES:: sage: P1xP1 = toric_varieties.P1xP1() sage: P1xP1.coordinate_ring() - Multivariate Polynomial Ring in s, t, x, y - over Rational Field + Multivariate Polynomial Ring in s, t, x, y over Rational Field TESTS:: @@ -1149,8 +1111,7 @@ def embedding_morphism(self): sage: P1xP1.embedding_morphism() Traceback (most recent call last): ... - ValueError: no default embedding was - defined for this toric variety + ValueError: no default embedding was defined for this toric variety sage: patch = P1xP1.affine_patch(0) sage: patch 2-d affine toric variety @@ -1158,8 +1119,7 @@ def embedding_morphism(self): Scheme morphism: From: 2-d affine toric variety To: 2-d toric variety covered by 4 affine patches - Defn: Defined on coordinates by sending [y : t] to - [1 : 1 : y : t] + Defn: Defined on coordinates by sending [y : t] to [1 : 1 : y : t] """ try: return self._embedding_morphism @@ -1212,9 +1172,7 @@ def inject_coefficients(self, scope=None, verbose=True): - ``verbose`` -- if ``True`` (default), names of injected generators will be printed. - OUTPUT: - - - none. + OUTPUT: None. EXAMPLES:: @@ -1311,7 +1269,7 @@ def is_homogeneous(self, polynomial): no homogeneous rescalings, for example:: sage: A1. = toric_varieties.A1() - sage: A1.is_homogeneous(z^3+z^7) + sage: A1.is_homogeneous(z^3 + z^7) True Finally, the degree group is really the Chow group @@ -1321,11 +1279,11 @@ def is_homogeneous(self, polynomial): from odd-degree homogeneous polynomials:: sage: A2_Z2. = toric_varieties.A2_Z2() - sage: A2_Z2.is_homogeneous(x+y+x^3+y^5+x^3*y^4) + sage: A2_Z2.is_homogeneous(x + y + x^3 + y^5 + x^3*y^4) True - sage: A2_Z2.is_homogeneous(x^2+x*y+y^4+(x*y)^5+x^4*y^4) + sage: A2_Z2.is_homogeneous(x^2 + x*y + y^4 + (x*y)^5 + x^4*y^4) True - sage: A2_Z2.is_homogeneous(x+y^2) + sage: A2_Z2.is_homogeneous(x + y^2) False """ if '_homogeneous_degrees_group' not in self.__dict__: @@ -1376,8 +1334,7 @@ def is_isomorphic(self, another): sage: TV1.is_isomorphic(TV2) Traceback (most recent call last): ... - NotImplementedError: - isomorphism check is not yet implemented + NotImplementedError: isomorphism check is not yet implemented """ if self is another: return True @@ -1395,9 +1352,7 @@ def is_affine(self): face lattice of a single cone. See also :func:`AffineToricVariety`. - OUTPUT: - - Boolean. + OUTPUT: A boolean. EXAMPLES:: @@ -1479,9 +1434,7 @@ def Kaehler_cone(self): r""" Return the closure of the Kähler cone of ``self``. - OUTPUT: - - - :class:`cone `. + OUTPUT: :class:`cone `. .. NOTE:: @@ -1526,9 +1479,7 @@ def Mori_cone(self): r""" Returns the Mori cone of ``self``. - OUTPUT: - - - :class:`cone `. + OUTPUT: :class:`cone `. .. NOTE:: @@ -1558,8 +1509,7 @@ def Mori_cone(self): sage: P4_11169.Mori_cone().rays() (3, 2, 0, 0, 0, 1, -6), (0, 0, 1, 1, 1, -3, 0) - in Ambient free module of rank 7 - over the principal ideal domain Integer Ring + in Ambient free module of rank 7 over the principal ideal domain Integer Ring """ # Ideally, self.Kaehler_cone().dual() should be it, but # so far this is not the case. @@ -1576,9 +1526,7 @@ def plot(self, **options): - any options for toric plots (see :func:`toric_plotter.options `), none are mandatory. - OUTPUT: - - - a plot. + OUTPUT: A plot. .. NOTE:: @@ -1617,10 +1565,8 @@ def rational_class_group(self): we write as addition) is the tensor product of the line bundles. The Picard group of a toric variety is always torsion-free. - OUTPUT: - - - :class:`rational divisor class group - `. + OUTPUT: :class:`rational divisor class group + `. .. NOTE:: @@ -1648,9 +1594,7 @@ def Chow_group(self, base_ring=ZZ): - ``base_ring`` -- either ``ZZ`` (default) or ``QQ``. The coefficient ring of the Chow group. - OUTPUT: - - A :class:`sage.schemes.toric.chow_group.ChowGroup_class` + OUTPUT: A :class:`sage.schemes.toric.chow_group.ChowGroup_class`. EXAMPLES:: @@ -1679,9 +1623,7 @@ def cartesian_product(self, other, variables. If not given, the index of each variable will coincide with the index of the corresponding ray of the fan. - OUTPUT: - - -- a :class:`toric variety `. + OUTPUT: A :class:`toric variety `. EXAMPLES:: @@ -1689,10 +1631,8 @@ def cartesian_product(self, other, sage: P1xP1 = P1.cartesian_product(P1); P1xP1 2-d toric variety covered by 4 affine patches sage: P1xP1.fan().rays() - N+N(-1, 0), - N+N( 1, 0), - N+N( 0, -1), - N+N( 0, 1) + N+N(-1, 0), N+N( 1, 0), + N+N( 0, -1), N+N( 0, 1) in 2-d lattice N+N """ return ToricVariety(self.fan().cartesian_product(other.fan()), @@ -1726,9 +1666,7 @@ def resolve(self, **kwds): `, see its documentation for the available options. - OUTPUT: - - - :class:`toric variety `. + OUTPUT: A :class:`toric variety `. EXAMPLES: @@ -1830,9 +1768,7 @@ def resolve_to_orbifold(self, **kwds): - this function accepts only keyword arguments. See :meth:`resolve` for documentation. - OUTPUT: - - - :class:`toric variety `. + OUTPUT: A :class:`toric variety `. EXAMPLES:: @@ -1863,10 +1799,8 @@ def subscheme(self, polynomials): - ``polynomials`` -- list of polynomials in the coordinate ring of ``self``. - OUTPUT: - - - :class:`subscheme of a toric variety - `. + OUTPUT: A :class:`subscheme of a toric variety + `. EXAMPLES: @@ -1874,7 +1808,7 @@ def subscheme(self, polynomials): with coordinates `(x, y)` for one and `(s, t)` for the other:: sage: P1xP1. = toric_varieties.P1xP1() - sage: X = P1xP1.subscheme([x*s + y*t, x^3+y^3]) + sage: X = P1xP1.subscheme([x*s + y*t, x^3 + y^3]) sage: X Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: @@ -1883,9 +1817,8 @@ def subscheme(self, polynomials): sage: X.defining_polynomials() (x*s + y*t, x^3 + y^3) sage: X.defining_ideal() - Ideal (x*s + y*t, x^3 + y^3) - of Multivariate Polynomial Ring in x, y, s, t - over Rational Field + Ideal (x*s + y*t, x^3 + y^3) of + Multivariate Polynomial Ring in x, y, s, t over Rational Field sage: X.base_ring() Rational Field sage: X.base_scheme() @@ -1893,9 +1826,7 @@ def subscheme(self, polynomials): sage: X.structure_morphism() Scheme morphism: From: Closed subscheme of 2-d CPR-Fano toric variety - covered by 4 affine patches defined by: - x*s + y*t, - x^3 + y^3 + covered by 4 affine patches defined by: x*s + y*t, x^3 + y^3 To: Spectrum of Rational Field Defn: Structure map """ @@ -1917,10 +1848,12 @@ def Stanley_Reisner_ideal(self): EXAMPLES:: - sage: fan = Fan([[0,1,3],[3,4],[2,0],[1,2,4]], [(-3, -2, 1), (0, 0, 1), (3, -2, 1), (-1, -1, 1), (1, -1, 1)]) - sage: X = ToricVariety(fan, coordinate_names='A B C D E', base_field=GF(5)) - sage: SR = X.Stanley_Reisner_ideal(); SR - Ideal (A*E, C*D, A*B*C, B*D*E) of Multivariate Polynomial Ring in A, B, C, D, E over Rational Field + sage: fan = Fan([[0,1,3], [3,4], [2,0], [1,2,4]], + ....: [(-3, -2, 1), (0, 0, 1), (3, -2, 1), (-1, -1, 1), (1, -1, 1)]) + sage: X = ToricVariety(fan, coordinate_names='A B C D E', base_field=GF(5)) # optional - sage.rings.finite_rings + sage: SR = X.Stanley_Reisner_ideal(); SR # optional - sage.rings.finite_rings + Ideal (A*E, C*D, A*B*C, B*D*E) of + Multivariate Polynomial Ring in A, B, C, D, E over Rational Field """ if "_SR" not in self.__dict__: R = PolynomialRing(QQ, self.variable_names()) @@ -1939,10 +1872,12 @@ def linear_equivalence_ideal(self): EXAMPLES:: - sage: fan = Fan([[0,1,3],[3,4],[2,0],[1,2,4]], [(-3, -2, 1), (0, 0, 1), (3, -2, 1), (-1, -1, 1), (1, -1, 1)]) - sage: X = ToricVariety(fan, coordinate_names='A B C D E', base_field=GF(5)) - sage: lin = X.linear_equivalence_ideal(); lin - Ideal (-3*A + 3*C - D + E, -2*A - 2*C - D - E, A + B + C + D + E) of Multivariate Polynomial Ring in A, B, C, D, E over Rational Field + sage: fan = Fan([[0,1,3], [3,4], [2,0], [1,2,4]], + ....: [(-3, -2, 1), (0, 0, 1), (3, -2, 1), (-1, -1, 1), (1, -1, 1)]) + sage: X = ToricVariety(fan, coordinate_names='A B C D E', base_field=GF(5)) # optional - sage.rings.finite_rings + sage: lin = X.linear_equivalence_ideal(); lin # optional - sage.rings.finite_rings + Ideal (-3*A + 3*C - D + E, -2*A - 2*C - D - E, A + B + C + D + E) of + Multivariate Polynomial Ring in A, B, C, D, E over Rational Field """ if "_linear_equivalence_ideal" not in self.__dict__: R = PolynomialRing(QQ, self.variable_names()) @@ -1980,7 +1915,8 @@ def cohomology_ring(self): sage: X.cohomology_ring() Rational cohomology ring of a 2-d CPR-Fano toric variety covered by 6 affine patches sage: X.cohomology_ring().defining_ideal() - Ideal (-u - y + z + w, x - y - v + w, x*y, x*v, x*z, u*v, u*z, u*w, y*z, y*w, v*w) of Multivariate Polynomial Ring in x, u, y, v, z, w over Rational Field + Ideal (-u - y + z + w, x - y - v + w, x*y, x*v, x*z, u*v, u*z, u*w, y*z, y*w, v*w) + of Multivariate Polynomial Ring in x, u, y, v, z, w over Rational Field sage: X.cohomology_ring().defining_ideal().ring() Multivariate Polynomial Ring in x, u, y, v, z, w over Rational Field sage: X.variable_names() @@ -2407,8 +2343,7 @@ def divisor(self, arg, base_ring=None, check=True, reduce=True): sage: dP6 = toric_varieties.dP6() sage: dP6.coordinate_ring() - Multivariate Polynomial Ring in x, u, y, v, z, w - over Rational Field + Multivariate Polynomial Ring in x, u, y, v, z, w over Rational Field sage: dP6.divisor(list(range(6))) V(u) + 2*V(y) + 3*V(v) + 4*V(z) + 5*V(w) sage: dP6.inject_variables() @@ -2476,8 +2411,7 @@ def divisor_group(self, base_ring=ZZ): sage: dP6 = toric_varieties.dP6() sage: Div = dP6.divisor_group(); Div - Group of ZZ-Divisors on 2-d CPR-Fano toric variety - covered by 6 affine patches + Group of ZZ-Divisors on 2-d CPR-Fano toric variety covered by 6 affine patches sage: Div(x) V(x) """ @@ -2542,7 +2476,7 @@ def _semigroup_ring(self, cone=None, names=None): EXAMPLES:: - sage: A2Z2 = Cone([(0,1),(2,1)]) + sage: A2Z2 = Cone([(0,1), (2,1)]) sage: AffineToricVariety(A2Z2)._semigroup_ring() (Multivariate Polynomial Ring in z0, z1, z2 over Rational Field, Ideal (-z0*z1 + z2^2) of Multivariate Polynomial Ring in z0, z1, z2 over Rational Field, @@ -2554,7 +2488,7 @@ def _semigroup_ring(self, cone=None, names=None): (Multivariate Polynomial Ring in z0, z1 over Rational Field, Ideal (0) of Multivariate Polynomial Ring in z0, z1 over Rational Field, 2-d cone in 2-d lattice M) - sage: P2.change_ring(GF(101))._semigroup_ring(cone) + sage: P2.change_ring(GF(101))._semigroup_ring(cone) # optional - sage.rings.finite_rings (Multivariate Polynomial Ring in z0, z1 over Finite Field of size 101, Ideal (0) of Multivariate Polynomial Ring in z0, z1 over Finite Field of size 101, 2-d cone in 2-d lattice M) @@ -2611,19 +2545,19 @@ def Spec(self, cone=None, names=None): formats. If not given, indexed variable names will be created automatically. - Output: + OUTPUT: The spectrum of the semigroup ring `\CC[\sigma^\vee \cap M]`. EXAMPLES:: - sage: quadrant = Cone([(1,0),(0,1)]) + sage: quadrant = Cone([(1,0), (0,1)]) sage: AffineToricVariety(quadrant).Spec() Spectrum of Multivariate Polynomial Ring in z0, z1 over Rational Field A more interesting example:: - sage: A2Z2 = Cone([(0,1),(2,1)]) + sage: A2Z2 = Cone([(0,1), (2,1)]) sage: AffineToricVariety(A2Z2).Spec(names='u,v,t') Spectrum of Quotient of Multivariate Polynomial Ring in u, v, t over Rational Field by the ideal (-u*v + t^2) @@ -2656,7 +2590,7 @@ def affine_algebraic_patch(self, cone=None, names=None): EXAMPLES:: - sage: cone = Cone([(0,1),(2,1)]) + sage: cone = Cone([(0,1), (2,1)]) sage: A2Z2 = AffineToricVariety(cone) sage: A2Z2.affine_algebraic_patch() Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: @@ -2768,8 +2702,7 @@ def orbit_closure(self, cone): Scheme morphism: From: 1-d toric variety covered by 2 affine patches To: 2-d CPR-Fano toric variety covered by 4 affine patches - Defn: Defined on coordinates by sending [z0 : z1] to - [0 : 1 : z1 : z0] + Defn: Defined on coordinates by sending [z0 : z1] to [0 : 1 : z1 : z0] TESTS:: @@ -2807,10 +2740,10 @@ def count_points(self): sage: o = lattice_polytope.cross_polytope(3) sage: V = ToricVariety(FaceFan(o)) - sage: V2 = V.change_ring(GF(2)) - sage: V2.point_set().cardinality() + sage: V2 = V.change_ring(GF(2)) # optional - sage.rings.finite_rings + sage: V2.point_set().cardinality() # optional - sage.rings.finite_rings 27 - sage: V2.count_points() + sage: V2.count_points() # optional - sage.rings.finite_rings 27 """ return self.point_set().cardinality() @@ -2838,18 +2771,19 @@ def Demazure_roots(self): Here are the remaining three examples listed in [Baz2011]_, Example 2.1 and 2.3:: sage: s = 3 - sage: cones = [(0,1),(1,2),(2,3),(3,0)] - sage: Hs = ToricVariety(Fan(rays=[(1,0),(0,-1),(-1,s),(0,1)], cones=cones)) + sage: cones = [(0,1), (1,2), (2,3), (3,0)] + sage: Hs = ToricVariety(Fan(rays=[(1,0), (0,-1), (-1,s), (0,1)], cones=cones)) sage: Hs.Demazure_roots() (M(-1, 0), M(1, 0), M(0, 1), M(1, 1), M(2, 1), M(3, 1)) - sage: P11s = ToricVariety(Fan(rays=[(1,0),(0,-1),(-1,s)], cones=[(0,1),(1,2),(2,0)])) + sage: P11s = ToricVariety(Fan(rays=[(1,0), (0,-1), (-1,s)], + ....: cones=[(0,1), (1,2), (2,0)])) sage: P11s.Demazure_roots() (M(-1, 0), M(1, 0), M(0, 1), M(1, 1), M(2, 1), M(3, 1)) sage: P11s.Demazure_roots() == Hs.Demazure_roots() True - sage: Bs = ToricVariety(Fan(rays=[(s,1),(s,-1),(-s,-1),(-s,1)], cones=cones)) + sage: Bs = ToricVariety(Fan(rays=[(s,1), (s,-1), (-s,-1), (-s,1)], cones=cones)) sage: Bs.Demazure_roots() () @@ -3491,9 +3425,9 @@ def part_of_degree(self, d): sage: P1xP1 = toric_varieties.P1xP1() sage: t = P1xP1.cohomology_ring().gen(0) sage: y = P1xP1.cohomology_ring().gen(2) - sage: 3*t+4*t^2*y+y+t*y+t+1 + sage: 3*t + 4*t^2*y + y + t*y + t + 1 [t*y + 4*t + y + 1] - sage: (3*t+4*t^2*y+y+t*y+t+1).part_of_degree(1) + sage: (3*t + 4*t^2*y + y + t*y + t + 1).part_of_degree(1) [4*t + y] """ Q = self.parent() diff --git a/src/sage/schemes/toric/weierstrass.py b/src/sage/schemes/toric/weierstrass.py index 552a91093d6..b0259f724b1 100644 --- a/src/sage/schemes/toric/weierstrass.py +++ b/src/sage/schemes/toric/weierstrass.py @@ -25,9 +25,9 @@ (that is, set one or more of the coefficients to zero) of the following three cases. In inhomogeneous coordinates, they are - * Cubic in `\mathbb{P}^2`: +* Cubic in `\mathbb{P}^2`: - .. MATH:: + .. MATH:: \begin{split} p(x,y) =&\; @@ -38,9 +38,9 @@ a_{02} y^{2} + a_{10} x + a_{01} y + a_{00} \end{split} - * Biquadric in `\mathbb{P}^1\times \mathbb{P}^1`: +* Biquadric in `\mathbb{P}^1\times \mathbb{P}^1`: - .. MATH:: + .. MATH:: \begin{split} p(x,y) =&\; @@ -51,10 +51,9 @@ y^2 a_{02} + y a_{01} + a_{00} \end{split} - * Anticanonical hypersurface in weighted projective space - `\mathbb{P}^2[1,1,2]`: +* Anticanonical hypersurface in weighted projective space `\mathbb{P}^2[1,1,2]`: - .. MATH:: + .. MATH:: \begin{split} p(x,y) =&\; @@ -160,20 +159,18 @@ def Discriminant(polynomial, variables=None): See :func:`WeierstrassForm` for how to specify the input polynomial(s) and variables. - OUTPUT: - - The discriminant of the elliptic curve. + OUTPUT: The discriminant of the elliptic curve. EXAMPLES:: sage: from sage.schemes.toric.weierstrass import Discriminant sage: R. = QQ[] - sage: Discriminant(x^3+y^3+z^3) + sage: Discriminant(x^3 + y^3 + z^3) 19683/16 sage: Discriminant(x*y*z) 0 sage: R. = QQ[] - sage: quadratic1 = w^2+x^2+y^2 + sage: quadratic1 = w^2 + x^2 + y^2 sage: quadratic2 = z^2 + w*x sage: Discriminant([quadratic1, quadratic2]) -1/16 @@ -196,18 +193,18 @@ def j_invariant(polynomial, variables=None): The j-invariant of the (irreducible) cubic. Notable special values: - * The Fermat cubic: `j(x^3+y^3+z^3) = 0` + * The Fermat cubic: `j(x^3+y^3+z^3) = 0` - * A nodal cubic: `j(-y^2 + x^2 + x^3) = \infty` + * A nodal cubic: `j(-y^2 + x^2 + x^3) = \infty` - * A cuspidal cubic `y^2=x^3` has undefined `j`-invariant. In this - case, a ``ValueError`` is returned. + * A cuspidal cubic `y^2=x^3` has undefined `j`-invariant. In this + case, a ``ValueError`` is raised. EXAMPLES:: sage: from sage.schemes.toric.weierstrass import j_invariant sage: R. = QQ[] - sage: j_invariant(x^3+y^3+z^3) + sage: j_invariant(x^3 + y^3 + z^3) 0 sage: j_invariant(-y^2 + x^2 + x^3) +Infinity @@ -538,7 +535,7 @@ def _check_homogeneity(polynomial, variables, weights, total_weight=None): ....: a11*x*y*z + a02*y^2*z + a10*x*z^2 + a01*y*z^2 + a00*z^3) sage: _check_homogeneity(p, [x,y,z], (1,1,1), 3) - sage: _check_homogeneity(p+x^4, [x,y,z], (1,1,1), 3) + sage: _check_homogeneity(p + x^4, [x,y,z], (1,1,1), 3) Traceback (most recent call last): ... ValueError: the polynomial is not homogeneous with weights (1, 1, 1) @@ -632,7 +629,7 @@ def _check_polynomial_P2(cubic, variables): sage: from sage.schemes.toric.weierstrass import _check_polynomial_P2 sage: R. = QQ[] - sage: cubic = x^3+y^3+z^3 + sage: cubic = x^3 + y^3 + z^3 sage: _check_polynomial_P2(cubic, [x,y,z]) (x, y, z) sage: _check_polynomial_P2(cubic, None) @@ -640,7 +637,7 @@ def _check_polynomial_P2(cubic, variables): sage: _check_polynomial_P2(cubic.subs(z=1), None) (x, y, None) sage: R. = QQ[] - sage: cubic = x^3+y^3+z^3 + t*x*y*z + sage: cubic = x^3 + y^3 + z^3 + t*x*y*z sage: _check_polynomial_P2(cubic, [x,y,z]) (x, y, z) sage: _check_polynomial_P2(cubic, [x,y,t]) @@ -684,11 +681,11 @@ def WeierstrassForm_P2(polynomial, variables=None): sage: from sage.schemes.toric.weierstrass import WeierstrassForm_P2 sage: R. = QQ[] - sage: WeierstrassForm_P2( x^3+y^3+z^3 ) + sage: WeierstrassForm_P2(x^3 + y^3 + z^3) (0, -27/4) sage: R. = QQ[] - sage: WeierstrassForm_P2( -y^2*z+x^3+a*x*z^2+b*z^3, [x,y,z] ) + sage: WeierstrassForm_P2(-y^2*z + x^3 + a*x*z^2 + b*z^3, [x,y,z]) (a, b) TESTS:: @@ -789,9 +786,9 @@ def _check_polynomial_P1xP1(biquadric, variables): sage: from sage.schemes.toric.weierstrass import _check_polynomial_P1xP1 sage: R. = QQ[] - sage: biquadric = ( x0^2*y0^2 + x0*x1*y0^2*2 + x1^2*y0^2*3 - ....: + x0^2*y0*y1*4 + x0*x1*y0*y1*5 + x1^2*y0*y1*6 - ....: + x0^2*y1^2*7 + x0*x1*y1^2*8 ) + sage: biquadric = (x0^2*y0^2 + x0*x1*y0^2*2 + x1^2*y0^2*3 + ....: + x0^2*y0*y1*4 + x0*x1*y0*y1*5 + x1^2*y0*y1*6 + ....: + x0^2*y1^2*7 + x0*x1*y1^2*8) sage: _check_polynomial_P1xP1(biquadric, [x0,x1,y0,y1]) [x0, x1, y0, y1] sage: _check_polynomial_P1xP1(biquadric, None) @@ -834,9 +831,9 @@ def _partial_discriminant(quadric, y0, y1=None): EXAMPLES:: sage: R. = QQ[] - sage: biquadric = ( x0^2*y0^2*a00 + x0*x1*y0^2*a10 + x1^2*y0^2*a20 - ....: + x0^2*y0*y1*a01 + x0*x1*y0*y1*a11 + x1^2*y0*y1*a21 - ....: + x0^2*y1^2*a02 + x0*x1*y1^2*a12 + x1^2*y1^2*a22 ) + sage: biquadric = (x0^2*y0^2*a00 + x0*x1*y0^2*a10 + x1^2*y0^2*a20 + ....: + x0^2*y0*y1*a01 + x0*x1*y0*y1*a11 + x1^2*y0*y1*a21 + ....: + x0^2*y1^2*a02 + x0*x1*y1^2*a12 + x1^2*y1^2*a22) sage: from sage.schemes.toric.weierstrass import _partial_discriminant sage: _partial_discriminant(biquadric, y0, y1) x0^4*a01^2 + 2*x0^3*x1*a01*a11 + x0^2*x1^2*a11^2 @@ -888,10 +885,10 @@ def WeierstrassForm_P1xP1(biquadric, variables=None): EXAMPLES:: sage: from sage.schemes.toric.weierstrass import WeierstrassForm_P1xP1 - sage: R.= QQ[] - sage: biquadric = ( x0^2*y0^2 + x0*x1*y0^2*2 + x1^2*y0^2*3 - ....: + x0^2*y0*y1*4 + x0*x1*y0*y1*5 + x1^2*y0*y1*6 - ....: + x0^2*y1^2*7 + x0*x1*y1^2*8 ) + sage: R. = QQ[] + sage: biquadric = (x0^2*y0^2 + x0*x1*y0^2*2 + x1^2*y0^2*3 + ....: + x0^2*y0*y1*4 + x0*x1*y0*y1*5 + x1^2*y0*y1*6 + ....: + x0^2*y1^2*7 + x0*x1*y1^2*8) sage: WeierstrassForm_P1xP1(biquadric, [x0, x1, y0, y1]) (1581/16, -3529/32) @@ -905,9 +902,9 @@ def WeierstrassForm_P1xP1(biquadric, variables=None): TESTS:: sage: R. = QQ[] - sage: biquadric = ( x0^2*y0^2*a00 + x0*x1*y0^2*a10 + x1^2*y0^2*a20 - ....: + x0^2*y0*y1*a01 + x0*x1*y0*y1*a11 + x1^2*y0*y1*a21 - ....: + x0^2*y1^2*a02 + x0*x1*y1^2*a12 ) + sage: biquadric = (x0^2*y0^2*a00 + x0*x1*y0^2*a10 + x1^2*y0^2*a20 + ....: + x0^2*y0*y1*a01 + x0*x1*y0*y1*a11 + x1^2*y0*y1*a21 + ....: + x0^2*y1^2*a02 + x0*x1*y1^2*a12) sage: WeierstrassForm_P1xP1(biquadric, [x0, x1, y0, y1]) (-1/48*a11^4 + 1/6*a01*a11^2*a21 - 1/3*a01^2*a21^2 + 1/6*a20*a11^2*a02 + 1/3*a20*a01*a21*a02 - 1/2*a10*a11*a21*a02 @@ -935,7 +932,7 @@ def WeierstrassForm_P1xP1(biquadric, variables=None): + 1/9*a10^2*a20*a02*a12^2 - 2/3*a00*a20^2*a02*a12^2 - 2/27*a10^3*a12^3 + 1/3*a00*a10*a20*a12^3) - sage: _ == WeierstrassForm_P1xP1(biquadric.subs(x1=1,y1=1), [x0, y0]) + sage: _ == WeierstrassForm_P1xP1(biquadric.subs(x1=1, y1=1), [x0, y0]) True """ x, y, s, t = _check_polynomial_P1xP1(biquadric, variables) @@ -1027,7 +1024,8 @@ def WeierstrassForm_P2_112(polynomial, variables=None): EXAMPLES:: sage: from sage.schemes.toric.weierstrass import WeierstrassForm_P2_112 - sage: fan = Fan(rays=[(1,0),(0,1),(-1,-2),(0,-1)],cones=[[0,1],[1,2],[2,3],[3,0]]) + sage: fan = Fan(rays=[(1,0),(0,1),(-1,-2),(0,-1)], + ....: cones=[[0,1],[1,2],[2,3],[3,0]]) sage: P112. = ToricVariety(fan) sage: (-P112.K()).sections_monomials() (z^4*t^2, x*z^3*t^2, x^2*z^2*t^2, x^3*z*t^2, @@ -1038,8 +1036,8 @@ def WeierstrassForm_P2_112(polynomial, variables=None): TESTS:: sage: R. = QQ[] - sage: p = ( a40*x^4*t^2 + a30*x^3*z*t^2 + a20*x^2*z^2*t^2 + a10*x*z^3*t^2 + - ....: a00*z^4*t^2 + a21*x^2*y*t + a11*x*y*z*t + a01*y*z^2*t + a02*y^2 ) + sage: p = (a40*x^4*t^2 + a30*x^3*z*t^2 + a20*x^2*z^2*t^2 + a10*x*z^3*t^2 + + ....: a00*z^4*t^2 + a21*x^2*y*t + a11*x*y*z*t + a01*y*z^2*t + a02*y^2) sage: WeierstrassForm_P2_112(p, [x,y,z,t]) (-1/48*a11^4 + 1/6*a21*a11^2*a01 - 1/3*a21^2*a01^2 + a00*a21^2*a02 - 1/2*a10*a21*a11*a02 + 1/6*a20*a11^2*a02 + 1/3*a20*a21*a01*a02 @@ -1061,15 +1059,15 @@ def WeierstrassForm_P2_112(polynomial, variables=None): + 1/3*a30*a20*a10*a02^3 - a40*a10^2*a02^3 - a30^2*a00*a02^3 + 8/3*a40*a20*a00*a02^3) - sage: _ == WeierstrassForm_P2_112(p.subs(z=1,t=1), [x,y]) + sage: _ == WeierstrassForm_P2_112(p.subs(z=1, t=1), [x,y]) True sage: cubic = p.subs(a40=0) sage: a,b = WeierstrassForm_P2_112(cubic, [x,y,z,t]) - sage: a = a.subs(t=1,z=1) - sage: b = b.subs(t=1,z=1) + sage: a = a.subs(t=1, z=1) + sage: b = b.subs(t=1, z=1) sage: from sage.schemes.toric.weierstrass import WeierstrassForm_P2 - sage: (a,b) == WeierstrassForm_P2(cubic.subs(t=1,z=1), [x,y]) + sage: (a,b) == WeierstrassForm_P2(cubic.subs(t=1, z=1), [x,y]) True """ x, y, z, t = _check_polynomial_P2_112(polynomial, variables) diff --git a/src/sage/schemes/toric/weierstrass_covering.py b/src/sage/schemes/toric/weierstrass_covering.py index fe3c45ed722..5c7b899d93a 100644 --- a/src/sage/schemes/toric/weierstrass_covering.py +++ b/src/sage/schemes/toric/weierstrass_covering.py @@ -161,10 +161,10 @@ def WeierstrassMap(polynomial, variables=None): 1/2*x^6*y^3 - 1/2*x^3*y^6 - 1/2*x^6*z^3 + 1/2*y^6*z^3 + 1/2*x^3*z^6 - 1/2*y^3*z^6, x*y*z) - sage: f, g = WeierstrassForm(cubic); (f,g) - (0, -27/4) - sage: cubic.divides(-Y^2 + X^3 + f*X*Z^4 + g*Z^6) - True + sage: f, g = WeierstrassForm(cubic); (f,g) + (0, -27/4) + sage: cubic.divides(-Y^2 + X^3 + f*X*Z^4 + g*Z^6) + True Only the affine span of the Newton polytope of the polynomial matters. For example:: @@ -192,8 +192,8 @@ def WeierstrassMap(polynomial, variables=None): - 1/27*t^4*z^6 - 4/81*t^2*x^4*y^2 - 4/81*t^2*x^3*y^2*z - 4/81*t^2*x*y^2*z^3 - 4/81*t^2*y^2*z^4 - 2/81*x^2*y^4 - 4/81*x*y^4*z - 2/81*y^4*z^2, - 0, - 1/3*t^2*x^2*z + 1/3*t^2*x*z^2 - 1/9*x*y^2 - 1/9*y^2*z) + 0, + 1/3*t^2*x^2*z + 1/3*t^2*x*z^2 - 1/9*x*y^2 - 1/9*y^2*z) sage: WeierstrassForm(x*y^2 + y^2 + x^3 + 1, transformation=True) (-1/27*x^6 - 4/81*x^4*y^2 - 2/81*x^2*y^4 - 2/27*x^5 - 4/81*x^3*y^2 - 4/81*x*y^4 - 5/27*x^4 - 2/81*y^4 - 8/27*x^3 @@ -280,7 +280,7 @@ def homogenize(inhomog, degree): def WeierstrassMap_P2(polynomial, variables=None): r""" - Map a cubic to its Weierstrass form + Map a cubic to its Weierstrass form. Input/output is the same as :func:`WeierstrassMap`, except that the input polynomial must be a cubic in `\mathbb{P}^2`, @@ -301,7 +301,7 @@ def WeierstrassMap_P2(polynomial, variables=None): sage: from sage.schemes.toric.weierstrass import WeierstrassForm_P2 sage: from sage.schemes.toric.weierstrass_covering import WeierstrassMap_P2 sage: R. = QQ[] - sage: equation = x^3+y^3+z^3+x*y*z + sage: equation = x^3 + y^3 + z^3 + x*y*z sage: f, g = WeierstrassForm_P2(equation) sage: X,Y,Z = WeierstrassMap_P2(equation) sage: equation.divides(-Y^2 + X^3 + f*X*Z^4 + g*Z^6) @@ -310,7 +310,7 @@ def WeierstrassMap_P2(polynomial, variables=None): sage: from sage.schemes.toric.weierstrass import WeierstrassForm_P2 sage: from sage.schemes.toric.weierstrass_covering import WeierstrassMap_P2 sage: R. = QQ[] - sage: equation = x^3+y^3+1 + sage: equation = x^3 + y^3 + 1 sage: f, g = WeierstrassForm_P2(equation) sage: X,Y,Z = WeierstrassMap_P2(equation) sage: equation.divides(-Y^2 + X^3 + f*X*Z^4 + g*Z^6) @@ -344,9 +344,9 @@ def WeierstrassMap_P1xP1(polynomial, variables=None): sage: from sage.schemes.toric.weierstrass_covering import WeierstrassMap_P1xP1 sage: from sage.schemes.toric.weierstrass import WeierstrassForm_P1xP1 - sage: R.= QQ[] - sage: biquadric = ( x0^2*y0^2 + x1^2*y0^2 + x0^2*y1^2 + x1^2*y1^2 + - ....: a * x0*x1*y0*y1*5 ) + sage: R. = QQ[] + sage: biquadric = (x0^2*y0^2 + x1^2*y0^2 + x0^2*y1^2 + x1^2*y1^2 + + ....: a * x0*x1*y0*y1*5) sage: f, g = WeierstrassForm_P1xP1(biquadric, [x0, x1, y0, y1]); (f,g) (-625/48*a^4 + 25/3*a^2 - 16/3, 15625/864*a^6 - 625/36*a^4 - 100/9*a^2 + 128/27) sage: X, Y, Z = WeierstrassMap_P1xP1(biquadric, [x0, x1, y0, y1]) @@ -356,8 +356,8 @@ def WeierstrassMap_P1xP1(polynomial, variables=None): sage: R = PolynomialRing(QQ, 'x,y,s,t', order='lex') sage: R.inject_variables() Defining x, y, s, t - sage: equation = ( s^2*(x^2+2*x*y+3*y^2) + s*t*(4*x^2+5*x*y+6*y^2) - ....: + t^2*(7*x^2+8*x*y+9*y^2) ) + sage: equation = (s^2*(x^2+2*x*y+3*y^2) + s*t*(4*x^2+5*x*y+6*y^2) + ....: + t^2*(7*x^2+8*x*y+9*y^2)) sage: X, Y, Z = WeierstrassMap_P1xP1(equation, [x,y,s,t]) sage: f, g = WeierstrassForm_P1xP1(equation, variables=[x,y,s,t]) sage: (-Y^2 + X^3 + f*X*Z^4 + g*Z^6).reduce(R.ideal(equation)) @@ -429,7 +429,8 @@ def WeierstrassMap_P2_112(polynomial, variables=None): Another example, this time in homogeneous coordinates:: - sage: fan = Fan(rays=[(1,0),(0,1),(-1,-2),(0,-1)],cones=[[0,1],[1,2],[2,3],[3,0]]) + sage: fan = Fan(rays=[(1,0),(0,1),(-1,-2),(0,-1)], + ....: cones=[[0,1],[1,2],[2,3],[3,0]]) sage: P112. = ToricVariety(fan) sage: (-P112.K()).sections_monomials() (z^4*t^2, x*z^3*t^2, x^2*z^2*t^2, x^3*z*t^2, diff --git a/src/sage/schemes/toric/weierstrass_higher.py b/src/sage/schemes/toric/weierstrass_higher.py index 034d3ead9e4..64ae772ab27 100644 --- a/src/sage/schemes/toric/weierstrass_higher.py +++ b/src/sage/schemes/toric/weierstrass_higher.py @@ -11,7 +11,7 @@ quadratic equations in `\mathbb{P}^3` :: sage: R. = QQ[] - sage: quadratic1 = w^2+x^2+y^2 + sage: quadratic1 = w^2 + x^2 + y^2 sage: quadratic2 = z^2 + w*x sage: WeierstrassForm([quadratic1, quadratic2]) (-1/4, 0) @@ -50,7 +50,7 @@ def WeierstrassForm2(polynomial, variables=None, transformation=False): sage: from sage.schemes.toric.weierstrass_higher import WeierstrassForm2 sage: R. = QQ[] - sage: quadratic1 = w^2+x^2+y^2 + sage: quadratic1 = w^2 + x^2 + y^2 sage: quadratic2 = z^2 + w*x sage: WeierstrassForm2([quadratic1, quadratic2]) (-1/4, 0) @@ -87,7 +87,7 @@ def _check_polynomials_P3(quadratic1, quadratic2, variables): sage: from sage.schemes.toric.weierstrass_higher import _check_polynomials_P3 sage: R. = QQ[] - sage: quadratic = w^2+x^2+y^2+z^2 + sage: quadratic = w^2 + x^2 + y^2 + z^2 sage: _check_polynomials_P3(w^2, quadratic, [w,x,y,z]) (w, x, y, z) sage: _check_polynomials_P3(w^2, quadratic, None) @@ -95,7 +95,7 @@ def _check_polynomials_P3(quadratic1, quadratic2, variables): sage: _check_polynomials_P3(z^2, quadratic.subs(w=0), None) (x, y, z, None) sage: R. = QQ[] - sage: quadratic = w^2+x^2+y^2+z^2 + t*(x*y+y*z+z*w+w*x) + sage: quadratic = w^2 + x^2 + y^2 + z^2 + t*(x*y+y*z+z*w+w*x) sage: _check_polynomials_P3(w^2, quadratic, [w,x,y,z]) (w, x, y, z) sage: _check_polynomials_P3(w^2, quadratic, [w,x,y,t]) @@ -157,7 +157,7 @@ def _biquadratic_syzygy_quartic(quadratic1, quadratic2, variables=None): sage: from sage.schemes.toric.weierstrass_higher import _biquadratic_syzygy_quartic sage: R. = QQ[] - sage: _biquadratic_syzygy_quartic(w^2+x^2+y^2, z^2) + sage: _biquadratic_syzygy_quartic(w^2 + x^2 + y^2, z^2) (Joint quaternary quadratic with coefficients (1, 1, 1, 0, 0, 0, 0, 0, 0, 0) and quaternary quadratic with coefficients (0, 0, 0, 1, 0, 0, 0, 0, 0, 0), Binary quartic with coefficients (0, 0, 0, -1, 0), {aux...}) @@ -203,7 +203,7 @@ def WeierstrassForm_P3(quadratic1, quadratic2, variables=None): sage: from sage.schemes.toric.weierstrass_higher import WeierstrassForm_P3 sage: R. = QQ[] - sage: quadratic1 = w^2+x^2+y^2 + sage: quadratic1 = w^2 + x^2 + y^2 sage: quadratic2 = z^2 + w*x sage: WeierstrassForm_P3(quadratic1, quadratic2) (-1/4, 0) @@ -242,7 +242,7 @@ def WeierstrassMap_P3(quadratic1, quadratic2, variables=None): sage: from sage.schemes.toric.weierstrass_higher import \ ....: WeierstrassMap_P3, WeierstrassForm_P3 sage: R. = QQ[] - sage: quadratic1 = w^2+x^2+y^2 + sage: quadratic1 = w^2 + x^2 + y^2 sage: quadratic2 = z^2 + w*x sage: X, Y, Z = WeierstrassMap_P3(quadratic1, quadratic2) sage: X @@ -262,17 +262,17 @@ def WeierstrassMap_P3(quadratic1, quadratic2, variables=None): TESTS:: - sage: R. = GF(101)[] - sage: p1 = w^2 + x^2 + y^2 + z^2 - sage: p2 = a0*w^2 + a1*x^2 + a2*y^2 + a3*z^2 - sage: X, Y, Z = WeierstrassMap_P3(p1, p2, [w,x,y,z]) - sage: X.total_degree(), len(X.coefficients()) + sage: R. = GF(101)[] # optional - sage.rings.finite_rings + sage: p1 = w^2 + x^2 + y^2 + z^2 # optional - sage.rings.finite_rings + sage: p2 = a0*w^2 + a1*x^2 + a2*y^2 + a3*z^2 # optional - sage.rings.finite_rings + sage: X, Y, Z = WeierstrassMap_P3(p1, p2, [w,x,y,z]) # optional - sage.rings.finite_rings + sage: X.total_degree(), len(X.coefficients()) # optional - sage.rings.finite_rings (22, 4164) - sage: Y.total_degree(), len(Y.coefficients()) + sage: Y.total_degree(), len(Y.coefficients()) # optional - sage.rings.finite_rings (33, 26912) - sage: Z.total_degree(), len(Z.coefficients()) + sage: Z.total_degree(), len(Z.coefficients()) # optional - sage.rings.finite_rings (10, 24) - sage: Z + sage: Z # optional - sage.rings.finite_rings w*x*y*z*a0^3*a1^2*a2 - w*x*y*z*a0^2*a1^3*a2 - w*x*y*z*a0^3*a1*a2^2 + w*x*y*z*a0*a1^3*a2^2 + w*x*y*z*a0^2*a1*a2^3 - w*x*y*z*a0*a1^2*a2^3 - w*x*y*z*a0^3*a1^2*a3 + w*x*y*z*a0^2*a1^3*a3 + w*x*y*z*a0^3*a2^2*a3