Path: blob/master/sage/schemes/generic/divisor_group.py
4095 views
"""1AUTHORS:23- David Kohel (2006): Initial version45- Volker Braun (2010-07-16): Documentation, doctests, coercion fixes, bugfixes.6"""78#*******************************************************************************9# Copyright (C) 2010 Volker Braun <[email protected]>10# Copyright (C) 2006 David Kohel <[email protected]>11# Distributed under the terms of the GNU General Public License (GPL)12# http://www.gnu.org/licenses/13#*******************************************************************************1415from sage.schemes.generic.divisor import Divisor_generic, Divisor_curve16from sage.structure.formal_sum import FormalSums17from sage.structure.unique_representation import UniqueRepresentation18from sage.rings.integer_ring import ZZ19from sage.rings.rational_field import QQ202122def DivisorGroup(scheme, base_ring=None):23r"""24Return the group of divisors on the scheme.2526INPUT:2728- ``scheme`` -- a scheme.2930- ``base_ring`` -- usually either `\ZZ` (default) or `\QQ`. The31coefficient ring of the divisors. Not to be confused with the32base ring of the scheme!3334OUTPUT:3536An instance of ``DivisorGroup_generic``.3738EXAMPLES::3940sage: from sage.schemes.generic.divisor_group import DivisorGroup41sage: DivisorGroup(Spec(ZZ))42Group of ZZ-Divisors on Spectrum of Integer Ring43sage: DivisorGroup(Spec(ZZ), base_ring=QQ)44Group of QQ-Divisors on Spectrum of Integer Ring45"""46if base_ring==None:47base_ring = ZZ4849from sage.schemes.plane_curves.curve import Curve_generic50if isinstance(scheme, Curve_generic):51DG = DivisorGroup_curve(scheme, base_ring)52else:53DG = DivisorGroup_generic(scheme, base_ring)5455return DG565758def is_DivisorGroup(x):59r"""60Return whether ``x`` is a :class:`DivisorGroup_generic`.6162INPUT:6364- ``x`` -- anything.6566OUTPUT:6768``True`` or ``False``.6970EXAMPLES::7172sage: from sage.schemes.generic.divisor_group import is_DivisorGroup, DivisorGroup73sage: Div = DivisorGroup(Spec(ZZ), base_ring=QQ)74sage: is_DivisorGroup(Div)75True76sage: is_DivisorGroup('not a divisor')77False78"""79return isinstance(x, DivisorGroup_generic)808182class DivisorGroup_generic(FormalSums):83r"""84The divisor group on a variety.85"""8687@staticmethod88def __classcall__(cls, scheme, base_ring=ZZ):89"""90Set the default value for the base ring.9192EXAMPLES::9394sage: from sage.schemes.generic.divisor_group import DivisorGroup_generic95sage: DivisorGroup_generic(Spec(ZZ),ZZ) == DivisorGroup_generic(Spec(ZZ)) # indirect test96True97"""98# Must not call super().__classcall__()!99return UniqueRepresentation.__classcall__(cls, scheme, base_ring)100101def __init__(self, scheme, base_ring):102r"""103Construct a :class:`DivisorGroup_generic`.104105INPUT:106107- ``scheme`` -- a scheme.108109- ``base_ring`` -- the coefficient ring of the divisor110group.111112Implementation note: :meth:`__classcall__` sets default value113for ``base_ring``.114115EXAMPLES::116117sage: from sage.schemes.generic.divisor_group import DivisorGroup_generic118sage: DivisorGroup_generic(Spec(ZZ), QQ)119Group of QQ-Divisors on Spectrum of Integer Ring120"""121super(DivisorGroup_generic,self).__init__(base_ring)122self._scheme = scheme123124def _repr_(self):125r"""126Return a string representation of the divisor group.127128EXAMPLES::129130sage: from sage.schemes.generic.divisor_group import DivisorGroup131sage: DivisorGroup(Spec(ZZ), base_ring=QQ)132Group of QQ-Divisors on Spectrum of Integer Ring133"""134ring = self.base_ring()135if ring == ZZ:136base_ring_str = 'ZZ'137elif ring == QQ:138base_ring_str = 'QQ'139else:140base_ring_str = '('+str(ring)+')'141return 'Group of '+base_ring_str+'-Divisors on '+str(self._scheme)142143def _element_constructor_(self, x, check=True, reduce=True):144r"""145Construct an element of the divisor group.146147EXAMPLES::148149sage: from sage.schemes.generic.divisor_group import DivisorGroup150sage: DivZZ=DivisorGroup(Spec(ZZ))151sage: DivZZ([(2,5)])1522*V(5)153"""154if isinstance(x, Divisor_generic):155P = x.parent()156if P is self:157return x158elif P == self:159return Divisor_generic(x._data, check=False, reduce=False, parent=self)160else:161x = x._data162if isinstance(x, list):163return Divisor_generic(x, check=check, reduce=reduce, parent=self)164if x == 0:165return Divisor_generic([], check=False, reduce=False, parent=self)166else:167return Divisor_generic([(self.base_ring()(1), x)], check=False, reduce=False, parent=self)168169def __cmp__(self, right):170r"""171Compare the divisor group.172173INPUT:174175- ``right`` -- anything.176177OUTPUT:178179``+1``, ``0``, or ``-1`` depending on how ``self`` and180``right`` compare.181182EXAMPLES::183184sage: from sage.schemes.generic.divisor_group import DivisorGroup185sage: D1 = DivisorGroup(Spec(ZZ));186sage: D2 = DivisorGroup(Spec(ZZ),base_ring=QQ);187sage: D3 = DivisorGroup(Spec(QQ));188sage: abs(cmp(D1,D1))1890190sage: abs(cmp(D1,D2))1911192sage: abs(cmp(D1,D3))1931194sage: abs(cmp(D2,D2))1950196sage: abs(cmp(D2,D3))1971198sage: abs(cmp(D3,D3))1990200sage: abs(cmp(D1, 'something'))2011202"""203if not is_DivisorGroup(right): return -1204c = cmp(self.base_ring(), right.base_ring())205if c!=0: return c206return cmp(self._scheme, right._scheme)207208def scheme(self):209r"""210Return the scheme supporting the divisors.211212EXAMPLES::213214sage: from sage.schemes.generic.divisor_group import DivisorGroup215sage: Div = DivisorGroup(Spec(ZZ)) # indirect test216sage: Div.scheme()217Spectrum of Integer Ring218"""219return self._scheme220221def _an_element_(self):222r"""223Return an element of the divisor group.224225EXAMPLES::226227sage: A.<x, y> = AffineSpace(2, CC)228sage: C = Curve(y^2 - x^9 - x)229sage: from sage.schemes.generic.divisor_group import DivisorGroup230sage: DivisorGroup(C).an_element() # indirect test2310232"""233return self._scheme.divisor([], base_ring=self.base_ring(), check=False, reduce=False)234235def base_extend(self, R):236"""237EXAMPLES::238239sage: from sage.schemes.generic.divisor_group import DivisorGroup240sage: DivisorGroup(Spec(ZZ),ZZ).base_extend(QQ)241Group of QQ-Divisors on Spectrum of Integer Ring242sage: DivisorGroup(Spec(ZZ),ZZ).base_extend(GF(7))243Group of (Finite Field of size 7)-Divisors on Spectrum of Integer Ring244245Divisor groups are unique::246247sage: A.<x, y> = AffineSpace(2, CC)248sage: C = Curve(y^2 - x^9 - x)249sage: DivisorGroup(C,ZZ).base_extend(QQ) is DivisorGroup(C,QQ)250True251"""252if self.base_ring().has_coerce_map_from(R):253return self254elif R.has_coerce_map_from(self.base_ring()):255return DivisorGroup(self.scheme(), base_ring=R)256257258class DivisorGroup_curve(DivisorGroup_generic):259r"""260Special case of the group of divisors on a curve.261"""262263def _element_constructor_(self, x, check=True, reduce=True):264r"""265Construct an element of the divisor group.266267EXAMPLES::268269sage: A.<x, y> = AffineSpace(2, CC)270sage: C = Curve(y^2 - x^9 - x)271sage: DivZZ=C.divisor_group(ZZ)272sage: DivQQ=C.divisor_group(QQ)273sage: DivQQ( DivQQ.an_element() ) # indirect test2740275sage: DivZZ( DivZZ.an_element() ) # indirect test2760277sage: DivQQ( DivZZ.an_element() ) # indirect test2780279"""280if isinstance(x, Divisor_curve):281P = x.parent()282if P is self:283return x284elif P == self:285return Divisor_curve(x._data, check=False, reduce=False, parent=self)286else:287x = x._data288if isinstance(x, list):289return Divisor_curve(x, check=check, reduce=reduce, parent=self)290if x == 0:291return Divisor_curve([], check=False, reduce=False, parent=self)292else:293return Divisor_curve([(self.base_ring()(1), x)], check=False, reduce=False, parent=self)294295296297298