# Ticket #11599: trac_11599_homset_new_coercion_model.patch

File trac_11599_homset_new_coercion_model.patch, 148.0 KB (added by vbraun, 10 years ago)

Updated patch

• ## doc/en/reference/structure.rst

# HG changeset patch
# User Volker Braun <vbraun@stp.dias.ie>
# Date 1325181309 0
# Node ID 39cd1100df9bd5631e517807780b926ae263506b
# Parent  9c4e903d21c02abc03b88cfd00d353c76acb2ef2
Trac #11599: Port the scheme morphisms / homsets to the
new parents and coercion model.

diff --git a/doc/en/reference/structure.rst b/doc/en/reference/structure.rst
 a sage/structure/factorization sage/structure/element sage/structure/unique_representation sage/structure/factory sage/structure/dynamic_class sage/structure/list_clone sage/structure/mutability
• ## sage/categories/map.pyx

diff --git a/sage/categories/map.pyx b/sage/categories/map.pyx
 a sage: f(x^2+2*x-1) x^2 + 2*x*y + y^2 + 2*x + 2*y - 1 """ def __init__(self, parent, codomain=None): """ INPUT: sage: f._repr_type_str 'bla' """ # todo: the following can break during unpickling of complex # objects with circular references! In that case, _slots might # contain incomplete objects. self._domain = _slots['_domain'] self._codomain = _slots['_codomain'] # Several pickles exist without a _repr_type_str, so # if there is none saved, we just set it to None. if _slots.has_key('_repr_type_str'):
• ## sage/categories/schemes.py

diff --git a/sage/categories/schemes.py b/sage/categories/schemes.py
 a Category of Schemes sage: Schemes(Spec(ZZ)) Category of schemes over Spectrum of Integer Ring Category of schemes over Integer Ring sage: Schemes(ZZ) Category of schemes over Spectrum of Integer Ring Category of schemes over Integer Ring """ if X is None: return Schemes_abstract() from sage.schemes.all import is_Scheme from sage.schemes.generic.scheme import is_Scheme if not is_Scheme(X): X = Schemes()(X) return Schemes_over_base(X) Spectrum of Integer Ring We create a scheme morphism from a ring homomorphism.x:: \ sage: phi = ZZ.hom(QQ); phi Ring Coercion morphism: From: Integer Ring To:   Rational Field """ from sage.schemes.generic.scheme import is_Scheme if is_Scheme(x): return x from sage.schemes.generic.morphism import is_SchemeMorphism if is_SchemeMorphism(x): return x from sage.rings.all import is_CommutativeRing, is_RingHomomorphism from sage.schemes.all import is_Scheme, Spec, is_SchemeMorphism if is_Scheme(x) or is_SchemeMorphism(x): return x elif is_CommutativeRing(x): from sage.schemes.generic.spec import Spec if is_CommutativeRing(x): return Spec(x) elif is_RingHomomorphism(x): A = Spec(x.codomain()) the parent for Hom(R, S) to be in a different class:: sage: Hom(Spec(ZZ), Spec(ZZ)).__class__ Currently, and to minimize the changes, this is done by delegating the job to SchemeHomset. This is not EXAMPLES:: sage: Schemes(Spec(ZZ)) Category of schemes over Spectrum of Integer Ring Category of schemes over Integer Ring TESTS:: EXAMPLES:: sage: Schemes(Spec(ZZ)) # indirect doctest Category of schemes over Spectrum of Integer Ring Category of schemes over Integer Ring """ # To work around the name of the class (schemes_over_base) return "schemes over %s"%self.base_scheme() from sage.schemes.generic.spec import is_Spec if is_Spec(self.base_scheme()): return "schemes over %s" % self.base_scheme().coordinate_ring() else: return "schemes over %s" % self.base_scheme()

diff --git a/sage/groups/additive_abelian/additive_abelian_wrapper.py b/sage/groups/additive_abelian/additive_abelian_wrapper.py
 a (0 : 1 : 0) sage: 3000000000000001 * M.0 (4 : -7 : 1) sage: M == loads(dumps(M)) sage: M == loads(dumps(M))    # optional - pickling http://trac.sagemath.org/sage_trac/ticket/11599 True We check that ridiculous operations are being avoided::
• ## sage/schemes/elliptic_curves/ell_curve_isogeny.py

diff --git a/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/sage/schemes/elliptic_curves/ell_curve_isogeny.py
 a x sage: phi.rational_maps() ((x^2 + 1)/x, (x^2*y - y)/x^2) sage: phi == loads(dumps(phi)) sage: phi == loads(dumps(phi))   # optional - pickling http://trac.sagemath.org/sage_trac/ticket/11599 True A more complicated example of a characteristic 2 field::
• ## sage/schemes/elliptic_curves/ell_generic.py

diff --git a/sage/schemes/elliptic_curves/ell_generic.py b/sage/schemes/elliptic_curves/ell_generic.py
 a characteristic = self.base_ring().characteristic() if characteristic != 0 and isinstance(args[0][0], rings.Rational) and isinstance(args[0][1], rings.Rational): if rings.mod(args[0][0].denominator(),characteristic) == 0 or rings.mod(args[0][1].denominator(),characteristic) == 0: args = self._reduce_point(args[0], characteristic) args = tuple(args) else: args = tuple(args[0]) return self._reduce_point(args[0], characteristic) args = tuple(args[0]) return plane_curve.ProjectiveCurve_generic.__call__(self, *args, **kwds) EXAMPLES:: sage: E=EllipticCurve(GF(5),[1,1]) sage: E._homset_class(GF(5^10,'a'),GF(5)) Abelian group of points on Finite Field in a of size 5^10 sage: E._homset_class(Spec(GF(5^10,'a'),GF(5)), E) Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 5^10 """ return homset.SchemeHomsetModule_abelian_variety_coordinates_field(*args, **kwds) sage: F = EllipticCurve('27a3') # should be the same one sage: E.isomorphisms(F); [Generic morphism: From: Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field To:   Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field Via:  (u,r,s,t) = (-1, 0, 0, -1), Generic morphism: From: Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field To:   Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field Via:  (u,r,s,t) = (1, 0, 0, 0)] From: Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field To:   Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field Via:  (u,r,s,t) = (-1, 0, 0, -1), Generic morphism: From: Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field To:   Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field Via:  (u,r,s,t) = (1, 0, 0, 0)] We can also find isomorphisms defined over extension fields::
• ## sage/schemes/elliptic_curves/ell_number_field.py

diff --git a/sage/schemes/elliptic_curves/ell_number_field.py b/sage/schemes/elliptic_curves/ell_number_field.py
 a sage: K. = NumberField(x^4 + x^3 + 11*x^2 + 41*x + 101) sage: EK = E.base_extend(K) sage: EK.torsion_points() [(5 : 5 : 1), (5 : -6 : 1), (16 : -61 : 1), (-3/55*t^3 - 7/55*t^2 - 2/55*t - 133/55 : 6/55*t^3 + 3/55*t^2 + 25/11*t + 156/55 : 1), (-9/121*t^3 - 21/121*t^2 - 127/121*t - 377/121 : -7/121*t^3 + 24/121*t^2 + 197/121*t + 16/121 : 1), (5/121*t^3 - 14/121*t^2 - 158/121*t - 453/121 : -49/121*t^3 - 129/121*t^2 - 315/121*t - 207/121 : 1), (10/121*t^3 + 49/121*t^2 + 168/121*t + 73/121 : 32/121*t^3 + 60/121*t^2 - 261/121*t - 807/121 : 1), (1/11*t^3 - 5/11*t^2 + 19/11*t - 40/11 : -6/11*t^3 - 3/11*t^2 - 26/11*t - 321/11 : 1), (14/121*t^3 - 15/121*t^2 + 90/121*t + 232/121 : 16/121*t^3 - 69/121*t^2 + 293/121*t - 46/121 : 1), (3/55*t^3 + 7/55*t^2 + 2/55*t + 78/55 : 7/55*t^3 - 24/55*t^2 + 9/11*t + 17/55 : 1), (-5/121*t^3 + 36/121*t^2 - 84/121*t + 24/121 : 34/121*t^3 - 27/121*t^2 + 305/121*t + 708/121 : 1), (-26/121*t^3 + 20/121*t^2 - 219/121*t - 995/121 : 15/121*t^3 + 156/121*t^2 - 232/121*t + 2766/121 : 1), (1/11*t^3 - 5/11*t^2 + 19/11*t - 40/11 : 6/11*t^3 + 3/11*t^2 + 26/11*t + 310/11 : 1), (-26/121*t^3 + 20/121*t^2 - 219/121*t - 995/121 : -15/121*t^3 - 156/121*t^2 + 232/121*t - 2887/121 : 1), (-5/121*t^3 + 36/121*t^2 - 84/121*t + 24/121 : -34/121*t^3 + 27/121*t^2 - 305/121*t - 829/121 : 1), (3/55*t^3 + 7/55*t^2 + 2/55*t + 78/55 : -7/55*t^3 + 24/55*t^2 - 9/11*t - 72/55 : 1), (14/121*t^3 - 15/121*t^2 + 90/121*t + 232/121 : -16/121*t^3 + 69/121*t^2 - 293/121*t - 75/121 : 1), (t : -1/11*t^3 - 6/11*t^2 - 19/11*t - 59/11 : 1), (10/121*t^3 + 49/121*t^2 + 168/121*t + 73/121 : -32/121*t^3 - 60/121*t^2 + 261/121*t + 686/121 : 1), (5/121*t^3 - 14/121*t^2 - 158/121*t - 453/121 : 49/121*t^3 + 129/121*t^2 + 315/121*t + 86/121 : 1), (-9/121*t^3 - 21/121*t^2 - 127/121*t - 377/121 : 7/121*t^3 - 24/121*t^2 - 197/121*t - 137/121 : 1), (-3/55*t^3 - 7/55*t^2 - 2/55*t - 133/55 : -6/55*t^3 - 3/55*t^2 - 25/11*t - 211/55 : 1), (0 : 1 : 0), (16 : 60 : 1), (t : 1/11*t^3 + 6/11*t^2 + 19/11*t + 48/11 : 1)] [(16 : 60 : 1), (5 : 5 : 1), (5 : -6 : 1), (16 : -61 : 1), (t : 1/11*t^3 + 6/11*t^2 + 19/11*t + 48/11 : 1), (-3/55*t^3 - 7/55*t^2 - 2/55*t - 133/55 : 6/55*t^3 + 3/55*t^2 + 25/11*t + 156/55 : 1), (-9/121*t^3 - 21/121*t^2 - 127/121*t - 377/121 : -7/121*t^3 + 24/121*t^2 + 197/121*t + 16/121 : 1), (5/121*t^3 - 14/121*t^2 - 158/121*t - 453/121 : -49/121*t^3 - 129/121*t^2 - 315/121*t - 207/121 : 1), (10/121*t^3 + 49/121*t^2 + 168/121*t + 73/121 : 32/121*t^3 + 60/121*t^2 - 261/121*t - 807/121 : 1), (1/11*t^3 - 5/11*t^2 + 19/11*t - 40/11 : -6/11*t^3 - 3/11*t^2 - 26/11*t - 321/11 : 1), (14/121*t^3 - 15/121*t^2 + 90/121*t + 232/121 : 16/121*t^3 - 69/121*t^2 + 293/121*t - 46/121 : 1), (3/55*t^3 + 7/55*t^2 + 2/55*t + 78/55 : 7/55*t^3 - 24/55*t^2 + 9/11*t + 17/55 : 1), (-5/121*t^3 + 36/121*t^2 - 84/121*t + 24/121 : 34/121*t^3 - 27/121*t^2 + 305/121*t + 708/121 : 1), (-26/121*t^3 + 20/121*t^2 - 219/121*t - 995/121 : 15/121*t^3 + 156/121*t^2 - 232/121*t + 2766/121 : 1), (1/11*t^3 - 5/11*t^2 + 19/11*t - 40/11 : 6/11*t^3 + 3/11*t^2 + 26/11*t + 310/11 : 1), (-26/121*t^3 + 20/121*t^2 - 219/121*t - 995/121 : -15/121*t^3 - 156/121*t^2 + 232/121*t - 2887/121 : 1), (-5/121*t^3 + 36/121*t^2 - 84/121*t + 24/121 : -34/121*t^3 + 27/121*t^2 - 305/121*t - 829/121 : 1), (3/55*t^3 + 7/55*t^2 + 2/55*t + 78/55 : -7/55*t^3 + 24/55*t^2 - 9/11*t - 72/55 : 1), (14/121*t^3 - 15/121*t^2 + 90/121*t + 232/121 : -16/121*t^3 + 69/121*t^2 - 293/121*t - 75/121 : 1), (t : -1/11*t^3 - 6/11*t^2 - 19/11*t - 59/11 : 1), (10/121*t^3 + 49/121*t^2 + 168/121*t + 73/121 : -32/121*t^3 - 60/121*t^2 + 261/121*t + 686/121 : 1), (5/121*t^3 - 14/121*t^2 - 158/121*t - 453/121 : 49/121*t^3 + 129/121*t^2 + 315/121*t + 86/121 : 1), (-9/121*t^3 - 21/121*t^2 - 127/121*t - 377/121 : 7/121*t^3 - 24/121*t^2 - 197/121*t - 137/121 : 1), (-3/55*t^3 - 7/55*t^2 - 2/55*t - 133/55 : -6/55*t^3 - 3/55*t^2 - 25/11*t - 211/55 : 1), (0 : 1 : 0)] :: sage: K. = NumberField(x^2 + 2*x + 10) sage: EK = E.base_extend(K) sage: EK.torsion_points() [(3 : -2 : 1), (8 : -27 : 1), (1/2 : 5/4*t + 1/2 : 1), (-t - 2 : 2*t + 8 : 1), (-7 : -5*t - 2 : 1), (-1 : 0 : 1), (-2 : 3 : 1), (-13/4 : 9/8 : 1), (-2 : -2 : 1), (t : -2*t + 4 : 1), (-7 : 5*t + 8 : 1), (-t - 2 : -t - 7 : 1), (1/2 : -5/4*t - 2 : 1), (0 : 1 : 0), (8 : 18 : 1), (t : t - 5 : 1)] [(8 : 18 : 1), (3 : -2 : 1), (8 : -27 : 1), (t : t - 5 : 1), (1/2 : 5/4*t + 1/2 : 1), (-t - 2 : 2*t + 8 : 1), (-7 : -5*t - 2 : 1), (-1 : 0 : 1), (-2 : 3 : 1), (-13/4 : 9/8 : 1), (-2 : -2 : 1), (t : -2*t + 4 : 1), (-7 : 5*t + 8 : 1), (-t - 2 : -t - 7 : 1), (1/2 : -5/4*t - 2 : 1), (0 : 1 : 0)] :: sage: K. = QuadraticField(-1) sage: EK = EllipticCurve(K,[0,0,0,0,-1]) sage: EK.torsion_points () [(0 : -i : 1), (1 : 0 : 1), (0 : i : 1), (-2 : 3*i : 1), (0 : 1 : 0), (-2 : -3*i : 1)] [(-2 : -3*i : 1), (0 : -i : 1), (1 : 0 : 1), (0 : i : 1), (-2 : 3*i : 1), (0 : 1 : 0)] """ T = self.torsion_subgroup() # make sure it is cached return sorted(T.points())           # these are also cached in T
