Ticket #7585: 7585_7_ideal.patch

File 7585_7_ideal.patch, 20.0 KB (added by David Roe, 13 years ago)
  • sage/rings/ideal.py

    # HG changeset patch
    # User David Roe <roed@math.harvard.edu>
    # Date 1260893171 18000
    # Node ID 19e9e072f71a609c9737eac697c2ccbbc23f188f
    # Parent  7094350d64cda104d0a4ac0519d07a51f72ad37c
    Added some functionality to ideals (is_maximal works more often now, and there's a new ideal class for univariate polynomial rings).  Changed the logic on what class is chosen for ideals so that it's easier to override with _ideal_class_.
    
    diff -r 7094350d64cd -r 19e9e072f71a sage/rings/ideal.py
    a b  
    143143    if len(args) == 1 and args[0] == []:
    144144        raise ValueError, "unable to determine which ring to embed the ideal in"
    145145
    146     if kwds.has_key('coerce'):
    147         coerce = kwds['coerce']
    148     else:
    149         coerce = True
    150 
    151146    first = args[0]
    152147
    153148    if not isinstance(first, sage.rings.ring.Ring):
    154         if isinstance(first, Ideal_generic):
     149        if isinstance(first, Ideal_generic) and len(args) == 1:
    155150            R = first.ring()
    156151            gens = first.gens()
    157152        else:
    158             gens = args
    159             if isinstance(first, (list, tuple, GeneratorType)):
     153            if isinstance(first, (list, tuple, GeneratorType)) and len(args) == 1:
    160154                gens = first
     155            else:
     156                gens = args
    161157            gens = Sequence(gens)
    162158            R = gens.universe()
    163             if not isinstance(R, sage.rings.ring.Ring):
    164                 raise TypeError, "unable to find common ring into which all ideal generators map"
    165             return R.ideal(gens)
    166159    else:
    167160        R = first
    168161        gens = args[1:]
    169         if isinstance(gens[0], Ideal_generic):
    170             gens = gens[0].gens()
    171         elif isinstance(gens[0], (list, tuple)):
    172             gens = gens[0]
    173 
    174162    if not commutative_ring.is_CommutativeRing(R):
    175163        raise TypeError, "R must be a commutative ring"
    176164
    177     if len(gens) == 0:
    178         gens = [R(0)]
    179         coerce = False
     165    return R.ideal(*gens)
    180166
    181     if coerce:
    182         gens = [R(g) for g in gens]
     167#     if len(gens) == 0:
     168#         gens = [R(0)]
     169#         coerce = False
    183170
    184     if isinstance(R, sage.rings.principal_ideal_domain.PrincipalIdealDomain):
    185         # Use GCD algorithm to obtain a principal ideal
    186         g = gens[0]
    187         for h in gens[1:]:
    188             g = R.gcd(g, h)
    189         return Ideal_pid(R, g)
     171#     if coerce:
     172#         gens = [R(g) for g in gens]
    190173
    191     if len(gens) == 1:
    192         return Ideal_principal(R, gens[0])
     174#     if isinstance(R, sage.rings.principal_ideal_domain.PrincipalIdealDomain):
     175#         # Use GCD algorithm to obtain a principal ideal
     176#         g = gens[0]
     177#         for h in gens[1:]:
     178#             g = R.gcd(g, h)
     179#         return Ideal_pid(R, g)
     180
     181#     if len(gens) == 1:
     182#         return Ideal_principal(R, gens[0])
    193183   
    194     return Ideal_generic(R, gens, coerce=False)
     184#     return Ideal_generic(R, gens, coerce=False)
    195185
    196186
    197187def is_Ideal(x):
     
    535525            sage: R = ZZ
    536526            sage: I = R.ideal(7)
    537527            sage: I.is_maximal()
    538             Traceback (most recent call last):
    539             ...
    540             NotImplementedError
     528            True
     529            sage: R.ideal(16).is_maximal()
     530            False
    541531        """
    542         raise NotImplementedError
     532        kd = self.ring().krull_dimension()
     533        if kd == 0: # every non-trivial ideal is maximal
     534            for g in self.gens():
     535                if g.is_unit():
     536                    return False
     537            return True
     538        elif kd == 1 and self.ring().is_integral_domain(): # every nontrivial ideal is maximal
     539            return self.is_prime()
     540        else:
     541            raise NotImplementedError
    543542
    544543    def is_primary(self, P=None):
    545544        r"""
     
    827826        if not isinstance(other, Ideal_generic):
    828827            other = self.ring().ideal(other)
    829828        return self.ring().ideal([y*x for x in self.gens() for y in other.gens()])
    830    
     829
     830    def norm(self):
     831        """
     832        Returns the norm of this ideal.
     833
     834        In the general case, this is just the ideal itself, since the ring it lies in can't be implicitly assumed to be an extension of anything.
     835
     836        We include this function for compatibility with cases such as ideals in number fields.
     837
     838        EXAMPLES::
     839
     840            sage: R.<t> = GF(8, names='a')[]
     841            sage: I = R.ideal(t^4 + t + 1)
     842            sage: I.norm()
     843            Principal ideal (t^4 + t + 1) of Univariate Polynomial Ring in t over Finite Field in a of size 2^3
     844        """
     845        return self
     846
     847    def absolute_norm(self):
     848        """
     849        Returns the absolute norm of this ideal.
     850
     851        In the general case, this is just the ideal itself, since the ring it lies in can't be implicitly assumed to be an extension of anything.
     852
     853        We include this function for compatibility with cases such as ideals in number fields.
     854
     855        EXAMPLES::
     856
     857            sage: R.<t> = GF(9, names='a')[]
     858            sage: I = R.ideal(t^4 + t + 1)
     859            sage: I.norm()
     860            Principal ideal (t^4 + t + 1) of Univariate Polynomial Ring in t over Finite Field in a of size 3^2
     861        """
    831862   
    832863class Ideal_principal(Ideal_generic):
    833864    """
    834865    A principal ideal.
    835866    """
    836     def __init__(self, ring, gen):
    837         Ideal_generic.__init__(self, ring, [gen])
     867    # now Ideal_principal takes a list.
     868    #def __init__(self, ring, gen):       
     869    #    Ideal_generic.__init__(self, ring, [gen])
    838870
    839871    def __repr__(self):
    840872        return "Principal ideal (%s) of %s"%(self.gen(), self.ring())
     
    10741106 
    10751107        raise NotImplementedError
    10761108
     1109    def is_maximal(self):
     1110        """
     1111        Returns whether this ideal is maximal.
     1112       
     1113        Principal ideal domains have Krull dimension 1 (or 0), so an ideal is maximal if and only if it's prime (and nonzero if the ring is not a field).
     1114
     1115        EXAMPLES::
     1116       
     1117            sage: R.<t> = GF(5)[]
     1118            sage: p = R.ideal(t^2 + 2)
     1119            sage: p.is_maximal()
     1120            True
     1121            sage: p = R.ideal(t^2 + 1)
     1122            sage: p.is_maximal()
     1123            False
     1124            sage: p = R.ideal(0)
     1125            sage: p.is_maximal()
     1126            False
     1127            sage: p = R.ideal(1)
     1128            sage: p.is_maximal()
     1129            False
     1130        """
     1131        if not self.ring().is_field() and self.is_zero():
     1132            return False
     1133        return self.is_prime()
     1134
    10771135    def residue_field(self):
    10781136        """
    10791137        Return the residue class field of this ideal, which must be prime.
  • sage/rings/number_field/number_field.py

    diff -r 7094350d64cd -r 19e9e072f71a sage/rings/number_field/number_field.py
    a b  
    17731773            return cmp(self.coerce_embedding()(self.gen()),
    17741774                       other.coerce_embedding()(other.gen()))
    17751775
    1776     def _ideal_class_(self):
     1776    def _ideal_class_(self, n=0):
    17771777        """
    17781778        Return the Python class used in defining the zero ideal of the ring
    17791779        of integers of this number field.
  • new file sage/rings/polynomial/ideal.py

    diff -r 7094350d64cd -r 19e9e072f71a sage/rings/polynomial/ideal.py
    - +  
     1
     2
     3from sage.rings.ideal import Ideal_pid
     4
     5class Ideal_1poly_field(Ideal_pid):
     6    """
     7    An ideal in a univariate polynomial ring over a field.
     8    """
     9    def residue_class_degree(self):
     10        """
     11        Returns the degree of the generator of this ideal.
     12
     13        This function is included for compatibility with ideals in rings of integers of number fields.
     14
     15        EXAMPLES::
     16
     17            sage: R.<t> = GF(5)[]
     18            sage: P = R.ideal(t^4 + t + 1)
     19            sage: P.residue_class_degree()
     20            4
     21        """
     22        return self.gen().degree()
     23
     24    def residue_field(self, names=None, check=True):
     25        """
     26        If this ideal is `P \subset F_p[t]`, returns the quotient `F_p[t]/P`.
     27
     28        EXAMPLES::
     29
     30            sage: R.<t> = GF(17)[]; P = R.ideal(t^3 + 2*t + 9)
     31            sage: k.<a> = P.residue_field(); k
     32            Residue field in a of Principal ideal (t^3 + 2*t + 9) of Univariate Polynomial Ring in t over Finite Field of size 17
     33        """
     34        if check:
     35            if not self.ring().base_ring().is_finite():
     36                raise TypeError, "residue fields only supported for polynomial rings over finite fields."
     37            if not self.is_prime():
     38                raise ValueError, "%s is not a prime ideal"%self
     39
     40        from sage.rings.residue_field import ResidueField
     41        return ResidueField(self, names, check=False)
     42   
  • sage/rings/polynomial/infinite_polynomial_ring.py

    diff -r 7094350d64cd -r 19e9e072f71a sage/rings/polynomial/infinite_polynomial_ring.py
    a b  
    511511                self._cache__gen[key] = res
    512512        return res
    513513   
    514     def _ideal_class_(self):
     514    def _ideal_class_(self, n=0):
    515515        """
    516516        Return :class:`SymmetricIdeals` (see there for further details).
    517517       
  • sage/rings/polynomial/laurent_polynomial_ring.py

    diff -r 7094350d64cd -r 19e9e072f71a sage/rings/polynomial/laurent_polynomial_ring.py
    a b  
    570570        vars = ', '.join([a + '^{\pm 1}' for a in self.latex_variable_names()])
    571571        return "%s[%s]"%(latex(self.base_ring()), vars)
    572572
    573     def _ideal_class_(self):
     573    def _ideal_class_(self, n=0):
    574574        """
    575575        EXAMPLES::
    576576
  • sage/rings/polynomial/multi_polynomial_libsingular.pyx

    diff -r 7094350d64cd -r 19e9e072f71a sage/rings/polynomial/multi_polynomial_libsingular.pyx
    a b  
    811811        coerce = kwds.get('coerce', True)
    812812        if len(gens) == 1:
    813813            gens = gens[0]
     814        from sage.rings.ideal import is_Ideal
     815        if is_Ideal(gens):
     816            if gens.ring() is self:
     817                return gens
     818            gens = gens.gens()
    814819        if is_SingularElement(gens):
    815820            gens = list(gens)
    816821            coerce = True
  • sage/rings/polynomial/multi_polynomial_ring.py

    diff -r 7094350d64cd -r 19e9e072f71a sage/rings/polynomial/multi_polynomial_ring.py
    a b  
    480480        Create an ideal in this polynomial ring.
    481481        """
    482482        do_coerce = False
    483         if len(gens) == 1 and isinstance(gens[0], (list, tuple)):
    484             gens = gens[0]
     483        if len(gens) == 1:
     484            from sage.rings.ideal import is_Ideal
     485            if is_Ideal(gens[0]):
     486                if gens[0].ring() is self:
     487                    return gens[0]
     488                gens = gens[0].gens()
     489            elif isinstance(gens[0], (list, tuple)):
     490                gens = gens[0]
    485491        if not self._has_singular:
    486492            # pass through
    487493            MPolynomialRing_generic.ideal(self,gens,**kwds)
  • sage/rings/polynomial/multi_polynomial_ring_generic.pyx

    diff -r 7094350d64cd -r 19e9e072f71a sage/rings/polynomial/multi_polynomial_ring_generic.pyx
    a b  
    248248        vars = ', '.join(self.latex_variable_names())
    249249        return "%s[%s]"%(sage.misc.latex.latex(self.base_ring()), vars)
    250250
    251     def _ideal_class_(self):
     251    def _ideal_class_(self, n=0):
    252252        return multi_polynomial_ideal.MPolynomialIdeal
    253253   
    254254    def _is_valid_homomorphism_(self, codomain, im_gens):
  • sage/rings/polynomial/polynomial_element.pyx

    diff -r 7094350d64cd -r 19e9e072f71a sage/rings/polynomial/polynomial_element.pyx
    a b  
    7373import polynomial_fateman
    7474
    7575from sage.rings.integer cimport Integer
     76from sage.rings.ideal import is_Ideal
    7677
    7778from sage.categories.map cimport Map
    7879from sage.categories.morphism cimport Morphism
     
    46574658            for k from 0 <= k <= self.degree():
    46584659                if self[k]:
    46594660                    return ZZ(k)
    4660                
    4661         if not isinstance(p, Polynomial) or not p.parent() is self.parent():
     4661        if isinstance(p, Polynomial):
     4662            p = self.parent().coerce(p)
     4663        elif is_Ideal(p) and p.ring() is self.parent():
     4664            if self.parent().is_field(): # common case
     4665                p = p.gen()
     4666            else:
     4667                raise NotImplementedError
     4668        else:
    46624669            raise TypeError, "The polynomial, p, must have the same parent as self."
    46634670
    46644671        if p.degree() == 0:
  • sage/rings/polynomial/polynomial_ring.py

    diff -r 7094350d64cd -r 19e9e072f71a sage/rings/polynomial/polynomial_ring.py
    a b  
    12111211        from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular
    12121212        self._has_singular = can_convert_to_singular(self)
    12131213
     1214    def _ideal_class_(self, n=0):
     1215        """
     1216        Returns the class representing ideals in univariate polynomial rings over fields.
     1217
     1218        EXAMPLES::
     1219
     1220            sage: R.<t> = GF(5)[]
     1221            sage: R._ideal_class_()
     1222            <class 'sage.rings.polynomial.ideal.Ideal_1poly_field'>
     1223        """
     1224        from sage.rings.polynomial.ideal import Ideal_1poly_field
     1225        return Ideal_1poly_field
     1226
    12141227    def divided_difference(self, points, full_table=False):
    12151228        """
    12161229        Return the Newton divided-difference coefficients of the `n`-th
  • sage/rings/ring.pyx

    diff -r 7094350d64cd -r 19e9e072f71a sage/rings/ring.pyx
    a b  
    6262include "../ext/python_bool.pxi"
    6363
    6464import re
     65from types import GeneratorType
    6566
    6667from sage.structure.parent_gens cimport ParentWithGens
    6768from sage.structure.parent cimport Parent
     
    283284        from sage.categories.rings import Rings
    284285        return Rings()
    285286
    286     def ideal(self, *x, **kwds):
     287    def ideal(self, *args, **kwds):
    287288        """
    288289        Return the ideal defined by x, i.e., generated by x.
    289290
     
    307308            sage: R.ideal( [x^3,y^3+x^3] )
    308309            Ideal (x^3, x^3 + y^3) of Multivariate Polynomial Ring in x, y over Rational Field
    309310        """
    310         C = self._ideal_class_()
    311         if len(x) == 1 and isinstance(x[0], (list, tuple)):
    312             x = x[0]
    313         return C(self, x, **kwds)
     311        if kwds.has_key('coerce'):
     312            coerce = kwds['coerce']
     313            del kwds['coerce']
     314        else:
     315            coerce = True
     316
     317        from sage.rings.ideal import Ideal_generic
     318        if len(args) == 0:
     319            gens = [self(0)]
     320        else:
     321            first = args[0]
     322            if isinstance(first, Ideal_generic) and len(args) == 1:
     323                R = first.ring()
     324                m = self.convert_map_from(R)
     325                if m is not None:
     326                    gens = [m(g) for g in first.gens()]
     327                    coerce = False
     328                else:
     329                    m = R.convert_map_from(self)
     330                    if m is not None:
     331                        raise NotImplementedError
     332                    else:
     333                        raise TypeError
     334            else:
     335                gens = args
     336                if isinstance(first, (list, tuple, GeneratorType)) and len(gens) == 1:
     337                    gens = first
     338
     339        if coerce:
     340            gens = [self(g) for g in gens]
     341        if isinstance(self, PrincipalIdealDomain):
     342            # Use GCD algorithm to obtain a principal ideal
     343            g = gens[0]
     344            for h in gens[1:]:
     345                g = self.gcd(g, h)
     346            gens = [g]
     347        C = self._ideal_class_(len(gens))
     348        if len(gens) == 1 and isinstance(gens[0], (list, tuple)):
     349            gens = gens[0]
     350        return C(self, gens, **kwds)
    314351
    315352    def __mul__(self, x):
    316353        """
     
    333370        else:
    334371            return x.ideal(self)    # switched because this is Pyrex / extension class
    335372
    336     def _ideal_class_(self):
     373    def _ideal_class_(self, n=0):
    337374        r"""
    338375        Return a callable object that can be used to create ideals in this
    339376        ring. For generic rings, this returns the factory function
    340377        :func:`sage.rings.ideal.Ideal`, which does its best to be clever about
    341378        what is required.
    342379
     380        This class can depend on `n`, the number of generators of the ideal.
     381
    343382        TODO: For noncommutative rings, distinguish between ideals, right
    344383        ideals, and left ideals.
    345384
    346385        EXAMPLES::
    347386
    348387            sage: RR._ideal_class_()
    349             <function Ideal at ...>
     388            <class 'sage.rings.ideal.Ideal_pid'>
    350389        """
    351         import sage.rings.ideal
    352         return sage.rings.ideal.Ideal
     390        # One might need more than just n, but I can't think of an example.
     391        from sage.rings.ideal import Ideal_generic, Ideal_principal
     392        if n == 1:
     393            return Ideal_principal
     394        else:
     395            return Ideal_generic
    353396
    354397    def principal_ideal(self, gen, coerce=True):
    355398        """
     
    15101553            y = self(y)
    15111554        return x.content(y)
    15121555
     1556    def _ideal_class_(self, n=0):
     1557        """
     1558        Ideals in PIDs have their own special class.
     1559        """
     1560        from sage.rings.ideal import Ideal_pid
     1561        return Ideal_pid
     1562
    15131563cdef class EuclideanDomain(PrincipalIdealDomain):
    15141564    """
    15151565    Generic Euclidean domain class.
  • sage/schemes/generic/point.py

    diff -r 7094350d64cd -r 19e9e072f71a sage/schemes/generic/point.py
    a b  
    143143
    144144            sage: P2.<x, y, z> = ProjectiveSpace(2, QQ)
    145145            sage: SchemeTopologicalPoint_prime_ideal(P2, y*z-x^2)
    146             Point on Projective Space of dimension 2 over Rational Field defined by the Principal ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field
     146            Point on Projective Space of dimension 2 over Rational Field defined by the Ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field
    147147        """
    148148        R = S.coordinate_ring()
    149149        from sage.rings.ideal import Ideal
     
    165165            sage: from sage.schemes.generic.point import SchemeTopologicalPoint_prime_ideal
    166166            sage: P2.<x, y, z> = ProjectiveSpace(2, QQ)
    167167            sage: pt = SchemeTopologicalPoint_prime_ideal(P2, y*z-x^2); pt
    168             Point on Projective Space of dimension 2 over Rational Field defined by the Principal ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field
     168            Point on Projective Space of dimension 2 over Rational Field defined by the Ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field
    169169            sage: pt._repr_()
    170             'Point on Projective Space of dimension 2 over Rational Field defined by the Principal ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field'
     170            'Point on Projective Space of dimension 2 over Rational Field defined by the Ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field'
    171171        """
    172172        return "Point on %s defined by the %s"%(self.scheme(),
    173173                                                self.prime_ideal())
     
    181181            sage: P2.<x, y, z> = ProjectiveSpace(2, QQ)
    182182            sage: pt = SchemeTopologicalPoint_prime_ideal(P2, y*z-x^2)
    183183            sage: pt.prime_ideal()
    184             Principal ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field
     184            Ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field
    185185        """
    186186        return self.__P
    187187