Ticket #2329: trac-2329-pt2.patch

File trac-2329-pt2.patch, 11.5 KB (added by craigcitro, 14 years ago)
  • sage/libs/pari/gen.pyx

    # HG changeset patch
    # User Craig Citro <craigcitro@gmail.com>
    # Date 1207438572 25200
    # Node ID 662372103fcc363bcd37657d823cbcabe94b003b
    # Parent  4cfc0b6188739fa51afed788a8bb38ab00433fe1
    Clean up trac #2329.
    
    diff -r 4cfc0b618873 -r 662372103fcc sage/libs/pari/gen.pyx
    a b cdef class gen(sage.structure.element.Ri 
    47914791        _sig_on
    47924792        return self.new_gen(bnfisintnorm(self.g, t0))
    47934793
     4794    def bnfisnorm(self, gen x, long flag=0):
     4795        t0GEN(x)
     4796        _sig_on
     4797        return self.new_gen(bnfisnorm(t0, self.g, flag, prec))
     4798
    47944799    def bnfisprincipal(self, x, long flag=1):
    47954800        t0GEN(x)
    47964801        _sig_on
  • sage/rings/integer.pyx

    diff -r 4cfc0b618873 -r 662372103fcc sage/rings/integer.pyx
    a b cdef class Integer(sage.structure.elemen 
    26672667
    26682668    def is_norm(self, K, certify=True):
    26692669        r"""
    2670         Determine whether or not self is a norm from K. If so, return
    2671         an element of K whose norm is self. If not, return False.
     2670        Determine whether or not self is an absolute norm from K.
    26722671
    26732672        This uses Pari's rnfisnorm, whose results (in some cases) are
    26742673        dependent on GRH. If certify=True, we have Pari that the
    cdef class Integer(sage.structure.elemen 
    26782677
    26792678        EXAMPLES:
    26802679            sage: K = NumberField(x**2-2,'beta')
    2681             sage: 4.is_norm(K)
     2680            sage: n = 4
     2681            sage: n.is_norm(K)
     2682            True
     2683            sage: 5.is_norm(K)
     2684            False
     2685            sage: 7.is_norm(QQ)
     2686            True
     2687        """
     2688        try:
     2689            self.element_of_norm(K, certify=certify)
     2690            return True
     2691        except ValueError:
     2692            return False
     2693
     2694    def element_of_norm(self, K, certify=True):
     2695        """
     2696        Return an element of the number field K whose absolute norm is
     2697        self. If no such element exists, raise a ValueError.
     2698
     2699        This uses Pari's bnfisnorm, whose results (in some cases) are
     2700        dependent on GRH. If certify=True, we have Pari that the
     2701        results are correct independent of GRH. In the case that K/QQ
     2702        is Galois, the results are valid even without certification.
     2703
     2704        EXAMPLES:
     2705            sage: K = NumberField(x**2-2,'beta')
     2706            sage: n = 4
     2707            sage: n.element_of_norm(K)
    26822708            -4*beta + 6
    2683             sage: 4.is_norm(K).norm()
     2709            sage: n.element_of_norm(K).norm()
    26842710            4
    2685             sage: 5.is_norm(K)
    2686             False
    2687             sage: 7.is_norm(QQ)
     2711            sage: n = 5
     2712            sage: n.element_of_norm(K)
     2713            Traceback (most recent call last):
     2714            ...
     2715            ValueError: 5 is not a norm from Number Field in beta with defining polynomial x^2 - 2
     2716            sage: n = 7
     2717            sage: n.element_of_norm(QQ)
    26882718            7
    26892719        """
    26902720        from sage.rings.number_field.all import is_NumberField
    26912721
    26922722        if not is_NumberField(K):
    26932723            raise ValueError, "K must be a NumberField"
    2694 
    26952724        if K.degree() == 1 or self.is_zero():
    26962725            return self
    2697 
    26982726        if certify:
    26992727            K.pari_bnf_certify()
    27002728
    2701         rel_poly = K.pari_bnf()
    2702         base_poly = sage.libs.pari.gen.pari('y')
    2703         rnf_data = base_poly.rnfisnorminit(rel_poly)
    2704 
    2705         x, q = self._pari_().rnfisnorm(rnf_data)
    2706 
     2729        x, q = self._pari_().bnfisnorm(K.pari_bnf())
    27072730        if not q.is_one():
    2708             return False
     2731            raise ValueError, "%s is not a norm from %s"%(self, K)
    27092732        else:
    27102733            deg = x[0].poldegree()+1
    27112734            coeffs = [ x[0].polcoeff(i)._sage_() for i in range(deg) ]
    27122735            return K(coeffs)
    27132736
     2737    def elements_of_norm(self, K, proof=True):
     2738        """
     2739        Alias for K.elements_of_norm(self, proof).
     2740
     2741        EXAMPLES:
     2742            sage: K = NumberField(x**3+5, 'alpha') ; n = 5
     2743            sage: n.elements_of_norm(K)
     2744            [-alpha]
     2745            sage: K.elements_of_norm(n)
     2746            [-alpha]
     2747            sage: [ y.norm() for y in n.elements_of_norm(K) ]
     2748            [5]
     2749        """
     2750        return K.elements_of_norm(self, proof=proof)
    27142751       
    27152752    def jacobi(self, b):
    27162753        r"""
  • sage/rings/number_field/number_field.py

    diff -r 4cfc0b618873 -r 662372103fcc sage/rings/number_field/number_field.py
    a b class NumberField_generic(number_field_b 
    21172117            sage: K.elements_of_norm(50)
    21182118            [7*a - 1, -5*a + 5, a - 7]           # 32-bit
    21192119            [7*a - 1, -5*a + 5, -7*a - 1]        # 64-bit
     2120            sage: [ y.norm() for y in K.elements_of_norm(50) ]
     2121            [50, 50, 50]
    21202122        """
    21212123        proof = proof_flag(proof)       
    21222124        B = self.pari_bnf(proof).bnfisintnorm(n)
    21232125        R = self.polynomial().parent()
    2124         return [self(QQ['x'](R(g))) for g in B]
     2126        # At this point, we should just coerce these solutions
     2127        # into self. However, Pari's bnfisintnorm sometimes returns
     2128        # elements off by -1, so we correct this.
     2129        elems = [ self(R(g)) for g in B ]
     2130        for i in range(len(elems)):
     2131            x = elems[i]
     2132            val = x.norm()
     2133            if val == QQ(-1*n) and (self.degree()%2):
     2134                elems[i] = -1*elems[i]
     2135            elif val != QQ(n):
     2136                raise ValueError, "bug in value returned by Pari's bnfisintnorm. Please report this to sage-devel@googlegroups.com."
     2137        return elems
    21252138
    21262139    def extension(self, poly, name=None, names=None, check=True):
    21272140        """
  • sage/rings/number_field/number_field_element.pyx

    diff -r 4cfc0b618873 -r 662372103fcc sage/rings/number_field/number_field_element.pyx
    a b cdef class NumberFieldElement(FieldEleme 
    640640
    641641    def is_norm(self, L, certify=True, rnf_data=None):
    642642        r"""
    643         Determine whether or not self is a norm from L. If so, return
    644         an element of L whose norm is self. If not, return False.
     643        Determine whether or not self is a norm from L.
    645644
    646645        This uses Pari's rnfisnorm, whose results (in some
    647646        cases) are dependent on GRH. If certify=True, we have Pari
    cdef class NumberFieldElement(FieldEleme 
    650649        that the results are valid even without certification.
    651650
    652651        EXAMPLES:
    653             sage: K = NumberField(x**3+5, 'beta')
     652            sage: K = NumberField(x**3+5, 'beta') ; beta = K.gen(0)
    654653            sage: L = K.extension(x**2+x+1, 'gamma')
    655654            sage: beta.is_norm(L)
    656655            False
    657656            sage: (beta**2).is_norm(L)
    658             beta*gamma + beta
    659             sage: (beta**2).is_norm(L).norm(K)
     657            True
     658        """
     659        try:
     660            self.element_of_norm(L, certify=certify, rnf_data=rnf_data)
     661            return True
     662        except ValueError:
     663            return False
     664
     665    def element_of_norm(self, L, certify=True, rnf_data=None):
     666        r"""
     667        Return an element of L whose relative norm to self.parent() is
     668        self. If no such element exists, raise a ValueError.
     669       
     670        This uses Pari's rnfisnorm, whose results (in some
     671        cases) are dependent on GRH. If certify=True, we have Pari
     672        that the results are correct independent of GRH. In the case
     673        that L/self.parent() is Galois, the Pari documentation suggests
     674        that the results are valid even without certification.
     675
     676        EXAMPLES:
     677            sage: K = NumberField(x**3+5, 'beta') ; beta = K.gen(0)
     678            sage: L = K.extension(x**2+x+1, 'gamma')
     679            sage: beta.element_of_norm(L)
     680            Traceback (most recent call last):
     681            ...
     682            ValueError: beta is not a norm from Number Field in gamma with defining polynomial x^2 + x + 1 over its base field
     683            sage: (beta**2).element_of_norm(L)
     684            -beta
     685            sage: (beta**2).element_of_norm(L).norm(K)
    660686            beta^2
    661687        """
    662688        K = self.parent()
    cdef class NumberFieldElement(FieldEleme 
    672698        x,q = self._pari_('y').rnfisnorm(rnf_data)
    673699
    674700        if not q.is_one():
    675             return False
     701            raise ValueError, "%s is not a norm from %s"%(self, L)
    676702        else:
    677703            deg = x[0].poldegree()+1
    678704            rep = [ x[0].polcoeff(i) for i in range(deg) ]
  • sage/rings/rational.pyx

    diff -r 4cfc0b618873 -r 662372103fcc sage/rings/rational.pyx
    a b cdef class Rational(sage.structure.eleme 
    545545
    546546    def is_norm(self, K, certify=True):
    547547        r"""
    548         Determine whether or not self is a norm from K. If so, return
    549         an element of K whose norm is self. If not, return False.
     548        Determine whether or not self is an absolute norm from K.
    550549
    551550        This uses Pari's rnfisnorm, whose results (in some cases) are
    552551        dependent on GRH. If certify=True, we have Pari that the
    cdef class Rational(sage.structure.eleme 
    557556        EXAMPLES:
    558557            sage: K = NumberField(x**2-2,'beta')
    559558            sage: (1/7).is_norm(K)
    560             1/7*beta + 3/7
     559            True
    561560            sage: (1/10).is_norm(K)
    562561            False
    563562            sage: (1/691).is_norm(QQ)
     563            True
     564            sage: 0.is_norm(K)
     565            True
     566        """
     567        try:
     568            self.element_of_norm(K, certify=certify)
     569            return True
     570        except ValueError:
     571            return False
     572
     573    def element_of_norm(self, K, certify=True):
     574        r"""
     575        Return an element of the number field K whose absolute norm is
     576        self. If no such element exists, raise a ValueError.
     577       
     578        This uses Pari's bnfisnorm, whose results (in some cases) are
     579        dependent on GRH. If certify=True, we have Pari that the
     580        results are correct independent of GRH. In the case that K/QQ
     581        is Galois, the results are valid even without certification.
     582
     583        EXAMPLES:
     584            sage: K = NumberField(x**2-2,'beta')
     585            sage: (1/7).element_of_norm(K)
     586            1/7*beta + 3/7
     587            sage: (1/10).element_of_norm(K)
     588            Traceback (most recent call last):
     589            ...
     590            ValueError: 1/10 is not a norm from Number Field in beta with defining polynomial x^2 - 2
     591            sage: (1/691).element_of_norm(QQ)
    564592            1/691
    565             sage: 0.is_norm(K)
     593            sage: n = 0 ; n.element_of_norm(K)
    566594            0
    567595        """
    568596        from sage.rings.number_field.all import is_NumberField
    cdef class Rational(sage.structure.eleme 
    570598
    571599        if not is_NumberField(K):
    572600            raise ValueError, "K must be a NumberField"
    573 
    574601        if K.degree() == 1 or self.is_zero():
    575602            return self
    576 
    577603        if certify:
    578604            K.pari_bnf_certify()
    579605
    580         rel_poly = K.pari_bnf()
    581         base_poly = sage.libs.pari.gen.pari('y')
    582         rnf_data = base_poly.rnfisnorminit(rel_poly)
    583 
    584         x, q = self._pari_().rnfisnorm(rnf_data)
    585 
     606        x, q = self._pari_().bnfisnorm(K.pari_bnf())
    586607        if not q.is_one():
    587             return False
     608            raise ValueError, "%s is not a norm from %s"%(self, K)
    588609        else:
    589610            deg = x[0].poldegree()+1
    590611            coeffs = [ QQ(x[0].polcoeff(i)) for i in range(deg) ]
    591612            return K(coeffs)
    592            
    593613
    594614    def squarefree_part(self):
    595615        """