• ## sage/schemes/elliptic_curves/ell_point.py

diff --git a/sage/schemes/elliptic_curves/ell_point.py b/sage/schemes/elliptic_curves/ell_point.py
 a sage: Q+Q == 4*P True """ if isinstance(other, (int, long, rings.Integer)) and other == 0: if self.is_zero(): return 0 else: return -1 return SchemePoint_projective_abelian_scheme.__cmp__(self, other) class EllipticCurvePoint_field(AdditiveGroupElement): # SchemeMorphism_abelian_variety_coordinates_field): assert isinstance(other, (int, long, rings.Integer)) and other == 0 if self.is_zero(): return 0 else: return -1 class EllipticCurvePoint_field(SchemeMorphism_abelian_variety_coordinates_field): """ A point on an elliptic curve over a field.  The point has coordinates in the base field. (1 : -2 : 1) """ point_homset = curve.point_homset() AdditiveGroupElement.__init__(self, point_homset) if is_SchemeMorphism(v) or isinstance(v,EllipticCurvePoint_field): v = list(v) elif v == 0: # some of the code assumes that E(0) has integral entries # irregardless of the base ring... #R = self.base_ring() #v = (R.zero(),R.one(),R.zero()) v = (0,1,0) if check: # mostly from SchemeMorphism_projective_coordinates_field d = point_homset.codomain().ambient_space().ngens() if is_SchemeMorphism(v) or isinstance(v, EllipticCurvePoint_field): v = list(v) elif v == 0: self._coords = Sequence((0,1,0), point_homset.value_ring()) return if not isinstance(v,(list,tuple)): raise TypeError, \ "Argument v (= %s) must be a scheme point, list, or tuple."%str(v) test = y**2 + (a1*x+a3)*y - (((x+a2)*x+a4)*x+a6) if not test == 0: raise TypeError, "Coordinates %s do not define a point on %s"%(list(v),curve) #            point_homset.codomain()._check_satisfies_equations(v) self._coords = v SchemeMorphism_abelian_variety_coordinates_field.__init__(self, point_homset, v, check=False) #AdditiveGroupElement.__init__(self, point_homset) def _repr_(self): """ sage: tor = E.torsion_points(); len(tor) 8 sage: [T.order() for T in tor] [2, 4, 4, 2, 4, 1, 4, 2] [4, 2, 4, 2, 4, 2, 4, 1] sage: all([T.is_divisible_by(3) for T in tor]) True sage: Set([T for T in tor if T.is_divisible_by(2)])
• ## sage/schemes/elliptic_curves/ell_torsion.py

diff --git a/sage/schemes/elliptic_curves/ell_torsion.py b/sage/schemes/elliptic_curves/ell_torsion.py
 a sage: type(T) sage: T == loads(dumps(T)) sage: T == loads(dumps(T))  # optional - pickling http://trac.sagemath.org/sage_trac/ticket/11599 True """
• ## sage/schemes/generic/affine_space.py

diff --git a/sage/schemes/generic/affine_space.py b/sage/schemes/generic/affine_space.py
 a r""" Return affine space of dimension n over the ring R. EXAMPLES: The dimension and ring can be given in either order. :: 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: A.coordinate_ring() Multivariate Polynomial Ring in X, Y over Rational Field Use the divide operator for base extension. :: 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. :: 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. :: There is also an affine space associated to each polynomial ring:: sage: R = GF(7)['x,y,z'] sage: A = AffineSpace(R); A raise TypeError, "You must specify the variables names of the coordinate ring." return AffineSpace_generic(n, R, names) class AffineSpace_generic(AmbientSpace, AffineScheme): """ Affine space of dimension n over the ring R. sage: X.base_ring() Rational Field sage: X.category() Category of schemes over Spectrum of Rational Field sage: X.structure_morphism () Category of schemes over Rational Field sage: X.structure_morphism() Scheme morphism: From: Affine Space of dimension 3 over Rational Field To:   Spectrum of Rational Field sage: loads(X.dumps()) == X True We create several other examples of affine spaces. :: We create several other examples of affine spaces:: sage: AffineSpace(5, PolynomialRing(QQ, 'z'), 'Z') Affine Space of dimension 5 over Univariate Polynomial Ring in z over Rational Field :: sage: AffineSpace(RealField(), 3, 'Z') Affine Space of dimension 3 over Real Field with 53 bits of precision :: sage: AffineSpace(Qp(7), 2, 'x') Affine Space of dimension 2 over 7-adic Field with capped relative precision 20 Even 0-dimensional affine spaces are supported. :: Even 0-dimensional affine spaces are supported:: sage: AffineSpace(0) Affine Space of dimension 0 over Integer Ring
• ## sage/schemes/generic/algebraic_scheme.py

diff --git a/sage/schemes/generic/algebraic_scheme.py b/sage/schemes/generic/algebraic_scheme.py
 a OUTPUT: A scheme morphism whose :meth:~morphism.PyMorphism.domain is self. A scheme morphism whose :meth:~morphism.SchemeMorphism.domain is self. * By default, it is the tautological embedding into its own ambient space :meth:ambient_space. ... 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/schemes/generic/ambient_space.py

diff --git a/sage/schemes/generic/ambient_space.py b/sage/schemes/generic/ambient_space.py
 a from sage.rings.all import Integer, is_CommutativeRing, ZZ from sage.structure.parent import Parent import scheme from sage.schemes.generic.scheme import Scheme def is_AmbientSpace(x): """ """ return isinstance(x, AmbientSpace) class AmbientSpace(scheme.Scheme, Parent): class AmbientSpace(Scheme): """ Base class for ambient spaces over a ring. n = Integer(n) if n < 0: raise ValueError, "n (=%s) must be nonnegative"%n self.__n = n self._base_ring = R self._dimension_relative = n Scheme.__init__(self, R) # NT: this seems to set improperly self._base_scheme to X instead of Spec(X)???? # scheme.Scheme.__init__(self, R) # This should be cleaned up by someone who knows about schemes (not me!) from sage.categories.schemes import Schemes Parent.__init__(self, R, category = Schemes(self.base_scheme())) #from sage.categories.schemes import Schemes #Parent.__init__(self, R, category = Schemes(self.base_scheme())) ####################################################################### # Derived classes must overload all of the following functions sage: A2Z.dimension_relative() 2 """ return self.__n return self._dimension_relative
• ## sage/schemes/generic/homset.py

