Ticket #9972: trac_9972_improve_element_constructors.3.patch

File trac_9972_improve_element_constructors.3.patch, 20.3 KB (added by novoselt, 9 years ago)
  • sage/geometry/cone.py

    # HG changeset patch
    # User Volker Braun <vbraun@stp.dias.ie>
    # Date 1287083344 -3600
    # Node ID 081e43f508634df34bf409af8b0f11d2a135a8a4
    # Parent  241bda86abc36028e5ad52efaa80e771944a1854
    Trac 9972: Make CohomologyRing._element_constructor_ accept cones as input.
    
    Also, x in fan now only checks for cones. Added method fan.support_contains(x) for support questions. "0 in fan" now returns False.
    
    diff -r 241bda86abc3 -r 081e43f50863 sage/geometry/cone.py
    a b  
    22722272            ...
    22732273            NotImplementedError: cone isomorphism is not implemented yet!
    22742274        """
     2275        if self is other:
     2276            return True
    22752277        if self.lattice() != other.lattice():
    22762278            return False
    22772279        raise NotImplementedError("cone isomorphism is not implemented yet!")
  • sage/geometry/fan.py

    diff -r 241bda86abc3 -r 081e43f50863 sage/geometry/fan.py
    a b  
    535535        (N(-1, 0), N(0, -1))
    536536        (N(1, 0), N(0, 1))
    537537        (N(0, 1), N(-1, 0))
    538      """
     538    """
    539539    if any(d <= 0 for d in polytope.distances([0]*polytope.dim())):
    540540        raise ValueError("face fans are defined only for polytopes containing"
    541541                         "the origin as an interior point!")
     
    596596    .. WARNING::
    597597
    598598        This class does not check that the input defines a valid cone of a
    599         fan. You should not construct objects of this class directly.
     599        fan. You must not construct objects of this class directly.
    600600
    601601    In addition to all of the properties of "regular" :class:`cones
    602602    <sage.geometry.cone.ConvexRationalPolyhedralCone>`, such cones know their
     
    912912            sage: cone1 = Cone([(0,-1), (1,0)])
    913913            sage: cone2 = Cone([(1,0), (0,1)])
    914914            sage: f = Fan([cone1, cone2])
     915            sage: f.generating_cone(0) in f
     916            True
    915917            sage: cone1 in f
    916918            True
    917             sage: (1,1) in f
    918             True
    919             sage: (-1,-1) in f
     919            sage: (1,1) in f    # not a cone
     920            False
     921            sage: "Ceci n'est pas un cone" in f
    920922            False
    921923        """
    922924        return self._contains(data)
     
    10721074            elements[labels[0]] = FanFace(tuple(range(self.nrays())), ())
    10731075            self._cone_lattice = FinitePoset(L, elements)
    10741076
    1075     def _contains(self, data):
     1077    def _contains(self, cone):
    10761078        r"""
    1077         Check if ``data`` is contained in ``self``.
     1079        Check if ``cone`` is a cone of the fan.
    10781080
    10791081        This function is called by :meth:`__contains__` and :meth:`contains`
    10801082        to ensure the same call depth for warning messages.
    10811083
    10821084        INPUT:
    10831085
    1084         - ``data`` -- anything. If it is not a cone, an attempt will be made
    1085           to convert it into a single point of the ambient space of ``self``.
    1086           If it fails, ``False`` will be returned.
     1086        - ``cone`` -- anything.
    10871087
    10881088        OUTPUT:
    10891089
    1090         - ``True`` if ``data`` is contained in ``self``, ``False`` otherwise.
    1091 
    1092         TESTS::
     1090        - ``False`` if ``cone`` is not a cone, if ``cone`` is a cone
     1091          of a different fan, or if ``cone`` is not equivalent to a
     1092          cone of the fan. ``True`` otherwise.
    10931093
    10941094        TESTS::
    10951095
     
    10981098            sage: f = Fan([cone1, cone2])
    10991099            sage: f._contains(cone1)
    11001100            True
    1101             sage: f._contains((1,1))
     1101            sage: f._contains((1,1))  # this is not a cone!
     1102            False
     1103
     1104        Note this case::
     1105
     1106            sage: cone1_f = f.generating_cone(0)
     1107            sage: cone1.is_equivalent(cone1_f)
    11021108            True
     1109            sage: cone1   in Fan([cone1, cone2])  # not a cone of any particular fan
     1110            True
     1111            sage: cone1_f in Fan([cone1, cone2])  # belongs to different fan!
     1112            False
    11031113        """
    1104         if is_Cone(data):
    1105             if data.lattice() != self.lattice():
    1106                 warnings.warn("you have checked if a fan contains a cone "
    1107                               "from another lattice, this is always False!",
    1108                               stacklevel=3)
    1109                 # We may need to take into account canonical maps, perhaps...
    1110                 return False
    1111             if (not data.is_strictly_convex()
    1112                 or not data.ray_set().issubset(self.ray_set())):
    1113                 return False
    1114             try:
    1115                 return data.is_equivalent(self.cone_containing(data.rays()))
    1116             except ValueError:  # No cone containing all these rays
    1117                 return False
    1118         # Now we try to treat data as a point
     1114        if not is_Cone(cone):
     1115            return False
     1116        if isinstance(cone, Cone_of_fan):
     1117            return self is cone.ambient()
     1118        if cone.lattice() != self.lattice():
     1119            warnings.warn("you have checked if a fan contains a cone "
     1120                          "from another lattice, this is always False!",
     1121                          stacklevel=3)
     1122            # We may need to take into account canonical maps, perhaps...
     1123            return False
     1124        if (not cone.is_strictly_convex()
     1125            or not cone.ray_set().issubset(self.ray_set())):
     1126            return False
     1127        try:
     1128            return cone.is_equivalent(self.cone_containing(cone.rays()))
     1129        except ValueError:  # No cone of then fan contains all these rays
     1130            return False
     1131
     1132    def support_contains(self, *args):
     1133        r"""
     1134        Check if a point is contained in the support of the fan.
     1135       
     1136        The support of a fan is the union of all cones of the fan. If
     1137        you want to know whether the fan contains a given cone, you
     1138        should use :meth:`contains` instead.
     1139
     1140        INPUT:
     1141
     1142        - ``*args`` -- an element of ``self.lattice()`` or something
     1143          that can be converted to it (for example, a list of
     1144          coordinates).
     1145
     1146        OUTPUT:
     1147
     1148        - ``True`` if ``point`` is contained in the support of the
     1149          fan, ``False`` otherwise.
     1150
     1151        TESTS::
     1152
     1153            sage: cone1 = Cone([(0,-1), (1,0)])
     1154            sage: cone2 = Cone([(1,0), (0,1)])
     1155            sage: f = Fan([cone1, cone2])
     1156
     1157        We check if some points are in this fan::
     1158
     1159            sage: f.support_contains(f.lattice()(1,0))
     1160            True
     1161            sage: f.support_contains(cone1)    # a cone is not a point of the lattice
     1162            False
     1163            sage: f.support_contains((1,0))
     1164            True
     1165            sage: f.support_contains(1,1)
     1166            True
     1167            sage: f.support_contains((-1,0))
     1168            False
     1169            sage: f.support_contains(f.lattice().dual()(1,0)) #random output (warning)
     1170            False
     1171            sage: f.support_contains(f.lattice().dual()(1,0))
     1172            False
     1173            sage: f.support_contains(1)
     1174            False
     1175            sage: f.support_contains(0)   # 0 converts to the origin in the lattice
     1176            True
     1177            sage: f.support_contains(1/2, sqrt(3))
     1178            True
     1179            sage: f.support_contains(-1/2, sqrt(3))
     1180            False
     1181        """
     1182        if len(args)==1:
     1183            point = args[0]
     1184        else:
     1185            point = args
     1186
    11191187        try:
    1120             data = self._ambient_space_point(data)
     1188            point = self._ambient_space_point(point)
    11211189        except TypeError, ex:
    11221190            if str(ex).endswith("have incompatible lattices!"):
    11231191                warnings.warn("you have checked if a fan contains a point "
     
    11261194            return False
    11271195        if self.is_complete():
    11281196            return True
    1129         return any(data in cone for cone in self)
     1197        return any(point in cone for cone in self)
    11301198
    11311199    def _latex_(self):
    11321200        r"""
     
    13391407
    13401408        OUTPUT:
    13411409
    1342         - :class:`cone of fan <Cone_of_fan>`.
     1410        - A :class:`cone of fan <Cone_of_fan>` whose ambient fan is
     1411          ``self``.
    13431412
    13441413        .. NOTE::
    13451414
     
    16091678        raise ValueError(
    16101679                    "dimension and codimension cannot be specified together!")
    16111680
    1612     def contains(self, *args):
     1681    def contains(self, cone):
    16131682        r"""
    1614         Check if a given point or cone is contained in ``self``.
     1683        Check if a given ``cone`` is contained in ``self``.
    16151684
    16161685        INPUT:
    16171686
    1618         - anything. If it is not a cone, an attempt will be made to convert
    1619           the input into a point of the ambient space of ``self``. If it
    1620           fails, ``False`` will be returned.
     1687        - ``cone`` -- anything.
    16211688
    16221689        OUTPUT:
    16231690
    1624         - ``True`` if the given point or cone is contained in ``self``,
    1625           ``False`` otherwise.
     1691        - ``False`` if ``cone`` is not a cone, if ``cone`` belongs to
     1692          a different fan, or if ``cone`` is not equivalent to a cone
     1693          of the fan. ``True`` otherwise.
    16261694
    16271695        .. NOTE::
    16281696
    1629             A point is contained in a fan if it is contained in its support.
    1630             A cone is contained in a fan if it is equivalent to one of the
    1631             cones of the fan, in particular, it is possible that all points of
    1632             the cone are in the fan, but the cone itself is not.
     1697            Recall that a fan is a (finite) collection of cones. A
     1698            cone is contained in a fan if it is equivalent to one of
     1699            the cones of the fan. In particular, it is possible that
     1700            all rays of the cone are in the fan, but the cone itself
     1701            is not.
     1702
     1703            If you want to know whether a point is in the support of
     1704            the fan, you should use :meth:`support_contains`.
    16331705
    16341706        EXAMPLES:
    16351707
    1636         We construct a simple fan::
     1708        We first construct a simple fan::
    16371709
    16381710            sage: cone1 = Cone([(0,-1), (1,0)])
    16391711            sage: cone2 = Cone([(1,0), (0,1)])
    16401712            sage: f = Fan([cone1, cone2])
    16411713
    1642         We check if some points are in this fan::
    1643 
    1644             sage: f.contains(f.lattice()(1,0))
    1645             True
    1646             sage: f.contains((1,0))
    1647             True
    1648             sage: f.contains(1,1)
    1649             True
    1650             sage: f.contains((-1,0))
    1651             False
    1652             sage: f.contains(f.lattice().dual()(1,0)) #random output (warning)
    1653             False
    1654             sage: f.contains(f.lattice().dual()(1,0))
    1655             False
    1656             sage: f.contains(1)
    1657             False
    1658             sage: f.contains(1/2, sqrt(3))
    1659             True
    1660             sage: f.contains(-1/2, sqrt(3))
    1661             False
    1662 
    16631714        Now we check if some cones are in this fan. First, we make sure that
    16641715        the order of rays of the input cone does not matter (``check=False``
    16651716        option ensures that rays of these cones will be listed exactly as they
     
    16741725
    16751726            sage: f.contains(Cone([(1,0)]))
    16761727            True
     1728            sage: Cone([(1,0)]) in f   # equivalent to the previous command
     1729            True
    16771730
    16781731        Finally, we test some cones which are not in this fan::
    16791732
     
    16811734            False
    16821735            sage: f.contains(Cone([(0,1), (-1,0)]))
    16831736            False
     1737
     1738        A point is not a cone::
     1739
     1740            sage: n = f.lattice()(1,1); n
     1741            N(1, 1)
     1742            sage: f.contains(n)
     1743            False
    16841744        """
    1685         data = flatten(args)
    1686         if len(data) == 1:
    1687            data = data[0]
    1688         return self._contains(data)
     1745        return self._contains(cone)
    16891746
    16901747    def embed(self, cone):
    16911748        r"""
  • sage/schemes/generic/toric_divisor.py

    diff -r 241bda86abc3 -r 081e43f50863 sage/schemes/generic/toric_divisor.py
    a b  
    348348            sage: TDiv = P2.toric_divisor_group()
    349349            sage: TDiv._element_constructor_([ (1,P2.gen(2)) ])
    350350            V(z)
     351            sage: TDiv( P2.fan(1)[0] )
     352            V(x)
    351353        """
    352354        if is_ToricDivisor(x):
    353355            if x.parent() is self:
     
    482484        ValueError: u + y is not a monomial!
    483485        sage: ToricDivisor(dP6, u*y)
    484486        V(u) + V(y)
    485         sage: ToricDivisor(dP6, dP6.fan(dim=1)[0] )
    486         V(x)
     487        sage: ToricDivisor(dP6, dP6.fan(dim=1)[2] )
     488        V(y)
     489        sage: cone = Cone(dP6.fan(dim=1)[2])
     490        sage: ToricDivisor(dP6, cone)
     491        V(y)
    487492        sage: N = dP6.fan().lattice()
    488493        sage: ToricDivisor(dP6, N(1,1) )
    489494        V(w)
     
    520525        arg = toric_variety.fan().cone_containing(arg)
    521526    # Divisor by a one-cone
    522527    if is_Cone(arg):
    523         if arg.dim() != 1:
     528        fan = toric_variety.fan()
     529        cone = fan.embed(arg)
     530        if cone.dim() != 1:
    524531            raise ValueError("Only 1-dimensional cones of the toric variety "
    525532                             "define divisors.")
    526         arg = arg.ambient_ray_indices()[0]
     533
     534        assert cone.ambient() is fan
     535        arg = cone.ambient_ray_indices()[0]
    527536    # Divisor by a ray index
    528537    if arg in ZZ:
    529538        arg = [(1, toric_variety.gen(arg))]
     
    789798            (3/2, 0, 1/2)
    790799            sage: QQ_Cartier.m(triangle_cone)
    791800            M(1, 0, 1)
     801            sage: QQ_Cartier.m(Cone(triangle_cone))
     802            M(1, 0, 1)
    792803            sage: Weil = X.divisor([1,1,1,0,0])
    793804            sage: Weil.m(square_cone)
    794805            Traceback (most recent call last):
     
    808819       
    809820        X = self.parent().scheme()
    810821        M = X.fan().dual_lattice()
     822        fan = X.fan()
     823        cone = fan.embed(cone)
    811824        if cone.is_trivial():
    812825            m = M(0)
    813826            self._m[cone] = m
    814827            return m
    815828
     829        assert cone.ambient() is fan
    816830        b = vector(self.coefficient(i) for i in cone.ambient_ray_indices())
    817831        A = cone.ray_matrix()
    818832        try:
     
    10221036            [y + v - w]
    10231037        """
    10241038        divisor = vector(self)
    1025         return sum([divisor[i] * cone.cohomology_class()
    1026                     for i, cone in enumerate(self.parent().scheme().fan(1))])
     1039        variety = self.parent().scheme()
     1040        HH = variety.cohomology_ring()
     1041        return sum([ divisor[i] * HH.gen(i) for i in range(0,HH.ngens()) ])
    10271042
    10281043    def Chern_character(self):
    10291044        r"""
  • sage/schemes/generic/toric_variety.py

    diff -r 241bda86abc3 -r 081e43f50863 sage/schemes/generic/toric_variety.py
    a b  
    294294        """
    295295        return self.ambient().toric_variety()
    296296
    297     def cohomology_class(self):
    298         r"""
    299         Return the cohomology class associated to the cone.
    300        
    301         OUTPUT:
    302 
    303         Returns the cohomology class of the orbit closure (a
    304         subvariety of the toric variety) associated to the cone.
    305 
    306         EXAMPLES::
    307          
    308             sage: dP6 = toric_varieties.dP6()
    309             sage: cone = dP6.fan().cone_containing(2,3); cone
    310             2-d cone of Rational polyhedral fan in 2-d lattice N
    311             sage: cone.cohomology_class()
    312             [-w^2]
    313         """
    314         if "_cohomology_class" not in self.__dict__:
    315             idx = self.ambient_ray_indices()
    316             self._cohomology_class = \
    317                 prod( self.toric_variety().cohomology_ring().gen(i) for i in idx )
    318         return self._cohomology_class
    319 
    320297
    321298class Fan_of_toric_variety(EnhancedFan):
    322299    r"""
     
    18761853                                          'implemented for orbifolds.')
    18771854            def V(cone): return abs(cone.ray_matrix().determinant())
    18781855            min_cone = min( self._fan.generating_cones(), key=V)
    1879             self._volume_class = min_cone.cohomology_class() / V(min_cone)
     1856            self._volume_class = self.cohomology_ring()(min_cone) / V(min_cone)
    18801857        if self._volume_class.is_zero():
    18811858            raise ValueError, 'Volume class does not exist.'
    18821859        return self._volume_class
     
    19001877        EXAMPLES::
    19011878
    19021879            sage: dP6 = toric_varieties.dP6()
    1903             sage: D = [ c.cohomology_class() for c in dP6.fan(dim=1) ]
     1880            sage: HH = dP6.cohomology_ring()
     1881            sage: D = [ HH(c) for c in dP6.fan(dim=1) ]
    19041882            sage: matrix([ [ D[i]*D[j] for i in range(0,6) ] for j in range(0,6) ])
    19051883            [ [w^2] [-w^2]    [0]    [0]    [0] [-w^2]]
    19061884            [[-w^2]  [w^2] [-w^2]    [0]    [0]    [0]]
     
    21202098        Lets test that the del Pezzo surface `dP_6` has degree 6, as its name implies::
    21212099
    21222100            sage: dP6 = toric_varieties.dP6()
     2101            sage: HH = dP6.cohomology_ring()
    21232102            sage: dP6.K()
    21242103            -V(x) - V(u) - V(y) - V(v) - V(z) - V(w)
    2125             sage: dP6.integrate( dP6.K().cohomology_class()^2 )
     2104            sage: dP6.integrate( HH(dP6.K())^2 )
    21262105            6
    21272106        """
    21282107        from sage.schemes.generic.toric_divisor import ToricDivisor
     
    29802959       
    29812960        INPUT::
    29822961       
    2983         - ``x`` -- something that defines a cohomology class.
     2962        - ``x`` -- something that defines a cohomology class. Either a
     2963          cohomology class, a cone of the fan, or something that can
     2964          be converted into a polynomial in the homogeneous
     2965          coordinates.
    29842966
    29852967        EXAMPLES::
     2968         
     2969            sage: dP6 = toric_varieties.dP6()
     2970            sage: H = dP6.cohomology_ring()
     2971            sage: cone = dP6.fan().cone_containing(2,3); cone
     2972            2-d cone of Rational polyhedral fan in 2-d lattice N
     2973            sage: H(cone)   # indirect doctest
     2974            [-w^2]
     2975            sage: H( Cone(cone) )
     2976            [-w^2]
     2977            sage: H( dP6.fan(0)[0] )   # trivial cone
     2978            [1]
    29862979
     2980
     2981        Numbers will be converted into the ring::
     2982           
    29872983            sage: P2 = toric_varieties.P2()
    29882984            sage: H = P2.cohomology_ring()
    29892985            sage: H._element_constructor_(1)
     
    29922988            [1]
    29932989            sage: type( H(1) )
    29942990            <class 'sage.schemes.generic.toric_variety.CohomologyClass'>
     2991            sage: P2.inject_variables()
     2992            Defining x, y, z
     2993            sage: H(1+x*y+z)
     2994            [z^2 + z + 1]
    29952995        """
     2996        fan = self._variety.fan()
     2997        if isinstance(x, CohomologyClass) and x.parent()==self:
     2998            return x
    29962999        if isinstance(x, QuotientRingElement):
    29973000            x = x.lift()
     3001        elif is_Cone(x):
     3002            cone = fan.embed(x)
     3003            assert cone.ambient() is fan
     3004            x = prod((self.cover_ring().gen(i) for i in cone.ambient_ray_indices()),
     3005                     z=self.cover_ring().one())
    29983006        else:
    2999             x = self.cover_ring()(x)
     3007            try:
     3008                # divisor, for example, know how to compute their own cohomology class
     3009                return x.cohomology_class()
     3010            except AttributeError:
     3011                # this ensures that rationals are converted to cohomology ring elements
     3012                x = self.cover_ring()(x)
    30003013        return CohomologyClass(self, x)
    30013014   
    30023015    # We definitely should not override __call__, but since our
     
    30803093    EXAMPLES::
    30813094   
    30823095        sage: P2 = toric_varieties.P2()
     3096        sage: HH = P2.cohomology_ring()
    30833097        sage: from sage.schemes.generic.toric_variety import is_CohomologyClass
    3084         sage: is_CohomologyClass( P2.cohomology_ring().one() )
     3098        sage: is_CohomologyClass( HH.one() )
    30853099        True
    3086         sage: is_CohomologyClass( (P2.fan(1)[0]).cohomology_class() )
     3100        sage: is_CohomologyClass( HH(P2.fan(1)[0]) )
    30873101        True
    30883102        sage: is_CohomologyClass('z')
    30893103        False
     
    30993113    .. WARNING::
    31003114
    31013115        You should not create instances of this class manually. The
    3102         generators of the cohomology ring can be obtained from
    3103         :meth:`ToricVariety_field.cohomology_ring`
    3104         and the cohomology class associated to cones of the fan from
    3105         :meth:`Cone_of_toric_variety.cohomology_class`
     3116        generators of the cohomology ring as well as the cohomology
     3117        classes associated to cones of the fan can be obtained from
     3118        :meth:`ToricVariety_field.cohomology_ring`.
    31063119   
    31073120    EXAMPLES::
    31083121   
    31093122        sage: P2 = toric_varieties.P2()
    3110         sage: cone = P2.fan(1)[0]
    3111         sage: cone.cohomology_class()
     3123        sage: P2.cohomology_ring().gen(0)
    31123124        [z]
    3113         sage: P2.cohomology_ring().gen(0)
     3125        sage: HH = P2.cohomology_ring()
     3126        sage: HH.gen(0)
     3127        [z]
     3128        sage: cone = P2.fan(1)[0];  HH(cone)
    31143129        [z]
    31153130    """
    31163131