Path: blob/master/sage/schemes/toric/divisor_class.pyx
4107 views
r"""1Toric rational divisor classes23This module is a part of the framework for :mod:`toric varieties4<sage.schemes.toric.variety>`.56AUTHORS:78- Volker Braun and Andrey Novoseltsev (2010-09-05): initial version.910TESTS:1112Toric rational divisor clases are elements of the rational class group of a13toric variety, represented as rational vectors in some basis::1415sage: dP6 = toric_varieties.dP6()16sage: Cl = dP6.rational_class_group()17sage: D = Cl([1, -2, 3, -4])18sage: D19Divisor class [1, -2, 3, -4]20sage: E = Cl([1/2, -2/3, 3/4, -4/5])21sage: E22Divisor class [1/2, -2/3, 3/4, -4/5]2324They behave much like ordinary vectors::2526sage: D + E27Divisor class [3/2, -8/3, 15/4, -24/5]28sage: 2 * D29Divisor class [2, -4, 6, -8]30sage: E / 1031Divisor class [1/20, -1/15, 3/40, -2/25]32sage: D * E33Traceback (most recent call last):34...35TypeError: cannot multiply two divisor classes!3637The only special method is :meth:`~ToricRationalDivisorClass.lift` to get a38divisor representing a divisor class::3940sage: D.lift()41V(x) - 2*V(u) + 3*V(y) - 4*V(v)42sage: E.lift()431/2*V(x) - 2/3*V(u) + 3/4*V(y) - 4/5*V(v)44"""454647#*****************************************************************************48# Copyright (C) 2010 Volker Braun <[email protected]>49# Copyright (C) 2010 Andrey Novoseltsev <[email protected]>50# Copyright (C) 2010 William Stein <[email protected]>51#52# Distributed under the terms of the GNU General Public License (GPL)53#54# http://www.gnu.org/licenses/55#*****************************************************************************565758include '../../ext/cdefs.pxi' # Needed for mpq* stuff59include '../../ext/stdsage.pxi' # Needed for PY_NEW6061from sage.misc.all import latex62from sage.modules.all import vector63from sage.modules.vector_rational_dense cimport Vector_rational_dense64from sage.rings.all import QQ65from sage.rings.rational cimport Rational66from sage.structure.element cimport Element, Vector67from sage.structure.element import is_Vector686970def is_ToricRationalDivisorClass(x):71r"""72Check if ``x`` is a toric rational divisor class.7374INPUT:7576- ``x`` -- anything.7778OUTPUT:7980- ``True`` if ``x`` is a toric rational divisor class, ``False`` otherwise.8182EXAMPLES::8384sage: from sage.schemes.toric.divisor_class import (85... is_ToricRationalDivisorClass)86sage: is_ToricRationalDivisorClass(1)87False88sage: dP6 = toric_varieties.dP6()89sage: D = dP6.rational_class_group().gen(0)90sage: D91Divisor class [1, 0, 0, 0]92sage: is_ToricRationalDivisorClass(D)93True94"""95return isinstance(x, ToricRationalDivisorClass)969798cdef class ToricRationalDivisorClass(Vector_rational_dense):99r"""100Create a toric rational divisor class.101102.. WARNING::103104You probably should not construct divisor classes explicitly.105106INPUT:107108- same as for109:class:`~sage.modules.vector_rational_dense.Vector_rational_dense`.110111OUTPUT:112113- toric rational divisor class.114115TESTS::116117sage: dP6 = toric_varieties.dP6()118sage: Cl = dP6.rational_class_group()119sage: D = dP6.divisor(2)120sage: Cl(D)121Divisor class [0, 0, 1, 0]122"""123124def __reduce__(self):125"""126Prepare ``self`` for pickling.127128TESTS::129130sage: dP6 = toric_varieties.dP6()131sage: Cl = dP6.rational_class_group()132sage: D = Cl([1, -2, 3, -4])133sage: D134Divisor class [1, -2, 3, -4]135sage: loads(dumps(D))136Divisor class [1, -2, 3, -4]137"""138return (_ToricRationalDivisorClass_unpickle_v1,139(self._parent, list(self), self._degree, self._is_mutable))140141cdef _new_c(self):142cdef ToricRationalDivisorClass y143y = PY_NEW(ToricRationalDivisorClass)144y._init(self._degree, self._parent)145return y146147cpdef _act_on_(self, other, bint self_on_left):148"""149Act on ``other``.150151INPUT:152153- ``other`` - something that154:class:`~sage.modules.vector_rational_dense.Vector_rational_dense`155can act on *except* for another toric rational divisor class.156157OUTPUT:158159- standard output for ``self`` acting as a rational vector on160``other`` if the latter one is not a toric rational divisor class.161162TESTS::163164sage: dP6 = toric_varieties.dP6()165sage: Cl = dP6.rational_class_group()166sage: D = Cl([1, -2, 3, -4])167sage: D168Divisor class [1, -2, 3, -4]169sage: D * D170Traceback (most recent call last):171...172TypeError: cannot multiply two divisor classes!173174We test standard behaviour::175176sage: v = vector([1, 2, 3, 4])177sage: v * D # indirect doctest178-10179sage: D * v # indirect doctest180-10181sage: v = vector([1, 2/3, 4/5, 6/7])182sage: v * D # indirect doctest183-143/105184sage: D * v # indirect doctest185-143/105186sage: A = matrix(4, range(16))187sage: A * D # indirect doctest188(-8, -16, -24, -32)189sage: D * A # indirect doctest190(-32, -34, -36, -38)191sage: B = A / 3192sage: B * D # indirect doctest193(-8/3, -16/3, -8, -32/3)194sage: D * B # indirect doctest195(-32/3, -34/3, -12, -38/3)196"""197# If we don't treat vectors separately, they get converted into198# divisor classes where multiplication is prohibited on purpose.199if isinstance(other, Vector_rational_dense):200return Vector_rational_dense._dot_product_(self, other)201cdef Vector v202if is_Vector(other) and not is_ToricRationalDivisorClass(other):203try:204v = vector(QQ, other)205if v._degree == self._degree:206return Vector_rational_dense._dot_product_(self, v)207except TypeError:208pass209# Now let the standard framework work...210return Vector_rational_dense._act_on_(self, other, self_on_left)211212cpdef Element _dot_product_(self, Vector right):213r"""214Raise a ``TypeError`` exception.215216Dot product is not defined on toric rational divisor classes.217218INPUT:219220- ``right`` - vector.221222OUTPUT:223224- ``TypeError`` exception is raised.225226TESTS::227228sage: c = toric_varieties.dP8().rational_class_group().gens()229sage: c[0]._dot_product_(c[1])230Traceback (most recent call last):231...232TypeError: cannot multiply two divisor classes!233sage: c[0] * c[1] # indirect doctest234Traceback (most recent call last):235...236TypeError: cannot multiply two divisor classes!237"""238raise TypeError("cannot multiply two divisor classes!")239240def _latex_(self):241r"""242Return a LaTeX representation of ``self``.243244OUTPUT:245246- string.247248TESTS::249250sage: D = toric_varieties.dP6().divisor(0).divisor_class()251sage: D._latex_()252'\\left[ 1, 0, 0, 0 \\right]_{\\mathop{Cl}_{\\QQ}\\left(\\mathbb{P}_{\\Delta^{2}}\\right)}'253"""254return r"\left[ %s \right]_{%s}" % (255", ".join([latex(e) for e in self]), latex(self.parent()))256257def _repr_(self):258r"""259Return a string representation of ``self``.260261OUTPUT:262263- string.264265EXAMPLES::266267sage: toric_varieties.dP6().divisor(0).divisor_class()._repr_()268'Divisor class [1, 0, 0, 0]'269"""270return 'Divisor class %s' % list(self)271272def lift(self):273r"""274Return a divisor representing this divisor class.275276OUTPUT:277278An instance of :class:`ToricDivisor` representing ``self``.279280EXAMPLES::281282sage: X = toric_varieties.Cube_nonpolyhedral()283sage: D = X.divisor([0,1,2,3,4,5,6,7]); D284V(z1) + 2*V(z2) + 3*V(z3) + 4*V(z4) + 5*V(z5) + 6*V(z6) + 7*V(z7)285sage: D.divisor_class()286Divisor class [29, 6, 8, 10, 0]287sage: Dequiv = D.divisor_class().lift(); Dequiv2886*V(z1) - 17*V(z2) - 22*V(z3) - 7*V(z4) + 25*V(z6) + 32*V(z7)289sage: Dequiv == D290False291sage: Dequiv.divisor_class() == D.divisor_class()292True293"""294Cl = self.parent()295return Cl._variety.divisor(Cl._lift_matrix * self)296297298def _ToricRationalDivisorClass_unpickle_v1(parent, entries,299degree, is_mutable):300"""301Unpickle a :class:`toric rational divisor class302<ToricRationalDivisorClass>`.303304INPUT:305306- ``parent`` -- rational divisor class group of a toric variety;307308- ``entries`` -- list of rationals specifying the divisor class;309310- ``degree`` -- integer, dimension of the ``parent``;311312- ``is_mutable`` -- boolean, whether the divisor class is mutable.313314OUTPUT:315316- :class:`toric rational divisor class <ToricRationalDivisorClass>`.317318TESTS::319320sage: dP6 = toric_varieties.dP6()321sage: Cl = dP6.rational_class_group()322sage: D = Cl([1, -2, 3, -4])323sage: D324Divisor class [1, -2, 3, -4]325sage: loads(dumps(D)) # indirect test326Divisor class [1, -2, 3, -4]327sage: from sage.schemes.toric.divisor_class import (328... _ToricRationalDivisorClass_unpickle_v1)329sage: _ToricRationalDivisorClass_unpickle_v1(330... Cl, [1, -2, 3, -4], 4, True)331Divisor class [1, -2, 3, -4]332"""333cdef ToricRationalDivisorClass v334v = PY_NEW(ToricRationalDivisorClass)335v._init(degree, parent)336cdef Rational z337for i from 0 <= i < degree:338z = Rational(entries[i])339mpq_init(v._entries[i])340mpq_set(v._entries[i], z.value)341v._is_mutable = is_mutable342return v343344345