diff --git a/sage/schemes/generic/homset.py b/sage/schemes/generic/homset.py
 a """ Set of homomorphisms between two schemes .. note:: You should not create the homsets manually. Instead, use the :meth:~sage.structure.parent.Hom method that is inherited by all schemes. """ #***************************************************************************** #                  http://www.gnu.org/licenses/ #***************************************************************************** import sage.structure.parent_old as parent_old from sage.categories.homset import HomsetWithBase from sage.rings.integer_ring import ZZ from sage.rings.finite_rings.constructor import is_FiniteField from sage.rings.rational_field import is_RationalField from sage.rings.morphism import is_RingHomomorphism from sage.structure.factory import UniqueFactory import spec import morphism from sage.rings.all import ( gcd, ZZ, QQ, is_CommutativeRing, is_RingHomomorphism, is_RationalField, is_FiniteField ) from sage.schemes.generic.scheme import is_Scheme from sage.schemes.generic.spec import Spec, is_Spec from sage.schemes.generic.morphism import ( SchemeMorphism, SchemeMorphism_structure_map, SchemeMorphism_spec, SchemeMorphism_affine_coordinates, SchemeMorphism_projective_coordinates_field ) from sage.schemes.generic.toric_morphism import SchemeMorphism_toric_coordinates_field def is_SchemeHomset(H): r""" Test whether H is a scheme homset. """ return isinstance(H, SchemeHomset_generic) def SchemeHomset(R, S, category=None, check=True): if spec.is_Spec(R) and spec.is_Spec(S): return SchemeHomset_spec(R, S, category=category, check=check) else: return SchemeHomset_generic(R, S, category=category, check=check) class SchemeHomset_generic(parent_old.Parent, HomsetWithBase): def __init__(self, X, Y, category=None, check=True, base=ZZ): HomsetWithBase.__init__(self, X, Y, category=category, check=check, base=base) #******************************************************************* # Factory for Hom sets of schemes #******************************************************************* class SchemeHomsetFactory(UniqueFactory): """ Factory for Hom sets of schemes. def has_coerce_map_from_impl(self, S): if self == S:   # an obvious case return True # Todo -- implement more cases. return False EXAMPLES:: sage: A2 = AffineSpace(QQ,2) sage: A3 = AffineSpace(QQ,3) sage: Hom = A3.Hom(A2) sage: Hom is copy(Hom) True sage: Hom is A3.Hom(A2) True sage: loads(Hom.dumps()) is Hom True Here is a tricy point. The Hom sets are not identical if domain/codomains are isomorphic but not identiacal:: sage: A3_iso = AffineSpace(QQ,3) sage: [ A3_iso is A3, A3_iso == A3 ] [False, True] sage: Hom_iso = A3_iso.Hom(A2) sage: Hom_iso is Hom False sage: Hom_iso == Hom True TESTS:: sage: Hom.base() Integer Ring sage: Hom.base_ring() Integer Ring """ def create_key_and_extra_args(self, X, Y, category=None, check=True, base=ZZ): """ Create a key that uniquely determines the Hom set. INPUT: - X -- a scheme. The domain of the morphisms. - Y -- a scheme. The codomain of the morphisms. - base -- a scheme or a ring. The base scheme of domain and codomain schemes. If a ring is specified, the spectrum of that ring will be used as base scheme. - check -- boolean (default: True). EXAMPLES:: 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 (..., ..., Category of schemes over Integer Ring) sage: extra {'Y': Affine Space of dimension 2 over Rational Field, 'X': Affine Space of dimension 3 over Rational Field, 'base_ring': Integer Ring, 'check': False} """ if not is_Scheme(X) and is_CommutativeRing(X): X = Spec(X) if not is_Scheme(Y) and is_CommutativeRing(Y): Y = Spec(Y) if is_Spec(base): base_spec = base base_ring = base.coordinate_ring() elif is_CommutativeRing(base): base_spec = Spec(base) base_ring = base else: raise ValueError('The base must be an affine scheme or a commutative ring.') if not category: from sage.categories.schemes import Schemes category = Schemes(base_spec) key = tuple([id(X), id(Y), category]) extra = {'X':X, 'Y':Y, 'base_ring':base_ring, 'check':check} return key, extra def create_object(self, version, key, **extra_args): """ Create a :class:SchemeHomset_generic. INPUT: - version -- object version. Currently not used. - key -- a key created by :meth:create_key_and_extra_args. - extra_args -- a dictionary of extra keyword arguments. EXAMPLES:: 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 sage: SHOMfactory = SchemeHomsetFactory('test') sage: SHOMfactory.create_object(0, [id(A3),id(A2),A3.category()], check=True, ...                             X=A3, Y=A2, base_ring=QQ) Set of morphisms From: Affine Space of dimension 3 over Rational Field To:   Affine Space of dimension 2 over Rational Field """ category = key[2] X = extra_args.pop('X') Y = extra_args.pop('Y') base_ring = extra_args.pop('base_ring') if is_Spec(X): return Y._homset_class(X, Y, category=category, base=base_ring, **extra_args) return SchemeHomset_generic(X, Y, category=category, base=base_ring, **extra_args) SchemeHomset = SchemeHomsetFactory('sage.schemes.generic.homset.SchemeHomset') #******************************************************************* # Base class #******************************************************************* class SchemeHomset_generic(HomsetWithBase): r""" The base class for Hom sets of schemes. INPUT: - X -- a scheme. The domain of the Hom set. - Y -- a scheme. The codomain of the Hom set. - category -- a category (optional). The category of the Hom set. - check -- boolean (optional, default=True). Whether to check the defining data for consistency. EXAMPLES:: sage: from sage.schemes.generic.homset import SchemeHomset_generic sage: A2 = AffineSpace(QQ,2) sage: Hom = SchemeHomset_generic(A2, A2); Hom Set of morphisms From: Affine Space of dimension 2 over Rational Field To:   Affine Space of dimension 2 over Rational Field sage: Hom.category() Category of hom sets in Category of Schemes """ Element = SchemeMorphism def __call__(self, *args, **kwds): r""" Make Hom sets callable. See the _call_() method of the derived class. All arguments are handed through. EXAMPLES:: sage: A2 = AffineSpace(QQ,2) sage: A2(4,5) (4, 5) """ # Homset (base of HomsetWithBase) overrides __call__ @#\$ from sage.structure.parent import Set_generic return Set_generic.__call__(self, *args, **kwds) def _repr_(self): try: return "Set of points of %s defined over %s"%(self.codomain(), self.domain().coordinate_ring()) except ValueError: return "Set of morphisms from %s to %s"%(self.domain(), self.codomain()) r""" Return a string representation. OUTPUT: A string. EXAMPLES:: sage: A = AffineSpace(4, QQ) sage: A.structure_morphism()._repr_() 'Scheme morphism:\n  From: Affine Space of dimension 4 over Rational Field\n  To:   Spectrum of Rational Field\n  Defn: Structure map' """ s = 'Set of morphisms' s += '\n  From: %s' % self.domain() s += '\n  To:   %s' % self.codomain() return s def natural_map(self): r""" Return a natural map in the Hom space. OUTPUT: A :class:SchemeMorphism if there is a natural map from domain to codomain. Otherwise, a NotImplementedError is raised. EXAMPLES:: sage: A = AffineSpace(4, QQ) sage: A.structure_morphism()   # indirect doctest Scheme morphism: From: Affine Space of dimension 4 over Rational Field To:   Spectrum of Rational Field Defn: Structure map """ X = self.domain() Y = self.codomain() if spec.is_Spec(Y) and Y.coordinate_ring() == X.base_ring(): return morphism.SchemeMorphism_structure_map(self) if is_Spec(Y) and Y.coordinate_ring() == X.base_ring(): return SchemeMorphism_structure_map(self) raise NotImplementedError def __call__(self, x, check=True): def _element_constructor_(self, x, check=True): """ Construct a scheme morphism. INPUT: - x -- a ring morphism, or a list or tuple of that define a ring morphism. - x -- a ring morphism, or a list or tuple of that define a ring morphism. - check -- (default: True) passed onto functions called by this to be more careful about input argument type checking - check -- boolean (default: True) passed onto functions called by this to be more careful about input argument type checking EXAMPLES:: From: Integer Ring To:   Rational Field :: sage: H = Hom(Spec(QQ,ZZ), Spec(ZZ)); H Set of points of Spectrum of Integer Ring defined over Rational Field :: sage: H = Hom(Spec(QQ, ZZ), Spec(ZZ)); H Set of rational points of Spectrum of Rational Field sage: phi = H(f); phi Affine Scheme morphism: From: Integer Ring To:   Rational Field TESTS:: TESTS: We illustrate input type checking:: sage: A. = AffineSpace(R) sage: C = A.subscheme(x*y-1) sage: H = C.Hom(C); H Set of points of Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: x*y - 1 defined over Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x*y - 1) 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 sage: H(1) Traceback (most recent call last): ... return self.domain()._point_morphism_class(self, x, check=check) if is_RingHomomorphism(x): return morphism.SchemeMorphism_spec(self, x, check=check) return SchemeMorphism_spec(self, x, check=check) raise TypeError, "x must be a ring homomorphism, list or tuple" class SchemeHomset_spec(SchemeHomset_generic): pass class SchemeHomset_coordinates(SchemeHomset_generic): """ Set of points on X defined over the base ring of X, and given by explicit tuples. Set of rational points of the scheme. Recall that the K-rational points of a scheme X over k can be identified with the set of morphisms Spec(K) \to X. In Sage, the rational points are implemented by such scheme morphisms. INPUT: See :class:SchemeHomset_generic. EXAMPLES:: sage: from sage.schemes.generic.homset import SchemeHomset_coordinates sage: SchemeHomset_coordinates(Spec(QQ), AffineSpace(ZZ,2)) Set of rational points of Affine Space of dimension 2 over Rational Field """ def __init__(self, X, S): R = X.base_ring() if R != S: X = X.base_extend(S) SchemeHomset_generic.__init__(self, spec.Spec(S, R), X) def __init__(self, X, Y, category=None, check=True, base=ZZ): """ Python constructor. INPUT: See :class:SchemeHomset_generic. EXAMPLES:: sage: from sage.schemes.generic.homset import SchemeHomset_coordinates sage: SchemeHomset_coordinates(Spec(QQ), AffineSpace(ZZ,2)) Set of rational points of Affine Space of dimension 2 over Rational Field """ if check and not is_Spec(X): raise ValueError('The domain must be an affine scheme.') SchemeHomset_generic.__init__(self, X, Y, category=category, check=check, base=base) def extended_codomain(self): """ Return the codomain with extended base, if necessary. OUTPUT: The codomain scheme, with its base ring extended to the codomain. That is, the codomain is of the form Spec(R) and the base ring of the domain is extended to R. EXAMPLES:: sage: P2 = ProjectiveSpace(QQ,2) sage: K. = NumberField(x^2 + x - (3^3-3)) sage: K_points = P2(K);  K_points Set of rational points of Projective Space of dimension 2 over Number Field in a with defining polynomial x^2 + x - 24 sage: K_points.codomain() 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 """ if '_extended_codomain' in self.__dict__: return self._extended_codomain R = self.domain().coordinate_ring() if R is not self.codomain().base_ring(): X = self.codomain().base_extend(R) else: X = self.codomain() self._extended_codomain = X return X def _repr_(self): S = self.domain() if S == self.codomain().base_scheme(): return "Set of Rational Points of %s"%self.codomain() if spec.is_Spec(S): S = S.coordinate_ring() return "Set of Rational Points over %s of %s"%(S, self.codomain()) """ Return a string representation of self. OUTPUT: A string. EXAMPLES:: sage: P2 = ProjectiveSpace(ZZ,2) sage: P2(QQ)._repr_() 'Set of rational points of Projective Space of dimension 2 over Rational Field' """ return 'Set of rational points of '+str(self.extended_codomain()) def value_ring(self): """ Returns S for a homset X(T) where T = Spec(S). Returns R for a homset X(Spec(R)) OUTPUT: A commutative ring. EXAMPLES:: sage: P2 = ProjectiveSpace(ZZ,2) sage: P2(QQ).value_ring() Rational Field """ T = self.domain() if spec.is_Spec(T): return T.coordinate_ring() else: raise TypeError, "Domain of argument must be of the form Spec(S)." dom = self.domain() assert is_Spec(dom) return dom.coordinate_ring() #******************************************************************* #******************************************************************* class SchemeHomset_affine_coordinates(SchemeHomset_coordinates): """ Set of points on X defined over the base ring of X, and given by explicit tuples. Set of rational points of an affine variety. INPUT: See :class:SchemeHomset_generic. EXAMPLES:: sage: from sage.schemes.generic.homset import SchemeHomset_affine_coordinates sage: SchemeHomset_affine_coordinates(Spec(QQ), AffineSpace(ZZ,2)) Set of rational points of Affine Space of dimension 2 over Rational Field """ def __call__(self, *v): def _element_constructor_(self, *v): """ The element contstructor. INPUT: - v -- anything that determines a scheme morphism in the hom set. OUTPUT: The scheme morphism determined by v. EXAMPLES:: sage: A2 = AffineSpace(ZZ,2) sage: F = GF(3) sage: F_points = A2(F);  type(F_points) sage: F_points([2,5]) (2, 2) """ if len(v) == 1: v = v[0] return morphism.SchemeMorphism_affine_coordinates(self, v) return SchemeMorphism_affine_coordinates(self, v) def points(self, B=0): r""" Return the set of points given by coordinate tuples with coordinates in the base ring. Return some or all rational points of an affine scheme. INPUT: - B -- an integer. - B -- integer (optional, default=0). The bound for the height of the coordinates. OUTPUT: - If the base ring is a finite field: the set of points given by coordinate tuples. - 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. = R[] sage: I = A.ideal(x^2-y^2-1) 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)." 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 #******************************************************************* class SchemeHomset_projective_coordinates_field(SchemeHomset_coordinates): """ Set of points on X defined over the base ring of X, and given by explicit tuples. Set of rational points of a projective variety over a field. INPUT: See :class:SchemeHomset_generic. EXAMPLES:: sage: from sage.schemes.generic.homset import SchemeHomset_projective_coordinates_field sage: SchemeHomset_projective_coordinates_field(Spec(QQ), ProjectiveSpace(QQ,2)) Set of rational points of Projective Space of dimension 2 over Rational Field """ def __call__(self, *v): def _element_constructor_(self, *v): """ The element contstructor. INPUT: - v -- anything that determines a scheme morphism in the hom set. OUTPUT: The scheme morphism determined by v. EXAMPLES:: sage: P2 = ProjectiveSpace(GF(3),2) sage: F. = GF(9,'a') sage: F_points = P2(F) sage: F_points([4,2*a]) (1 : 2*a : 1) """ if len(v) == 1: v = v[0] X = self.codomain() try: return X._point_class(X, v) except AttributeError:  # should be very rare return morphism.SchemeMorphism_projective_coordinates_field(self, v) X = self.extended_codomain() return X.point(v) 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. = GF(4,'a') sage: P1(F).points() [(0 : 1), (1 : 0), (1 : 1), (a : 1), (a + 1 : 1)] """ 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)." 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) return enum_projective_finite_field(self.extended_codomain()) else: raise TypeError, "Unable to enumerate points over %s."%R class SchemeHomset_projective_coordinates_ring(SchemeHomset_coordinates): """ Set of points on X defined over the base ring of X, and given by explicit tuples. Set of rational points of a projective variety over a commutative ring. INPUT: See :class:SchemeHomset_generic. EXAMPLES:: sage: from sage.schemes.generic.homset import SchemeHomset_projective_coordinates_ring sage: SchemeHomset_projective_coordinates_ring(Spec(ZZ), ProjectiveSpace(ZZ,2)) Set of rational points of Projective Space of dimension 2 over Integer Ring """ def __call__(self, *v): def _element_constructor_(self, *v): r""" The element constructor. This is currently not implemented. EXAMPLES:: sage: from sage.schemes.generic.homset import SchemeHomset_projective_coordinates_ring sage: Hom = SchemeHomset_projective_coordinates_ring(Spec(ZZ), ProjectiveSpace(ZZ,2)) sage: Hom(1,2,3) Traceback (most recent call last): ... NotImplementedError """ raise NotImplementedError def points(self, B=0): raise NotImplementedError # fixed when __call__ is defined. try: R = self.value_ring() except TypeError: raise TypeError, "Domain of argument must be of the form Spec(S)." """ Return some or all rational points of a projective scheme. INPUT: - B -- integer (optional, default=0). The bound for the coordinates. OUTPUT: This is currently not implemented and will raise NotImplementedError. EXAMPLES:: sage: from sage.schemes.generic.homset import SchemeHomset_projective_coordinates_ring sage: Hom = SchemeHomset_projective_coordinates_ring(Spec(ZZ), ProjectiveSpace(ZZ,2)) sage: Hom.points(5) Traceback (most recent call last): ... NotImplementedError """ raise NotImplementedError # fixed when _element_constructor_ is defined. R = self.value_ring() if R == ZZ: if not B > 0: raise TypeError, "A positive bound B (= %s) must be specified."%B # Abelian varieties #******************************************************************* class SchemeHomsetModule_abelian_variety_coordinates_field(SchemeHomset_projective_coordinates_field): def __init__(self, X, S, category=None, check=True): r""" EXAMPLES: The bug reported at trac #1785 is fixed:: r""" Set of rational points of an abelian variety. INPUT: See :class:SchemeHomset_generic. TESTS: 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 (3 : a : 1) sage: P in E False sage: P in E.base_extend(K) True """ R = X.base_ring() if R != S: X = X.base_extend(S) Y = spec.Spec(S, R) HomsetWithBase.__init__(self, Y, X, category=category, check = check, base = ZZ) 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 (3 : a : 1) sage: P in E False sage: P in E.base_extend(K) True sage: P in X.codomain() False sage: P in X.extended_codomain() True """ def _repr_(self): return "Abelian group of points on %s"%self.codomain() """ Return a string representation of self. OUTPUT: String. EXAMPLES:: sage: E = EllipticCurve('37a') sage: X = E(QQ) sage: X._repr_() 'Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field' """ s = 'Abelian group of points on ' + str(self.extended_codomain()) return s def base_extend(self, R): if R != sage.rings.integer_ring.ZZ: raise NotImplementedError, "Abelian variety point sets not implemented as modules over rings other than ZZ." if not R is ZZ: raise NotImplementedError('Abelian variety point sets not implemented ' 'as modules over rings other than ZZ.') return self #******************************************************************* class SchemeHomset_toric_coordinates_field(SchemeHomset_coordinates): """ Construct the Hom-space of morphisms given on coordinates. .. WARNING:: You should not create objects of this class directly. Set of rational points of a toric variety. INPUT: OUPUT: - :class:SchemeHomset_toric_coordinates_field. A scheme morphism of type :class:SchemeHomset_toric_coordinates_field. EXAMPLES:: sage: P1xP1 = toric_varieties.P1xP1() sage: P1xP1(QQ) Set of rational points of 2-d CPR-Fano toric variety covered by 4 affine patches TESTS:: sage: fan = FaceFan(lattice_polytope.octahedron(2)) sage: P1xP1 = ToricVariety(fan) sage: import sage.schemes.generic.homset as HOM sage: HOM.SchemeHomset_toric_coordinates_field(P1xP1, QQ) Set of Rational Points of 2-d toric variety covered by 4 affine patches A better way to construct the same Hom-space as above:: sage: P1xP1(QQ) Set of Rational Points of 2-d toric variety covered by 4 affine patches sage: HOM.SchemeHomset_toric_coordinates_field(Spec(QQ), P1xP1) Set of rational points of 2-d CPR-Fano toric variety covered by 4 affine patches """ # Mimicking SchemeHomset_projective_coordinates_field, # affine spaces implement only "except" case def __call__(self, *arg): r""" Construct a morphism from given parameters. INPUT: - data determining a morphism. TESTS:: sage: fan = FaceFan(lattice_polytope.octahedron(2)) sage: P1xP1 = ToricVariety(fan) sage: import sage.schemes.generic.homset as HOM sage: H = HOM.SchemeHomset_toric_coordinates_field(P1xP1, QQ) sage: H(1,2,3,4) [1 : 2 : 3 : 4] """ # This may break for one-dimensional varieties. if len(arg) == 1: arg = arg[0] X = self.codomain() try: return X._point_class(X, arg) except AttributeError:  # should be very rare return SchemeMorphism_toric_coordinates_field(self, arg) pass
