Ticket #9972: trac_9972_improve_element_constructors.patch

File trac_9972_improve_element_constructors.patch, 20.8 KB (added by vbraun, 9 years ago)

Updated patch

  • sage/geometry/cone.py

    # HG changeset patch
    # User Volker Braun <vbraun@stp.dias.ie>
    # Date 1287083344 -3600
    # Node ID d5cde56a3d01dfb68f420ecc8b4b1b92b755f1b7
    # Parent  af4f35b4ba4ece96039f8fff254244e2a8f8732b
    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 af4f35b4ba4e -r d5cde56a3d01 sage/geometry/cone.py
    a b  
    22482248            ...
    22492249            NotImplementedError: cone isomorphism is not implemented yet!
    22502250        """
     2251        if self is other:
     2252            return True
    22512253        if self.lattice() != other.lattice():
    22522254            return False
    22532255        raise NotImplementedError("cone isomorphism is not implemented yet!")
  • sage/geometry/fan.py

    diff -r af4f35b4ba4e -r d5cde56a3d01 sage/geometry/fan.py
    a b  
    533533        (N(-1, 0), N(0, -1))
    534534        (N(1, 0), N(0, 1))
    535535        (N(0, 1), N(-1, 0))
    536      """
     536    """
    537537    if any(d <= 0 for d in polytope.distances([0]*polytope.dim())):
    538538        raise ValueError("face fans are defined only for polytopes containing"
    539539                         "the origin as an interior point!")
     
    594594    .. WARNING::
    595595
    596596        This class does not check that the input defines a valid cone of a
    597         fan. You should not construct objects of this class directly.
     597        fan. You must not construct objects of this class directly.
    598598
    599599    In addition to all of the properties of "regular" :class:`cones
    600600    <sage.geometry.cone.ConvexRationalPolyhedralCone>`, such cones know their
     
    898898        else:
    899899            return cmp(type(self), type(right))
    900900
    901     def __contains__(self, data):
     901    def __contains__(self, cone):
    902902        r"""
    903         Check if ``data`` is contained in ``self``.
     903        Check if ``cone`` is equivalent to a cone of the fan.
    904904
    905905        See :meth:`_contains` (which is called by this function) for
    906906        documentation.
     
    910910            sage: cone1 = Cone([(0,-1), (1,0)])
    911911            sage: cone2 = Cone([(1,0), (0,1)])
    912912            sage: f = Fan([cone1, cone2])
     913            sage: f.generating_cone(0) in f
     914            True
    913915            sage: cone1 in f
    914916            True
    915             sage: (1,1) in f
    916             True
    917             sage: (-1,-1) in f
     917            sage: (1,1) in f    # not a cone
     918            False
     919            sage: "Ceci n'est pas un cone" in f
    918920            False
    919921        """
    920         return self._contains(data)
     922        return self._contains(cone)
    921923
    922924    def __iter__(self):
    923925        r"""
     
    10701072            elements[labels[0]] = FanFace(tuple(range(self.nrays())), ())
    10711073            self._cone_lattice = FinitePoset(L, elements)
    10721074
    1073     def _contains(self, data):
     1075    def _contains(self, cone):
    10741076        r"""
    1075         Check if ``data`` is contained in ``self``.
     1077        Check if ``cone`` is equivalent to a cone of the fan.
    10761078
    10771079        This function is called by :meth:`__contains__` and :meth:`contains`
    10781080        to ensure the same call depth for warning messages.
    10791081
    10801082        INPUT:
    10811083
    1082         - ``data`` -- anything. If it is not a cone, an attempt will be made
    1083           to convert it into a single point of the ambient space of ``self``.
    1084           If it fails, ``False`` will be returned.
     1084        - ``cone`` -- anything.
    10851085
    10861086        OUTPUT:
    10871087
    1088         - ``True`` if ``data`` is contained in ``self``, ``False`` otherwise.
    1089 
    1090         TESTS::
     1088        - ``False`` if ``cone`` is not a cone or if ``cone`` is not
     1089          equivalent to a cone of the fan. ``True`` otherwise.
    10911090
    10921091        TESTS::
    10931092
     
    10961095            sage: f = Fan([cone1, cone2])
    10971096            sage: f._contains(cone1)
    10981097            True
    1099             sage: f._contains((1,1))
     1098            sage: f._contains((1,1))  # this is not a cone!
     1099            False
     1100
     1101        Note that the ambient fan of the cone does not matter::
     1102
     1103            sage: cone1_f = f.generating_cone(0)
     1104            sage: cone1_f is cone1
     1105            False
     1106            sage: cone1_f.is_equivalent(cone1)
     1107            True
     1108            sage: cone1   in Fan([cone1, cone2])  # not a cone of any particular fan
     1109            True
     1110            sage: cone1_f in Fan([cone1, cone2])  # belongs to different fan, but equivalent cone
    11001111            True
    11011112        """
    1102         if is_Cone(data):
    1103             if data.lattice() != self.lattice():
    1104                 warnings.warn("you have checked if a fan contains a cone "
    1105                               "from another lattice, this is always False!",
    1106                               stacklevel=3)
    1107                 # We may need to take into account canonical maps, perhaps...
    1108                 return False
    1109             if (not data.is_strictly_convex()
    1110                 or not data.ray_set().issubset(self.ray_set())):
    1111                 return False
    1112             try:
    1113                 return data.is_equivalent(self.cone_containing(data.rays()))
    1114             except ValueError:  # No cone containing all these rays
    1115                 return False
    1116         # Now we try to treat data as a point
     1113        if not is_Cone(cone):
     1114            return False
     1115        if cone.lattice() != self.lattice():
     1116            warnings.warn("you have checked if a fan contains a cone "
     1117                          "from another lattice, this is always False!",
     1118                          stacklevel=3)
     1119            # We may need to take into account canonical maps, perhaps...
     1120            return False
     1121        if (not cone.is_strictly_convex()
     1122            or not cone.ray_set().issubset(self.ray_set())):
     1123            return False
     1124        try:
     1125            return cone.is_equivalent(self.cone_containing(cone.rays()))
     1126        except ValueError:  # No cone of then fan contains all these rays
     1127            return False
     1128
     1129    def support_contains(self, *args):
     1130        r"""
     1131        Check if a point is contained in the support of the fan.
     1132       
     1133        The support of a fan is the union of all cones of the fan. If
     1134        you want to know whether the fan contains a given cone, you
     1135        should use :meth:`contains` instead.
     1136
     1137        INPUT:
     1138
     1139        - ``*args`` -- an element of ``self.lattice()`` or something
     1140          that can be converted to it (for example, a list of
     1141          coordinates).
     1142
     1143        OUTPUT:
     1144
     1145        - ``True`` if ``point`` is contained in the support of the
     1146          fan, ``False`` otherwise.
     1147
     1148        TESTS::
     1149
     1150            sage: cone1 = Cone([(0,-1), (1,0)])
     1151            sage: cone2 = Cone([(1,0), (0,1)])
     1152            sage: f = Fan([cone1, cone2])
     1153
     1154        We check if some points are in this fan::
     1155
     1156            sage: f.support_contains(f.lattice()(1,0))
     1157            True
     1158            sage: f.support_contains(cone1)    # a cone is not a point of the lattice
     1159            False
     1160            sage: f.support_contains((1,0))
     1161            True
     1162            sage: f.support_contains(1,1)
     1163            True
     1164            sage: f.support_contains((-1,0))
     1165            False
     1166            sage: f.support_contains(f.lattice().dual()(1,0)) #random output (warning)
     1167            False
     1168            sage: f.support_contains(f.lattice().dual()(1,0))
     1169            False
     1170            sage: f.support_contains(1)
     1171            False
     1172            sage: f.support_contains(0)   # 0 converts to the origin in the lattice
     1173            True
     1174            sage: f.support_contains(1/2, sqrt(3))
     1175            True
     1176            sage: f.support_contains(-1/2, sqrt(3))
     1177            False
     1178        """
     1179        if len(args)==1:
     1180            point = args[0]
     1181        else:
     1182            point = args
     1183
    11171184        try:
    1118             data = self._ambient_space_point(data)
     1185            point = self._ambient_space_point(point)
    11191186        except TypeError, ex:
    11201187            if str(ex).endswith("have incompatible lattices!"):
    11211188                warnings.warn("you have checked if a fan contains a point "
     
    11241191            return False
    11251192        if self.is_complete():
    11261193            return True
    1127         return any(data in cone for cone in self)
     1194        return any(point in cone for cone in self)
    11281195
    11291196    def _latex_(self):
    11301197        r"""
     
    13371404
    13381405        OUTPUT:
    13391406
    1340         - :class:`cone of fan <Cone_of_fan>`.
     1407        - A :class:`cone of fan <Cone_of_fan>` whose ambient fan is
     1408          ``self``.
    13411409
    13421410        .. NOTE::
    13431411
     
    16071675        raise ValueError(
    16081676                    "dimension and codimension cannot be specified together!")
    16091677
    1610     def contains(self, *args):
     1678    def contains(self, cone):
    16111679        r"""
    1612         Check if a given point or cone is contained in ``self``.
     1680        Check if a given ``cone`` is equivalent to a cone of the fan.
    16131681
    16141682        INPUT:
    16151683
    1616         - anything. If it is not a cone, an attempt will be made to convert
    1617           the input into a point of the ambient space of ``self``. If it
    1618           fails, ``False`` will be returned.
     1684        - ``cone`` -- anything.
    16191685
    16201686        OUTPUT:
    16211687
    1622         - ``True`` if the given point or cone is contained in ``self``,
    1623           ``False`` otherwise.
     1688        - ``False`` if ``cone`` is not a cone or if ``cone`` is not
     1689          equivalent to a cone of the fan. ``True`` otherwise.
    16241690
    16251691        .. NOTE::
    16261692
    1627             A point is contained in a fan if it is contained in its support.
    1628             A cone is contained in a fan if it is equivalent to one of the
    1629             cones of the fan, in particular, it is possible that all points of
    1630             the cone are in the fan, but the cone itself is not.
     1693            Recall that a fan is a (finite) collection of cones. A
     1694            cone is contained in a fan if it is equivalent to one of
     1695            the cones of the fan. In particular, it is possible that
     1696            all rays of the cone are in the fan, but the cone itself
     1697            is not.
     1698
     1699            If you want to know whether a point is in the support of
     1700            the fan, you should use :meth:`support_contains`.
    16311701
    16321702        EXAMPLES:
    16331703
    1634         We construct a simple fan::
     1704        We first construct a simple fan::
    16351705
    16361706            sage: cone1 = Cone([(0,-1), (1,0)])
    16371707            sage: cone2 = Cone([(1,0), (0,1)])
    16381708            sage: f = Fan([cone1, cone2])
    16391709
    1640         We check if some points are in this fan::
    1641 
    1642             sage: f.contains(f.lattice()(1,0))
    1643             True
    1644             sage: f.contains((1,0))
    1645             True
    1646             sage: f.contains(1,1)
    1647             True
    1648             sage: f.contains((-1,0))
    1649             False
    1650             sage: f.contains(f.lattice().dual()(1,0)) #random output (warning)
    1651             False
    1652             sage: f.contains(f.lattice().dual()(1,0))
    1653             False
    1654             sage: f.contains(1)
    1655             False
    1656             sage: f.contains(1/2, sqrt(3))
    1657             True
    1658             sage: f.contains(-1/2, sqrt(3))
    1659             False
    1660 
    16611710        Now we check if some cones are in this fan. First, we make sure that
    16621711        the order of rays of the input cone does not matter (``check=False``
    16631712        option ensures that rays of these cones will be listed exactly as they
     
    16721721
    16731722            sage: f.contains(Cone([(1,0)]))
    16741723            True
     1724            sage: Cone([(1,0)]) in f   # equivalent to the previous command
     1725            True
    16751726
    16761727        Finally, we test some cones which are not in this fan::
    16771728
    16781729            sage: f.contains(Cone([(1,1)]))
    16791730            False
    1680             sage: f.contains(Cone([(0,1), (-1,0)]))
     1731            sage: f.contains(Cone([(1,0), (-0,1)]))
     1732            True
     1733
     1734        A point is not a cone::
     1735
     1736            sage: n = f.lattice()(1,1); n
     1737            N(1, 1)
     1738            sage: f.contains(n)
    16811739            False
    16821740        """
    1683         data = flatten(args)
    1684         if len(data) == 1:
    1685            data = data[0]
    1686         return self._contains(data)
     1741        return self._contains(cone)
    16871742
    16881743    def embed(self, cone):
    16891744        r"""
  • sage/schemes/generic/toric_divisor.py

    diff -r af4f35b4ba4e -r d5cde56a3d01 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 af4f35b4ba4e -r d5cde56a3d01 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"""
     
    18441821                                          'implemented for orbifolds.')
    18451822            def V(cone): return abs(cone.ray_matrix().determinant())
    18461823            min_cone = min( self._fan.generating_cones(), key=V)
    1847             self._volume_class = min_cone.cohomology_class() / V(min_cone)
     1824            self._volume_class = self.cohomology_ring()(min_cone) / V(min_cone)
    18481825        if self._volume_class.is_zero():
    18491826            raise ValueError, 'Volume class does not exist.'
    18501827        return self._volume_class
     
    18681845        EXAMPLES::
    18691846
    18701847            sage: dP6 = toric_varieties.dP6()
    1871             sage: D = [ c.cohomology_class() for c in dP6.fan(dim=1) ]
     1848            sage: HH = dP6.cohomology_ring()
     1849            sage: D = [ HH(c) for c in dP6.fan(dim=1) ]
    18721850            sage: matrix([ [ D[i]*D[j] for i in range(0,6) ] for j in range(0,6) ])
    18731851            [ [w^2] [-w^2]    [0]    [0]    [0] [-w^2]]
    18741852            [[-w^2]  [w^2] [-w^2]    [0]    [0]    [0]]
     
    20882066        Lets test that the del Pezzo surface `dP_6` has degree 6, as its name implies::
    20892067
    20902068            sage: dP6 = toric_varieties.dP6()
     2069            sage: HH = dP6.cohomology_ring()
    20912070            sage: dP6.K()
    20922071            -V(x) - V(u) - V(y) - V(v) - V(z) - V(w)
    2093             sage: dP6.integrate( dP6.K().cohomology_class()^2 )
     2072            sage: dP6.integrate( HH(dP6.K())^2 )
    20942073            6
    20952074        """
    20962075        from sage.schemes.generic.toric_divisor import ToricDivisor
     
    29482927       
    29492928        INPUT::
    29502929       
    2951         - ``x`` -- something that defines a cohomology class.
     2930        - ``x`` -- something that defines a cohomology class. Either a
     2931          cohomology class, a cone of the fan, or something that can
     2932          be converted into a polynomial in the homogeneous
     2933          coordinates.
    29522934
    29532935        EXAMPLES::
     2936         
     2937            sage: dP6 = toric_varieties.dP6()
     2938            sage: H = dP6.cohomology_ring()
     2939            sage: cone = dP6.fan().cone_containing(2,3); cone
     2940            2-d cone of Rational polyhedral fan in 2-d lattice N
     2941            sage: H(cone)   # indirect doctest
     2942            [-w^2]
     2943            sage: H( Cone(cone) )
     2944            [-w^2]
     2945            sage: H( dP6.fan(0)[0] )   # trivial cone
     2946            [1]
    29542947
     2948
     2949        Numbers will be converted into the ring::
     2950           
    29552951            sage: P2 = toric_varieties.P2()
    29562952            sage: H = P2.cohomology_ring()
    29572953            sage: H._element_constructor_(1)
     
    29602956            [1]
    29612957            sage: type( H(1) )
    29622958            <class 'sage.schemes.generic.toric_variety.CohomologyClass'>
     2959            sage: P2.inject_variables()
     2960            Defining x, y, z
     2961            sage: H(1+x*y+z)
     2962            [z^2 + z + 1]
    29632963        """
     2964        fan = self._variety.fan()
     2965        if isinstance(x, CohomologyClass) and x.parent()==self:
     2966            return x
    29642967        if isinstance(x, QuotientRingElement):
    29652968            x = x.lift()
     2969        elif is_Cone(x):
     2970            cone = fan.embed(x)
     2971            assert cone.ambient() is fan
     2972            x = prod((self.cover_ring().gen(i) for i in cone.ambient_ray_indices()),
     2973                     z=self.cover_ring().one())
    29662974        else:
    2967             x = self.cover_ring()(x)
     2975            try:
     2976                # divisor, for example, know how to compute their own cohomology class
     2977                return x.cohomology_class()
     2978            except AttributeError:
     2979                # this ensures that rationals are converted to cohomology ring elements
     2980                x = self.cover_ring()(x)
    29682981        return CohomologyClass(self, x)
    29692982   
    29702983    # We definitely should not override __call__, but since our
     
    30483061    EXAMPLES::
    30493062   
    30503063        sage: P2 = toric_varieties.P2()
     3064        sage: HH = P2.cohomology_ring()
    30513065        sage: from sage.schemes.generic.toric_variety import is_CohomologyClass
    3052         sage: is_CohomologyClass( P2.cohomology_ring().one() )
     3066        sage: is_CohomologyClass( HH.one() )
    30533067        True
    3054         sage: is_CohomologyClass( (P2.fan(1)[0]).cohomology_class() )
     3068        sage: is_CohomologyClass( HH(P2.fan(1)[0]) )
    30553069        True
    30563070        sage: is_CohomologyClass('z')
    30573071        False
     
    30673081    .. WARNING::
    30683082
    30693083        You should not create instances of this class manually. The
    3070         generators of the cohomology ring can be obtained from
    3071         :meth:`ToricVariety_field.cohomology_ring`
    3072         and the cohomology class associated to cones of the fan from
    3073         :meth:`Cone_of_toric_variety.cohomology_class`
     3084        generators of the cohomology ring as well as the cohomology
     3085        classes associated to cones of the fan can be obtained from
     3086        :meth:`ToricVariety_field.cohomology_ring`.
    30743087   
    30753088    EXAMPLES::
    30763089   
    30773090        sage: P2 = toric_varieties.P2()
    3078         sage: cone = P2.fan(1)[0]
    3079         sage: cone.cohomology_class()
     3091        sage: P2.cohomology_ring().gen(0)
    30803092        [z]
    3081         sage: P2.cohomology_ring().gen(0)
     3093        sage: HH = P2.cohomology_ring()
     3094        sage: HH.gen(0)
     3095        [z]
     3096        sage: cone = P2.fan(1)[0];  HH(cone)
    30823097        [z]
    30833098    """
    30843099