source: sage/rings/number_field/number_field_ideal.py @ 7478:3f402d2103e1

Revision 7478:3f402d2103e1, 28.8 KB checked in by William Stein <wstein@…>, 6 years ago (diff)

trac #1342 -- bugs and lack of docs in number field residue_field

Line 
1"""
2Number Field Ideals
3
4AUTHOR:
5   -- Steven Sivek (2005-05-16)
6   -- Willia Stein (2007-09-06): vastly improved the doctesting   
7
8TESTS:
9We test that pickling works:
10    sage: K.<a> = NumberField(x^2 - 5)
11    sage: I = K.ideal(2/(5+a))
12    sage: I == loads(dumps(I))
13    True
14"""
15
16#*****************************************************************************
17#       Copyright (C) 2004 William Stein <wstein@gmail.com>
18#
19#  Distributed under the terms of the GNU General Public License (GPL)
20#
21#    This code is distributed in the hope that it will be useful,
22#    but WITHOUT ANY WARRANTY; without even the implied warranty of
23#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24#    General Public License for more details.
25#
26#  The full text of the GPL is available at:
27#
28#                  http://www.gnu.org/licenses/
29#*****************************************************************************
30
31import operator
32
33import sage.misc.latex as latex
34
35import sage.rings.field_element as field_element
36import sage.rings.polynomial.polynomial_element as polynomial
37import sage.rings.polynomial.polynomial_ring as polynomial_ring
38import sage.rings.rational_field as rational_field
39import sage.rings.integer_ring as integer_ring
40import sage.rings.rational as rational
41import sage.rings.integer as integer
42import sage.rings.arith as arith
43import sage.misc.misc as misc
44
45import number_field
46import number_field_element
47
48from sage.libs.all import pari_gen
49from sage.rings.ideal import (Ideal_generic, Ideal_fractional)
50from sage.misc.misc import prod
51from sage.structure.element import generic_power
52from sage.structure.factorization import Factorization
53
54QQ = rational_field.RationalField()
55ZZ = integer_ring.IntegerRing()
56
57def is_NumberFieldIdeal(x):
58    """
59    Return True if x is a fractional ideal of a number field.
60
61    EXAMPLES:
62        sage: is_NumberFieldIdeal(2/3)
63        False
64        sage: is_NumberFieldIdeal(ideal(5))
65        False
66        sage: k.<a> = NumberField(x^2 + 2)
67        sage: I = k.ideal([a + 1]); I
68        Fractional ideal (a + 1)
69        sage: is_NumberFieldIdeal(I)
70        True
71    """
72    return isinstance(x, NumberFieldIdeal)
73
74def convert_from_zk_basis(field, hnf):
75    """
76    Used internally in the number field ideal implementation for
77    converting from the order basis to the number field basis.
78
79    INPUT:
80        field -- a number field
81        hnf -- a pari HNF matrix, output by the pari_hnf() function.
82
83    EXAMPLES:
84        sage: from sage.rings.number_field.number_field_ideal import convert_from_zk_basis
85        sage: k.<a> = NumberField(x^2 + 23)
86        sage: I = k.factor_integer(3)[0][0]; I
87        Fractional ideal (3, -1/2*a + 1/2)
88        sage: hnf = I.pari_hnf(); hnf
89        [3, 0; 0, 1]
90        sage: convert_from_zk_basis(k, hnf)
91        [3, 1/2*x - 1/2]
92   
93    """
94    return field.pari_nf().getattr('zk') * hnf
95
96class NumberFieldIdeal(Ideal_fractional):
97    """
98    An ideal of a number field.
99    """
100    def __init__(self, field, gens, coerce=True):
101        """
102        INPUT:
103            field -- a number field
104            x -- a list of NumberFieldElements belonging to the field
105
106        EXAMPLES:
107            sage: NumberField(x^2 + 1, 'a').ideal(7)
108            Fractional ideal (7)
109        """
110        if not isinstance(field, number_field.NumberField_generic):
111            raise TypeError, "field (=%s) must be a number field."%field
112
113        Ideal_generic.__init__(self, field, gens, coerce)
114
115    def _latex_(self):
116        """
117        EXAMPLES:
118            sage: K.<a> = NumberField(x^2 + 23)
119            sage: latex(K.fractional_ideal([2, 1/2*a - 1/2]))
120            \left(2, \frac{1}{2}a - \frac{1}{2}\right)
121        """
122        return '\\left(%s\\right)'%(", ".join([latex.latex(g) for g in \
123                                                 self.gens_reduced()]))
124       
125
126    def __cmp__(self, other):
127        """
128        Compare these a fractional ideal of a number field to
129        something else.
130
131        EXAMPLES:
132            sage: K.<a> = NumberField(x^2 + 3); K
133            Number Field in a with defining polynomial x^2 + 3
134            sage: f = K.factor_integer(15); f
135            (Fractional ideal (1/2*a - 3/2))^2 * (Fractional ideal (5))
136            sage: cmp(f[0][0], f[1][0])
137            -1
138            sage: cmp(f[0][0], f[0][0])
139            0
140            sage: cmp(f[1][0], f[0][0])
141            1
142            sage: f[1][0] == 5
143            True
144            sage: f[1][0] == GF(7)(5)
145            False
146        """
147        if not isinstance(other, NumberFieldIdeal):
148            return cmp(type(self), type(other))
149        return cmp(self.pari_hnf(), other.pari_hnf())
150
151    def _contains_(self, x):
152        """
153        Return True if x is an element of this fractional ideal.
154
155        This function is called (indirectly) when the \code{in}
156        operator is used.
157
158        EXAMPLES:
159            sage: K.<a> = NumberField(x^2 + 23); K
160            Number Field in a with defining polynomial x^2 + 23
161            sage: I = K.factor_integer(13)[0][0]; I
162            Fractional ideal (13, a - 4)
163            sage: a in I
164            False
165            sage: 13 in I
166            True
167            sage: 13/2 in I
168            False
169            sage: a + 9 in I
170            True
171
172            sage: K.<a> = NumberField(x^4 + 3); K
173            Number Field in a with defining polynomial x^4 + 3
174            sage: I = K.factor_integer(13)[0][0]
175            sage: I  # random sign in output
176            Fractional ideal (-2*a^2 - 1)
177            sage: 2/3 in I
178            False
179            sage: 1 in I
180            False
181            sage: 13 in I
182            True
183            sage: 1 in I*I^(-1)
184            True
185            sage: I   # random sign in output
186            Fractional ideal (-2*a^2 - 1)
187        """
188        # For now, $x \in I$ if and only if $\langle x \rangle + I = I$.
189        # Is there a better way to do this?
190        x_ideal = self.number_field().ideal(x)
191        return self + x_ideal == self
192
193    def __elements_from_hnf(self, hnf):
194        """
195        Convert a PARI Hermite normal form matrix to a list of
196        NumberFieldElements.
197
198        EXAMPLES:
199            sage: K.<a> = NumberField(x^3 + 389); K
200            Number Field in a with defining polynomial x^3 + 389
201            sage: I = K.factor_integer(17)[0][0]; I
202            Fractional ideal (-100*a^2 + 730*a - 5329)
203            sage: hnf = I.pari_hnf(); hnf
204            [17, 0, 13; 0, 17, 8; 0, 0, 1]
205            sage: I._NumberFieldIdeal__elements_from_hnf(hnf)
206            [17, 17*a, a^2 + 8*a + 13]
207            sage: I._NumberFieldIdeal__elements_from_hnf(hnf^(-1))
208            [1/17, 1/17*a, a^2 - 8/17*a - 13/17]
209        """
210        K = self.number_field()
211        nf = K.pari_nf()
212        R = K.polynomial().parent()
213        return [ K(R(x)) for x in convert_from_zk_basis(K, hnf) ]
214
215    def __repr__(self):
216        return "Fractional ideal %s"%self._repr_short()
217
218    def _repr_short(self):
219        """
220        Efficient string representation of this fraction ideal.
221
222        EXAMPLES:
223            sage: K.<a> = NumberField(x^4 + 389); K
224            Number Field in a with defining polynomial x^4 + 389
225            sage: I = K.factor_integer(17)[0][0]; I
226            Fractional ideal (17, a^2 - 6)
227            sage: I._repr_short()
228            '(17, a^2 - 6)'       
229        """
230        #NOTE -- we will *have* to not reduce the gens soon, since this
231        # makes things insanely slow in general.
232        # When I fix this, I *have* to also change the _latex_ method.
233        return '(%s)'%(', '.join([str(x) for x in self.gens_reduced()]))
234
235    def __div__(self, other):
236        """
237        Return the quotient self / other.
238       
239        EXAMPLES:
240            sage: R.<x> = PolynomialRing(QQ)
241            sage: K.<a> = NumberField(x^2 - 5)
242            sage: I = K.ideal(2/(5+a))
243            sage: J = K.ideal(17+a)
244            sage: I/J
245            Fractional ideal (-17/1420*a + 1/284)
246            sage: (I/J) * J
247            Fractional ideal (-1/5*a)
248            sage: (I/J) * J == I
249            True
250        """
251        return self * other.__invert__()
252
253    def __invert__(self):
254        """
255        Return the multiplicative inverse of self.  Call with ~self.
256
257        EXAMPLES:
258            sage: R.<x> = PolynomialRing(QQ)
259            sage: K.<a> = NumberField(x^3 - 2)
260            sage: I = K.ideal(2/(5+a))
261            sage: ~I
262            Fractional ideal (1/2*a + 5/2)
263            sage: 1/I
264            Fractional ideal (1/2*a + 5/2)
265            sage: (1/I) * I
266            Fractional ideal (1)
267        """
268        if self.is_zero():
269            raise ZeroDivisionError
270        nf = self.number_field().pari_nf()
271        hnf = nf.idealdiv(self.number_field().ideal(1).pari_hnf(),
272                          self.pari_hnf())
273        I = self.number_field().ideal(self.__elements_from_hnf(hnf))
274        I.__pari_hnf = hnf
275        return I
276
277    def __pow__(self, r):
278        """
279        Return self to the power of right.
280
281        EXAMPLES:
282            sage: R.<x> = PolynomialRing(QQ)
283            sage: K.<a> = NumberField(x^3 - 2)
284            sage: I = K.ideal(2/(5+a))
285            sage: J = I^2
286            sage: K = I^(-2)
287            sage: J*K
288            Fractional ideal (1)
289        """
290        return generic_power(self, r)
291
292    def _pari_(self):
293        """
294        Returns PARI Hermite Normal Form representations of this
295        ideal.
296
297        EXAMPLES:
298            sage: K.<w> = NumberField(x^2 + 23)
299            sage: I = K.class_group().0.ideal(); I
300            Fractional ideal (2, 1/2*w - 1/2)
301            sage: I._pari_()
302            [2, 0; 0, 1]
303        """
304        return self.pari_hnf()
305
306    def _pari_init_(self):
307        return str(self._pari_())
308
309    def pari_hnf(self):
310        """
311        Return PARI's representation of this ideal in Hermite normal form.
312
313        EXAMPLES:
314            sage: R.<x> = PolynomialRing(QQ)
315            sage: K.<a> = NumberField(x^3 - 2)
316            sage: I = K.ideal(2/(5+a))
317            sage: I.pari_hnf()
318            [2, 0, 50/127; 0, 2, 244/127; 0, 0, 2/127]
319        """
320        try:
321            return self.__pari_hnf
322        except AttributeError:
323            nf = self.number_field().pari_nf()
324            self.__pari_hnf = nf.idealhnf(0)
325            hnflist = [ nf.idealhnf(x.polynomial()) for x in self.gens() ]
326            for ideal in hnflist:
327                self.__pari_hnf = nf.idealadd(self.__pari_hnf, ideal)
328            return self.__pari_hnf
329
330    def divides(self, other):
331        """
332        Returns True if this ideal divides other and False otherwise.
333
334        EXAMPLES:
335            sage: K.<a> = CyclotomicField(11); K
336            Cyclotomic Field of order 11 and degree 10
337            sage: I = K.factor_integer(31)[0][0]; I
338            Fractional ideal (-3*a^7 - 4*a^5 - 3*a^4 - 3*a^2 - 3*a - 3)
339            sage: I.divides(I)
340            True
341            sage: I.divides(31)
342            True
343            sage: I.divides(29)
344            False           
345        """
346        if not isinstance(other, NumberFieldIdeal):
347            other = self.number_field().ideal(other)
348        if self.is_zero():
349            return other.is_zero # since 0 \subset 0
350        return (other / self).is_integral()
351
352    def factor(self):
353        """
354        Factorization of this ideal in terms of prime ideals.
355
356        EXAMPLES:
357            sage: K.<a> = NumberField(x^4 + 23); K
358            Number Field in a with defining polynomial x^4 + 23
359            sage: I = K.ideal(19); I
360            Fractional ideal (19)
361            sage: F = I.factor(); F
362            (Fractional ideal (a^2 + 2*a + 2)) * (Fractional ideal (a^2 - 2*a + 2))
363            sage: type(F)
364            <class 'sage.structure.factorization.Factorization'>
365            sage: list(F)
366            [(Fractional ideal (a^2 + 2*a + 2), 1), (Fractional ideal (a^2 - 2*a + 2), 1)]
367            sage: F.prod()
368            Fractional ideal (19)
369        """
370        try:
371            return self.__factorization
372        except AttributeError:
373            if self.is_zero():
374                self.__factorization = Factorization([])
375                return self.__factorization
376            K = self.number_field()
377            F = list(K.pari_nf().idealfactor(self.pari_hnf()))
378            P, exps = F[0], F[1]
379            A = []
380            zk_basis = K.pari_nf().getattr('zk')
381            for i, p in enumerate(P):
382                prime, alpha = p.getattr('gen')
383                I = K.ideal([ZZ(prime), K(zk_basis * alpha)])
384                I._pari_prime = p
385                A.append((I,ZZ(exps[i])))
386            self.__factorization = Factorization(A)
387            return self.__factorization
388
389    def reduce_equiv(self):
390        """
391        Return a small ideal that is equivalent to self in the group
392        of fractional ideals modulo principal ideals.  Very often (but
393        not always) if self is principal then this function returns
394        the unit ideal.
395
396        ALGORITHM: Calls pari's idealred function.
397
398        EXAMPLES:
399            sage: K.<w> = NumberField(x^2 + 23)
400            sage: I = ideal(w*23^5); I
401            Fractional ideal (6436343*w)
402            sage: I.reduce_equiv()
403            Fractional ideal (1)
404            sage: I = K.class_group().0.ideal()^10; I
405            Fractional ideal (1024, 1/2*w + 979/2)
406            sage: I.reduce_equiv()
407            Fractional ideal (2, 1/2*w - 1/2)
408        """
409        K = self.number_field()
410        P = K.pari_nf()
411        hnf = P.idealred(self.pari_hnf())
412        gens = self.__elements_from_hnf(hnf)
413        return K.ideal(gens)
414
415    def gens_reduced(self, proof=None):
416        r"""
417        Express this ideal in terms of at most two generators, and one
418        if possible.
419
420        Note that if the ideal is not principal, then this uses PARI's
421        \code{idealtwoelt} function, which takes exponential time, the
422        first time it is called for each ideal.  Also, this indirectly
423        uses \code{bnfisprincipal}, so set \code{proof=True} if you
424        want to prove correctness (which \emph{is} the default).
425
426        EXAMPLE:
427            sage: R.<x> = PolynomialRing(QQ)
428            sage: K.<i> = NumberField(x^2+1, 'i')
429            sage: J = K.ideal([i+1, 2])
430            sage: J.gens()
431            (i + 1, 2)
432            sage: J.gens_reduced()
433            (i + 1,)
434        """
435        from sage.structure.proof.proof import get_flag
436        proof = get_flag(proof, "number_field")
437        try:
438            ## Compute the single generator, if it exists           
439            dummy = self.is_principal(proof)
440            return self.__reduced_generators
441        except AttributeError:
442            K = self.number_field()
443            nf = K.pari_nf()
444            R = K.polynomial().parent()
445            if self.is_prime():
446                a = self.smallest_integer()
447                alpha = nf.idealtwoelt(self.pari_hnf(), a)
448            else:
449                a, alpha = nf.idealtwoelt(self.pari_hnf())
450            gens = [ QQ(a), K(R(nf.getattr('zk')*alpha)) ]
451            if gens[1] in self.number_field().ideal(gens[0]):
452                gens = [ gens[0] ]
453            elif gens[0] in self.number_field().ideal(gens[1]):
454                gens = [ gens[1] ]
455            self.__reduced_generators = tuple(gens)
456            return self.__reduced_generators
457
458    def integral_basis(self):
459        r"""
460        Return a list of generators for this ideal as a $\mathbb{Z}$-module.
461
462        EXAMPLE:
463            sage: R.<x> = PolynomialRing(QQ)       
464            sage: K.<i> = NumberField(x^2 + 1)
465            sage: J = K.ideal(i+1)
466            sage: J.integral_basis()
467            [2, i + 1]
468        """
469        hnf = self.pari_hnf()
470        return self.__elements_from_hnf(hnf)
471
472    def integral_split(self):
473        """
474        Return a tuple (I, d), where I is an integral ideal, and d is the
475        smallest positive integer such that this ideal is equal to I/d.
476
477        EXAMPLE:
478            sage: R.<x> = PolynomialRing(QQ)
479            sage: K.<a> = NumberField(x^2-5)
480            sage: I = K.ideal(2/(5+a))
481            sage: I.is_integral()
482            False
483            sage: J,d = I.integral_split()
484            sage: J
485            Fractional ideal (-1/2*a + 5/2)
486            sage: J.is_integral()
487            True
488            sage: d
489            5
490            sage: I == J/d
491            True
492        """
493        try:
494            return self.__integral_split
495        except AttributeError:
496            if self.is_integral():
497                self.__integral_split = (self, ZZ(1))
498            else:
499                factors = self.factor()
500                denom_list = filter(lambda (p,e): e < 0 , factors)
501                denominator = prod([ p.smallest_integer()**(-e)
502                                     for (p,e) in denom_list ])
503                ## Get a list of the primes dividing the denominator
504                plist = [ p.smallest_integer() for (p,e) in denom_list ]
505                for p in plist:
506                    while denominator % p == 0 and (self*(denominator/p)).is_integral():
507                        denominator //= p
508                self.__integral_split = (self*denominator, denominator)
509            return self.__integral_split
510
511    def is_integral(self):
512        """
513        Return True if this ideal is integral.
514
515        EXAMPLES:
516           sage: R.<x> = PolynomialRing(QQ)       
517           sage: K.<a> = NumberField(x^5-x+1)
518           sage: K.ideal(a).is_integral()
519           True
520           sage: (K.ideal(1) / (3*a+1)).is_integral()
521           False
522        """
523        try:
524            return self.__is_integral
525        except AttributeError:
526            one = self.number_field().ideal(1)
527            self.__is_integral = (self+one == one)
528            return self.__is_integral
529
530    def is_maximal(self):
531        """
532        Return True if this ideal is maximal.
533
534        EXAMPLES:
535            sage: K.<a> = NumberField(x^3 + 3); K
536            Number Field in a with defining polynomial x^3 + 3
537            sage: K.ideal(5).is_maximal()
538            False
539            sage: K.ideal(7).is_maximal()
540            True       
541        """
542        return self.is_prime() and not self.is_zero()
543
544    def is_prime(self):
545        """
546        Return True if this ideal is prime.
547
548        EXAMPLES:
549            sage: K.<a> = NumberField(x^2 - 17); K
550            Number Field in a with defining polynomial x^2 - 17
551            sage: K.ideal(5).is_prime()
552            True
553            sage: K.ideal(13).is_prime()
554            False
555            sage: K.ideal(17).is_prime()
556            False       
557        """
558        try:
559            return self._pari_prime is not None
560        except AttributeError:
561            if self.is_zero():
562                self._pari_prime = []
563                return True
564            K = self.number_field()
565            F = list(K.pari_nf().idealfactor(self.pari_hnf()))
566            ### We should definitely cache F as the factorization of self
567            P, exps = F[0], F[1]
568            if len(P) != 1 or exps[0] != 1:
569                self._pari_prime = None
570            else:
571                self._pari_prime = P[0]
572            return self._pari_prime is not None
573
574    def is_principal(self, proof=None):
575        r"""
576        Return True if this ideal is principal.
577
578        Since it uses the PARI method \code{bnfisprincipal}, specify
579        \code{proof=True} (this is the default setting) to prove the
580        correctness of the output.
581
582        EXAMPLES:
583        We create equal ideals in two different ways, and note that
584        they are both actually principal ideals.
585            sage: K = QuadraticField(-119,'a')
586            sage: P = K.ideal([2]).factor()[1][0]
587            sage: I = P^5
588            sage: I.is_principal()
589            True
590        """
591        from sage.structure.proof.proof import get_flag
592        proof = get_flag(proof, "number_field")
593        try:
594            return self.__is_principal
595        except AttributeError:
596            if len (self.gens()) <= 1:
597                self.__is_principal = True
598                self.__reduced_generators = self.gens()
599                return self.__is_principal
600            bnf = self.number_field().pari_bnf(proof)
601            v = bnf.bnfisprincipal(self.pari_hnf())
602            self.__is_principal = is_pari_zero_vector(v[0])
603            if self.__is_principal:
604                K = self.number_field()
605                R = K.polynomial().parent()
606                g = K(R(bnf.getattr('zk') * v[1]))
607                self.__reduced_generators = tuple([g])
608            return self.__is_principal
609
610    def is_trivial(self, proof=None):
611        """
612        Returns True if this is a trivial ideal.
613       
614        EXAMPLES:
615            sage: F.<a> = QuadraticField(-5)
616            sage: I = F.ideal(3)
617            sage: I.is_trivial()
618            False
619            sage: J = F.ideal(5)
620            sage: J.is_trivial()
621            False
622            sage: (I+J).is_trivial()
623            True
624        """
625        return self.is_zero() or \
626            self == self.number_field().ideal(1)
627
628    def is_zero(self):
629        """
630        Return True if this is the zero ideal.
631
632        EXAMPLES:
633            sage: K.<a> = NumberField(x^2 + 2); K
634            Number Field in a with defining polynomial x^2 + 2
635            sage: K.ideal(3).is_zero()
636            False
637            sage: K.ideal(0).is_zero()
638            True
639        """
640        return self == self.number_field().ideal(0)
641
642    def norm(self):
643        """
644        Return the norm of this fractional ideal as a rational number.
645
646        EXAMPLES:
647            sage: K.<a> = NumberField(x^4 + 23); K
648            Number Field in a with defining polynomial x^4 + 23
649            sage: I = K.ideal(19); I
650            Fractional ideal (19)
651            sage: factor(I.norm())
652            19^4
653            sage: F = I.factor()
654            sage: F[0][0].norm().factor()
655            19^2       
656        """
657        return QQ(self.number_field().pari_nf().idealnorm(self.pari_hnf()))
658
659    def number_field(self):
660        """
661        Return the number field that this is a fractional ideal in.
662
663        EXAMPLES:
664            sage: K.<a> = NumberField(x^2 + 2); K
665            Number Field in a with defining polynomial x^2 + 2
666            sage: K.ideal(3).number_field()
667            Number Field in a with defining polynomial x^2 + 2
668            sage: K.ideal(0).number_field()
669            Number Field in a with defining polynomial x^2 + 2       
670        """
671        return self.ring()
672
673    def ramification_index(self):
674        r"""
675        Return the ramification index of this ideal, assuming it is prime
676        and nonzero.  Otherwise, raise a ValueError.
677
678        The ramification index is the power of this prime appearing in
679        the factorization of the prime in $\ZZ$ that this primes lies
680        over.
681
682        EXAMPLES:
683            sage: K.<a> = NumberField(x^2 + 2); K
684            Number Field in a with defining polynomial x^2 + 2
685            sage: f = K.factor_integer(2); f
686            (Fractional ideal (-a))^2
687            sage: f[0][0].ramification_index()
688            2
689            sage: K.ideal(13).ramification_index()
690            1
691            sage: K.ideal(17).ramification_index()
692            Traceback (most recent call last):
693            ...
694            ValueError: the ideal (= Fractional ideal (17)) is not prime
695        """
696        if self.is_zero():
697            raise ValueError, "The input idea must be nonzero"
698        if self.is_prime():
699            return ZZ(self._pari_prime.getattr('e'))
700        raise ValueError, "the ideal (= %s) is not prime"%self
701
702    def residue_field(self, names=None):
703        """
704        Return the residue class field of this ideal, which must
705        be prime.
706
707        EXAMPLES:
708            sage: K.<a> = NumberField(x^3-7)
709            sage: P = K.ideal(29).factor()[0][0]
710            sage: P.residue_field()
711            Residue field in abar of Fractional ideal (2*a^2 + 3*a - 10)
712            sage: P.residue_field('z')
713            Residue field in z of Fractional ideal (2*a^2 + 3*a - 10)
714
715        Another example:
716            sage: K.<a> = NumberField(x^3-7)
717            sage: P = K.ideal(389).factor()[0][0]; P
718            Fractional ideal (389, a^2 - 44*a - 9)
719            sage: P.residue_class_degree()
720            2
721            sage: P.residue_field()
722            Residue field in abar of Fractional ideal (389, a^2 - 44*a - 9)
723            sage: P.residue_field('z')
724            Residue field in z of Fractional ideal (389, a^2 - 44*a - 9)
725            sage: FF.<w> = P.residue_field()
726            sage: FF
727            Residue field in w of Fractional ideal (389, a^2 - 44*a - 9)
728            sage: FF((a+1)^390)
729            36
730            sage: FF(a)
731            w
732        """
733        if not self.is_prime():
734            raise ValueError, "The ideal must be prime"
735        return self.number_field().residue_field(self, names = names)
736
737    def residue_class_degree(self):
738        r"""
739        Return the residue class degree of this ideal, assuming it is
740        prime and nonzero.  Otherwise, raise a ValueError.
741
742        The residue class degree of a prime ideal $I$ is the degree of
743        the extension $O_K/I$ of its prime subfield.
744
745        EXAMPLES:
746            sage: K.<a> = NumberField(x^5 + 2); K
747            Number Field in a with defining polynomial x^5 + 2
748            sage: f = K.factor_integer(19); f
749            (Fractional ideal (a^2 + a - 3)) * (Fractional ideal (-2*a^4 - a^2 + 2*a - 1)) * (Fractional ideal (a^2 + a - 1))
750            sage: [i.residue_class_degree() for i, _ in f]   
751            [2, 2, 1]       
752        """
753        if self.is_zero():
754            raise ValueError, "The ideal (=%s) is zero"%self
755        if self.is_prime():
756            return ZZ(self._pari_prime.getattr('f'))
757        raise ValueError, "the ideal (= %s) is not prime"%self
758
759    def smallest_integer(self):
760        r"""
761        Return the smallest nonnegative integer in $I \cap \mathbb{Z}$,
762        where $I$ is this ideal.  If $I = 0$, raise a ValueError.
763       
764        EXAMPLE:
765            sage: R.<x> = PolynomialRing(QQ)
766            sage: K.<a> = NumberField(x^2+6)
767            sage: I = K.ideal([4,a])/7
768            sage: I.smallest_integer()
769            2
770        """
771        if self.is_zero():
772            raise ValueError, "ideal (= %s) must be nonzero"%self
773        try:
774            return self.__smallest_integer
775        except AttributeError:
776            if self.is_prime():
777                self.__smallest_integer = ZZ(self._pari_prime.getattr('p'))
778                return self.__smallest_integer
779            if self.is_integral():
780                factors = self.factor()
781                bound = prod([ p.smallest_integer()**e for (p,e) in factors ])
782                plist = [ p.smallest_integer() for (p,e) in factors ]
783                plist.sort()
784                indices = filter(lambda(i): i==0 or plist[i] != plist[i-1],
785                                 range(0,len(plist)))
786                plist = [ plist[i] for i in indices ] ## unique list of primes
787                for p in plist:
788                    while bound % p == 0 and (self/(bound/p)).is_integral():
789                        bound /= p
790                self.smallest_integer = ZZ(bound)
791                return self.__smallest_integer
792            I,d = self.integral_split() ## self = I/d
793            n = I.smallest_integer()    ## n/d in self
794            self.__smallest_integer =  n / arith.gcd(ZZ(n),ZZ(d))
795            return self.__smallest_integer
796
797    def valuation(self, p):
798        r"""
799        Return the valuation of this ideal at the prime $\mathfrak{p}$.
800        If $\mathfrak{p}$ is not prime, raise a ValueError.
801
802        INPUT:
803            p -- a prime ideal of this number field.
804
805        EXAMPLES:
806            sage: K.<a> = NumberField(x^5 + 2); K
807            Number Field in a with defining polynomial x^5 + 2
808            sage: i = K.ideal(38); i
809            Fractional ideal (38)
810            sage: i.valuation(K.factor_integer(19)[0][0])
811            1
812            sage: i.valuation(K.factor_integer(2)[0][0])
813            5
814            sage: i.valuation(K.factor_integer(3)[0][0])
815            0
816            sage: i.valuation(0)
817            Traceback (most recent call last):
818            ...
819            ValueError: p (= Fractional ideal (0)) must be a nonzero prime
820        """
821        if not isinstance(p, NumberFieldIdeal):
822            p = self.number_field().ideal(p)
823        if p.is_zero() or not p.is_prime():
824            raise ValueError, "p (= %s) must be a nonzero prime"%p
825        if p.ring() != self.number_field():
826            raise ValueError, "p (= %s) must be an ideal in %s"%self.number_field()
827        nf = self.number_field().pari_nf()
828        return ZZ(nf.idealval(self.pari_hnf(), p._pari_prime))
829
830
831
832def is_pari_zero_vector(z):
833    """
834    Return True if each entry of the PARI matrix row or vector z is 0.
835
836    EXAMPLES:
837        sage: from sage.rings.number_field.number_field_ideal import is_pari_zero_vector
838        sage: is_pari_zero_vector(pari('[]~'))
839        True
840        sage: is_pari_zero_vector(pari('[0,0]~'))
841        True
842        sage: is_pari_zero_vector(pari('[0,0,0,0,0]~'))
843        True
844        sage: is_pari_zero_vector(pari('[0,0,0,1,0]~'))
845        False
846    """
847    for a in z:
848        if a:
849            return False
850    return True
Note: See TracBrowser for help on using the repository browser.