• ## sage/schemes/generic/morphism.py

diff --git a/sage/schemes/generic/morphism.py b/sage/schemes/generic/morphism.py
 a """ Scheme morphism .. note:: You should never create the morphisms directy. Instead, use the :meth:~sage.schemes.generic.scheme.hom and :meth:~sage.structure.parent.Hom methods that are inherited by all schemes. AUTHORS: - David Kohel, William Stein from point                    import is_SchemeTopologicalPoint import scheme def is_SchemeMorphism(f): """ Return True if f is a scheme morphism or a point on an elliptic curve. Test whether f is a scheme morphism. INPUT: - f -- anything. OUTPUT: Boolean. Return True if fa is a scheme morphism or a point on an elliptic curve. EXAMPLES:: sage: R. = QQ[]; A. = AffineSpace(R); H = A.Hom(A) sage: f = H([y,x^2+y]) sage: sage.schemes.generic.morphism.is_SchemeMorphism(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) sage: from sage.schemes.generic.morphism import is_SchemeMorphism sage: is_SchemeMorphism(f) True """ from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field # TODO: fix circular ref. from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field return isinstance(f, (SchemeMorphism, EllipticCurvePoint_field)); class PyMorphism(Element): class SchemeMorphism(Element): """ Base class for scheme morphisms INPUT: - parent -- the parent of the morphism. EXAMPLES:: sage: from sage.schemes.generic.scheme import Scheme sage: X = Scheme(ZZ) sage: Hom = X.Hom(X) sage: from sage.schemes.generic.morphism import SchemeMorphism sage: f = SchemeMorphism(Hom) sage: type(f) """ def __init__(self, parent): """ The Pyhon constructor. EXAMPLES:: sage: from sage.schemes.generic.scheme import Scheme sage: X = Scheme(ZZ) sage: Hom = X.Hom(X) sage: from sage.schemes.generic.morphism import SchemeMorphism sage: f = SchemeMorphism(Hom) sage: type(f) """ if not isinstance(parent, Homset): raise TypeError, "parent (=%s) must be a Homspace"%parent Element.__init__(self, parent) self._domain = parent.domain() self._codomain = parent.codomain() def _repr_defn(self): r""" Return a string representation of the definition of self. OUTPUT: String. EXAMPLES:: sage: from sage.schemes.generic.scheme import Scheme sage: X = Scheme(ZZ) sage: Hom = X.Hom(X) sage: from sage.schemes.generic.morphism import SchemeMorphism sage: f = SchemeMorphism(Hom) sage: f._repr_defn() Traceback (most recent call last): ... NotImplementedError """ raise NotImplementedError def _repr_type(self): return "Generic" r""" Return a string representation of the type of self. def _repr_defn(self): return "" OUTPUT: String. EXAMPLES:: sage: from sage.schemes.generic.scheme import Scheme sage: X = Scheme(ZZ) sage: Hom = X.Hom(X) sage: from sage.schemes.generic.morphism import SchemeMorphism sage: f = SchemeMorphism(Hom) sage: f._repr_type() 'Scheme' """ return "Scheme" def _repr_(self): r""" Return a string representation of self. OUTPUT: String. EXAMPLES:: sage: from sage.schemes.generic.scheme import Scheme sage: X = Scheme(ZZ) sage: Hom = X.Hom(X) sage: from sage.schemes.generic.morphism import SchemeMorphism sage: f = SchemeMorphism(Hom) sage: f._repr_() Traceback (most recent call last): ... NotImplementedError """ if self.is_endomorphism(): s = "%s endomorphism of %s"%(self._repr_type(), self.domain()) else: if d != '': s += "\n  Defn: %s"%('\n        '.join(self._repr_defn().split('\n'))) return s def domain(self): """ Return the domain of the morphism. OUTPUT: A scheme. The domain of the morphism self. EXAMPLES:: sage: A2 = AffineSpace(QQ,2) sage: A2.structure_morphism().domain() Affine Space of dimension 2 over Rational Field """ return self._domain def codomain(self): """ Return the codomain (range) of the morphism. OUTPUT: A scheme. The codomain of the morphism self. EXAMPLES:: sage: A2 = AffineSpace(QQ,2) sage: A2.structure_morphism().codomain() Spectrum of Rational Field """ return self.parent().codomain() def category(self): """ Return the category of the hom set. OUTPUT: A category. EXAMPLES:: EXAMPLES:: sage: A2 = AffineSpace(QQ,2) sage: A2.structure_morphism().category() Category of hom sets in Category of Schemes """ return self.parent().category() def is_endomorphism(self): """ Return wether the morphism is an endomorphism. OUTPUT: Boolean. Whether the domain and codomain are identical. EXAMPLES:: sage: X = AffineSpace(QQ,2) sage: X.structure_morphism().is_endomorphism() False sage: X.identity_morphism().is_endomorphism() True """ return self.parent().is_endomorphism_set() def _composition_(self, right, homset): return FormalCompositeMorphism(homset, right, self) """ Helper to construct the composition of two morphisms. EXAMPLES:: sage: X = AffineSpace(QQ,2) sage: f = X.structure_morphism() sage: g = X.identity_morphism() sage: f._composition_(g, f.parent()) Traceback (most recent call last): ... NotImplementedError sage: f * g Traceback (most recent call last): ... TypeError: unsupported operand type(s) for *: 'SchemeMorphism_structure_map' and 'SchemeMorphism_id' """ raise NotImplementedError def __pow__(self, n, dummy=None): """ Exponentiate an endomorphism. INPUT: - n -- integer. The exponent. OUTPUT: A scheme morphism in the same endomorphism set as self. EXAMPLES:: sage: X = AffineSpace(QQ,2) sage: id = X.identity_morphism() sage: id^0 Scheme endomorphism of Affine Space of dimension 2 over Rational Field Defn: Identity map sage: id^2 Traceback (most recent call last): ... TypeError: unsupported operand type(s) for *: 'SchemeMorphism_id' and 'SchemeMorphism_id' """ if not self.is_endomorphism(): raise TypeError, "self must be an endomorphism." # todo -- what about the case n=0 -- need to specify the identity map somehow. if n==0: return self.domain().identity_morphism() return generic_power(self, n) class SchemeMorphism(PyMorphism): """ A scheme morphism """ def __init__(self, parent): PyMorphism.__init__(self, parent) def _repr_type(self): return "Scheme" def glue_along_domains(self, other): r""" Glue two morphism INPUT: - other -- a scheme morphism with the same domain. OUTPUT: Assuming that self and other are open immersions with the same domain, return scheme obtained by gluing along the images. We construct a scheme isomorphic to the projective line over \mathrm{Spec}(\QQ) by gluing two copies of \mathbb{A}^1 minus a point. :: minus a point:: sage: R. = PolynomialRing(QQ, 2) sage: S. = R.quotient(x*y - 1) Scheme obtained by gluing X and Y along U, where 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) :: U: Spectrum of Quotient of Multivariate Polynomial Ring in x, y 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 To:   Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x*y - 1) To:   Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x*y - 1) Defn: x |--> xbar sage: b 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 y over Rational Field Defn: Ring morphism: From: Univariate Polynomial Ring in y over Rational Field To:   Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x*y - 1) To:   Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x*y - 1) Defn: y |--> ybar """ import glue class SchemeMorphism_id(SchemeMorphism): """ Return the identity morphism from X to itself. Return the identity morphism from X to itself. INPUT: - X -- the scheme. EXAMPLES:: sage: X = Spec(ZZ) sage: X.identity_morphism() sage: X.identity_morphism()  # indirect doctest Scheme endomorphism of Spectrum of Integer Ring Defn: Identity map """ def __init__(self, X): """ The Python constructor. See :class:SchemeMorphism_id for details. TESTS:: sage: Spec(ZZ).identity_morphism() Scheme endomorphism of Spectrum of Integer Ring Defn: Identity map """ SchemeMorphism.__init__(self, X.Hom(X)) def _repr_defn(self): return "Identity map" r""" Return a string representation of the definition of self. OUTPUT: String. EXAMPLES:: sage: Spec(ZZ).identity_morphism()._repr_defn() 'Identity map' """ return 'Identity map' class SchemeMorphism_structure_map(SchemeMorphism): r""" The structure morphism INPUT: - parent -- homset with codomain equal to the base scheme of the domain. EXAMPLES:: sage: Spec(ZZ).structure_morphism()    # indirect doctest Scheme morphism: From: Spectrum of Integer Ring To:   Spectrum of Integer Ring Defn: Structure map """ def __init__(self, parent): """ INPUT: The Python constuctor. - parent - homset with codomain equal to the base scheme of the domain. See :class:SchemeMorphism_structure_map for details. TESTS:: sage: from sage.schemes.generic.morphism import SchemeMorphism_structure_map sage: SchemeMorphism_structure_map( Spec(QQ).Hom(Spec(ZZ)) ) Scheme morphism: From: Spectrum of Rational Field To:   Spectrum of Integer Ring Defn: Structure map """ SchemeMorphism.__init__(self, parent) if self.domain().base_scheme() != self.codomain(): raise ValueError, "parent must have codomain equal the base scheme of domain." def _repr_defn(self): return "Structure map" r""" Return a string representation of the definition of self. OUTPUT: String. EXAMPLES:: sage: Spec(ZZ).structure_morphism()._repr_defn() 'Structure map' """ return 'Structure map' class SchemeMorphism_spec(SchemeMorphism): """ A morphism of spectrums of rings Morphism of spectra of rings INPUT: - parent -- homset whose domain and codomain are affine schemes. - phi -- a ring morphism with matching domain and codomain. - check -- boolean (optional, default:True). Whether to check the input for consistency. EXAMPLES:: To:   Rational Field Defn: x |--> 7 :: sage: X = Spec(QQ); Y = Spec(R) sage: f = X.hom(phi); f Affine Scheme morphism: To:   Rational Field Defn: x |--> 7 :: sage: f.ring_homomorphism() Ring morphism: From: Univariate Polynomial Ring in x over Rational Field Defn: x |--> 7 """ def __init__(self, parent, phi, check=True): """ The Python constuctor. See :class:SchemeMorphism_structure_map for details. TESTS:: sage: from sage.schemes.generic.morphism import SchemeMorphism_spec sage: SchemeMorphism_spec(Spec(QQ).Hom(Spec(ZZ)), ZZ.hom(QQ)) Affine Scheme morphism: From: Spectrum of Rational Field To:   Spectrum of Integer Ring Defn: Ring Coercion morphism: From: Integer Ring To:   Rational Field """ SchemeMorphism.__init__(self, parent) if check: if not is_RingHomomorphism(phi): raise TypeError, "phi (=%s) must be a ring homomorphism"%phi raise TypeError("phi (=%s) must be a ring homomorphism" % phi) if phi.domain() != parent.codomain().coordinate_ring(): raise TypeError, "phi (=%s) must have domain %s"%(phi, parent.codomain().coordinate_ring()) raise TypeError("phi (=%s) must have domain %s" % (phi, parent.codomain().coordinate_ring())) if phi.codomain() != parent.domain().coordinate_ring(): raise TypeError, "phi (=%s) must have codomain %s"%(phi, parent.domain().coordinate_ring()) raise TypeError("phi (=%s) must have codomain %s" % (phi, parent.domain().coordinate_ring())) self.__ring_homomorphism = phi def __call__(self, P): r""" Make morphisms callable. INPUT: - P -- a scheme point. OUTPUT: The image scheme point. EXAMPLES:: sage: R. = PolynomialRing(QQ) sage: phi = R.hom([QQ(7)]) sage: X = Spec(QQ); Y = Spec(R) sage: f = X.hom(phi) sage: f(X.an_element()) Traceback (most recent call last): ... NotImplementedError """ if not is_SchemeTopologicalPoint(P) and P in self.domain(): raise TypeError, "P (=%s) must be a topological scheme point of %s"%(P, self) S = self.ring_homomorphism().inverse_image(P.prime_ideal()) return self.codomain()(S) def _repr_type(self): r""" Return a string representation of the type of self. OUTPUT: String. EXAMPLES:: sage: R. = PolynomialRing(QQ) sage: phi = R.hom([QQ(7)]) sage: X = Spec(QQ); Y = Spec(R) sage: f = X.hom(phi) sage: f._repr_type() 'Affine Scheme' """ return "Affine Scheme" def _repr_defn(self): r""" Return a string representation of the type of self. OUTPUT: String. EXAMPLES:: sage: R. = PolynomialRing(QQ) sage: phi = R.hom([QQ(7)]) sage: X = Spec(QQ); Y = Spec(R) sage: f = X.hom(phi) sage: f._repr_type() 'Affine Scheme' """ return repr(self.ring_homomorphism()) def ring_homomorphism(self): """ Return the underlying ring homomorphism. def ring_homomorphism(self): OUTPUT: A ring homomorphism. EXAMPLES:: sage: R. = PolynomialRing(QQ) sage: phi = R.hom([QQ(7)]) sage: X = Spec(QQ); Y = Spec(R) sage: f = X.hom(phi) sage: f.ring_homomorphism() Ring morphism: From: Univariate Polynomial Ring in x over Rational Field To:   Rational Field Defn: x |--> 7 """ return self.__ring_homomorphism """ A morphism of schemes determined by rational functions that define what the morphism does on points in the ambient space. INPUT: - parent -- homset whose domain and codomain are affine schemes. - polys -- a list/tuple/iterable of polynomials defining the scheme morphism. - check -- boolean (optional, default:True). Whether to check the input for consistency. EXAMPLES: sage: f = H([exp(x),exp(y)]) Traceback (most recent call last): ... TypeError: polys (=[e^x, e^y]) must be elements of Multivariate Polynomial Ring in x, y over Rational Field TypeError: polys (=[e^x, e^y]) must be elements of Multivariate Polynomial Ring in x, y over Rational Field """ def __init__(self, parent, polys, check=True): """ The Python constructor. See :class:SchemeMorphism_on_points for details. EXAMPLES:: sage: A2. = AffineSpace(QQ,2) sage: H = A2.Hom(A2) 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) """ if check: if not isinstance(polys, (list, tuple)): raise TypeError, "polys (=%s) must be a list or tuple"%polys def defining_polynomials(self): """ Return the immutable sequence of polynomials that defines this scheme morphism. Return the defining polynomials. OUTPUT: An immutable sequence of polynomials that defines this scheme morphism. EXAMPLES:: """ Apply this morphism to a point in the domain. INPUT: - x -- anything that defines a point in the domain. OUTPUT: A point in the codomain. EXAMPLES:: sage: R. = QQ[] def _repr_defn(self): """ This function is used internally for printing. Return a string representation of the definition of self. OUTPUT: String. EXAMPLES:: Defn: Defined on coordinates by sending (x, y) to (x : y : 1) """ pass class SchemeMorphism_on_points_projective_space(SchemeMorphism_on_points): """ sage: H([exp(x),exp(y)]) Traceback (most recent call last): ... TypeError: polys (=[e^x, e^y]) must be elements of Multivariate Polynomial Ring in x, y over Rational Field TypeError: polys (=[e^x, e^y]) must be elements of Multivariate Polynomial Ring in x, y over Rational Field """ def __init__(self, parent, polys, check=True): """ The Python constructor. See :class:SchemeMorphism_on_points for details. EXAMPLES:: sage: P1. = ProjectiveSpace(QQ,1) sage: H = P1.Hom(P1) sage: H([y,2*x]) Scheme endomorphism of Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x : y) to (y : 2*x) """ SchemeMorphism_on_points.__init__(self, parent, polys, check) if check: # morphisms from projective space are always given by ############################################################################ class SchemeMorphism_coordinates(SchemeMorphism): """ Base class for rational points on schemes. Recall that the K-rational points of a scheme X over k can be identified with the set of morphisms Spec(K) \to X. In Sage, the rational points are implemented by such scheme morphisms. EXAMPLES:: sage: from sage.schemes.generic.morphism import SchemeMorphism sage: f = SchemeMorphism(Spec(ZZ).Hom(Spec(ZZ))) sage: type(f) """ def _repr_(self): r""" Return a string representation of self. OUTPUT: String. EXAMPLES:: sage: A = AffineSpace(2, QQ) sage: a = A(1,2) sage: a._repr_() '(1, 2)' """ return self.codomain().ambient_space()._repr_generic_point(self._coords) def _latex_(self): r""" Return a latex representation of self. OUTPUT: String. EXAMPLES:: sage: A = AffineSpace(2, QQ) sage: a = A(1,2) sage: latex(a) == a._latex_() True sage: a._latex_() '\\left(1, 2\\right)' """ return self.codomain().ambient_space()._latex_generic_point(self._coords) def __getitem__(self, n): """ Return the n-th coordinate. OUTPUT: The coordinate values as an element of the base ring. EXAMPLES:: sage: A = AffineSpace(2, QQ) sage: a = A(1,2) sage: a[0] 1 sage: a[1] 2 """ return self._coords[n] def __iter__(self): """ Iterate over the coordinates of the point. OUTPUT: An iterator. EXAMPLES:: sage: A = AffineSpace(2, QQ) sage: a = A(1,2) sage: iter = a.__iter__() sage: iter.next() 1 sage: iter.next() 2 sage: list(a) [1, 2] """ return iter(self._coords) def __tuple__(self): """ Return the coordinates as a tuple. OUTPUT: A tuple. EXAMPLES:: sage: A = AffineSpace(2, QQ) sage: a = A(1,2) sage: tuple(a) (1, 2) """ return self._coords def __len__(self): """ Return the number of coordinates. OUTPUT: Integer. The number of coordinates used to describe the point. EXAMPLES:: sage: A = AffineSpace(2, QQ) sage: a = A(1,2) sage: len(a) 2 """ return len(self._coords) def __cmp__(self, other): """ Compare two scheme morphisms. INPUT: - other -- anything. To compare against the scheme morphism self. OUTPUT: +1, 0, or -1. EXAMPLES:: sage: A = AffineSpace(2, QQ) sage: a = A(1,2) sage: b = A(3,4) sage: a.__cmp__(b) -1 sage: a != b True """ if not isinstance(other, SchemeMorphism_coordinates): try: other = self.codomain().ambient_space()(other) return cmp(self._coords, other._coords) def scheme(self): """ Return the scheme whose point is represented. OUTPUT: A scheme. EXAMPLES:: sage: A = AffineSpace(2, QQ) sage: a = A(1,2) sage: a.scheme() Affine Space of dimension 2 over Rational Field """ return self.codomain() #******************************************************************* class SchemeMorphism_affine_coordinates(SchemeMorphism_coordinates): """ A morphism determined by giving coordinates in a ring. A rational point on an affine scheme. INPUT: - X -- a subscheme of an ambient affine space over a ring R. -  X - a subscheme of an ambient affine space over a ring R. -  v - a list or tuple of coordinates in R - v -- a list/tuple/iterable of coordinates in R. - check -- boolean (optional, default:True). Whether to check the input for consistency. EXAMPLES:: (1, 2) """ def __init__(self, X, v, check=True): if scheme.is_Scheme(X): X = X(X.base_ring()) """ The Python constructor. See :class:SchemeMorphism_affine_coordinates for details. TESTS:: sage: from sage.schemes.generic.morphism import SchemeMorphism_affine_coordinates sage: A3. = AffineSpace(QQ, 3) sage: SchemeMorphism_affine_coordinates(A3(QQ), [1,2,3]) (1, 2, 3) """ SchemeMorphism.__init__(self, X) if is_SchemeMorphism(v): v = list(v) if check: # Verify that there are the right number of coords d = X.codomain().ambient_space().ngens() d = self.codomain().ambient_space().ngens() if len(v) != d: raise TypeError, \ "Argument v (=%s) must have %s coordinates."%(v, d) if is_SchemeMorphism(v): v = list(v) if not isinstance(v,(list,tuple)): raise TypeError, \ "Argument v (= %s) must be a scheme point, list, or tuple."%str(v) # Make sure the coordinates all lie in the appropriate ring v = Sequence(v, X.value_ring()) # Verify that the point satisfies the equations of X. X.codomain()._check_satisfies_equations(v) self._coords = v X.extended_codomain()._check_satisfies_equations(v) self._coords = tuple(v) #******************************************************************* #******************************************************************* class SchemeMorphism_projective_coordinates_ring(SchemeMorphism_coordinates): """ A morphism determined by giving coordinates in a ring (how?). A rational point of projective space over a ring (how?). Currently this is not implemented. EXAMPLES: sage: from sage.schemes.generic.morphism import SchemeMorphism_projective_coordinates_ring sage: SchemeMorphism_projective_coordinates_ring(None, None) Traceback (most recent call last): ... NotImplementedError """ def __init__(self, X, v, check=True): """ The Python constructor EXAMPLES: sage: from sage.schemes.generic.morphism import SchemeMorphism_projective_coordinates_ring sage: SchemeMorphism_projective_coordinates_ring(None, None) Traceback (most recent call last): ... NotImplementedError """ raise NotImplementedError class SchemeMorphism_projective_coordinates_field(SchemeMorphism_projective_coordinates_ring): """ A morphism determined by giving coordinates in a field. A rational point of projective space over a field. INPUT: -  X -- a subscheme of an ambient projective space over a field K -  X - a subscheme of an ambient projective space over a field K - v -- a list or tuple of coordinates in K -  v - a list or tuple of coordinates in K - check -- boolean (optional, default:True). Whether to check the input for consistency. EXAMPLES:: sage: P = ProjectiveSpace(3, RR) sage: P(2,3,4,5) (0.400000000000000 : 0.600000000000000 : 0.800000000000000 : 1.00000000000000) :: Not all homogeneous coordinates are allowed to vanish simultaneously:: sage: P = ProjectiveSpace(3, QQ) sage: P(0,0,0,0) ValueError: [0, 0, 0, 0] does not define a valid point since all entries are 0 """ def __init__(self, X, v, check=True): if scheme.is_Scheme(X): X = X(X.base_ring()) """ The Python constructor. See :class:SchemeMorphism_projective_coordinates_field for details. EXAMPLES:: sage: P = ProjectiveSpace(2, CDF) sage: P(2+I, 3-I, 4+5*I) (0.317073170732 - 0.146341463415*I : 0.170731707317 - 0.463414634146*I : 1.0) """ SchemeMorphism.__init__(self, X) if check: from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field # TODO: fix circular ref. from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field d = X.codomain().ambient_space().ngens() if is_SchemeMorphism(v) or isinstance(v, EllipticCurvePoint_field): v = list(v) #******************************************************************* # Abelian varieties #******************************************************************* class SchemeMorphism_abelian_variety_coordinates_field(AdditiveGroupElement, SchemeMorphism_projective_coordinates_field): def __mul__(self, n): if isinstance(n, (RingElement, int, long)): # [n]*P - multiplication by n. return AdditiveGroupElement._rmul_(self, Integer(n)) else: # Function composition return SchemeMorphism_projective_coordinates_field.__mul__(self, n) class SchemeMorphism_abelian_variety_coordinates_field\ (AdditiveGroupElement, SchemeMorphism_projective_coordinates_field): """ A rational point of an abelian variety over a field. EXAMPLES:: sage: E = EllipticCurve([0,0,1,-1,0]) sage: origin = E(0) sage: origin.domain() Spectrum of Rational Field sage: origin.codomain() Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field """ pass
