def rational_points(self, F=None): """ Return the list of `F`-rational points on the affine space self, where `F` is a given finite field, or the base ring of self. EXAMPLES:: sage: A = AffineSpace(1, GF(3)) sage: A.rational_points() [(0), (1), (2)] sage: A.rational_points(GF(3^2, 'b')) [(0), (b), (b + 1), (2*b + 1), (2), (2*b), (2*b + 2), (b + 2), (1)] sage: AffineSpace(2, ZZ).rational_points(GF(2)) [(0, 0), (1, 0), (0, 1), (1, 1)] TESTS:: sage: AffineSpace(2, QQ).rational_points() Traceback (most recent call last): ... TypeError: Base ring (= Rational Field) must be a finite field. sage: AffineSpace(1, GF(3)).rational_points(ZZ) Traceback (most recent call last): ... TypeError: Second argument (= Integer Ring) must be a finite field. """ if F == None: if not is_FiniteField(self.base_ring()): raise TypeError("Base ring (= %s) must be a finite field."%self.base_ring()) return [ P for P in self ] elif not is_FiniteField(F): raise TypeError("Second argument (= %s) must be a finite field."%F) return [ P for P in self.base_extend(F) ]
def rational_points(self, F=None): """ Return the list of `F`-rational points on the affine space self, where `F` is a given finite field, or the base ring of self. EXAMPLES:: sage: A = AffineSpace(1, GF(3)) sage: A.rational_points() [(0), (1), (2)] sage: A.rational_points(GF(3^2, 'b')) [(0), (b), (b + 1), (2*b + 1), (2), (2*b), (2*b + 2), (b + 2), (1)] sage: AffineSpace(2, ZZ).rational_points(GF(2)) [(0, 0), (1, 0), (0, 1), (1, 1)] TESTS:: sage: AffineSpace(2, QQ).rational_points() Traceback (most recent call last): ... TypeError: Base ring (= Rational Field) must be a finite field. sage: AffineSpace(1, GF(3)).rational_points(ZZ) Traceback (most recent call last): ... TypeError: Second argument (= Integer Ring) must be a finite field. """ if F is None: if not is_FiniteField(self.base_ring()): raise TypeError("Base ring (= %s) must be a finite field."%self.base_ring()) return [ P for P in self ] elif not is_FiniteField(F): raise TypeError("Second argument (= %s) must be a finite field."%F) return [ P for P in self.base_extend(F) ]
def points(self, B=0): """ Return some or all rational points of a projective scheme. INPUT: - `B` -- integer (optional, default=0). The bound for the coordinates. OUTPUT: A list of points. Over a finite field, all points are returned. Over an infinite field, all points satisfying the bound are returned. EXAMPLES:: sage: P1 = ProjectiveSpace(GF(2),1) sage: F.<a> = GF(4,'a') sage: P1(F).points() [(0 : 1), (1 : 0), (1 : 1), (a : 1), (a + 1 : 1)] """ from sage.schemes.projective.projective_rational_point import enum_projective_rational_field from sage.schemes.projective.projective_rational_point import enum_projective_finite_field R = self.value_ring() if is_RationalField(R): if not B > 0: raise TypeError( "A positive bound B (= %s) must be specified." % B) return enum_projective_rational_field(self, B) elif is_FiniteField(R): return enum_projective_finite_field(self.extended_codomain()) else: raise TypeError("Unable to enumerate points over %s." % R)
def __init__(self, degree, base_ring, category=None): """ Base class for matrix groups over generic base rings You should not use this class directly. Instead, use one of the more specialized derived classes. INPUT: - ``degree`` -- integer. The degree (matrix size) of the matrix group. - ``base_ring`` -- ring. The base ring of the matrices. TESTS:: sage: G = GL(2, QQ) sage: from sage.groups.matrix_gps.matrix_group import MatrixGroup_generic sage: isinstance(G, MatrixGroup_generic) True """ assert is_Ring(base_ring) assert is_Integer(degree) self._deg = degree if self._deg <= 0: raise ValueError('the degree must be at least 1') if (category is None) and is_FiniteField(base_ring): from sage.categories.finite_groups import FiniteGroups category = FiniteGroups() super(MatrixGroup_generic, self).__init__(base=base_ring, category=category)
def _single_variate(base_ring, name, sparse, implementation): import sage.rings.polynomial.polynomial_ring as m name = normalize_names(1, name) key = (base_ring, name, sparse, implementation if not sparse else None) R = _get_from_cache(key) if not R is None: return R if isinstance(base_ring, ring.CommutativeRing): if is_IntegerModRing(base_ring) and not sparse: n = base_ring.order() if n.is_prime(): R = m.PolynomialRing_dense_mod_p(base_ring, name, implementation=implementation) elif n > 1: R = m.PolynomialRing_dense_mod_n(base_ring, name, implementation=implementation) else: # n == 1! R = m.PolynomialRing_integral_domain( base_ring, name) # specialized code breaks in this case. elif is_FiniteField(base_ring) and not sparse: R = m.PolynomialRing_dense_finite_field( base_ring, name, implementation=implementation) elif isinstance(base_ring, padic_base_leaves.pAdicFieldCappedRelative): R = m.PolynomialRing_dense_padic_field_capped_relative( base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedRelative): R = m.PolynomialRing_dense_padic_ring_capped_relative( base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedAbsolute): R = m.PolynomialRing_dense_padic_ring_capped_absolute( base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingFixedMod): R = m.PolynomialRing_dense_padic_ring_fixed_mod(base_ring, name) elif base_ring.is_field(proof=False): R = m.PolynomialRing_field(base_ring, name, sparse) elif base_ring.is_integral_domain(proof=False): R = m.PolynomialRing_integral_domain(base_ring, name, sparse, implementation) else: R = m.PolynomialRing_commutative(base_ring, name, sparse) else: R = m.PolynomialRing_general(base_ring, name, sparse) if hasattr(R, '_implementation_names'): for name in R._implementation_names: real_key = key[0:3] + (name, ) _save_in_cache(real_key, R) else: _save_in_cache(key, R) return R
def points(self, B=0): """ Return some or all rational points of a projective scheme. INPUT: - `B` -- integer (optional, default=0). The bound for the coordinates. OUTPUT: A list of points. Over a finite field, all points are returned. Over an infinite field, all points satisfying the bound are returned. EXAMPLES:: sage: P1 = ProjectiveSpace(GF(2),1) sage: F.<a> = GF(4,'a') sage: P1(F).points() [(0 : 1), (1 : 0), (1 : 1), (a : 1), (a + 1 : 1)] """ from sage.schemes.projective.projective_rational_point import enum_projective_rational_field from sage.schemes.projective.projective_rational_point import enum_projective_finite_field R = self.value_ring() if is_RationalField(R): if not B > 0: raise TypeError("A positive bound B (= %s) must be specified."%B) return enum_projective_rational_field(self,B) elif is_FiniteField(R): return enum_projective_finite_field(self.extended_codomain()) else: raise TypeError("Unable to enumerate points over %s."%R)
def AffineSpace(n, R=None, names='x'): r""" Return affine space of dimension `n` over the ring `R`. EXAMPLES: The dimension and ring can be given in either order:: sage: AffineSpace(3, QQ, 'x') Affine Space of dimension 3 over Rational Field sage: AffineSpace(5, QQ, 'x') Affine Space of dimension 5 over Rational Field sage: A = AffineSpace(2, QQ, names='XY'); A Affine Space of dimension 2 over Rational Field sage: A.coordinate_ring() Multivariate Polynomial Ring in X, Y over Rational Field Use the divide operator for base extension:: sage: AffineSpace(5, names='x')/GF(17) Affine Space of dimension 5 over Finite Field of size 17 The default base ring is `\ZZ`:: sage: AffineSpace(5, names='x') Affine Space of dimension 5 over Integer Ring There is also an affine space associated to each polynomial ring:: sage: R = GF(7)['x,y,z'] sage: A = AffineSpace(R); A Affine Space of dimension 3 over Finite Field of size 7 sage: A.coordinate_ring() is R True """ if is_MPolynomialRing(n) and R is None: R = n A = AffineSpace(R.ngens(), R.base_ring(), R.variable_names()) A._coordinate_ring = R return A if isinstance(R, (int, long, Integer)): n, R = R, n if R is None: R = ZZ # default is the integers if names is None: if n == 0: names = '' else: raise TypeError( "You must specify the variables names of the coordinate ring.") names = normalize_names(n, names) if R in _Fields: if is_FiniteField(R): return AffineSpace_finite_field(n, R, names) else: return AffineSpace_field(n, R, names) return AffineSpace_generic(n, R, names)
def AffineSpace(n, R=None, names='x'): r""" Return affine space of dimension `n` over the ring `R`. EXAMPLES: The dimension and ring can be given in either order:: sage: AffineSpace(3, QQ, 'x') Affine Space of dimension 3 over Rational Field sage: AffineSpace(5, QQ, 'x') Affine Space of dimension 5 over Rational Field sage: A = AffineSpace(2, QQ, names='XY'); A Affine Space of dimension 2 over Rational Field sage: A.coordinate_ring() Multivariate Polynomial Ring in X, Y over Rational Field Use the divide operator for base extension:: sage: AffineSpace(5, names='x')/GF(17) Affine Space of dimension 5 over Finite Field of size 17 The default base ring is `\ZZ`:: sage: AffineSpace(5, names='x') Affine Space of dimension 5 over Integer Ring There is also an affine space associated to each polynomial ring:: sage: R = GF(7)['x,y,z'] sage: A = AffineSpace(R); A Affine Space of dimension 3 over Finite Field of size 7 sage: A.coordinate_ring() is R True """ if is_MPolynomialRing(n) and R is None: R = n A = AffineSpace(R.ngens(), R.base_ring(), R.variable_names()) A._coordinate_ring = R return A if isinstance(R, (int, long, Integer)): n, R = R, n if R is None: R = ZZ # default is the integers if names is None: if n == 0: names = '' else: raise TypeError("You must specify the variables names of the coordinate ring.") names = normalize_names(n, names) if R in _Fields: if is_FiniteField(R): return AffineSpace_finite_field(n, R, names) else: return AffineSpace_field(n, R, names) return AffineSpace_generic(n, R, names)
def points(self, B=0): r""" Return some or all rational points of an affine scheme. INPUT: - ``B`` -- integer (optional, default: 0). The bound for the height of the coordinates. OUTPUT: - If the base ring is a finite field: all points of the scheme, given by coordinate tuples. - If the base ring is `\QQ` or `\ZZ`: the subset of points whose coordinates have height ``B`` or less. EXAMPLES: The bug reported at #11526 is fixed:: sage: A2 = AffineSpace(ZZ,2) sage: F = GF(3) sage: A2(F).points() [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] sage: R = ZZ sage: A.<x,y> = R[] sage: I = A.ideal(x^2-y^2-1) sage: V = AffineSpace(R,2) sage: X = V.subscheme(I) sage: M = X(R) sage: M.points(1) [(-1, 0), (1, 0)] :: sage: u = QQ['u'].0 sage: K.<v> = NumberField(u^2 + 3) sage: A.<x,y> = AffineSpace(K,2) sage: len(A(K).points(9)) 361 """ R = self.value_ring() if is_RationalField(R) or R == ZZ: if not B > 0: raise TypeError("A positive bound B (= %s) must be specified."%B) from sage.schemes.affine.affine_rational_point import enum_affine_rational_field return enum_affine_rational_field(self,B) if R in NumberFields(): from sage.schemes.affine.affine_rational_point import enum_affine_number_field return enum_affine_number_field(self,B) elif is_FiniteField(R): from sage.schemes.affine.affine_rational_point import enum_affine_finite_field return enum_affine_finite_field(self) else: raise TypeError("Unable to enumerate points over %s."%R)
def points(self, B=0): """ Return some or all rational points of a projective scheme. INPUT: - `B` -- integer (optional, default=0). The bound for the coordinates. OUTPUT: A list of points. Over a finite field, all points are returned. Over an infinite field, all points satisfying the bound are returned. EXAMPLES:: sage: P.<x,y> = ProjectiveSpace(QQ,1) sage: P(QQ).points(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)] :: sage: u = QQ['u'].0 sage: K.<v> = NumberField(u^2 + 3) sage: P.<x,y,z> = ProjectiveSpace(K,2) sage: len(P(K).points(9)) 381 :: sage: P1 = ProjectiveSpace(GF(2),1) sage: F.<a> = GF(4,'a') sage: P1(F).points() [(0 : 1), (1 : 0), (1 : 1), (a : 1), (a + 1 : 1)] """ R = self.value_ring() if is_RationalField(R): if not B > 0: raise TypeError("A positive bound B (= %s) must be specified."%B) from sage.schemes.projective.projective_rational_point import enum_projective_rational_field return enum_projective_rational_field(self,B) elif R in NumberFields(): from sage.schemes.projective.projective_rational_point import enum_projective_number_field return enum_projective_number_field(self,B) elif is_FiniteField(R): from sage.schemes.projective.projective_rational_point import enum_projective_finite_field return enum_projective_finite_field(self.extended_codomain()) else: raise TypeError("Unable to enumerate points over %s."%R)
def _single_variate(base_ring, name, sparse, implementation): import sage.rings.polynomial.polynomial_ring as m name = normalize_names(1, name) key = (base_ring, name, sparse, implementation if not sparse else None) R = _get_from_cache(key) if not R is None: return R if isinstance(base_ring, ring.CommutativeRing): if is_IntegerModRing(base_ring) and not sparse: n = base_ring.order() if n.is_prime(): R = m.PolynomialRing_dense_mod_p(base_ring, name, implementation=implementation) elif n > 1: R = m.PolynomialRing_dense_mod_n(base_ring, name, implementation=implementation) else: # n == 1! R = m.PolynomialRing_integral_domain(base_ring, name) # specialized code breaks in this case. elif is_FiniteField(base_ring) and not sparse: R = m.PolynomialRing_dense_finite_field(base_ring, name, implementation=implementation) elif isinstance(base_ring, padic_base_leaves.pAdicFieldCappedRelative): R = m.PolynomialRing_dense_padic_field_capped_relative(base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedRelative): R = m.PolynomialRing_dense_padic_ring_capped_relative(base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedAbsolute): R = m.PolynomialRing_dense_padic_ring_capped_absolute(base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingFixedMod): R = m.PolynomialRing_dense_padic_ring_fixed_mod(base_ring, name) elif base_ring.is_field(proof=False): R = m.PolynomialRing_field(base_ring, name, sparse) elif base_ring.is_integral_domain(proof=False): R = m.PolynomialRing_integral_domain(base_ring, name, sparse, implementation) else: R = m.PolynomialRing_commutative(base_ring, name, sparse) else: R = m.PolynomialRing_general(base_ring, name, sparse) if hasattr(R, "_implementation_names"): for name in R._implementation_names: real_key = key[0:3] + (name,) _save_in_cache(real_key, R) else: _save_in_cache(key, R) return R
def points(self, B=0): from sage.schemes.generic.rational_point import enum_projective_rational_field from sage.schemes.generic.rational_point import enum_projective_finite_field try: R = self.value_ring() except TypeError: raise TypeError, "Domain of argument must be of the form Spec(S)." if is_RationalField(R): if not B > 0: raise TypeError, "A positive bound B (= %s) must be specified." % B return enum_projective_rational_field(self, B) elif is_FiniteField(R): return enum_projective_finite_field(self) else: raise TypeError, "Unable to enumerate points over %s." % R
def points(self, B=0): r""" Return some or all rational points of an affine scheme. INPUT: - ``B`` -- integer (optional, default: 0). The bound for the height of the coordinates. OUTPUT: - If the base ring is a finite field: all points of the scheme, given by coordinate tuples. - If the base ring is `\QQ` or `\ZZ`: the subset of points whose coordinates have height ``B`` or less. EXAMPLES: The bug reported at #11526 is fixed:: sage: A2 = AffineSpace(ZZ,2) sage: F = GF(3) sage: A2(F).points() [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] sage: R = ZZ sage: A.<x,y> = R[] sage: I = A.ideal(x^2-y^2-1) sage: V = AffineSpace(R,2) sage: X = V.subscheme(I) sage: M = X(R) sage: M.points(1) [(-1, 0), (1, 0)] """ R = self.value_ring() if is_RationalField(R) or R == ZZ: if not B > 0: raise TypeError( "A positive bound B (= %s) must be specified." % B) from sage.schemes.affine.affine_rational_point import enum_affine_rational_field return enum_affine_rational_field(self, B) elif is_FiniteField(R): from sage.schemes.affine.affine_rational_point import enum_affine_finite_field return enum_affine_finite_field(self) else: raise TypeError("Unable to enumerate points over %s." % R)
def rational_points(self, F=None): """ Return the list of `F`-rational points on the affine space self, where `F` is a given finite field, or the base ring of self. EXAMPLES:: sage: P = ProjectiveSpace(1, GF(3)) sage: P.rational_points() [(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)] """ if F is None: return [ P for P in self ] elif not is_FiniteField(F): raise TypeError("Second argument (= %s) must be a finite field."%F) return [ P for P in self.base_extend(F) ]
def rational_points(self, F=None): """ Return the list of `F`-rational points on the affine space self, where `F` is a given finite field, or the base ring of self. EXAMPLES:: sage: P = ProjectiveSpace(1, GF(3)) sage: P.rational_points() [(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)] """ if F is None: return [P for P in self] elif not is_FiniteField(F): raise TypeError("Second argument (= %s) must be a finite field." % F) return [P for P in self.base_extend(F)]
def points(self, B=0): r""" Return the set of points given by coordinate tuples with coordinates in the base ring. INPUT: - ``B`` -- an integer. OUTPUT: - If the base ring is a finite field: the set of points given by coordinate tuples. - If the base ring is `\QQ` or `\ZZ`: the subset of points whose coordinates have height ``B`` or less. EXAMPLES: The bug reported at #11526 is fixed:: sage: R = ZZ sage: A.<x,y> = R[] sage: I = A.ideal(x^2-y^2-1) sage: V = AffineSpace(R,2) sage: X = V.subscheme(I) sage: M = X(R) sage: M.points(1) [(-1, 0), (1, 0)] """ try: R = self.value_ring() except TypeError: raise TypeError, "Domain of argument must be of the form Spec(S)." if is_RationalField(R) or R == ZZ: if not B > 0: raise TypeError, "A positive bound B (= %s) must be specified." % B from sage.schemes.generic.rational_point import enum_affine_rational_field return enum_affine_rational_field(self, B) elif is_FiniteField(R): from sage.schemes.generic.rational_point import enum_affine_finite_field return enum_affine_finite_field(self) else: raise TypeError, "Unable to enumerate points over %s." % R
def create_object(self, version, key, **kwds): """ Create an object from a ``UniqueFactory`` key. EXAMPLES:: sage: E = EllipticCurve.create_object(0, (GF(3), (1, 2, 0, 1, 2))) sage: type(E) <class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'> .. NOTE:: Keyword arguments are currently only passed to the constructor for elliptic curves over `\\QQ`; elliptic curves over other fields do not support them. """ R, x = key if R is rings.QQ: from ell_rational_field import EllipticCurve_rational_field return EllipticCurve_rational_field(x, **kwds) elif is_NumberField(R): from ell_number_field import EllipticCurve_number_field return EllipticCurve_number_field(R, x) elif rings.is_pAdicField(R): from ell_padic_field import EllipticCurve_padic_field return EllipticCurve_padic_field(R, x) elif is_FiniteField(R) or (is_IntegerModRing(R) and R.characteristic().is_prime()): from ell_finite_field import EllipticCurve_finite_field return EllipticCurve_finite_field(R, x) elif R in _Fields: from ell_field import EllipticCurve_field return EllipticCurve_field(R, x) from ell_generic import EllipticCurve_generic return EllipticCurve_generic(R, x)
def lfsr_sequence(key, fill, n): r""" This function creates an lfsr sequence. INPUT: - ``key`` - a list of finite field elements, [c_0,c_1,...,c_k]. - ``fill`` - the list of the initial terms of the lfsr sequence, [x_0,x_1,...,x_k]. - ``n`` - number of terms of the sequence that the function returns. OUTPUT: The lfsr sequence defined by `x_{n+1} = c_kx_n+...+c_0x_{n-k}`, for `n \leq k`. EXAMPLES:: sage: F = GF(2); l = F(1); o = F(0) sage: F = GF(2); S = LaurentSeriesRing(F,'x'); x = S.gen() sage: fill = [l,l,o,l]; key = [1,o,o,l]; n = 20 sage: L = lfsr_sequence(key,fill,20); L [1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0] sage: g = berlekamp_massey(L); g x^4 + x^3 + 1 sage: (1)/(g.reverse()+O(x^20)) 1 + x + x^2 + x^3 + x^5 + x^7 + x^8 + x^11 + x^15 + x^16 + x^17 + x^18 + O(x^20) sage: (1+x^2)/(g.reverse()+O(x^20)) 1 + x + x^4 + x^8 + x^9 + x^10 + x^11 + x^13 + x^15 + x^16 + x^19 + O(x^20) sage: (1+x^2+x^3)/(g.reverse()+O(x^20)) 1 + x + x^3 + x^5 + x^6 + x^9 + x^13 + x^14 + x^15 + x^16 + x^18 + O(x^20) sage: fill = [l,l,o,l]; key = [l,o,o,o]; n = 20 sage: L = lfsr_sequence(key,fill,20); L [1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1] sage: g = berlekamp_massey(L); g x^4 + 1 sage: (1+x)/(g.reverse()+O(x^20)) 1 + x + x^4 + x^5 + x^8 + x^9 + x^12 + x^13 + x^16 + x^17 + O(x^20) sage: (1+x+x^3)/(g.reverse()+O(x^20)) 1 + x + x^3 + x^4 + x^5 + x^7 + x^8 + x^9 + x^11 + x^12 + x^13 + x^15 + x^16 + x^17 + x^19 + O(x^20) AUTHORS: - Timothy Brock (2005-11): with code modified from Python Cookbook, http://aspn.activestate.com/ASPN/Python/Cookbook/ """ if not isinstance(key, list): raise TypeError, "key must be a list" key = Sequence(key) F = key.universe() if not is_FiniteField(F): raise TypeError, "universe of sequence must be a finite field" s = fill k = len(fill) L = [] for i in range(n): s0 = copy.copy(s) L.append(s[0]) s = s[1:k] s.append(sum([key[i] * s0[i] for i in range(k)])) return L
def points(self, B=0): r""" Return some or all rational points of an affine scheme. INPUT: - ``B`` -- integer (optional, default: 0). The bound for the height of the coordinates. OUTPUT: - If the base ring is a finite field: all points of the scheme, given by coordinate tuples. - If the base ring is `\QQ` or `\ZZ`: the subset of points whose coordinates have height ``B`` or less. EXAMPLES: The bug reported at #11526 is fixed:: sage: A2 = AffineSpace(ZZ,2) sage: F = GF(3) sage: A2(F).points() [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] sage: R = ZZ sage: A.<x,y> = R[] sage: I = A.ideal(x^2-y^2-1) sage: V = AffineSpace(R,2) sage: X = V.subscheme(I) sage: M = X(R) sage: M.points(1) [(-1, 0), (1, 0)] :: sage: u = QQ['u'].0 sage: K.<v> = NumberField(u^2 + 3) sage: A.<x,y> = AffineSpace(K,2) sage: len(A(K).points(9)) 361 :: sage: A.<x,y> = AffineSpace(QQ,2) sage: E = A.subscheme([x^2 + y^2 - 1, y^2 - x^3 + x^2 + x - 1]) sage: E(A.base_ring()).points() [(-1, 0), (0, -1), (0, 1), (1, 0)] """ X = self.codomain() from sage.schemes.affine.affine_space import is_AffineSpace if not is_AffineSpace(X) and X.base_ring() in Fields(): # Then X must be a subscheme dim_ideal = X.defining_ideal().dimension() if dim_ideal < 0: # no points return [] if dim_ideal == 0: # if X zero-dimensional N = len(X.ambient_space().gens()) S = X.defining_polynomials()[0].parent() R = PolynomialRing(S.base_ring(),'s',N,order='lex') phi = S.hom(R.gens(),R) J = R.ideal([phi(t) for t in X.defining_polynomials()]) D = J.variety() points = [] for d in D: P = [d[t] for t in R.gens()] points.append(X(P)) points.sort() return points R = self.value_ring() if is_RationalField(R) or R == ZZ: if not B > 0: raise TypeError("A positive bound B (= %s) must be specified."%B) from sage.schemes.affine.affine_rational_point import enum_affine_rational_field return enum_affine_rational_field(self,B) if R in NumberFields(): if not B > 0: raise TypeError("A positive bound B (= %s) must be specified."%B) from sage.schemes.affine.affine_rational_point import enum_affine_number_field return enum_affine_number_field(self,B) elif is_FiniteField(R): from sage.schemes.affine.affine_rational_point import enum_affine_finite_field return enum_affine_finite_field(self) else: raise TypeError("Unable to enumerate points over %s."%R)
def points(self, B=0, prec=53): """ Return some or all rational points of a projective scheme. INPUT: - `B` - integer (optional, default=0). The bound for the coordinates. - ``prec`` - he precision to use to compute the elements of bounded height for number fields OUTPUT: A list of points. Over a finite field, all points are returned. Over an infinite field, all points satisfying the bound are returned. .. WARNING:: In the current implementation, the output of the [Doyle-Krumm] algorithm cannot be guaranteed to be correct due to the necessity of floating point computations. In some cases, the default 53-bit precision is considerably lower than would be required for the algorithm to generate correct output. EXAMPLES:: sage: P.<x,y> = ProjectiveSpace(QQ,1) sage: P(QQ).points(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)] :: sage: u = QQ['u'].0 sage: K.<v> = NumberField(u^2 + 3) sage: P.<x,y,z> = ProjectiveSpace(K,2) sage: len(P(K).points(1.8)) 381 :: sage: P1 = ProjectiveSpace(GF(2),1) sage: F.<a> = GF(4,'a') sage: P1(F).points() [(0 : 1), (1 : 0), (1 : 1), (a : 1), (a + 1 : 1)] :: sage: P.<x,y,z> = 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)] """ X = self.codomain() from sage.schemes.projective.projective_space import is_ProjectiveSpace if not is_ProjectiveSpace(X) and X.base_ring() in Fields(): #Then it must be a subscheme dim_ideal = X.defining_ideal().dimension() if dim_ideal < 1: # no points return [] if dim_ideal == 1: # if X zero-dimensional points = set() for i in range(X.ambient_space().dimension_relative() + 1): Y = X.affine_patch(i) phi = Y.projective_embedding() aff_points = Y.rational_points() for PP in aff_points: points.add(X.ambient_space()(list(phi(PP)))) points = sorted(points) return points R = self.value_ring() if is_RationalField(R): if not B > 0: raise TypeError("A positive bound B (= %s) must be specified."%B) from sage.schemes.projective.projective_rational_point import enum_projective_rational_field return enum_projective_rational_field(self,B) elif R in NumberFields(): if not B > 0: raise TypeError("A positive bound B (= %s) must be specified."%B) from sage.schemes.projective.projective_rational_point import enum_projective_number_field return enum_projective_number_field(self,B, prec=prec) elif is_FiniteField(R): from sage.schemes.projective.projective_rational_point import enum_projective_finite_field return enum_projective_finite_field(self.extended_codomain()) else: raise TypeError("Unable to enumerate points over %s."%R)
def lfsr_sequence(key, fill, n): r""" This function creates an lfsr sequence. INPUT: - ``key`` - a list of finite field elements, [c_0,c_1,...,c_k]. - ``fill`` - the list of the initial terms of the lfsr sequence, [x_0,x_1,...,x_k]. - ``n`` - number of terms of the sequence that the function returns. OUTPUT: The lfsr sequence defined by `x_{n+1} = c_kx_n+...+c_0x_{n-k}`, for `n \leq k`. EXAMPLES:: sage: F = GF(2); l = F(1); o = F(0) sage: F = GF(2); S = LaurentSeriesRing(F,'x'); x = S.gen() sage: fill = [l,l,o,l]; key = [1,o,o,l]; n = 20 sage: L = lfsr_sequence(key,fill,20); L [1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0] sage: g = berlekamp_massey(L); g x^4 + x^3 + 1 sage: (1)/(g.reverse()+O(x^20)) 1 + x + x^2 + x^3 + x^5 + x^7 + x^8 + x^11 + x^15 + x^16 + x^17 + x^18 + O(x^20) sage: (1+x^2)/(g.reverse()+O(x^20)) 1 + x + x^4 + x^8 + x^9 + x^10 + x^11 + x^13 + x^15 + x^16 + x^19 + O(x^20) sage: (1+x^2+x^3)/(g.reverse()+O(x^20)) 1 + x + x^3 + x^5 + x^6 + x^9 + x^13 + x^14 + x^15 + x^16 + x^18 + O(x^20) sage: fill = [l,l,o,l]; key = [l,o,o,o]; n = 20 sage: L = lfsr_sequence(key,fill,20); L [1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1] sage: g = berlekamp_massey(L); g x^4 + 1 sage: (1+x)/(g.reverse()+O(x^20)) 1 + x + x^4 + x^5 + x^8 + x^9 + x^12 + x^13 + x^16 + x^17 + O(x^20) sage: (1+x+x^3)/(g.reverse()+O(x^20)) 1 + x + x^3 + x^4 + x^5 + x^7 + x^8 + x^9 + x^11 + x^12 + x^13 + x^15 + x^16 + x^17 + x^19 + O(x^20) AUTHORS: - Timothy Brock (2005-11): with code modified from Python Cookbook, http://aspn.activestate.com/ASPN/Python/Cookbook/ """ if not isinstance(key, list): raise TypeError, "key must be a list" key = Sequence(key) F = key.universe() if not is_FiniteField(F): raise TypeError, "universe of sequence must be a finite field" s = fill k = len(fill) L = [] for i in range(n): s0 = copy.copy(s) L.append(s[0]) s = s[1:k] s.append(sum([key[i]*s0[i] for i in range(k)])) return L
def ProjectiveSpace(n, R=None, names='x'): r""" Return projective space of dimension `n` over the ring `R`. EXAMPLES: The dimension and ring can be given in either order. :: sage: ProjectiveSpace(3, QQ) Projective Space of dimension 3 over Rational Field sage: ProjectiveSpace(5, QQ) Projective Space of dimension 5 over Rational Field sage: P = ProjectiveSpace(2, QQ, names='XYZ'); P Projective Space of dimension 2 over Rational Field sage: P.coordinate_ring() Multivariate Polynomial Ring in X, Y, Z over Rational Field The divide operator does base extension. :: sage: ProjectiveSpace(5)/GF(17) Projective Space of dimension 5 over Finite Field of size 17 The default base ring is `\ZZ`. :: sage: ProjectiveSpace(5) Projective Space of dimension 5 over Integer Ring There is also an projective space associated each polynomial ring. :: sage: R = GF(7)['x,y,z'] sage: P = ProjectiveSpace(R); P Projective Space of dimension 2 over Finite Field of size 7 sage: P.coordinate_ring() Multivariate Polynomial Ring in x, y, z over Finite Field of size 7 sage: P.coordinate_ring() is R True :: sage: ProjectiveSpace(3, Zp(5), 'y') Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20 :: sage: ProjectiveSpace(2,QQ,'x,y,z') Projective Space of dimension 2 over Rational Field :: sage: PS.<x,y>=ProjectiveSpace(1,CC) sage: PS Projective Space of dimension 1 over Complex Field with 53 bits of precision Projective spaces are not cached, i.e., there can be several with the same base ring and dimension (to facilitate gluing constructions). """ if is_MPolynomialRing(n) and R is None: A = ProjectiveSpace(n.ngens() - 1, n.base_ring()) A._coordinate_ring = n return A if isinstance(R, (int, long, Integer)): n, R = R, n if R is None: R = ZZ # default is the integers if R in _Fields: if is_FiniteField(R): return ProjectiveSpace_finite_field(n, R, names) if is_RationalField(R): return ProjectiveSpace_rational_field(n, R, names) else: return ProjectiveSpace_field(n, R, names) elif is_CommutativeRing(R): return ProjectiveSpace_ring(n, R, names) else: raise TypeError("R (=%s) must be a commutative ring" % R)
def MatrixGroup(gens): r""" Return the matrix group with given generators. INPUT: - ``gens`` - list of matrices in a matrix space or matrix group EXAMPLES:: sage: F = GF(5) sage: gens = [matrix(F,2,[1,2, -1, 1]), matrix(F,2, [1,1, 0,1])] sage: G = MatrixGroup(gens); G Matrix group over Finite Field of size 5 with 2 generators: [[[1, 2], [4, 1]], [[1, 1], [0, 1]]] In the second example, the generators are a matrix over `\ZZ`, a matrix over a finite field, and the integer `2`. Sage determines that they both canonically map to matrices over the finite field, so creates that matrix group there. :: sage: gens = [matrix(2,[1,2, -1, 1]), matrix(GF(7), 2, [1,1, 0,1]), 2] sage: G = MatrixGroup(gens); G Matrix group over Finite Field of size 7 with 3 generators: [[[1, 2], [6, 1]], [[1, 1], [0, 1]], [[2, 0], [0, 2]]] Each generator must be invertible:: sage: G = MatrixGroup([matrix(ZZ,2,[1,2,3,4])]) Traceback (most recent call last): ... ValueError: each generator must be an invertible matrix but one is not: [1 2] [3 4] Some groups aren't supported:: sage: SL(2, CC).gens() Traceback (most recent call last): ... NotImplementedError: Matrix group over Complex Field with 53 bits of precision not implemented. sage: G = SL(0, QQ) Traceback (most recent call last): ... ValueError: The degree must be at least 1 """ if len(gens) == 0: raise ValueError, "gens must have positive length" try: R = gens[0].base_ring() except AttributeError: raise TypeError, "gens must be a list of matrices" for i in range(len(gens)): if not is_Matrix(gens[i]): try: gens[i] = gens[i].matrix() except AttributeError: pass if is_FiniteField(R): return MatrixGroup_gens_finite_field(gens) else: return MatrixGroup_gens(gens)
def Curve(F): """ Return the plane or space curve defined by `F`, where `F` can be either a multivariate polynomial, a list or tuple of polynomials, or an algebraic scheme. If `F` is in two variables the curve is affine, and if it is homogenous in `3` variables, then the curve is projective. EXAMPLE: A projective plane curve :: sage: x,y,z = QQ['x,y,z'].gens() sage: C = Curve(x^3 + y^3 + z^3); C Projective Curve over Rational Field defined by x^3 + y^3 + z^3 sage: C.genus() 1 EXAMPLE: Affine plane curves :: sage: x,y = GF(7)['x,y'].gens() sage: C = Curve(y^2 + x^3 + x^10); C Affine Curve over Finite Field of size 7 defined by x^10 + x^3 + y^2 sage: C.genus() 0 sage: x, y = QQ['x,y'].gens() sage: Curve(x^3 + y^3 + 1) Affine Curve over Rational Field defined by x^3 + y^3 + 1 EXAMPLE: A projective space curve :: sage: x,y,z,w = QQ['x,y,z,w'].gens() sage: C = Curve([x^3 + y^3 - z^3 - w^3, x^5 - y*z^4]); C Projective Space Curve over Rational Field defined by x^3 + y^3 - z^3 - w^3, x^5 - y*z^4 sage: C.genus() 13 EXAMPLE: An affine space curve :: sage: x,y,z = QQ['x,y,z'].gens() sage: C = Curve([y^2 + x^3 + x^10 + z^7, x^2 + y^2]); C Affine Space Curve over Rational Field defined by x^10 + z^7 + x^3 + y^2, x^2 + y^2 sage: C.genus() 47 EXAMPLE: We can also make non-reduced non-irreducible curves. :: sage: x,y,z = QQ['x,y,z'].gens() sage: Curve((x-y)*(x+y)) Projective Conic Curve over Rational Field defined by x^2 - y^2 sage: Curve((x-y)^2*(x+y)^2) Projective Curve over Rational Field defined by x^4 - 2*x^2*y^2 + y^4 EXAMPLE: A union of curves is a curve. :: sage: x,y,z = QQ['x,y,z'].gens() sage: C = Curve(x^3 + y^3 + z^3) sage: D = Curve(x^4 + y^4 + z^4) sage: C.union(D) Projective Curve over Rational Field defined by x^7 + x^4*y^3 + x^3*y^4 + y^7 + x^4*z^3 + y^4*z^3 + x^3*z^4 + y^3*z^4 + z^7 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 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 EXAMPLE: In three variables, the defining equation must be homogeneous. If the parent polynomial ring is in three variables, then the defining ideal must be homogeneous. :: sage: x,y,z = QQ['x,y,z'].gens() 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) Traceback (most recent call last): ... TypeError: x^2 + y^2 + z is not a homogeneous polynomial! The defining polynomial must always be nonzero:: sage: P1.<x,y> = ProjectiveSpace(1,GF(5)) sage: Curve(0*x) Traceback (most recent call last): ... ValueError: defining polynomial of curve must be nonzero """ if is_AlgebraicScheme(F): return Curve(F.defining_polynomials()) if isinstance(F, (list, tuple)): if len(F) == 1: return Curve(F[0]) F = Sequence(F) P = F.universe() if not is_MPolynomialRing(P): raise TypeError("universe of F must be a multivariate polynomial ring") for f in F: if not f.is_homogeneous(): A = AffineSpace(P.ngens(), P.base_ring()) A._coordinate_ring = P return AffineSpaceCurve_generic(A, F) A = ProjectiveSpace(P.ngens()-1, P.base_ring()) A._coordinate_ring = P return ProjectiveSpaceCurve_generic(A, F) if not is_MPolynomial(F): raise TypeError("F (=%s) must be a multivariate polynomial"%F) P = F.parent() k = F.base_ring() if F.parent().ngens() == 2: if F == 0: raise ValueError("defining polynomial of curve must be nonzero") A2 = AffineSpace(2, P.base_ring()) A2._coordinate_ring = P if is_FiniteField(k): if k.is_prime_field(): return AffineCurve_prime_finite_field(A2, F) else: return AffineCurve_finite_field(A2, F) else: return AffineCurve_generic(A2, F) elif F.parent().ngens() == 3: if F == 0: raise ValueError("defining polynomial of curve must be nonzero") P2 = ProjectiveSpace(2, P.base_ring()) P2._coordinate_ring = P if F.total_degree() == 2 and k.is_field(): return Conic(F) if is_FiniteField(k): if k.is_prime_field(): return ProjectiveCurve_prime_finite_field(P2, F) else: return ProjectiveCurve_finite_field(P2, F) else: return ProjectiveCurve_generic(P2, F) else: raise TypeError("Number of variables of F (=%s) must be 2 or 3"%F)
def EllipticCurve(x=None, y=None, j=None, minimal_twist=True): r""" Construct an elliptic curve. In Sage, an elliptic curve is always specified by its a-invariants .. math:: y^2 + a_1 xy + a_3 y = x^3 + a_2 x^2 + a_4 x + a_6. INPUT: There are several ways to construct an elliptic curve: - ``EllipticCurve([a1,a2,a3,a4,a6])``: Elliptic curve with given a-invariants. The invariants are coerced into the parent of the first element. If all are integers, they are coerced into the rational numbers. - ``EllipticCurve([a4,a6])``: Same as above, but `a_1=a_2=a_3=0`. - ``EllipticCurve(label)``: Returns the elliptic curve over Q from the Cremona database with the given label. The label is a string, such as ``"11a"`` or ``"37b2"``. The letters in the label *must* be lower case (Cremona's new labeling). - ``EllipticCurve(R, [a1,a2,a3,a4,a6])``: Create the elliptic curve over ``R`` with given a-invariants. Here ``R`` can be an arbitrary ring. Note that addition need not be defined. - ``EllipticCurve(j=j0)`` or ``EllipticCurve_from_j(j0)``: Return an elliptic curve with j-invariant ``j0``. - ``EllipticCurve(polynomial)``: Read off the a-invariants from the polynomial coefficients, see :func:`EllipticCurve_from_Weierstrass_polynomial`. In each case above where the input is a list of length 2 or 5, one can instead give a 2 or 5-tuple instead. EXAMPLES: We illustrate creating elliptic curves:: sage: EllipticCurve([0,0,1,-1,0]) Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field We create a curve from a Cremona label:: sage: EllipticCurve('37b2') Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field sage: EllipticCurve('5077a') Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field sage: EllipticCurve('389a') Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field Old Cremona labels are allowed:: sage: EllipticCurve('2400FF') Elliptic Curve defined by y^2 = x^3 + x^2 + 2*x + 8 over Rational Field Unicode labels are allowed:: sage: EllipticCurve(u'389a') Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field We create curves over a finite field as follows:: sage: EllipticCurve([GF(5)(0),0,1,-1,0]) 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]) 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 "elliptic curve over a finite field":: sage: F = Zmod(101) sage: EllipticCurve(F, [2, 3]) Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 101 sage: E = EllipticCurve([F(2), F(3)]) sage: type(E) <class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'> sage: E.category() Category of schemes over Ring of integers modulo 101 In contrast, elliptic curves over `\ZZ/N\ZZ` with `N` composite are of type "generic elliptic curve":: sage: F = Zmod(95) sage: EllipticCurve(F, [2, 3]) Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 95 sage: E = EllipticCurve([F(2), F(3)]) sage: type(E) <class 'sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic_with_category'> sage: E.category() Category of schemes over Ring of integers modulo 95 The following is a curve over the complex numbers:: 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 sage: E.j_invariant() 2988.97297297297 We can also create elliptic curves by giving the Weierstrass equation:: sage: x, y = var('x,y') 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.<x,y> = GF(5)[] sage: EllipticCurve(x^3 + x^2 + 2 - y^2 - y*x) Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 2 over Finite Field of size 5 We can explicitly specify the `j`-invariant:: sage: E = EllipticCurve(j=1728); E; E.j_invariant(); E.label() Elliptic Curve defined by y^2 = x^3 - x over Rational Field 1728 '32a2' sage: E = EllipticCurve(j=GF(5)(2)); E; E.j_invariant() 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) Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 144169 By default, when a rational value of `j` is given, the constructed curve is a minimal twist (minimal conductor for curves with that `j`-invariant). This can be changed by setting the optional parameter ``minimal_twist``, which is True by default, to False:: sage: EllipticCurve(j=100) Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field sage: E =EllipticCurve(j=100); E Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field sage: E.conductor() 33129800 sage: E.j_invariant() 100 sage: E =EllipticCurve(j=100, minimal_twist=False); E Elliptic Curve defined by y^2 = x^3 + 488400*x - 530076800 over Rational Field sage: E.conductor() 298168200 sage: E.j_invariant() 100 Without this option, constructing the curve could take a long time 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.j_invariant() == 2^256+1 True TESTS:: sage: R = ZZ['u', 'v'] sage: EllipticCurve(R, [1,1]) Elliptic Curve defined by y^2 = x^3 + x + 1 over Multivariate Polynomial Ring in u, v over Integer Ring We create a curve and a point over QQbar (see #6879):: sage: E = EllipticCurve(QQbar,[0,1]) sage: E(0) (0 : 1 : 0) sage: E.base_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 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() Elliptic Curve defined by y^2 = x^3 + 5*x + 6 over Algebraic Field Algebraic Field See :trac:`6657` :: 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) 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` :: sage: E = EllipticCurve([QQbar(1),3]); E Elliptic Curve defined by y^2 = x^3 + x + 3 over Algebraic Field sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> 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) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E = EllipticCurve([i,i]); E Elliptic Curve defined by y^2 = x^3 + I*x + I over Symbolic Ring sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E.category() Category of schemes over Symbolic Ring sage: SR in Fields() 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 sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E.category() Category of schemes over Fraction Field of Univariate Polynomial Ring in t over Rational Field See :trac:`12517`:: sage: E = EllipticCurve([1..5]) sage: EllipticCurve(E.a_invariants()) Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field See :trac:`11773`:: sage: E = EllipticCurve() Traceback (most recent call last): ... TypeError: invalid input to EllipticCurve constructor """ import ell_generic, ell_field, ell_finite_field, ell_number_field, ell_rational_field, ell_padic_field # here to avoid circular includes if j is not None: if not x is None: if is_Ring(x): try: j = x(j) except (ZeroDivisionError, ValueError, TypeError): raise ValueError, "First parameter must be a ring containing %s" % j else: raise ValueError, "First parameter (if present) must be a ring when j is specified" return EllipticCurve_from_j(j, minimal_twist) if x is None: raise TypeError, "invalid input to EllipticCurve constructor" if is_SymbolicEquation(x): x = x.lhs() - x.rhs() if parent(x) is SR: x = x._polynomial_(rings.QQ['x', 'y']) if is_MPolynomial(x): if y is None: return EllipticCurve_from_Weierstrass_polynomial(x) else: return EllipticCurve_from_cubic(x, y, morphism=False) if is_Ring(x): if is_RationalField(x): return ell_rational_field.EllipticCurve_rational_field(x, y) elif is_FiniteField(x) or (is_IntegerModRing(x) and x.characteristic().is_prime()): return ell_finite_field.EllipticCurve_finite_field(x, y) elif rings.is_pAdicField(x): return ell_padic_field.EllipticCurve_padic_field(x, y) elif is_NumberField(x): return ell_number_field.EllipticCurve_number_field(x, y) elif x in _Fields: return ell_field.EllipticCurve_field(x, y) return ell_generic.EllipticCurve_generic(x, y) if isinstance(x, unicode): x = str(x) if isinstance(x, basestring): return ell_rational_field.EllipticCurve_rational_field(x) if is_RingElement(x) and y is None: raise TypeError, "invalid input to EllipticCurve constructor" if not isinstance(x, (list, tuple)): raise TypeError, "invalid input to EllipticCurve constructor" x = Sequence(x) if not (len(x) in [2, 5]): raise ValueError, "sequence of coefficients must have length 2 or 5" R = x.universe() if isinstance(x[0], (rings.Rational, rings.Integer, int, long)): return ell_rational_field.EllipticCurve_rational_field(x, y) elif is_NumberField(R): return ell_number_field.EllipticCurve_number_field(x, y) elif rings.is_pAdicField(R): return ell_padic_field.EllipticCurve_padic_field(x, y) elif is_FiniteField(R) or (is_IntegerModRing(R) and R.characteristic().is_prime()): return ell_finite_field.EllipticCurve_finite_field(x, y) elif R in _Fields: return ell_field.EllipticCurve_field(x, y) return ell_generic.EllipticCurve_generic(x, y)
def Curve(F): """ Return the plane or space curve defined by `F`, where `F` can be either a multivariate polynomial, a list or tuple of polynomials, or an algebraic scheme. If `F` is in two variables the curve is affine, and if it is homogenous in `3` variables, then the curve is projective. EXAMPLE: A projective plane curve :: sage: x,y,z = QQ['x,y,z'].gens() sage: C = Curve(x^3 + y^3 + z^3); C Projective Curve over Rational Field defined by x^3 + y^3 + z^3 sage: C.genus() 1 EXAMPLE: Affine plane curves :: sage: x,y = GF(7)['x,y'].gens() sage: C = Curve(y^2 + x^3 + x^10); C Affine Curve over Finite Field of size 7 defined by x^10 + x^3 + y^2 sage: C.genus() 0 sage: x, y = QQ['x,y'].gens() sage: Curve(x^3 + y^3 + 1) Affine Curve over Rational Field defined by x^3 + y^3 + 1 EXAMPLE: A projective space curve :: sage: x,y,z,w = QQ['x,y,z,w'].gens() sage: C = Curve([x^3 + y^3 - z^3 - w^3, x^5 - y*z^4]); C Projective Space Curve over Rational Field defined by x^3 + y^3 - z^3 - w^3, x^5 - y*z^4 sage: C.genus() 13 EXAMPLE: An affine space curve :: sage: x,y,z = QQ['x,y,z'].gens() sage: C = Curve([y^2 + x^3 + x^10 + z^7, x^2 + y^2]); C Affine Space Curve over Rational Field defined by x^10 + z^7 + x^3 + y^2, x^2 + y^2 sage: C.genus() 47 EXAMPLE: We can also make non-reduced non-irreducible curves. :: sage: x,y,z = QQ['x,y,z'].gens() sage: Curve((x-y)*(x+y)) Projective Conic Curve over Rational Field defined by x^2 - y^2 sage: Curve((x-y)^2*(x+y)^2) Projective Curve over Rational Field defined by x^4 - 2*x^2*y^2 + y^4 EXAMPLE: A union of curves is a curve. :: sage: x,y,z = QQ['x,y,z'].gens() sage: C = Curve(x^3 + y^3 + z^3) sage: D = Curve(x^4 + y^4 + z^4) sage: C.union(D) Projective Curve over Rational Field defined by x^7 + x^4*y^3 + x^3*y^4 + y^7 + x^4*z^3 + y^4*z^3 + x^3*z^4 + y^3*z^4 + z^7 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 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 EXAMPLE: In three variables, the defining equation must be homogeneous. If the parent polynomial ring is in three variables, then the defining ideal must be homogeneous. :: sage: x,y,z = QQ['x,y,z'].gens() 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) Traceback (most recent call last): ... TypeError: x^2 + y^2 + z is not a homogeneous polynomial! The defining polynomial must always be nonzero:: sage: P1.<x,y> = ProjectiveSpace(1,GF(5)) sage: Curve(0*x) Traceback (most recent call last): ... ValueError: defining polynomial of curve must be nonzero """ if is_AlgebraicScheme(F): return Curve(F.defining_polynomials()) if isinstance(F, (list, tuple)): if len(F) == 1: return Curve(F[0]) F = Sequence(F) P = F.universe() if not is_MPolynomialRing(P): raise TypeError, "universe of F must be a multivariate polynomial ring" for f in F: if not f.is_homogeneous(): A = AffineSpace(P.ngens(), P.base_ring()) A._coordinate_ring = P return AffineSpaceCurve_generic(A, F) A = ProjectiveSpace(P.ngens() - 1, P.base_ring()) A._coordinate_ring = P return ProjectiveSpaceCurve_generic(A, F) if not is_MPolynomial(F): raise TypeError, "F (=%s) must be a multivariate polynomial" % F P = F.parent() k = F.base_ring() if F.parent().ngens() == 2: if F == 0: raise ValueError, "defining polynomial of curve must be nonzero" A2 = AffineSpace(2, P.base_ring()) A2._coordinate_ring = P if is_FiniteField(k): if k.is_prime_field(): return AffineCurve_prime_finite_field(A2, F) else: return AffineCurve_finite_field(A2, F) else: return AffineCurve_generic(A2, F) elif F.parent().ngens() == 3: if F == 0: raise ValueError, "defining polynomial of curve must be nonzero" P2 = ProjectiveSpace(2, P.base_ring()) P2._coordinate_ring = P if F.total_degree() == 2 and k.is_field(): return Conic(F) if is_FiniteField(k): if k.is_prime_field(): return ProjectiveCurve_prime_finite_field(P2, F) else: return ProjectiveCurve_finite_field(P2, F) else: return ProjectiveCurve_generic(P2, F) else: raise TypeError, "Number of variables of F (=%s) must be 2 or 3" % F
def Conic(base_field, F=None, names=None, unique=True): r""" Return the plane projective conic curve defined by ``F`` over ``base_field``. The input form ``Conic(F, names=None)`` is also accepted, in which case the fraction field of the base ring of ``F`` is used as base field. INPUT: - ``base_field`` -- The base field of the conic. - ``names`` -- a list, tuple, or comma separated string of three variable names specifying the names of the coordinate functions of the ambient space `\Bold{P}^3`. If not specified or read off from ``F``, then this defaults to ``'x,y,z'``. - ``F`` -- a polynomial, list, matrix, ternary quadratic form, or list or tuple of 5 points in the plane. If ``F`` is a polynomial or quadratic form, then the output is the curve in the projective plane defined by ``F = 0``. If ``F`` is a polynomial, then it must be a polynomial of degree at most 2 in 2 variables, or a homogeneous polynomial in of degree 2 in 3 variables. If ``F`` is a matrix, then the output is the zero locus of `(x,y,z) F (x,y,z)^t`. If ``F`` is a list of coefficients, then it has length 3 or 6 and gives the coefficients of the monomials `x^2, y^2, z^2` or all 6 monomials `x^2, xy, xz, y^2, yz, z^2` in lexicographic order. If ``F`` is a list of 5 points in the plane, then the output is a conic through those points. - ``unique`` -- Used only if ``F`` is a list of points in the plane. If the conic through the points is not unique, then raise ``ValueError`` if and only if ``unique`` is True OUTPUT: A plane projective conic curve defined by ``F`` over a field. EXAMPLES: Conic curves given by polynomials :: 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 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 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') 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 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 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)]) Projective Conic Curve over Finite Field of size 13 defined by x^2 - y*z """ if not (is_IntegralDomain(base_field) or base_field is None): if names is None: names = F F = base_field base_field = None if isinstance(F, (list, tuple)): if len(F) == 1: return Conic(base_field, F[0], names) if names is None: names = "x,y,z" if len(F) == 5: L = [] for f in F: if isinstance(f, SchemeMorphism_point_affine): C = Sequence(f, universe=base_field) if len(C) != 2: raise TypeError("points in F (=%s) must be planar" % F) C.append(1) elif isinstance(f, SchemeMorphism_point_projective_field): C = Sequence(f, universe=base_field) elif isinstance(f, (list, tuple)): C = Sequence(f, universe=base_field) if len(C) == 2: C.append(1) else: raise TypeError("F (=%s) must be a sequence of planar " "points" % F) if len(C) != 3: raise TypeError("points in F (=%s) must be planar" % F) P = C.universe() if not is_IntegralDomain(P): raise TypeError("coordinates of points in F (=%s) must " "be in an integral domain" % F) L.append( Sequence( [C[0] ** 2, C[0] * C[1], C[0] * C[2], C[1] ** 2, C[1] * C[2], C[2] ** 2], P.fraction_field() ) ) M = Matrix(L) if unique and M.rank() != 5: raise ValueError("points in F (=%s) do not define a unique " "conic" % F) con = Conic(base_field, Sequence(M.right_kernel().gen()), names) con.point(F[0]) return con F = Sequence(F, universe=base_field) base_field = F.universe().fraction_field() temp_ring = PolynomialRing(base_field, 3, names) (x, y, z) = temp_ring.gens() if len(F) == 3: return Conic(F[0] * x ** 2 + F[1] * y ** 2 + F[2] * z ** 2) if len(F) == 6: return Conic(F[0] * x ** 2 + F[1] * x * y + F[2] * x * z + F[3] * y ** 2 + F[4] * y * z + F[5] * z ** 2) raise TypeError("F (=%s) must be a sequence of 3 or 6" "coefficients" % F) if is_QuadraticForm(F): F = F.matrix() if is_Matrix(F) and F.is_square() and F.ncols() == 3: if names is None: names = "x,y,z" temp_ring = PolynomialRing(F.base_ring(), 3, names) F = vector(temp_ring.gens()) * F * vector(temp_ring.gens()) if not is_MPolynomial(F): raise TypeError("F (=%s) must be a three-variable polynomial or " "a sequence of points or coefficients" % F) if F.total_degree() != 2: raise TypeError("F (=%s) must have degree 2" % F) if base_field is None: base_field = F.base_ring() if not is_IntegralDomain(base_field): raise ValueError("Base field (=%s) must be a field" % base_field) base_field = base_field.fraction_field() if names is None: names = F.parent().variable_names() pol_ring = PolynomialRing(base_field, 3, names) if F.parent().ngens() == 2: (x, y, z) = pol_ring.gens() F = pol_ring(F(x / z, y / z) * z ** 2) if F == 0: raise ValueError("F must be nonzero over base field %s" % base_field) if F.total_degree() != 2: raise TypeError("F (=%s) must have degree 2 over base field %s" % (F, base_field)) if F.parent().ngens() == 3: P2 = ProjectiveSpace(2, base_field, names) if is_PrimeFiniteField(base_field): return ProjectiveConic_prime_finite_field(P2, F) if is_FiniteField(base_field): return ProjectiveConic_finite_field(P2, F) if is_RationalField(base_field): return ProjectiveConic_rational_field(P2, F) if is_NumberField(base_field): return ProjectiveConic_number_field(P2, F) return ProjectiveConic_field(P2, F) raise TypeError("Number of variables of F (=%s) must be 2 or 3" % F)
def EllipticCurve(x=None, y=None, j=None, minimal_twist=True): r""" Construct an elliptic curve. In Sage, an elliptic curve is always specified by its a-invariants .. math:: y^2 + a_1 xy + a_3 y = x^3 + a_2 x^2 + a_4 x + a_6. INPUT: There are several ways to construct an elliptic curve: - ``EllipticCurve([a1,a2,a3,a4,a6])``: Elliptic curve with given a-invariants. The invariants are coerced into the parent of the first element. If all are integers, they are coerced into the rational numbers. - ``EllipticCurve([a4,a6])``: Same as above, but `a_1=a_2=a_3=0`. - ``EllipticCurve(label)``: Returns the elliptic curve over Q from the Cremona database with the given label. The label is a string, such as ``"11a"`` or ``"37b2"``. The letters in the label *must* be lower case (Cremona's new labeling). - ``EllipticCurve(R, [a1,a2,a3,a4,a6])``: Create the elliptic curve over ``R`` with given a-invariants. Here ``R`` can be an arbitrary ring. Note that addition need not be defined. - ``EllipticCurve(j=j0)`` or ``EllipticCurve_from_j(j0)``: Return an elliptic curve with j-invariant ``j0``. - ``EllipticCurve(polynomial)``: Read off the a-invariants from the polynomial coefficients, see :func:`EllipticCurve_from_Weierstrass_polynomial`. In each case above where the input is a list of length 2 or 5, one can instead give a 2 or 5-tuple instead. EXAMPLES: We illustrate creating elliptic curves:: sage: EllipticCurve([0,0,1,-1,0]) Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field We create a curve from a Cremona label:: sage: EllipticCurve('37b2') Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field sage: EllipticCurve('5077a') Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field sage: EllipticCurve('389a') Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field Old Cremona labels are allowed:: sage: EllipticCurve('2400FF') Elliptic Curve defined by y^2 = x^3 + x^2 + 2*x + 8 over Rational Field Unicode labels are allowed:: sage: EllipticCurve(u'389a') Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field We create curves over a finite field as follows:: sage: EllipticCurve([GF(5)(0),0,1,-1,0]) 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]) 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 "elliptic curve over a finite field":: sage: F = Zmod(101) sage: EllipticCurve(F, [2, 3]) Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 101 sage: E = EllipticCurve([F(2), F(3)]) sage: type(E) <class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'> sage: E.category() Category of schemes over Ring of integers modulo 101 In contrast, elliptic curves over `\ZZ/N\ZZ` with `N` composite are of type "generic elliptic curve":: sage: F = Zmod(95) sage: EllipticCurve(F, [2, 3]) Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 95 sage: E = EllipticCurve([F(2), F(3)]) sage: type(E) <class 'sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic_with_category'> sage: E.category() Category of schemes over Ring of integers modulo 95 The following is a curve over the complex numbers:: 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 sage: E.j_invariant() 2988.97297297297 We can also create elliptic curves by giving the Weierstrass equation:: sage: x, y = var('x,y') 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.<x,y> = GF(5)[] sage: EllipticCurve(x^3 + x^2 + 2 - y^2 - y*x) Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 2 over Finite Field of size 5 We can explicitly specify the `j`-invariant:: sage: E = EllipticCurve(j=1728); E; E.j_invariant(); E.label() Elliptic Curve defined by y^2 = x^3 - x over Rational Field 1728 '32a2' sage: E = EllipticCurve(j=GF(5)(2)); E; E.j_invariant() 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) Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 144169 By default, when a rational value of `j` is given, the constructed curve is a minimal twist (minimal conductor for curves with that `j`-invariant). This can be changed by setting the optional parameter ``minimal_twist``, which is True by default, to False:: sage: EllipticCurve(j=100) Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field sage: E =EllipticCurve(j=100); E Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field sage: E.conductor() 33129800 sage: E.j_invariant() 100 sage: E =EllipticCurve(j=100, minimal_twist=False); E Elliptic Curve defined by y^2 = x^3 + 488400*x - 530076800 over Rational Field sage: E.conductor() 298168200 sage: E.j_invariant() 100 Without this option, constructing the curve could take a long time 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.j_invariant() == 2^256+1 True TESTS:: sage: R = ZZ['u', 'v'] sage: EllipticCurve(R, [1,1]) Elliptic Curve defined by y^2 = x^3 + x + 1 over Multivariate Polynomial Ring in u, v over Integer Ring We create a curve and a point over QQbar (see #6879):: sage: E = EllipticCurve(QQbar,[0,1]) sage: E(0) (0 : 1 : 0) sage: E.base_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 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() Elliptic Curve defined by y^2 = x^3 + 5*x + 6 over Algebraic Field Algebraic Field See :trac:`6657` :: 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) 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` :: sage: E = EllipticCurve([QQbar(1),3]); E Elliptic Curve defined by y^2 = x^3 + x + 3 over Algebraic Field sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> 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) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E = EllipticCurve([i,i]); E Elliptic Curve defined by y^2 = x^3 + I*x + I over Symbolic Ring sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E.category() Category of schemes over Symbolic Ring sage: SR in Fields() 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 sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E.category() Category of schemes over Fraction Field of Univariate Polynomial Ring in t over Rational Field See :trac:`12517`:: sage: E = EllipticCurve([1..5]) sage: EllipticCurve(E.a_invariants()) Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field See :trac:`11773`:: sage: E = EllipticCurve() Traceback (most recent call last): ... TypeError: invalid input to EllipticCurve constructor """ import ell_generic, ell_field, ell_finite_field, ell_number_field, ell_rational_field, ell_padic_field # here to avoid circular includes if j is not None: if not x is None: if is_Ring(x): try: j = x(j) except (ZeroDivisionError, ValueError, TypeError): raise ValueError, "First parameter must be a ring containing %s"%j else: raise ValueError, "First parameter (if present) must be a ring when j is specified" return EllipticCurve_from_j(j, minimal_twist) if x is None: raise TypeError, "invalid input to EllipticCurve constructor" if is_SymbolicEquation(x): x = x.lhs() - x.rhs() if parent(x) is SR: x = x._polynomial_(rings.QQ['x', 'y']) if is_MPolynomial(x): if y is None: return EllipticCurve_from_Weierstrass_polynomial(x) else: return EllipticCurve_from_cubic(x, y, morphism=False) if is_Ring(x): if is_RationalField(x): return ell_rational_field.EllipticCurve_rational_field(x, y) elif is_FiniteField(x) or (is_IntegerModRing(x) and x.characteristic().is_prime()): return ell_finite_field.EllipticCurve_finite_field(x, y) elif rings.is_pAdicField(x): return ell_padic_field.EllipticCurve_padic_field(x, y) elif is_NumberField(x): return ell_number_field.EllipticCurve_number_field(x, y) elif x in _Fields: return ell_field.EllipticCurve_field(x, y) return ell_generic.EllipticCurve_generic(x, y) if isinstance(x, unicode): x = str(x) if isinstance(x, basestring): return ell_rational_field.EllipticCurve_rational_field(x) if is_RingElement(x) and y is None: raise TypeError, "invalid input to EllipticCurve constructor" if not isinstance(x, (list, tuple)): raise TypeError, "invalid input to EllipticCurve constructor" x = Sequence(x) if not (len(x) in [2,5]): raise ValueError, "sequence of coefficients must have length 2 or 5" R = x.universe() if isinstance(x[0], (rings.Rational, rings.Integer, int, long)): return ell_rational_field.EllipticCurve_rational_field(x, y) elif is_NumberField(R): return ell_number_field.EllipticCurve_number_field(x, y) elif rings.is_pAdicField(R): return ell_padic_field.EllipticCurve_padic_field(x, y) elif is_FiniteField(R) or (is_IntegerModRing(R) and R.characteristic().is_prime()): return ell_finite_field.EllipticCurve_finite_field(x, y) elif R in _Fields: return ell_field.EllipticCurve_field(x, y) return ell_generic.EllipticCurve_generic(x, y)
def Conic(base_field, F=None, names=None, unique=True): r""" Return the plane projective conic curve defined by ``F`` over ``base_field``. The input form ``Conic(F, names=None)`` is also accepted, in which case the fraction field of the base ring of ``F`` is used as base field. INPUT: - ``base_field`` -- The base field of the conic. - ``names`` -- a list, tuple, or comma separated string of three variable names specifying the names of the coordinate functions of the ambient space `\Bold{P}^3`. If not specified or read off from ``F``, then this defaults to ``'x,y,z'``. - ``F`` -- a polynomial, list, matrix, ternary quadratic form, or list or tuple of 5 points in the plane. If ``F`` is a polynomial or quadratic form, then the output is the curve in the projective plane defined by ``F = 0``. If ``F`` is a polynomial, then it must be a polynomial of degree at most 2 in 2 variables, or a homogeneous polynomial in of degree 2 in 3 variables. If ``F`` is a matrix, then the output is the zero locus of `(x,y,z) F (x,y,z)^t`. If ``F`` is a list of coefficients, then it has length 3 or 6 and gives the coefficients of the monomials `x^2, y^2, z^2` or all 6 monomials `x^2, xy, xz, y^2, yz, z^2` in lexicographic order. If ``F`` is a list of 5 points in the plane, then the output is a conic through those points. - ``unique`` -- Used only if ``F`` is a list of points in the plane. If the conic through the points is not unique, then raise ``ValueError`` if and only if ``unique`` is True OUTPUT: A plane projective conic curve defined by ``F`` over a field. EXAMPLES: Conic curves given by polynomials :: 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 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 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') 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 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 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)]) Projective Conic Curve over Finite Field of size 13 defined by x^2 - y*z """ if not (is_IntegralDomain(base_field) or base_field is None): if names is None: names = F F = base_field base_field = None if isinstance(F, (list, tuple)): if len(F) == 1: return Conic(base_field, F[0], names) if names is None: names = 'x,y,z' if len(F) == 5: L = [] for f in F: if isinstance(f, SchemeMorphism_point_affine): C = Sequence(f, universe=base_field) if len(C) != 2: raise TypeError("points in F (=%s) must be planar" % F) C.append(1) elif isinstance(f, SchemeMorphism_point_projective_field): C = Sequence(f, universe=base_field) elif isinstance(f, (list, tuple)): C = Sequence(f, universe=base_field) if len(C) == 2: C.append(1) else: raise TypeError("F (=%s) must be a sequence of planar " \ "points" % F) if len(C) != 3: raise TypeError("points in F (=%s) must be planar" % F) P = C.universe() if not is_IntegralDomain(P): raise TypeError("coordinates of points in F (=%s) must " \ "be in an integral domain" % F) L.append( Sequence([ C[0]**2, C[0] * C[1], C[0] * C[2], C[1]**2, C[1] * C[2], C[2]**2 ], P.fraction_field())) M = Matrix(L) if unique and M.rank() != 5: raise ValueError("points in F (=%s) do not define a unique " \ "conic" % F) con = Conic(base_field, Sequence(M.right_kernel().gen()), names) con.point(F[0]) return con F = Sequence(F, universe=base_field) base_field = F.universe().fraction_field() temp_ring = PolynomialRing(base_field, 3, names) (x, y, z) = temp_ring.gens() if len(F) == 3: return Conic(F[0] * x**2 + F[1] * y**2 + F[2] * z**2) if len(F) == 6: return Conic(F[0]*x**2 + F[1]*x*y + F[2]*x*z + F[3]*y**2 + \ F[4]*y*z + F[5]*z**2) raise TypeError("F (=%s) must be a sequence of 3 or 6" \ "coefficients" % F) if is_QuadraticForm(F): F = F.matrix() if is_Matrix(F) and F.is_square() and F.ncols() == 3: if names is None: names = 'x,y,z' temp_ring = PolynomialRing(F.base_ring(), 3, names) F = vector(temp_ring.gens()) * F * vector(temp_ring.gens()) if not is_MPolynomial(F): raise TypeError("F (=%s) must be a three-variable polynomial or " \ "a sequence of points or coefficients" % F) if F.total_degree() != 2: raise TypeError("F (=%s) must have degree 2" % F) if base_field is None: base_field = F.base_ring() if not is_IntegralDomain(base_field): raise ValueError("Base field (=%s) must be a field" % base_field) base_field = base_field.fraction_field() if names is None: names = F.parent().variable_names() pol_ring = PolynomialRing(base_field, 3, names) if F.parent().ngens() == 2: (x, y, z) = pol_ring.gens() F = pol_ring(F(x / z, y / z) * z**2) if F == 0: raise ValueError("F must be nonzero over base field %s" % base_field) if F.total_degree() != 2: raise TypeError("F (=%s) must have degree 2 over base field %s" % \ (F, base_field)) if F.parent().ngens() == 3: P2 = ProjectiveSpace(2, base_field, names) if is_PrimeFiniteField(base_field): return ProjectiveConic_prime_finite_field(P2, F) if is_FiniteField(base_field): return ProjectiveConic_finite_field(P2, F) if is_RationalField(base_field): return ProjectiveConic_rational_field(P2, F) if is_NumberField(base_field): return ProjectiveConic_number_field(P2, F) return ProjectiveConic_field(P2, F) raise TypeError("Number of variables of F (=%s) must be 2 or 3" % F)
def HyperellipticCurve(f, h=None, names=None, PP=None, check_squarefree=True): r""" Returns the hyperelliptic curve `y^2 + h y = f`, for univariate polynomials `h` and `f`. If `h` is not given, then it defaults to 0. INPUT: - ``f`` - univariate polynomial - ``h`` - optional univariate polynomial - ``names`` (default: ``["x","y"]``) - names for the coordinate functions - ``check_squarefree`` (default: ``True``) - test if the input defines a hyperelliptic curve when f is homogenized to degree `2g+2` and h to degree `g+1` for some g. .. WARNING:: When setting ``check_squarefree=False`` or using a base ring that is not a field, the output curves are not to be trusted. For example, the output of ``is_singular`` is always ``False``, without this being properly tested in that case. .. NOTE:: The words "hyperelliptic curve" are normally only used for curves of genus at least two, but this class allows more general smooth double covers of the projective line (conics and elliptic curves), even though the class is not meant for those and some outputs may be incorrect. EXAMPLES: Basic examples:: sage: R.<x> = 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) Hyperelliptic Curve over Rational Field defined by y^2 + (x - 2)*y = x^19 + x + 1 sage: k.<a> = GF(9); R.<x> = 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 Characteristic two:: sage: P.<x> = 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: HyperellipticCurve(x^8+1, x) Traceback (most recent call last): ... ValueError: Not a hyperelliptic curve: highly singular at infinity. sage: HyperellipticCurve(x^8+x^7+1, x^4) Traceback (most recent call last): ... ValueError: Not a hyperelliptic curve: singularity in the provided affine patch. sage: F.<t> = PowerSeriesRing(FiniteField(2)) sage: P.<x> = 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 We can change the names of the variables in the output:: sage: k.<a> = GF(9); R.<x> = 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 This class also allows curves of genus zero or one, which are strictly speaking not hyperelliptic:: sage: P.<x> = QQ[] sage: HyperellipticCurve(x^2+1) Hyperelliptic Curve over Rational Field defined by y^2 = x^2 + 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) Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + 2*x + 2 Double roots:: sage: P.<x> = GF(7)[] 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 The input for a (smooth) hyperelliptic curve of genus `g` should not contain polynomials of degree greater than `2g+2`. In the following example, the hyperelliptic curve has genus 2 and there exists a model `y^2 = F` of degree 6, so the model `y^2 + yh = f` of degree 200 is not allowed.:: sage: P.<x> = QQ[] sage: h = x^100 sage: F = x^6+1 sage: f = F-h^2/4 sage: HyperellipticCurve(f, h) Traceback (most recent call last): ... ValueError: Not a hyperelliptic curve: highly singular at infinity. sage: HyperellipticCurve(F) Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 1 An example with a singularity over an inseparable extension of the base field:: sage: F.<t> = GF(5)[] sage: P.<x> = F[] sage: HyperellipticCurve(x^5+t) Traceback (most recent call last): ... ValueError: Not a hyperelliptic curve: singularity in the provided affine patch. 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^*`.:: sage: P.<x> = ZZ[] sage: HyperellipticCurve(3*x^7+6*x+6) Hyperelliptic Curve over Integer Ring defined by y^2 = 3*x^7 + 6*x + 6 """ if (not is_Polynomial(f)) or f == 0: raise TypeError, "Arguments f (=%s) and h (= %s) must be polynomials " \ "and f must be non-zero" % (f,h) P = f.parent() if h is None: h = P(0) try: h = P(h) except TypeError: raise TypeError, \ "Arguments f (=%s) and h (= %s) must be polynomials in the same ring"%(f,h) df = f.degree() dh_2 = 2*h.degree() if dh_2 < df: g = (df-1)//2 else: g = (dh_2-1)//2 if check_squarefree: # Assuming we are working over a field, this checks that after # resolving the singularity at infinity, we get a smooth double cover # of P^1. if P(2) == 0: # characteristic 2 if h == 0: raise ValueError, \ "In characteristic 2, argument h (= %s) must be non-zero."%h if h[g+1] == 0 and f[2*g+1]**2 == f[2*g+2]*h[g]**2: raise ValueError, "Not a hyperelliptic curve: " \ "highly singular at infinity." should_be_coprime = [h, f*h.derivative()**2+f.derivative()**2] else: # characteristic not 2 F = f + h**2/4 if not F.degree() in [2*g+1, 2*g+2]: raise ValueError, "Not a hyperelliptic curve: " \ "highly singular at infinity." should_be_coprime = [F, F.derivative()] try: smooth = should_be_coprime[0].gcd(should_be_coprime[1]).degree()==0 except (AttributeError, NotImplementedError, TypeError): try: smooth = should_be_coprime[0].resultant(should_be_coprime[1])!=0 except (AttributeError, NotImplementedError, TypeError): raise NotImplementedError, "Cannot determine whether " \ "polynomials %s have a common root. Use " \ "check_squarefree=False to skip this check." % \ should_be_coprime if not smooth: raise ValueError, "Not a hyperelliptic curve: " \ "singularity in the provided affine patch." R = P.base_ring() PP = ProjectiveSpace(2, R) if names is None: names = ["x","y"] if is_FiniteField(R): if g == 2: return HyperellipticCurve_g2_finite_field(PP, f, h, names=names, genus=g) else: return HyperellipticCurve_finite_field(PP, f, h, names=names, genus=g) elif is_RationalField(R): if g == 2: return HyperellipticCurve_g2_rational_field(PP, f, h, names=names, genus=g) else: return HyperellipticCurve_rational_field(PP, f, h, names=names, genus=g) elif is_pAdicField(R): if g == 2: return HyperellipticCurve_g2_padic_field(PP, f, h, names=names, genus=g) else: return HyperellipticCurve_padic_field(PP, f, h, names=names, genus=g) else: if g == 2: return HyperellipticCurve_g2_generic(PP, f, h, names=names, genus=g) else: return HyperellipticCurve_generic(PP, f, h, names=names, genus=g)
def ProjectiveSpace(n, R=None, names='x'): r""" Return projective space of dimension `n` over the ring `R`. EXAMPLES: The dimension and ring can be given in either order. :: sage: ProjectiveSpace(3, QQ) Projective Space of dimension 3 over Rational Field sage: ProjectiveSpace(5, QQ) Projective Space of dimension 5 over Rational Field sage: P = ProjectiveSpace(2, QQ, names='XYZ'); P Projective Space of dimension 2 over Rational Field sage: P.coordinate_ring() Multivariate Polynomial Ring in X, Y, Z over Rational Field The divide operator does base extension. :: sage: ProjectiveSpace(5)/GF(17) Projective Space of dimension 5 over Finite Field of size 17 The default base ring is `\ZZ`. :: sage: ProjectiveSpace(5) Projective Space of dimension 5 over Integer Ring There is also an projective space associated each polynomial ring. :: sage: R = GF(7)['x,y,z'] sage: P = ProjectiveSpace(R); P Projective Space of dimension 2 over Finite Field of size 7 sage: P.coordinate_ring() Multivariate Polynomial Ring in x, y, z over Finite Field of size 7 sage: P.coordinate_ring() is R True :: sage: ProjectiveSpace(3, Zp(5), 'y') Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20 :: sage: ProjectiveSpace(2,QQ,'x,y,z') Projective Space of dimension 2 over Rational Field :: sage: PS.<x,y>=ProjectiveSpace(1,CC) sage: PS Projective Space of dimension 1 over Complex Field with 53 bits of precision Projective spaces are not cached, i.e., there can be several with the same base ring and dimension (to facilitate gluing constructions). """ if is_MPolynomialRing(n) and R is None: A = ProjectiveSpace(n.ngens()-1, n.base_ring()) A._coordinate_ring = n return A if isinstance(R, (int, long, Integer)): n, R = R, n if R is None: R = ZZ # default is the integers if R in _Fields: if is_FiniteField(R): return ProjectiveSpace_finite_field(n, R, names) if is_RationalField(R): return ProjectiveSpace_rational_field(n, R, names) else: return ProjectiveSpace_field(n, R, names) elif is_CommutativeRing(R): return ProjectiveSpace_ring(n, R, names) else: raise TypeError("R (=%s) must be a commutative ring"%R)
def points(self, B=0, prec=53): """ Return some or all rational points of a projective scheme. INPUT: - `B` - integer (optional, default=0). The bound for the coordinates. - ``prec`` - he precision to use to compute the elements of bounded height for number fields OUTPUT: A list of points. Over a finite field, all points are returned. Over an infinite field, all points satisfying the bound are returned. .. WARNING:: In the current implementation, the output of the [Doyle-Krumm] algorithm cannot be guaranteed to be correct due to the necessity of floating point computations. In some cases, the default 53-bit precision is considerably lower than would be required for the algorithm to generate correct output. EXAMPLES:: sage: P.<x,y> = ProjectiveSpace(QQ,1) sage: P(QQ).points(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)] :: sage: u = QQ['u'].0 sage: K.<v> = NumberField(u^2 + 3) sage: P.<x,y,z> = ProjectiveSpace(K,2) sage: len(P(K).points(1.8)) 381 :: sage: P1 = ProjectiveSpace(GF(2),1) sage: F.<a> = GF(4,'a') sage: P1(F).points() [(0 : 1), (1 : 0), (1 : 1), (a : 1), (a + 1 : 1)] :: sage: P.<x,y,z> = 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)] """ X = self.codomain() from sage.schemes.projective.projective_space import is_ProjectiveSpace if not is_ProjectiveSpace(X) and X.base_ring() in Fields(): #Then it must be a subscheme dim_ideal = X.defining_ideal().dimension() if dim_ideal < 1: # no points return [] if dim_ideal == 1: # if X zero-dimensional points = set() for i in range(X.ambient_space().dimension_relative() + 1): Y = X.affine_patch(i) phi = Y.projective_embedding() aff_points = Y.rational_points() for PP in aff_points: points.add(X.ambient_space()(list(phi(PP)))) points = sorted(points) return points R = self.value_ring() if is_RationalField(R): if not B > 0: raise TypeError( "A positive bound B (= %s) must be specified." % B) from sage.schemes.projective.projective_rational_point import enum_projective_rational_field return enum_projective_rational_field(self, B) elif R in NumberFields(): if not B > 0: raise TypeError( "A positive bound B (= %s) must be specified." % B) from sage.schemes.projective.projective_rational_point import enum_projective_number_field return enum_projective_number_field(self, B, prec=prec) elif is_FiniteField(R): from sage.schemes.projective.projective_rational_point import enum_projective_finite_field return enum_projective_finite_field(self.extended_codomain()) else: raise TypeError("Unable to enumerate points over %s." % R)