Ticket #2329: trac_2329_rnfisnorm4.patch

File trac_2329_rnfisnorm4.patch, 24.8 KB (added by fwclarke, 11 years ago)

apply only this latest file (works on sage 4.6.1.alpha3)

  • sage/libs/pari/decl.pxi

    # HG changeset patch
    # User Francis Clarke <F.Clarke@Swansea.ac.uk>
    # Date 1293411223 0
    # Node ID 861de9632ac5f5955e33995e20d8ab07e848775a
    # Parent  74c569fadcf6e3eb8570dd81a9c41db856ebf079
    Trac: 2329: add interface to rnfisnorm
    
    diff -r 74c569fadcf6 -r 861de9632ac5 sage/libs/pari/decl.pxi
    a b  
    695695
    696696    # buch4.c
    697697
    698     GEN     bnfisnorm(GEN bnf,GEN x,long flag,long PREC)
     698    GEN     bnfisnorm(GEN bnf, GEN x, long flag)
    699699    GEN     rnfisnorm(GEN S, GEN x, long flag)
     700    GEN     rnfisnorminit(GEN T, GEN relpol, int galois)
    700701    GEN     bnfissunit(GEN bnf,GEN suni,GEN x)
    701702    GEN     bnfsunit(GEN bnf,GEN s,long PREC)
    702703    long    nfhilbert(GEN bnf,GEN a,GEN b)
  • sage/libs/pari/gen.pyx

    diff -r 74c569fadcf6 -r 861de9632ac5 sage/libs/pari/gen.pyx
    a b  
    65546554        sig_on()
    65556555        return self.new_gen(bnfisintnorm(self.g, t0))
    65566556
     6557    def bnfisnorm(self, gen x, long flag=0):
     6558        t0GEN(x)
     6559        sig_on()
     6560        return self.new_gen(bnfisnorm(t0, self.g, flag))
     6561
    65576562    def bnfisprincipal(self, x, long flag=1):
    65586563        t0GEN(x)
    65596564        sig_on()
     
    76267631        return self.new_gen(thueinit(self.g, flag, prec))
    76277632
    76287633
    7629 
    7630    
     7634    def rnfisnorminit(self, polrel, flag=2):
     7635        t0GEN(polrel)
     7636        sig_on()
     7637        return self.new_gen(rnfisnorminit(self.g, t0, flag))
     7638
     7639    def rnfisnorm(self, T, flag=0):
     7640        t0GEN(T)
     7641        sig_on()
     7642        return self.new_gen(rnfisnorm(t0, self.g, flag))
    76317643
    76327644    ###########################################
    76337645    # 8: Vectors, matrices, LINEAR ALGEBRA and sets
  • sage/rings/integer.pyx

    diff -r 74c569fadcf6 -r 861de9632ac5 sage/rings/integer.pyx
    a b  
    388388    specifying an alternative parent to ``IntegerRing()``.
    389389    """
    390390
    391     def __init__(self, x=None, unsigned int base=0, parent = None):
     391    def __init__(self, x=None, unsigned int base=0, parent=None):
    392392        """
    393393        We illustrate how to create integers with parents different
    394394        from ``IntegerRing()``::
    395395
    396396            sage: from sage.rings.integer import IntegerWrapper
    397397
    398             sage: n = IntegerWrapper(3, parent = Primes()) # indirect doctest
     398            sage: n = IntegerWrapper(3, parent=Primes()) # indirect doctest
    399399            sage: n
    400400            3
    401401            sage: n.parent()
     
    419419
    420420        """
    421421        if parent is not None:
    422             Element.__init__(self, parent = parent)
    423         Integer.__init__(self, x, base = base)
     422            Element.__init__(self, parent=parent)
     423        Integer.__init__(self, x, base=base)
    424424
    425425cdef class Integer(sage.structure.element.EuclideanDomainElement):
    426426    r"""
     
    41524152            else:
    41534153                return False
    41544154        return mpz_perfect_power_p(self.value)
    4155        
     4155
     4156    def is_norm(self, K, element=False, proof=True):
     4157        r"""
     4158        See ``QQ(self).is_norm()``.
     4159       
     4160        EXAMPLES::
     4161
     4162            sage: K = NumberField(x**2 - 2, 'beta')
     4163            sage: n = 4
     4164            sage: n.is_norm(K)
     4165            True
     4166            sage: 5.is_norm(K)
     4167            False
     4168            sage: 7.is_norm(QQ)
     4169            True
     4170            sage: n.is_norm(K, element=True)
     4171            (True, 4*beta + 6)
     4172            sage: n.is_norm(K, element=True)[1].norm()
     4173            4
     4174            sage: n = 5
     4175            sage: n.is_norm(K, element=True)
     4176            (False, None)
     4177            sage: n = 7
     4178            sage: n.is_norm(QQ, element=True)
     4179            (True, 7)
     4180
     4181        """
     4182        from sage.rings.rational_field import QQ
     4183        return QQ(self).is_norm(K, element=element, proof=proof)
     4184
     4185    def bnfisnorm(self, K, certify=True, extra_primes=0):
     4186        r"""
     4187        See ``QQ(self).bnfisnorm()``.
     4188       
     4189        EXAMPLES::
     4190       
     4191            sage: 3.bnfisnorm(QuadraticField(-1, 'i'))
     4192            (1, 3)
     4193            sage: 7.bnfisnorm(CyclotomicField(7))
     4194            (-zeta7^2 + zeta7, 1)
     4195        """
     4196        from sage.rings.rational_field import QQ
     4197        return QQ(self).bnfisnorm(K, certify=certify, extra_primes=extra_primes)
     4198
     4199     
    41564200    def jacobi(self, b):
    41574201        r"""
    41584202        Calculate the Jacobi symbol `\left(\frac{self}{b}\right)`.
  • sage/rings/number_field/number_field.py

    diff -r 74c569fadcf6 -r 861de9632ac5 sage/rings/number_field/number_field.py
    a b  
    10061006        else:
    10071007            assert category.is_subcategory(default_category), "%s is not a subcategory of %s"%(category, default_category)
    10081008
    1009         ParentWithGens.__init__(self, QQ, name, category = category)
     1009        ParentWithGens.__init__(self, QQ, name, category=category)
    10101010        if not isinstance(polynomial, polynomial_element.Polynomial):
    10111011            raise TypeError, "polynomial (=%s) must be a polynomial"%repr(polynomial)
    10121012       
     
    25922592            self.__pari_bnf_certified = True
    25932593        return self.__pari_bnf_certified
    25942594
     2595    def pari_rnfnorm_data(self, L):
     2596        """
     2597        Return the pari rnfisnorminit data corresponding to the
     2598        extension L/self.
     2599
     2600        EXAMPLES::
     2601       
     2602            sage: K = NumberField(x**2-2,'alpha')
     2603            sage: L = K.extension(x**2+5, 'gamma')
     2604            sage: ls = K.pari_rnfnorm_data(L) ; len(ls)
     2605            8
     2606
     2607            sage: K.<a> = NumberField(x^2 + x + 1)
     2608            sage: P.<X> = K[]
     2609            sage: L.<b> = NumberField(X^3 + a)
     2610            sage: ls = K.pari_rnfnorm_data(L); len(ls)
     2611            8
     2612        """
     2613        if L.base_field() != self:
     2614            raise ValueError, "L must be an extension of self"
     2615       
     2616        relpoly = L.defining_polynomial()
     2617        Kbnf = self.absolute_polynomial()._pari_with_name('y').bnfinit()
     2618        coeffs = [ a._pari_('y') for a in relpoly.coeffs() ]
     2619
     2620        polrel = sage.libs.pari.gen.pari(coeffs).Polrev()
     2621        return Kbnf.rnfisnorminit(polrel)
     2622
    25952623    def _gap_init_(self):
    25962624        """
    25972625        Create a gap object representing self and return its name
     
    27032731        gens = [self.ideal(hnf) for hnf in k.bnf_get_gen()]
    27042732       
    27052733        G = ClassGroup(cycle_structure, names, self, gens, proof=proof)       
    2706         self.__class_group[proof,names] = G
     2734        self.__class_group[proof, names] = G
    27072735        return G
    27082736
    27092737    def class_number(self, proof=None):
     
    28802908            sage: K.selmer_group([K.ideal(2, -a+1), K.ideal(3, a+1)], 3)
    28812909            [2, a + 1]
    28822910            sage: K.selmer_group([K.ideal(2, -a+1), K.ideal(3, a+1), K.ideal(a)], 3)
    2883             [2, a + 1, a]    # 32-bit
    2884             [2, a + 1, -a]   # 64-bit
     2911            [2, a + 1, a]
    28852912            sage: K.<a> = NumberField(polygen(QQ))
    28862913            sage: K.selmer_group([],5)
    28872914            []
     
    34883515            self.__gen = self._element_class(self, X)
    34893516            return self.__gen
    34903517
    3491     def is_field(self, proof = True):
     3518    def is_field(self, proof=True):
    34923519        """
    34933520        Return True since a number field is a field.
    34943521       
     
    36143641            return GaloisGroup_v2(self, names)
    36153642       
    36163643        elif type=="pari":
    3617             return GaloisGroup_v1(self.absolute_polynomial().galois_group(pari_group = True, algorithm = algorithm), self)
     3644            return GaloisGroup_v1(self.absolute_polynomial().galois_group(pari_group=True, algorithm=algorithm), self)
    36183645        elif type=="gap":
    3619             return GaloisGroup_v1(self.absolute_polynomial().galois_group(pari_group = False, algorithm = algorithm), self)
     3646            return GaloisGroup_v1(self.absolute_polynomial().galois_group(pari_group=False, algorithm=algorithm), self)
    36203647        else:
    36213648            raise ValueError, "Galois group type must be None, 'pari', or 'gap'."
    36223649       
     
    40584085                       prec = prec)
    40594086        s = 'nf = nfinit(%s);'%self.absolute_polynomial()
    40604087        s += 'dzk = dirzetak(nf,cflength());'
    4061         Z.init_coeffs('dzk[k]',pari_precode = s,
     4088        Z.init_coeffs('dzk[k]', pari_precode=s,
    40624089                      max_imaginary_part=max_imaginary_part,
    40634090                      max_asymp_coeffs=max_asymp_coeffs)         
    40644091        Z.check_functional_equation()
     
    42564283            self.__regulator = RealField(53)(k.bnf_get_reg())
    42574284            return self.__regulator
    42584285
    4259     def residue_field(self, prime, names = None, check = True):
     4286    def residue_field(self, prime, names=None, check=True):
    42604287        """
    42614288        Return the residue field of this number field at a given prime, ie
    42624289        `O_K / p O_K`.
     
    43224349        if check and not prime.is_prime():
    43234350            raise ValueError, "%s is not a prime ideal"%prime
    43244351        from sage.rings.residue_field import ResidueField
    4325         return ResidueField(prime, names = names, check = False)
     4352        return ResidueField(prime, names=names, check=False)
    43264353
    43274354    def signature(self):
    43284355        """
     
    43604387                A[j,i] = t
    43614388        return A
    43624389
    4363     def uniformizer(self, P, others = "positive"):
     4390    def uniformizer(self, P, others="positive"):
    43644391        """
    43654392        Returns an element of self with valuation 1 at the prime ideal P.
    43664393       
     
    53275354        except KeyError:
    53285355            pass
    53295356
    5330         B = map(self, self._pari_integral_basis(v = v))
     5357        B = map(self, self._pari_integral_basis(v=v))
    53315358
    53325359        if len(v) == 0 or v is None:
    53335360            is_maximal = True
     
    53375364        import sage.rings.number_field.order as order
    53385365        O = order.absolute_order_from_module_generators(B,
    53395366                 check_integral=False, check_rank=False,
    5340                  check_is_ring=False, is_maximal = is_maximal)
     5367                 check_is_ring=False, is_maximal=is_maximal)
    53415368       
    53425369        self.__maximal_order[v] = O
    53435370        return O
     
    56385665        embs.sort()
    56395666        v = [ self.hom([ e ], check=False) for e in embs ]
    56405667        put_natural_embedding_first(v)
    5641         self.__embeddings[self] = Sequence(v, cr = (v != []), immutable=True,
     5668        self.__embeddings[self] = Sequence(v, cr=(v != []), immutable=True,
    56425669                                        check=False, universe=self.Hom(self))
    56435670        return self.__embeddings[self]
    56445671
  • sage/rings/number_field/number_field_element.pyx

    diff -r 74c569fadcf6 -r 861de9632ac5 sage/rings/number_field/number_field_element.pyx
    a b  
    936936        """
    937937        return self.number_field().complex_embeddings(prec)[i](self)
    938938
     939
     940    def is_norm(self, L, element=False, proof=True):
     941        r"""
     942        Determine whether self is the relative norm of an element
     943        of L/K, where K is self.parent().
     944       
     945        INPUT:
     946       
     947         - L -- a number field containing K=self.parent()
     948         - element -- True or False, whether to also output an element
     949           of which self is a norm
     950         - proof -- If True, then the output is correct unconditionally.
     951           If False, then the output is correct under GRH.
     952       
     953        OUTPUT:
     954       
     955        If element is False, then the output is a boolean B, which is
     956        True if and only if self is the relative norm of an element of L
     957        to K.
     958        If element is False, then the output is a pair (B, x), where
     959        B is as above. If B is True, then x is an element of L such that
     960        self == x.norm(K). Otherwise, x is None.
     961       
     962        ALGORITHM:
     963       
     964        Uses Pari's rnfisnorm. See self.rnfisnorm().
     965
     966        EXAMPLES::
     967
     968            sage: K.<beta> = NumberField(x^3+5)
     969            sage: Q.<X> = K[]
     970            sage: L = K.extension(X^2+X+beta, 'gamma')
     971            sage: (beta/2).is_norm(L)
     972            False
     973            sage: beta.is_norm(L)
     974            True
     975
     976        With a relative base field::
     977
     978            sage: K.<a, b> = NumberField([x^2 - 2, x^2 - 3])
     979            sage: L.<c> = K.extension(x^2 - 5)
     980            sage: (2*a*b).is_norm(L)
     981            True
     982            sage: _, v = (2*b*a).is_norm(L, element=True)
     983            sage: v.norm(K) == 2*a*b
     984            True
     985
     986        Non-Galois number fields::
     987           
     988            sage: K.<a> = NumberField(x^2 + x + 1)
     989            sage: Q.<X> = K[]
     990            sage: L.<b> = NumberField(X^4 + a + 2)
     991            sage: (a/4).is_norm(L)
     992            True
     993            sage: (a/2).is_norm(L)
     994            Traceback (most recent call last):
     995            ...
     996            NotImplementedError: is_norm is not implemented unconditionally for norms from non-Galois number fields
     997            sage: (a/2).is_norm(L, proof=False)
     998            False
     999
     1000            sage: K.<a> = NumberField(x^3 + x + 1)
     1001            sage: Q.<X> = K[]
     1002            sage: L.<b> = NumberField(X^4 + a)
     1003            sage: t = (-a).is_norm(L, element=True); t
     1004            (True, b^3 + 1)
     1005            sage: t[1].norm(K)
     1006            -a
     1007
     1008        AUTHORS:
     1009
     1010        - Craig Citro (2008-04-05)
     1011
     1012        - Marco Streng (2010-12-03)
     1013        """
     1014        if not element:
     1015            return self.is_norm(L, element=True, proof=proof)[0]
     1016
     1017        K = self.parent()
     1018        from sage.rings.number_field.all import is_AbsoluteNumberField, \
     1019                                                is_NumberField
     1020        if not is_NumberField(L):
     1021            raise ValueError, "L (=%s) must be a NumberField in is_norm" % L
     1022       
     1023        if is_AbsoluteNumberField(L):
     1024            Lrel = L.relativize(K.hom(L), ('a', 'b'))
     1025            b, x = self.is_norm(Lrel, element=True, proof=proof)
     1026            h = Lrel.structure()[0]
     1027            return b, h(x)
     1028
     1029        if L.relative_degree() == 1 or self.is_zero():
     1030            return True, L(self)
     1031
     1032        a, b = self.rnfisnorm(L, certify=proof)
     1033        if b == 1:
     1034            assert a.norm(K) == self
     1035            return True, a
     1036
     1037        if L.is_galois_relative():
     1038            return False, None
     1039
     1040        # The following gives the galois closure of K/QQ, but the galois
     1041        # closure of K/self.parent() would suffice.
     1042        M = L.galois_closure('a')
     1043        from sage.functions.log import log
     1044        from sage.functions.other import floor
     1045        extra_primes = floor(12*log(abs(M.discriminant()))**2)
     1046        a, b = self.rnfisnorm(L, certify=proof, extra_primes=extra_primes)
     1047        if b == 1:
     1048            assert a.norm(K) == self
     1049            return True, a
     1050
     1051        if proof:
     1052            raise NotImplementedError, "is_norm is not implemented unconditionally for norms from non-Galois number fields"
     1053        return False, None
     1054
     1055    def rnfisnorm(self, L, certify=True, extra_primes=0):
     1056        r"""
     1057        Gives the output of the Pari function rnfisnorm.
     1058       
     1059        This tries to decide whether the number field element self is
     1060        the norm of some x in the extension L/K (with K = self.parent()).
     1061
     1062        The output is a pair (x, q), where self = Norm(x)*q. The
     1063        algorithm looks for a solution x that is an S-integer, with S
     1064        a list of places of L containing at least the ramified primes,
     1065        the generators of the class group of L, as well as those primes
     1066        dividing self.
     1067       
     1068        If L/K is Galois, then this is enough; otherwise,
     1069        extra_primes is used to add more primes to S: all the places
     1070        above the primes p <= extra_primes (resp. p|extra_primes) if
     1071        extra_primes > 0 (resp. extra_primes < 0).
     1072
     1073        The answer is guaranteed (i.e., self is a norm iff q = 1) if the
     1074        field is Galois, or, under GRH, if S contains all primes less
     1075        than 12log^2|\disc(M)|, where M is the normal closure of L/K.
     1076
     1077        INPUT:
     1078       
     1079         - L -- a relative number field with base field self.parent()
     1080         - certify -- whether to certify outputs of Pari init functions.
     1081           If false, truth of the output depends on GRH.
     1082         - extra_primes -- an integer as explained above.
     1083
     1084        OUTPUT:
     1085       
     1086        A pair (x, q) with x in L and q in K as explained above
     1087        such that self == x.norm(K)*q.
     1088       
     1089        ALGORITHM:
     1090       
     1091        Uses Pari's rnfisnorm.
     1092       
     1093        EXAMPLES::
     1094       
     1095            sage: K.<a> = NumberField(x^3 + x^2 - 2*x - 1, 'a')
     1096            sage: P.<X> = K[]
     1097            sage: L = NumberField(X^2 + a^2 + 2*a + 1, 'b')
     1098            sage: K(17).rnfisnorm(L)
     1099            ((a^2 - 2)*b - 4, 1)
     1100           
     1101            sage: K.<a> = NumberField(x^3 + x + 1)
     1102            sage: Q.<X> = K[]
     1103            sage: L.<b> = NumberField(X^4 + a)
     1104            sage: t = (-a).rnfisnorm(L); t
     1105            (b^3 + 1, 1)
     1106            sage: t[0].norm(K)
     1107            -a
     1108            sage: t = K(3).rnfisnorm(L); t
     1109            ((-a^2 - 1)*b^3 + b^2 + a*b + a^2 + 1, -3*a)
     1110            sage: t[0].norm(K)*t[1]
     1111            3
     1112
     1113        An example where the base field is a relative field::
     1114
     1115            sage: K.<a, b> = NumberField([x^2 - 2, x^2 - 3])
     1116            sage: L.<c> = K.extension(x^3 + 2)
     1117            sage: t = (2*a + b).rnfisnorm(L); t[1]
     1118            (b - 2)*a + 2*b - 3
     1119            sage: t[0].norm(K)*t[1]
     1120            2*a + b
     1121
     1122        AUTHORS:
     1123
     1124        - Craig Citro (2008-04-05)
     1125
     1126        - Marco Streng (2010-12-03)
     1127
     1128        - Francis Clarke (2010-12-26)
     1129        """
     1130        K = self.parent()
     1131        from sage.rings.number_field.all import is_RelativeNumberField
     1132        if (not is_RelativeNumberField(L)) or L.base_field() != K:
     1133            raise ValueError, "L (=%s) must be a relative number field with base field K (=%s) in rnfisnorm" % (L, K)
     1134
     1135        if certify:
     1136            K.pari_bnf_certify()
     1137
     1138        rnf_data = K.pari_rnfnorm_data(L)
     1139        x, q = self._pari_('y').rnfisnorm(rnf_data)
     1140
     1141        degL = L.relative_degree()
     1142        repx = [K(x.lift().polcoeff(i).lift()) for i in range(degL)]
     1143        x = L(repx)
     1144
     1145        from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
     1146        degK = K.absolute_degree()
     1147        coeffsq = [q.lift().polcoeff(i)._sage_() for i in range(degK)]
     1148        q = PolynomialRing(QQ, 't')(coeffsq)(K.absolute_generator())
     1149
     1150        return x, q
     1151
    9391152    def _mpfr_(self, R):
    9401153        """
    9411154        EXAMPLES::
  • sage/rings/rational.pyx

    diff -r 74c569fadcf6 -r 861de9632ac5 sage/rings/rational.pyx
    a b  
    11681168        """
    11691169        return mpq_sgn(self.value) >= 0 and mpz_perfect_square_p(mpq_numref(self.value)) and mpz_perfect_square_p(mpq_denref(self.value))
    11701170
     1171    def is_norm(self, L, element=False, proof=True):
     1172        r"""
     1173        Determine whether self is the norm of an element of L.
     1174       
     1175        INPUT:
     1176       
     1177         - L -- a number field
     1178         - element -- True or False, whether to also output an element
     1179           of which self is a norm
     1180         - proof -- If True, then the output is correct unconditionally.
     1181           If False, then the output assumes GRH.
     1182       
     1183        OUTPUT:
     1184       
     1185        If element is False, then the output is a boolean B, which is
     1186        True if and only if self is the norm of an element of L.
     1187        If element is False, then the output is a pair (B, x), where
     1188        B is as above. If B is True, then x an element of L such that
     1189        self == x.norm(). Otherwise, x is None.
     1190       
     1191        ALGORITHM:
     1192       
     1193        Uses Pari's bnfisnorm. See self.bnfisnorm().
     1194
     1195        EXAMPLES::
     1196
     1197            sage: K = NumberField(x^2 - 2, 'beta')
     1198            sage: (1/7).is_norm(K)
     1199            True
     1200            sage: (1/10).is_norm(K)
     1201            False
     1202            sage: 0.is_norm(K)
     1203            True
     1204            sage: (1/7).is_norm(K, element=True)
     1205            (True, -3/7*beta + 5/7)
     1206            sage: (1/10).is_norm(K, element=True)
     1207            (False, None)
     1208            sage: (1/691).is_norm(QQ, element=True)
     1209            (True, 1/691)
     1210
     1211        The number field doesn't have to be defined by an
     1212        integral polynomial::
     1213           
     1214            sage: (1/5).is_norm(QuadraticField(5/4, 'a'), element=True)
     1215            (True, -1/5*a + 1/2)
     1216           
     1217        A non-Galois number field::
     1218       
     1219            sage: K.<b> = NumberField(x^3-2)
     1220            sage: x, y = (3/5).is_norm(K, element=True); x
     1221            True
     1222            sage: y.norm()
     1223            3/5
     1224           
     1225            sage: 7.is_norm(K)
     1226            Traceback (most recent call last):
     1227            ...
     1228            NotImplementedError: is_norm is not implemented unconditionally for norms from non-Galois number fields
     1229            sage: 7.is_norm(K, proof=False)
     1230            False
     1231
     1232        AUTHORS:
     1233
     1234        - Craig Citro (2008-04-05)
     1235
     1236        - Marco Streng (2010-12-03)
     1237        """
     1238        if not element:
     1239            return self.is_norm(L, element=True, proof=proof)[0]
     1240
     1241        from sage.rings.number_field.all import is_NumberField
     1242        if not is_NumberField(L):
     1243            raise ValueError, "L (=%s) must be a NumberField in is_norm" % L
     1244        if L.degree() == 1 or self.is_zero():
     1245            return True, L(self)
     1246        d = L.polynomial().denominator()
     1247        if not d == 1:
     1248            M, M_to_L = L.subfield(L.gen()*d)
     1249            b, x = self.is_norm(M, element=True, proof=proof)
     1250            if b:
     1251                x = M_to_L(x)
     1252            return b, x
     1253        a, b = self.bnfisnorm(L, certify=proof)
     1254        if b == 1:
     1255            assert a.norm() == self
     1256            return True, a
     1257        if L.is_galois():
     1258            return False, None
     1259        M = L.galois_closure('a')
     1260        from sage.functions.log import log
     1261        from sage.functions.other import floor
     1262        extra_primes = floor(12*log(abs(M.discriminant()))**2)
     1263        a, b = self.bnfisnorm(L, certify=proof, extra_primes=extra_primes)
     1264        if b == 1:
     1265            assert a.norm() == self
     1266            return True, a
     1267        if proof:
     1268            raise NotImplementedError, "is_norm is not implemented unconditionally for norms from non-Galois number fields"
     1269        return False, None
     1270
     1271    def bnfisnorm(self, K, certify=True, extra_primes=0):
     1272        r"""
     1273        This gives the output of the Pari function bnfisnorm.
     1274       
     1275        Tries to tell whether the rational number self is the norm of some
     1276        element y in K. Returns a pair (a, b) where self = Norm(a)*b. Looks for
     1277        a solution that is an S-unit, with S a certain set of prime ideals
     1278        containing (among others) all primes dividing self.
     1279       
     1280        If K is known to be Galois, set extra_primes = 0 (in this case, self
     1281        is a norm iff b = 1).
     1282       
     1283        If extra_primes is non-zero, the program adds to S the following
     1284        prime ideals, depending on the sign of extra_primes.
     1285        If extra_primes > 0, the ideals of norm less than extra_primes.
     1286        And if extra_primes < 0, the ideals dividing extra_primes.
     1287
     1288        Assuming GRH, the answer is guaranteed (i.e., self is a norm
     1289        iff b = 1), if S contains all primes less than 12log(\disc(L))^2,
     1290        where L is the Galois closure of K.
     1291
     1292        INPUT:
     1293       
     1294         - K -- a number field
     1295         - certify -- whether to certify the output of bnfinit.
     1296           If false, then correctness of the output depends on GRH.
     1297         - extra_primes -- an integer as explained above
     1298
     1299        OUTPUT:
     1300       
     1301        A pair (a, b) with a in K and b in `QQ` such that self == Norm(a)*b
     1302        as explained above.
     1303       
     1304        ALGORITHM:
     1305       
     1306        Uses Pari's bnfisnorm.
     1307       
     1308        EXAMPLES::
     1309       
     1310            sage: QQ(2).bnfisnorm(QuadraticField(-1, 'i'))
     1311            (i + 1, 1)
     1312            sage: 7.bnfisnorm(NumberField(x^3-2, 'b'))
     1313            (1, 7)
     1314       
     1315        AUTHORS:
     1316
     1317        - Craig Citro (2008-04-05)
     1318
     1319        - Marco Streng (2010-12-03)
     1320        """
     1321        from sage.rings.number_field.all import is_NumberField
     1322        if not is_NumberField(K):
     1323            raise ValueError, "K must be a NumberField in bnfisnorm"
     1324        if certify:
     1325            K.pari_bnf_certify()
     1326
     1327        a, b = self._pari_().bnfisnorm(K.pari_bnf(), flag=extra_primes)
     1328        deg = K.degree()
     1329        coeffs = [ a.lift().polcoeff(i)._sage_() for i in range(deg) ]
     1330        from sage.rings.rational_field import QQ
     1331        return K(coeffs), QQ(b._sage_())
     1332
     1333
    11711334    def is_perfect_power(self, expected_value=False):
    11721335        r"""
    11731336        Returns ``True`` if self is a perfect power. 
     
    26882851        mpz_cdiv_q(n.value, mpq_numref(self.value), mpq_denref(self.value))
    26892852        return n
    26902853
    2691     def round(Rational self, mode = "away"):
     2854    def round(Rational self, mode="away"):
    26922855        """
    26932856        Returns the nearest integer to self, rounding away from 0 by
    26942857        default, for consistency with the builtin Python round.