• ## sage/schemes/generic/projective_space.py

diff --git a/sage/schemes/generic/projective_space.py b/sage/schemes/generic/projective_space.py
 a Spectrum of Rational Field sage: X.base_ring() Rational Field sage: X.structure_morphism () sage: X.structure_morphism() Scheme morphism: From: Projective Space of dimension 3 over Rational Field To:   Spectrum of Rational Field
• ## sage/schemes/generic/scheme.py

diff --git a/sage/schemes/generic/scheme.py b/sage/schemes/generic/scheme.py
 a #******************************************************************************* from sage.structure.parent import Parent from sage.misc.all import cached_method from sage.rings.all import (IntegerRing, is_CommutativeRing, ZZ, is_RingHomomorphism, GF, PowerSeriesRing, Rationals) def is_Scheme(x): """ Return True if x is a scheme. Test whether x is a scheme. INPUT: - x -- anything. OUTPUT: Boolean. Whether x derives from :class:Scheme. EXAMPLES:: return isinstance(x, Scheme) # If a derived class sets any of the properties, _base_scheme, _base_ring, # or _base_morphism, it will determine the others.  If none are set, # the base defaults to Spec(Z) with the canonical morphism. class Scheme(Parent): def __init__(self, X, category = None): """ The base class for all schemes. INPUT: - X -- a scheme, scheme morphism, commutative ring, commutative ring morphism, or None (optional). Determines the base scheme. If a commutative ring is passed, the spectrum of the ring will be used as base. - category -- the category (optional). Will be automatically construted by default. EXAMPLES:: sage: from sage.schemes.generic.scheme import Scheme sage: Scheme(ZZ) A scheme is in the category of all schemes over its base:: sage: ProjectiveSpace(4, QQ).category() Category of schemes over Rational Field There is a special and unique Spec(\ZZ) that is the default base scheme:: sage: Spec(ZZ).base_scheme() is Spec(QQ).base_scheme() True """ def __init__(self, X=None, category=None): """ A scheme. Construct a scheme. TESTS:: sage: R. = QQ[] sage: X = Spec(RmodI) sage: TestSuite(X).run(skip = ["_test_an_element", "_test_elements", ...                            "_test_some_elements", "_test_category"]) # See #7946 A scheme is in the category of all schemes over the base scheme of self:: sage: ProjectiveSpace(4, QQ).category() Category of schemes over Spectrum of Rational Field """ from sage.schemes.generic.spec import is_Spec if is_Spec(X): self._base_ring = X.coordinate_ring() base = self._base_ring from sage.schemes.generic.morphism import is_SchemeMorphism if X is None: try: from sage.schemes.generic.spec import SpecZ self._base_scheme = SpecZ except ImportError:  # we are currently constructing SpecZ self._base_ring = ZZ elif is_Scheme(X): self._base_scheme = X elif is_SchemeMorphism(X): self._base_morphism = X elif is_CommutativeRing(X): self._base_ring = X elif is_RingHomomorphism(X): self._base_ring = X.codomain() else: self._base_scheme = X base = self._base_scheme raise ValueError('The base must be define by a scheme, ' 'scheme morphism, or commutative ring.') from sage.categories.schemes import Schemes default_category = Schemes(self.base_scheme()) if not X: default_category = Schemes() else: default_category = Schemes(self.base_scheme()) if category is None: category = default_category else: assert category.is_subcategory(default_category), \ "%s is not a subcategory of %s"%(category, default_category) Parent.__init__(self, base, category = category) Parent.__init__(self, self.base_ring(), category = category) def __cmp__(self, X): def __cmp__(left, right): """ Compare two schemes. INPUT: - right -- anything. To compare against the scheme left. OUTPUT: +1, 0, or -1. EXAMPLES:: sage: X = Spec(QQ);  Y = Spec(QQ) sage: X == Y True sage: X is Y False """ if not isinstance(X, self.__class__): if not is_Scheme(right): return -1 return self._cmp_(X) return left._cmp_(right) def union(self, X): """ Return the disjoint union of the schemes self and X. Return the disjoint union of the schemes self and X. EXAMPLES:: def base_extend(self, Y): """ Y is either a scheme in the same category as self or a ring. Extend the base of the scheme. Derived clases must override this method. EXAMPLES:: sage: X = Spec(QQ) sage: from sage.schemes.generic.scheme import Scheme sage: X = Scheme(ZZ) sage: X.base_scheme() Spectrum of Integer Ring sage: X.base_extend(QQ) def __call__(self, *args): """ If S is a ring or scheme, return the set X(S) of S-valued points on X. If S is a list or tuple or just the coordinates, return a point in X(T), where T is the base scheme of self. Call syntax for schemes. INPUT/OUTPUT: The arguments must be one of the following: - a ring or a scheme S. Output will be the set X(S) of S-valued points on X. - If S is a list or tuple or just the coordinates, return a point in X(T), where T is the base scheme of self. EXAMPLES:: We create some point sets:: sage: A(QQ) Set of Rational Points of Affine Space of dimension 2 over Rational Field 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 :: 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 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)) Traceback (most recent call last): ... ValueError: no natural map from the base ring (=Rational Field) to R (=Finite Field of size 7)! ValueError: There must be a natural map S --> R, but S = Rational Field and R = Finite Field of size 7 We create some points:: (1, 0) We create the same point by giving the coordinates of the point directly. :: directly:: sage: A( 1,0 ) (1, 0) """ if len(args) == 0: raise TypeError, "0-dimensional affine space has no points" raise TypeError('You need to specify at least one argument.') S = args[0] if is_CommutativeRing(S): return self.point(S) return self.point(args) @cached_method def point_homset(self, S = None): """ Return the set of S-valued points of this scheme. INPUT: - S -- a commutative ring. OUTPUT: The set of morphisms Spec(S)\to X. EXAMPLES:: sage: P = ProjectiveSpace(ZZ, 3) sage: P.point_homset(ZZ) Set of Rational Points of Projective Space of dimension 3 over Integer Ring 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 Set of rational points of Projective Space of dimension 3 over Rational Field sage: P.point_homset(GF(11)) Set of Rational Points of Projective Space of dimension 3 over Finite Field of size 11 Set of rational points of Projective Space of dimension 3 over Finite Field of size 11 TESTS:: sage: P = ProjectiveSpace(QQ,3) sage: P.point_homset(GF(11)) Traceback (most recent call last): ... ValueError: There must be a natural map S --> R, but S = Rational Field and R = Finite Field of size 11 """ if S is None or S == self.base_ring(): # optimize common case try: return self.__ring_point_homset except AttributeError: self.__ring_point_homset = self._homset_class(self,self.base_ring()) return self.__ring_point_homset try: return self.__point_homset[S] except AttributeError: self.__point_homset = {} except KeyError: pass H = self._homset_class(self, S) self.__point_homset[S] = H return H if S is None: S = self.base_ring() from sage.schemes.generic.spec import Spec SpecS = Spec(S, self.base_ring()) from sage.schemes.generic.homset import SchemeHomset return SchemeHomset(SpecS, self) def point(self, v, check=True): return self._point_class(self, v, check=check) """ Create a point. INPUT: - v -- anything that defines a point. - check -- boolean (optional, default=True). Whether to check the defining data for consistency. OUTPUT: A point of the scheme. EXAMPLES:: sage: A2 = AffineSpace(QQ,2) sage: A2.point([4,5]) (4, 5) """ # todo: update elliptic curve stuff to take point_homset as argument from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve if is_EllipticCurve(self): return self._point_class(self, v, check=check) return self._point_class(self.point_homset(), v, check=check) def _point_class(self): """ Return the Hom set from some affine scheme to self. OUTPUT: A scheme hom set, see :mod:~sage.schemes.generic.homset. EXAMPLES:: sage: X = Spec(QQ) """ raise NotImplementedError def _homset_class(self): def _homset_class(self, *args, **kwds): """ Return the Hom set from self to another scheme. EXAMPLES:: sage: X = Spec(QQ) sage: from sage.schemes.generic.scheme import Scheme sage: X = Scheme(QQ) sage: X._homset_class() Traceback (most recent call last): ... """ raise NotImplementedError def __div__(self, Y): """ Return the base extension of self to Y. See :meth:base_extend for details. EXAMPLES:: sage: A = AffineSpace(3, ZZ) """ Return the base ring of the scheme self. OUTPUT: A commutative ring. EXAMPLES:: sage: A = AffineSpace(4, QQ) sage: A.base_ring() Rational Field :: sage: X = Spec(QQ) sage: X.base_ring() Integer Ring def base_scheme(self): """ Return the base scheme of the scheme self. Return the base scheme. OUTPUT: A scheme. EXAMPLES:: sage: A.base_scheme() Spectrum of Rational Field :: sage: X = Spec(QQ) sage: X.base_scheme() Spectrum of Integer Ring try: return self._base_scheme except AttributeError: from sage.schemes.generic.spec import Spec, SpecZ if hasattr(self, '_base_morphism'): self._base_scheme = self._base_morphism.codomain() elif hasattr(self, '_base_ring'): import spec from sage.schemes.generic.spec import Spec self._base_scheme = Spec(self._base_ring) else: import spec from sage.schemes.generic.spec import SpecZ self._base_scheme = SpecZ return self._base_scheme def base_morphism(self): """ Return the structure morphism from the scheme self to its base Return the structure morphism from self to its base scheme. OUTPUT: A scheme morphism. EXAMPLES:: To:   Spectrum of Rational Field Defn: Structure map :: sage: X = Spec(QQ) sage: X.base_morphism() Scheme morphism: def coordinate_ring(self): """ Return the coordinate ring of this scheme, if defined. Otherwise raise a ValueError. Return the coordinate ring. OUTPUT: The global coordinate ring of this scheme, if defined. Otherwise raise a ValueError. EXAMPLES:: """ Return the absolute dimension of this scheme. OUTPUT: Integer. EXAMPLES:: sage: R. = QQ[] def dimension_relative(self): """ Return the relative dimension of this scheme over its base. OUTPUT: Integer. EXAMPLES:: def identity_morphism(self): """ Return the identity morphism of the scheme self. Return the identity morphism. OUTPUT: The identity morphism of the scheme self. EXAMPLES:: def hom(self, x, Y=None, check=True): """ Return the scheme morphism from self to Y defined by x. If x is a scheme, try to determine a natural map to x. Return the scheme morphism from self to Y defined by x. INPUT: - x -- anything hat determines a scheme morphism. If x is a scheme, try to determine a natural map to x. If Y is not given, try to determine Y from context. - Y -- the codomain scheme (optional). If Y is not given, try to determine Y from context. - check -- boolean (optional, default=True). Whether to check the defining data for consistency. OUTPUT: The scheme morphism from self to Y defined by x. EXAMPLES:: def _Hom_(self, Y, category=None, check=True): """ Return the set of scheme morphisms from self to Y. Return the set of scheme morphisms from self to Y. INPUT: - Y -- a scheme. The codomain of the Hom set. - category -- a category (optional). The category of the Hom set. - check -- boolean (optional, default=True). Whether to check the defining data for consistency. OUTPUT: The set of morphisms from self to Y. EXAMPLES:: sage: P = ProjectiveSpace(ZZ, 3) sage: S = Spec(ZZ) sage: S._Hom_(P) Set of points of Projective Space of dimension 3 over Integer Ring defined over Integer Ring Set of rational points of Projective Space of dimension 3 over Integer Ring """ from sage.schemes.generic.homset import SchemeHomset return SchemeHomset(self, Y, category=category, check=check) def count_points(self, n): r""" Count points over \GF{q}, \ldots, \GF{q^n} on a scheme over a finite field \GF{q}. Count points over finite fields. INPUT: - n -- integer. OUTPUT: An integer. The number of points over \GF{q}, \ldots, \GF{q^n} on a scheme over a finite field \GF{q}. .. note:: ... NotImplementedError: Point counting only implemented for schemes over prime fields """ F = self.base_ring() if not F.is_finite(): raise TypeError, "Point counting only defined for schemes over finite fields" def zeta_series(self, n, t): """ Return the zeta series. Compute a power series approximation to the zeta function of a scheme over a finite field. INPUT: -  n - the number of terms of the power series to compute returned OUTPUT: A power series approximating the zeta function of self OUTPUT: A power series approximating the zeta function of self EXAMPLES:: sage: P. = PolynomialRing(GF(3)) """ def hom(self, x, Y=None): r""" Return the scheme morphism from self to Y defined by x. Return the scheme morphism from self to Y defined by x. INPUT: - x -- anything hat determines a scheme morphism. If x is a scheme, try to determine a natural map to x. If Y is not given, try to determine from context. - Y -- the codomain scheme (optional). If Y is not given, try to determine Y from context. - check -- boolean (optional, default=True). Whether to check the defining data for consistency. OUTPUT: The scheme morphism from self to Y defined by x. EXAMPLES: We construct the inclusion from \mathrm{Spec}(\QQ) into \mathrm{Spec}(\ZZ) induced by the inclusion from \ZZ into \QQ. :: EXAMPLES: We construct the inclusion from \mathrm{Spec}(\QQ) into \mathrm{Spec}(\ZZ) induced by the inclusion from \ZZ into \QQ:: sage: X = Spec(QQ) sage: X.hom(ZZ.hom(QQ)) import spec Y = spec.Spec(x.domain()) return Scheme.hom(self, x, Y) #import morphism #import spec
• ## sage/schemes/generic/spec.py

diff --git a/sage/schemes/generic/spec.py b/sage/schemes/generic/spec.py
 a """ Spec of a ring Spectrum of a ring as affine scheme. """ #******************************************************************************* from sage.rings.commutative_ring import is_CommutativeRing from sage.rings.integer_ring import ZZ import scheme import point from sage.schemes.generic.scheme import AffineScheme from sage.schemes.generic.point import SchemeTopologicalPoint_prime_ideal def is_Spec(X): """ Test whether X is a Spec. INPUT: - X -- anything. OUTPUT: Boolean. EXAMPLES:: sage: from sage.schemes.generic.spec import is_Spec """ return isinstance(X, Spec) class Spec(scheme.AffineScheme): class Spec(AffineScheme): r""" The spectrum of a commutative ring, as a scheme. schemes, which is important for gluing to construct more general schemes. INPUT: - R -- a commutative ring. - S -- a commutative ring (optional, default:\ZZ). The base ring. EXAMPLES:: sage: Spec(QQ) 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(skip = ["_test_an_element", "_test_elements", "_test_some_elements", "_test_category"]) # see # 7946 sage: TestSuite(X).run(skip = ["_test_an_element", "_test_elements", ...                            "_test_some_elements"]) sage: A = Spec(ZZ); B = Spec(ZZ) sage: A is B sage: A == B True A TypeError is raised if the input is not a CommutativeRing. :: A TypeError is raised if the input is not a commutative ring:: sage: Spec(5) Traceback (most recent call last): sage: Spec(FreeAlgebra(QQ,2, 'x')) Traceback (most recent call last): ... TypeError: R (=Free Algebra on 2 generators (x0, x1) over Rational Field) must be a commutative ring TypeError: R (=Free Algebra on 2 generators (x0, x1) over Rational Field) must be a commutative ring EXAMPLES:: TESTS:: sage: X = Spec(ZZ) sage: X Integer Ring sage: X.dimension() 1 sage: Spec(QQ,QQ).base_scheme() Spectrum of Rational Field sage: Spec(RDF,QQ).base_scheme() Spectrum of Rational Field """ def __init__(self, R, S=None, check=True): def __init__(self, R, S=None): """ Construct the spectrum of the ring R. See :class:Spec for details. EXAMPLES:: sage: Spec(ZZ) S.hom(R) except TypeError: raise ValueError, "There must be a natural map S --> R, but S = %s and R = %s"%(S,R) self._base_ring = S AffineScheme.__init__(self, S) def _cmp_(self, X): """ Return the result of the comparison of self and X. Compare self and X. Spec's are compared with self using comparison of the underlying rings.  If X is not a Spec, then the result is platform-dependent (either self < X or X < self, but never self == X). INPUT: - X -- anything. OUTPUT: +1, 0, or -1. EXAMPLES:: def __hash__(self): """ Return the hash value. OUTPUT: A 32/64-bit hash value, depending on architecture. TESTS:: sage: hash(Spec(ZZ)) def _repr_(self): """ Return a string representation of self. OUTPUT: String. EXAMPLES:: sage: Spec(PolynomialRing(QQ, 3, 'x')) """ LaTeX representation of this Spec. OUTPUT: String. EXAMPLES:: sage: S = Spec(PolynomialRing(ZZ, 2, 'x')) def __call__(self, x): """ Create a point of this Spec.  The argument x can be a prime ideal of the coordinate ring, or an element (or list of elements) of the coordinate ring which generates a prime ideal. Call syntax for Spec. INPUT: - x -- a prime ideal of the coordinate ring, or an element (or list of elements) of the coordinate ring which generates a prime ideal. OUTPUT: A point of this Spec. EXAMPLES:: sage: S(ZZ.ideal(next_prime(1000000))) Point on Spectrum of Integer Ring defined by the Principal ideal (1000003) of Integer Ring :: sage: R. = QQ[] 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 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 """ return point.SchemeTopologicalPoint_prime_ideal(self, x) return SchemeTopologicalPoint_prime_ideal(self, x) def _an_element_(self): r""" Return an element of the spectrum of the ring. OUTPUT: A point of the affine scheme self. EXAMPLES:: sage: Spec(QQ).an_element() Point on Spectrum of Rational Field defined by the Principal ideal (0) of Rational Field sage: Spec(ZZ).an_element()    # random output Point on Spectrum of Integer Ring defined by the Principal ideal (811) of Integer Ring """ if self.coordinate_ring() is ZZ: from sage.rings.arith import random_prime return self(random_prime(1000)) return self(0) def coordinate_ring(self): """ Return the underlying ring of this scheme. OUTPUT: A commutative ring. EXAMPLES:: sage: Spec(QQ).coordinate_ring() def is_noetherian(self): """ Return True if this scheme is Noetherian. Test whether self is Noetherian. OUTPUT: Boolean. Return True if this scheme is Noetherian. EXAMPLES:: """ Return the absolute dimension of this scheme. OUTPUT: Integer. EXAMPLES:: sage: S = Spec(ZZ) """ Return the relative dimension of this scheme over its base. OUTPUT: Integer. EXAMPLES:: sage: S = Spec(ZZ) """ return self.__R.krull_dimension() - self.base_ring().krull_dimension() def base_extend(self, R): """ Extend the base ring/scheme. INPUT: - R -- an affine scheme or a commutative ring. EXAMPLES:: sage: Spec_ZZ = Spec(ZZ);  Spec_ZZ Spectrum of Integer Ring sage: Spec_ZZ.base_extend(QQ) Spectrum of Rational Field """ if is_CommutativeRing(R): return Spec(self.coordinate_ring().base_extend(R), self.base_ring()) if not self.base_scheme() == R.base_scheme(): raise ValueError('The new base scheme must be a scheme over the old base scheme.') return Spec(self.coordinate_ring().base_extend(new_base.coordinate_ring()), self.base_ring()) def _homset_class(self, *args, **kwds): """ Return the Hom set class. EXAMPLES:: sage: Spec(QQ)._homset_class(Spec(QQ), Spec(ZZ)) Set of rational points of Spectrum of Rational Field """ from sage.schemes.generic.homset import SchemeHomset_coordinates return SchemeHomset_coordinates(*args, **kwds) SpecZ = Spec(ZZ)
• ## sage/schemes/generic/toric_variety.py

diff --git a/sage/schemes/generic/toric_variety.py b/sage/schemes/generic/toric_variety.py
 a are all zero. :: sage: parent(origin) Set of Rational Points of 2-d affine toric variety Set of rational points of 2-d affine toric variety As you can see, by default toric varieties live over the field of rational numbers:: sage: origin [0 : 0] sage: parent(origin) Set of Rational Points of 2-d affine toric variety Set of rational points of 2-d affine toric variety Only affine toric varieties have points whose (homogeneous) coordinates are all zero. sage: fan = FaceFan(lattice_polytope.octahedron(2)) sage: P1xP1 = ToricVariety(fan) sage: P1xP1._homset_class(P1xP1, P1xP1.base_ring()) Set of Rational Points of 2-d toric variety sage: P1xP1._homset_class(Spec(QQ), P1xP1) Set of rational points of 2-d toric variety covered by 4 affine patches """ return SchemeHomset_toric_coordinates_field(*args, **kwds)
• ## sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py

diff --git a/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py b/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py
 a return S.gens() def local_coordinates_at_nonweierstrass(self, P, prec = 20, name = 't'): """ """ For a non-Weierstrass point P = (a,b) on the hyperelliptic curve y^2 = f(x), returns (x(t), y(t)) such that (y(t))^2 = f(x(t)), where t = x - a is the local parameter. (x(t),y(t)) such that y(t)^2 = f(x(t)) and t = x - a is the local parameter at P EXAMPLES: 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 -2 + t + O(t^5) sage: y 12 - 19/2*t - 19/32*t^2 + 61/256*t^3 - 5965/24576*t^4 + O(t^5) AUTHOR: - Jennifer Balakrishnan (2007-12) 12 - 19/2*t - 19/32*t^2 + 61/256*t^3 - 5965/24576*t^4 + O(t^5) AUTHOR: - Jennifer Balakrishnan (2007-12) """ d = P[1] if d == 0:
• ## sage/schemes/hyperelliptic_curves/jacobian_generic.py

diff --git a/sage/schemes/hyperelliptic_curves/jacobian_generic.py b/sage/schemes/hyperelliptic_curves/jacobian_generic.py
 a 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 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 Closed subscheme of Projective Space of dimension 2 over Number Field in t with defining polynomial x^2 - 2 defined by: -x0^5 + x0*x1*x2^3 + x1^2*x2^3 + x0*x2^4 - x2^5 Set of rational points of Closed subscheme of Projective Space of dimension 2 over Number Field in t with defining polynomial x^2 - 2 defined by: -x0^5 + x0*x1*x2^3 + x1^2*x2^3 + x0*x2^4 - x2^5 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 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/schemes/hyperelliptic_curves/jacobian_homset.py

diff --git a/sage/schemes/hyperelliptic_curves/jacobian_homset.py b/sage/schemes/hyperelliptic_curves/jacobian_homset.py
 a 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 #                  http://www.gnu.org/licenses/ #***************************************************************************** import sage.schemes.generic.spec as spec from sage.rings.all import is_Polynomial, PolynomialRing, Integer, ZZ from sage.schemes.generic.homset import SchemeHomset_generic from sage.rings.all import is_Polynomial, PolynomialRing, Integer, is_Integer, ZZ from sage.schemes.generic.homset import SchemeHomset_coordinates from sage.schemes.generic.morphism import is_SchemeMorphism #from sage.schemes.jacobians.abstract_jacobian import Jacobian_generic from sage.schemes.generic.spec import Spec, is_Spec from jacobian_morphism import JacobianMorphism_divisor_class_field from sage.rings.integer import Integer, is_Integer class JacobianHomset_divisor_classes(SchemeHomset_generic): def __init__(self, X, S): class JacobianHomset_divisor_classes(SchemeHomset_coordinates): def __init__(self, Y, X, **kwds): R = X.base_ring() SchemeHomset_generic.__init__(self, spec.Spec(S, R), X) S = Y.coordinate_ring() SchemeHomset_coordinates.__init__(self, Y, X, **kwds) P2 = X.curve()._printing_ring if S != R: y = str(P2.gen()) Returns S for a homset X(T) where T = Spec(S). """ T = self.domain() if spec.is_Spec(T): if is_Spec(T): return T.coordinate_ring() else: raise TypeError, "Domain of argument must be of the form Spec(S)."
• ## sage/schemes/hyperelliptic_curves/jacobian_morphism.py

diff --git a/sage/schemes/hyperelliptic_curves/jacobian_morphism.py b/sage/schemes/hyperelliptic_curves/jacobian_morphism.py
 a sage: x = GF(37)['x'].gen() sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x); H 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 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 At this time, Jacobians of hyperelliptic curves are handled differently than elliptic curves:: sage: J = H.jacobian(); J 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 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 Set of 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 defined over Finite Field of size 37 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 Points on the Jacobian are represented by Mumford's polynomials. First we find a couple of points on the curve:: sage: H = HyperellipticCurve(f); H Hyperelliptic Curve over Rational Field defined by y^2 = x^5 - x sage: J = H.jacobian()(QQ); J Set of points of Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 - x defined over Rational Field Set of rational points of Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 - x The following point is 2-torsion:: sage: H = HyperellipticCurve(f, x); H Hyperelliptic Curve over Rational Field defined by y^2 + x*y = x^5 - x sage: J = H.jacobian()(QQ); J Set of points of Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 + x*y = x^5 - x defined over Rational Field Set of rational points of Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 + x*y = x^5 - x The following point is 2-torsion:: sage: F. = NumberField(x^2 - 2, 'a') sage: J = H.jacobian()(F); J Set of points of Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x defined over Number Field in a with defining polynomial x^2 - 2 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: 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 Set of 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 defined over Finite Field in a of size 7^2 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 :: 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 verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation. Set of points of Jacobian of Hyperelliptic Curve over Finite Field of size 1000000000000000000000000000057 defined by y^2 + 2*x*y = x^7 + x^2 + 1 defined over Finite Field of size 1000000000000000000000000000057 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 (x + 1000000000000000000000000000056, y + 1000000000000000000000000000056) sage: 10*Q # indirect doctest 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: J = H.jacobian()(GF(37));  J 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 :: sage: P1 = J(H.lift_x(2)); P1 # indirect doctest (x + 35, y + 26) sage: P1.parent() Set of 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 defined over Finite Field of size 37 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 sage: type(P1) """ sage: H = HyperellipticCurve(f) sage: F. = NumberField(x^2 - 2, 'a') sage: J = H.jacobian()(F); J Set of points of Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x defined over Number Field in a with defining polynomial x^2 - 2 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: H = HyperellipticCurve(f) sage: F. = NumberField(x^2 - 2, 'a') sage: J = H.jacobian()(F); J Set of points of Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x defined over Number Field in a with defining polynomial x^2 - 2 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: H = HyperellipticCurve(f) sage: F. = NumberField(x^2 - 2, 'a') sage: J = H.jacobian()(F); J Set of points of Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x defined over Number Field in a with defining polynomial x^2 - 2 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: H = HyperellipticCurve(f) sage: F. = NumberField(x^2 - 2, 'a') sage: J = H.jacobian()(F); J Set of points of Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x defined over Number Field in a with defining polynomial x^2 - 2 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: H = HyperellipticCurve(f); H Hyperelliptic Curve over Rational Field defined by y^2 = x^5 - x sage: J = H.jacobian()(QQ); J Set of points of Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 - x defined over Rational Field Set of rational points of Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 - x The following point is 2-torsion::
• ## sage/schemes/jacobians/abstract_jacobian.py

diff --git a/sage/schemes/jacobians/abstract_jacobian.py b/sage/schemes/jacobians/abstract_jacobian.py
 a Projective Curve over Rational Field defined by x^3 + y^3 + z^3 """ return self.__curve def change_ring(self, R): r""" Return the Jacobian over the ring R. INPUT: - R -- a field. The new base ring. OUTPUT: The Jacobian over the ring R. EXAMPLES:: sage: R. = QQ['x'] 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: Jac.change_ring(RDF) 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 INPUT: - R -- a field. The new base field. OUTPUT: The Jacobian over the ring R. EXAMPLES:: sage: R. = QQ['x'] 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 Number Field in a with defining polynomial x^2 + 1 defined by y^2 = x^3 - 10*x + 9 """ if not is_Field(R): raise ValueError('Not a field: '+str(R)) if self.base_ring() is R: return self if not R.has_coerce_map_from(self.base_ring()): raise ValueError('no natural map from the base ring (=%s) to R (=%s)!' % (self.base_ring(), R)) return self.change_ring(R)
• ## sage/schemes/plane_curves/curve.py

diff --git a/sage/schemes/plane_curves/curve.py b/sage/schemes/plane_curves/curve.py
 a from sage.schemes.generic.divisor import Divisor_curve class Curve_generic(AlgebraicScheme_subscheme): r""" EXAMPLES:: sage: A. = AffineSpace(QQ,3) sage: C = Curve([x-y,z-2]) sage: loads(C.dumps()) == C True """ def _repr_(self): """ EXAMPLES: sage: A. = AffineSpace(QQ,3) EXAMPLES:: sage: A. = AffineSpace(QQ,3) sage: C = Curve([x-y,z-2]) sage: C Affine Space Curve over Rational Field defined by x - y, z - 2
diff --git a/sage/schemes/readme.py b/sage/schemes/readme.py
diff --git a/sage/structure/factory.pyx b/sage/structure/factory.pyx
 a r""" Factory for unique objects More general than :mod:~sage.structure.unique_representation, the :class:UniqueFactory class can specify a subset of the arguments that serve as the unique key. Typically, this is used to construct objects that accept an optional check=[True|False] argument, but whose result should be unique irregardless of said optional argument. """ #***************************************************************************** #  Copyright (C) 2008 Robert Bradshaw # #  Distributed under the terms of the GNU General Public License (GPL) # #    This code is distributed in the hope that it will be useful, #    but WITHOUT ANY WARRANTY; without even the implied warranty of #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU #    General Public License for more details. # #  The full text of the GPL is available at: # #                  http://www.gnu.org/licenses/ #****************************************************************************** import weakref, types, copy_reg from sage_object cimport SageObject will return the same object for the same version of Sage, and distinct (but hopefully equal) objects for different versions of Sage. Typically one only needs to implement create_key and create_object. Typically one only needs to implement :meth:create_key and :meth:create_object. """ cdef readonly _name def __init__(self, name): """ INPUT: name -- a name in the global namespace referring to self or a fully qualified path name to self, which is used to locate the factory on unpickling. - name -- string. A name in the global namespace referring to self or a fully qualified path name to self, which is used to locate the factory on unpickling. EXAMPLES: EXAMPLES:: sage: from sage.structure.factory import UniqueFactory sage: fake_factory = UniqueFactory('ZZ') sage: loads(dumps(fake_factory)) def __reduce__(self): """ EXAMPLES: EXAMPLES:: sage: A = FiniteField(127) sage: A is loads(dumps(A)) # indirect doctest True sage: D is loads(dumps(D)) True TESTS: TESTS:: sage: loads(dumps(FiniteField)) is FiniteField True sage: from sage.structure.factory import test_factory sage: from sage.structure.test_factory import test_factory sage: loads(dumps(test_factory)) is test_factory True """ Do not override this method, override create_key and create_object and put the docstring in the body of the class. EXAMPLES: sage: from sage.structure.factory import test_factory EXAMPLES:: sage: from sage.structure.test_factory import test_factory sage: _ = test_factory(1,2,3); _ Making object (1, 2, 3) It already created one, so don't re-create. It already created one, so don't re-create:: sage: test_factory(1,2,3) sage: test_factory(1,2,3) is test_factory(1,2,3) True Of course, with a different key, a new object will be created. Of course, with a different key, a new object will be created:: sage: test_factory(1,2,3) is test_factory(1,2,4) Making object (1, 2, 4) False if necessary (for example, it isn't in the cache or it is unpickling from an older version of Sage). EXAMPLES: sage: from sage.structure.factory import test_factory EXAMPLES:: sage: from sage.structure.test_factory import test_factory sage: a = test_factory.get_object(3.0, 'a', {}); a Making object a sage: test_factory.get_object(3.0, 'a', {}) is test_factory.get_object(3.0, 'a', {}) True sage: test_factory.get_object(3.0, 'a', {}) is test_factory.get_object(3.1, 'a', {}) Defaults to the Sage version that is passed in, but courser granularity can be provided. EXAMPLES: sage: from sage.structure.factory import test_factory EXAMPLES:: sage: from sage.structure.test_factory import test_factory sage: test_factory.get_version((3,1,0)) (3, 1, 0) """ Return a tuple containing the key (uniquely defining data) and any extra arguments (empty by default). Defaults to \code{self.create_key}. Defaults to :meth:create_key. EXAMPLES: sage: from sage.structure.factory import test_factory EXAMPLES:: sage: from sage.structure.test_factory import test_factory sage: test_factory.create_key_and_extra_args(1, 2, key=5) ((1, 2), {}) sage: GF.create_key_and_extra_args(3, foo='value') Given the arguments and keywords, create a key that uniquely determines this object. EXAMPLES: sage: from sage.structure.factory import test_factory EXAMPLES:: sage: from sage.structure.test_factory import test_factory sage: test_factory.create_key(1, 2, key=5) (1, 2) """ Create the object from the key and extra arguments. This is only called if the object was not found in the cache. EXAMPLES: sage: from sage.structure.factory import test_factory EXAMPLES:: sage: from sage.structure.test_factory import test_factory sage: test_factory.create_object(0, (1,2,3)) Making object (1, 2, 3) sage: test_factory('a') Making object ('a',) sage: test_factory('a') # NOT called again """ raise NotImplementedError may result in a new (more specific) key. This allows the more specific key to be cached as well, and used for pickling. EXAMPLES: EXAMPLES:: sage: key, _ = GF.create_key_and_extra_args(27, 'k'); key (27, ('k',), 'conway', None, '{}', 3, 3, True) sage: K = GF.create_object(0, key); K cpdef reduce_data(self, obj): """ The results of this function can be returned from __reduce__. This is here so the factory internals can change without having to re-write __reduce__ methods that use it. The results of this function can be returned from :meth:__reduce__. This is here so the factory internals can change without having to re-write :meth:__reduce__ methods that use it. EXAMPLE: EXAMPLE:: sage: V = FreeModule(ZZ, 5) sage: factory, data = FreeModule.reduce_data(V) sage: factory(*data) sage: factory(*data) is V True sage: from sage.structure.factory import test_factory sage: from sage.structure.test_factory import test_factory sage: a = test_factory(1, 2) Making object (1, 2) sage: test_factory.reduce_data(a) (, (, (, (...), (1, 2), {})) NOTE: The (...) here is the Sage version. Note that the ellipsis (...) here stands for the Sage version. """ return generic_factory_unpickle, obj._factory_data """ Method used for unpickling the object. The unpickling mechanism needs a plain Python function to call. It takes a factory as the first argument, passes the rest of the arguments onto the factory's get_object method. The unpickling mechanism needs a plain Python function to call. It takes a factory as the first argument, passes the rest of the arguments onto the factory's :meth:UniqueFactory.get_object method. EXAMPLES: EXAMPLES:: sage: V = FreeModule(ZZ, 5) sage: func, data = FreeModule.reduce_data(V) sage: func is sage.structure.factory.generic_factory_unpickle def generic_factory_reduce(self, proto): """ Used to provide a __reduce__ method if one does not already exist. Used to provide a __reduce__ method if one does not already exist. EXAMPLES: EXAMPLES:: sage: V = QQ^6 sage: sage.structure.factory.generic_factory_reduce(V, 1) == V.__reduce_ex__(1) True """ Used in unpickling the factory itself. EXAMPLES: EXAMPLES:: sage: from sage.structure.factory import lookup_global sage: lookup_global('ZZ') Integer Ring return getattr(all, name) class A: # something we can weakref pass class UniqueFactoryTester(UniqueFactory): def create_key(self, *args, **kwds): """ EXAMPLES: sage: from sage.structure.factory import UniqueFactoryTester sage: test_factory = UniqueFactoryTester('foo') sage: test_factory.create_key(1, 2, 3) (1, 2, 3) """ return args def create_object(self, version, key, **extra_args): """ EXAMPLES: sage: from sage.structure.factory import UniqueFactoryTester sage: test_factory = UniqueFactoryTester('foo') sage: test_factory.create_object('version', key=(1, 2, 4)) Making object (1, 2, 4) """ print "Making object", key return A() test_factory = UniqueFactoryTester('sage.structure.factory.test_factory') # To make the pickle jar happy: from sage.structure.test_factory import test_factory
diff --git a/sage/structure/test_factory.py b/sage/structure/test_factory.py
new file mode 100644