Ticket #9541: trac_9541-part10-libsingular_technical_stuff.patch

File trac_9541-part10-libsingular_technical_stuff.patch, 53.8 KB (added by was, 7 years ago)
  • module_list.py

    # HG changeset patch
    # User William Stein <wstein@gmail.com>
    # Date 1279980735 25200
    # Node ID 33929e45edc22b90bca891fc02d692d0d8514694
    # Parent  313613462727c43cf4142c5b82c73b5009dd67b1
    [mq]: trac_9541-part10-libsingular_technical_stuff.patch
    
    diff -r 313613462727 -r 33929e45edc2 module_list.py
    a b  
    12171217              extra_compile_args=["-std=c99", "-D_XPG6"]
    12181218              ),
    12191219   
     1220    Extension('sage.rings.number_field.number_field_fast',
     1221              sources = ['sage/rings/number_field/number_field_fast.pyx']),
     1222
    12201223    Extension('sage.rings.number_field.number_field_element',
    12211224              sources = ['sage/rings/number_field/number_field_element.pyx']),
    12221225
  • sage/libs/flint/fmpq_poly.c

    diff -r 313613462727 -r 33929e45edc2 sage/libs/flint/fmpq_poly.c
    a b  
    35553555   
    35563556    if (fmpq_poly_is_zero(op))
    35573557    {
    3558         str = calloc(2, sizeof(char));
     3558        str = (char*) calloc(2, sizeof(char));
    35593559        str[0] = '0';
    35603560        str[1] = '\0';
    35613561        return str;
     
    35813581    }
    35823582   
    35833583    mpq_init(q);
    3584     str = calloc(len, sizeof(char));
     3584    str = (char*) calloc(len, sizeof(char));
    35853585    sprintf(str, "%lu", fmpq_poly_length(op));
    35863586    for (j = 0; str[j] != '\0'; j++);
    35873587    str[j++] = ' ';
     
    36253625   
    36263626    if (fmpq_poly_is_zero(op))     /* Zero polynomial                        */
    36273627    {
    3628         str = calloc(2, sizeof(char));
     3628        str = (char*) calloc(2, sizeof(char));
    36293629        str[0] = '0';
    36303630        str[1] = '\0';
    36313631        return str;
     
    36743674    }
    36753675   
    36763676    mpq_init(q);
    3677     str = calloc(len, sizeof(char));
     3677    str = (char*) calloc(len, sizeof(char));
    36783678    j = 0;
    36793679   
    36803680    /* Print the leading term                                                */
  • sage/rings/integer_ring.pyx

    diff -r 313613462727 -r 33929e45edc2 sage/rings/integer_ring.pyx
    a b  
    227227
    228228    def __init__(self):
    229229        ParentWithGens.__init__(self, self, ('x',), normalize=False, category = EuclideanDomains())
    230         self._populate_coercion_lists_(element_constructor=integer.Integer, 
     230        self._populate_coercion_lists_(element_constructor=integer.Integer,
    231231                                       init_no_parent=True,
    232232                                       convert_method_name='_integer_')
    233233       
  • sage/rings/number_field/implementation.pxd

    diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/implementation.pxd
    a b  
    1515cdef class ArithmeticImplementation_flint(ArithmeticImplementation):
    1616    cdef fmpq_poly_t modulus
    1717
    18 cdef class ArithmeticImplementation_libsingular(ArithmeticImplementation):
    19     cdef object nf_t_wrap
    20     cdef object ideal
    21     cdef object ring
    22 
    2318cdef class ArithmeticImplementation_quadratic(ArithmeticImplementation):
    2419    pass
  • sage/rings/number_field/implementation.pyx

    diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/implementation.pyx
    a b  
    178178        """
    179179        return True
    180180
    181 from number_field_element_libsingular import nf_t_wrap
    182 
    183 cdef class ArithmeticImplementation_libsingular(ArithmeticImplementation):
    184     def __init__(self, ideal):
    185         """
    186         EXAMPLES::
    187 
    188             sage: sage.rings.number_field.implementation.ArithmeticImplementation_libsingular()
    189             Arithmetic implementation 'singular'
    190         """
    191         ArithmeticImplementation.__init__(self, 'singular')
    192         self.nf_t_wrap = nf_t_wrap(ideal)
    193         self.ideal = ideal
    194         self.ring = ideal.ring()
    195 
    196181cdef class ArithmeticImplementation_quadratic(ArithmeticImplementation):
    197182    def __init__(self):
    198183        """
  • sage/rings/number_field/maps.py

    diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/maps.py
    a b  
    731731        """
    732732        return self.__to_V(self.__to_K(x))
    733733
     734####################################################
     735# Maps between relative number fields and towers of
     736# univariate quotient polynomial rings.
     737####################################################
     738
     739class MapRelativeNumberFieldToPolynomialQuotientTower(NumberFieldIsomorphism):
     740    def __init__(self, K, Q, base_Q0_to_K0, base_K0_to_Q0):
     741        """
     742        The isomorphism from a relative number field to a polynomial
     743        quotient tower, which sends the generator for the relative number
     744        field to the generator for the quotient ring, and sends the bases
     745        as specified.
     746
     747        INPUT:
     748            - `K` -- relative number field
     749            - `Q` -- quotient of multivariate polynomial ring
     750            - ``base_Q0_to_K0`` -- map on base from poly quotient ring to base field
     751            - ``base_K0_to_Q0`` -- map on base from base field to poly quotient ring
     752
     753        EXAMPLES::
     754
     755            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t=K.polynomial_quotient_tower()
     756            sage: t
     757            Isomorphism map:
     758              From: Number Field in a with defining polynomial x^2 + 7 over its base field
     759              To:   Univariate Quotient Polynomial Ring in a over Univariate Quotient Polynomial Ring in b over Rational Field with modulus x^3 + 2 with modulus x^2 + 7
     760        """
     761        self._K = K
     762        self._Q = Q
     763        self._base_Q0_to_K0 = base_Q0_to_K0
     764        self._base_K0_to_Q0 = base_K0_to_Q0
     765        NumberFieldIsomorphism.__init__(self, Hom(K, Q))
     766
     767    def __cmp__(self, right):
     768        """
     769        EXAMPLES::
     770       
     771            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t=K.polynomial_quotient_tower()
     772            sage: loads(dumps(t)) == t
     773            True
     774        """
     775        c = cmp(type(self),type(right))
     776        if c: return c
     777        return cmp((self._K,self._Q), (right._K,right._Q))
     778   
     779    def _call_(self, x):
     780        """
     781        EXAMPLES::
     782       
     783            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q,f,t=K.polynomial_quotient_tower()
     784            sage: r = K.random_element(); r
     785            (79797/95*b^2 + 135*b - 55473/95)*a - 91/2*b^2 + 279184/95*b + 161878/95
     786            sage: t(r)
     787            (79797/95*b^2 + 135*b - 55473/95)*a - 91/2*b^2 + 279184/95*b + 161878/95
     788            sage: f(t(r)) == r
     789            True
     790        """
     791        f = x.relative_polynomial()
     792        v = [self._base_K0_to_Q0(a) for a in f.list()]
     793        return self._Q(v)
     794   
     795    def inverse(self):
     796        """
     797        Return the inverse of this isomorphism.
     798               
     799        EXAMPLES::
     800       
     801            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t = K.polynomial_quotient_tower()
     802            sage: t.inverse()
     803            Isomorphism map:
     804              From: Univariate Quotient Polynomial Ring in a over Univariate Quotient Polynomial Ring in b over Rational Field with modulus x^3 + 2 with modulus x^2 + 7
     805              To:   Number Field in a with defining polynomial x^2 + 7 over its base field
     806        """
     807        return PolynomialQuotientTowerToRelativeNumberField(
     808            self._K, self._Q, self._base_Q0_to_K0, self._base_K0_to_Q0)
     809
     810class PolynomialQuotientTowerToRelativeNumberField(NumberFieldIsomorphism):
     811    def __init__(self, K, Q, base_Q0_to_K0, base_K0_to_Q0):
     812        """
     813        The isomorphism from a polynomial quotient tower to a relative
     814        number field, which sends the generator for the quotient ring to
     815        the generator for the relative number field, and sends the bases
     816        as specified.
     817
     818        EXAMPLES::
     819
     820            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t=K.polynomial_quotient_tower()
     821            sage: f
     822            Isomorphism map:
     823              From: Univariate Quotient Polynomial Ring in a over Univariate Quotient Polynomial Ring in b over Rational Field with modulus x^3 + 2 with modulus x^2 + 7
     824              To:   Number Field in a with defining polynomial x^2 + 7 over its base field
     825        """
     826        self._K = K
     827        self._Q = Q
     828        self._base_Q0_to_K0 = base_Q0_to_K0
     829        self._base_K0_to_Q0 = base_K0_to_Q0
     830        NumberFieldIsomorphism.__init__(self, Hom(Q,K))
     831   
     832    def __cmp__(self, right):
     833        """
     834        EXAMPLES::
     835       
     836            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t=K.polynomial_quotient_tower()
     837            sage: loads(dumps(f)) == f
     838            True
     839        """
     840        c = cmp(type(self),type(right))
     841        if c: return c
     842        return cmp((self._K,self._Q), (right._K,right._Q))
     843
     844    def _call_(self, x):
     845        """
     846        EXAMPLES::
     847       
     848            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q,f,t = K.polynomial_quotient_tower()
     849            sage: r = Q.random_element()
     850            sage: f(r)
     851            (-12*b^2 + 1/2*b - 1/95)*a - 1/2*b^2 - 4
     852            sage: t(f(r)) == r
     853            True
     854        """
     855        v = [self._base_Q0_to_K0(a) for a in x.list()]
     856        return self._K(v)
     857
     858    def inverse(self):
     859        """
     860        Return the inverse of this isomorphism.
     861       
     862        EXAMPLES::
     863
     864            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q,f,t = K.polynomial_quotient_tower()       
     865            sage: f.inverse()
     866            Isomorphism map:
     867              From: Number Field in a with defining polynomial x^2 + 7 over its base field
     868              To:   Univariate Quotient Polynomial Ring in a over Univariate Quotient Polynomial Ring in b over Rational Field with modulus x^3 + 2 with modulus x^2 + 7
     869        """
     870        return MapRelativeNumberFieldToPolynomialQuotientTower(
     871            self._K, self._Q, self._base_Q0_to_K0, self._base_K0_to_Q0)
     872
     873
     874####################################################
     875# Maps between relative number fields and a quotient
     876# of a multivariate polynomial ring over QQ.
     877####################################################
     878
     879class MapRelativeNumberFieldToMPolynomialQuotient(NumberFieldIsomorphism):
     880    def __init__(self, K, Q, base_Q0_to_K0, base_K0_to_Q0):
     881        """
     882        The isomorphism from a relative number field to a quotient of a
     883        multivariate polynomial ring.
     884
     885        EXAMPLES::
     886
     887            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]);  Q, f, t = K.multi_polynomial_quotient_ring()
     888            sage: t
     889            Isomorphism map:
     890              From: Number Field in a with defining polynomial x^2 + 7 over its base field
     891              To:   Quotient of Multivariate Polynomial Ring in x, x over Rational Field by the ideal (x^3 + 2, x^2 + 7)
     892
     893        Notice above that amusingly that there are two distinct variables
     894        that both print as x.  Sage should deal with this just fine.
     895        """
     896        self._K = K
     897        self._Q = Q
     898        self._base_Q0_to_K0 = base_Q0_to_K0
     899        self._base_K0_to_Q0 = base_K0_to_Q0
     900        Q0 = base_Q0_to_K0.domain()
     901        self._phi = Q0.cover_ring().hom(Q.gens()[1:])
     902                   
     903        NumberFieldIsomorphism.__init__(self, Hom(K, Q))
     904   
     905    def _call_(self, x):
     906        """
     907        EXAMPLES::
     908       
     909            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t = K.multi_polynomial_quotient_ring()
     910            sage: r = K.random_element(); r
     911            (79797/95*b^2 + 135*b - 55473/95)*a - 91/2*b^2 + 279184/95*b + 161878/95
     912            sage: t(r)
     913            79797/95*a*b^2 + 135*a*b - 91/2*b^2 - 55473/95*a + 279184/95*b + 161878/95
     914            sage: f(t(r)) == r
     915            True
     916        """
     917        f = x.relative_polynomial()
     918        x = self._Q.gen(0)
     919        return sum(self._phi(self._base_K0_to_Q0(a).lift())*x**i for i,a in enumerate(f.list()))
     920   
     921    def __cmp__(self, right):
     922        """
     923        EXAMPLES::
     924       
     925            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]);  Q, f, t = K.multi_polynomial_quotient_ring()
     926            sage: loads(dumps(t)) == t
     927            True
     928        """
     929        c = cmp(type(self),type(right))
     930        if c: return c
     931        return cmp((self._K,self._Q), (right._K,right._Q))
     932
     933    def inverse(self):
     934        """
     935        Return the inverse of this isomorphism.
     936               
     937        EXAMPLES::
     938       
     939            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t = K.multi_polynomial_quotient_ring()
     940            sage: t.inverse()
     941            Isomorphism map:
     942              From: Quotient of Multivariate Polynomial Ring in x, x over Rational Field by the ideal (x^3 + 2, x^2 + 7)
     943              To:   Number Field in a with defining polynomial x^2 + 7 over its base field
     944        """
     945        return MPolynomialQuotientToRelativeNumberField(
     946            self._K, self._Q, self._base_Q0_to_K0, self._base_K0_to_Q0)
     947
     948class MPolynomialQuotientToRelativeNumberField(NumberFieldIsomorphism):
     949    def __init__(self, K, Q, base_Q0_to_K0, base_K0_to_Q0):
     950        """
     951        The isomorphism from a quotient of a multivariate polynomial ring
     952        to a relative number field.
     953
     954        EXAMPLES::
     955
     956            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t = K.multi_polynomial_quotient_ring()
     957            sage: f
     958            Isomorphism map:
     959                  From: Quotient of Multivariate Polynomial Ring in x, x over Rational Field by the ideal (x^3 + 2, x^2 + 7)
     960                  To:   Number Field in a with defining polynomial x^2 + 7 over its base field
     961
     962        TESTS::
     963            sage: loads(dumps(f)) == f
     964        """
     965        self._K = K
     966        self._Q = Q
     967        self._base_Q0_to_K0 = base_Q0_to_K0
     968        self._base_K0_to_Q0 = base_K0_to_Q0
     969        Q0 = base_Q0_to_K0.domain()
     970   
     971        NumberFieldIsomorphism.__init__(self, Hom(Q,K))
     972
     973    def _call_(self, x):
     974        """
     975        EXAMPLES::
     976       
     977            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q,f,t = K.polynomial_quotient_tower()
     978            sage: r = Q.random_element()
     979            sage: f(r)
     980            (-12*b^2 + 1/2*b - 1/95)*a - 1/2*b^2 - 4
     981            sage: t(f(r)) == r
     982            True
     983        """
     984        # psi has to be initialized outside of __init__, because the __init__ method
     985        # above is called *during* the construction of K.
     986        if not hasattr(self, '_psi'):
     987            self._psi = Q.hom([K.gen()] + [K(base_Q0_to_K0(g)) for g in Q0.gens()])
     988        return self._psi(x)
     989
     990    def __cmp__(self, right):
     991        """
     992        EXAMPLES::
     993       
     994            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]);  Q, f, t = K.multi_polynomial_quotient_ring()
     995            sage: loads(dumps(f)) == f
     996            True
     997        """
     998        c = cmp(type(self),type(right))
     999        if c: return c
     1000        return cmp((self._K,self._Q), (right._K,right._Q))
     1001
     1002    def inverse(self):
     1003        """
     1004        Return the inverse of this isomorphism.
     1005       
     1006        EXAMPLES::
     1007
     1008            sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q,f,t = K.polynomial_quotient_tower()       
     1009            sage: f.inverse()
     1010            Isomorphism map:
     1011              From: Number Field in a with defining polynomial x^2 + 7 over its base field
     1012              To:   Univariate Quotient Polynomial Ring in a over Univariate Quotient Polynomial Ring in b over Rational Field with modulus x^3 + 2 with modulus x^2 + 7
     1013        """
     1014        return MapRelativeNumberFieldToPolynomialQuotientTower(
     1015            self._K, self._Q, self._base_Q0_to_K0, self._base_K0_to_Q0)
  • sage/rings/number_field/morphism.py

    diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/morphism.py
    a b  
    256256    """
    257257    def __call__(self, im_gen, base_hom=None, check=True):
    258258        """
     259        EXAMPLES::
     260       
    259261            sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 3]); H = Hom(K,K); H
    260262            Automorphism group of Number Field in a with defining polynomial x^2 + 1 over its base field
    261263            sage: type(H)
  • sage/rings/number_field/number_field.py

    diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/number_field.py
    a b  
    22Number Fields
    33
    44AUTHORS:
    5 
    6 - William Stein (2004, 2005): initial version
    7 
    8 - Steven Sivek (2006-05-12): added support for relative extensions
    9 
    10 - William Stein (2007-09-04): major rewrite and documentation
    11 
    12 - Robert Bradshaw (2008-10): specified embeddings into ambient fields
     5    - William Stein (2004, 2005): initial version
     6    - Steven Sivek (2006-05-12): added support for relative extensions
     7    - William Stein (2007-09-04): major rewrite and documentation
     8    - Robert Bradshaw (2008-10): specified embeddings into ambient fields
    139
    1410.. note::
    1511
     
    256252#      - 'generic'
    257253#      - 'singular'
    258254#DEFAULT_IMPLEMENTATION = {'relative':'generic', 'absolute':'generic'}
    259 DEFAULT_IMPLEMENTATION = {'relative':'ntl', 'absolute':'ntl'}
     255DEFAULT_IMPLEMENTATION = {'relative':'singular', 'absolute':'flint'}
    260256
    261257_nf_cache = {}
    262258def NumberField(polynomial, name=None, check=True, names=None, cache=True,
     
    481477
    482478    R = polynomial.base_ring()
    483479    polynomial = polynomial.change_ring(R.fraction_field())
    484 
     480   
     481    implementation = 'flint'
    485482    if implementation == 'default':
     483        # disable quadratic for now, since flint is fast and quadratic causes lots of trouble
    486484        if polynomial.degree() == 2 and polynomial.base_ring() == QQ:
    487485            implementation = 'quadratic'
    488486        else:
     
    502500            _nf_cache[key] = weakref.ref(S)
    503501        return S
    504502
    505     if polynomial.degree() == 2:
     503    # TODO -- ??
     504    if False and polynomial.degree() == 2:
    506505        K = NumberField_quadratic(polynomial, name, latex_name, check, embedding, implementation=implementation)
    507506    else:
    508507        K = NumberField_absolute(polynomial, name, latex_name, check, embedding, implementation=implementation)
     
    10141013        self._integral_basis_dict = {}
    10151014        embedding = number_field_morphisms.create_embedding_from_approx(self, embedding)
    10161015        self._populate_coercion_lists_(embedding=embedding)
    1017 
     1016       
    10181017    def _element_constructor_(self, x):
    10191018        r"""
    10201019        Make x into an element of this number field, possibly not canonically.
     
    18711870        c = cmp(self.variable_name(), other.variable_name())
    18721871        if c: return c
    18731872        # compare coefficients so that the polynomial variable does not count
    1874         c = cmp(list(self.__polynomial), list(other.__polynomial))
     1873        c = cmp(list(self.relative_polynomial()), list(other.relative_polynomial()))
    18751874        if c: return c
    18761875        # compare implementations
    18771876        c = cmp(self.implementation(), other.implementation())
     
    33413340            if implementation == 'quadratic':
    33423341                # extension of quadratic must be represented by ntl
    33433342                implementation = 'ntl'
     3343        if implementation == 'flint':
     3344            implementation = 'singular'
    33443345        if not isinstance(poly, polynomial_element.Polynomial):
    33453346            try:
    33463347                poly = poly.polynomial(self)
     
    33533354        if name is None:
    33543355            raise TypeError, "the variable name must be specified."
    33553356        from sage.rings.number_field.number_field_rel import NumberField_relative
    3356         return NumberField_relative(self, poly, str(name), check=check,
    3357                                     embedding=embedding, implementation=implementation)
     3357        if implementation == 'singular':
     3358            from number_field_fast import NumberField_libsingular
     3359            return NumberField_libsingular(self, poly, str(name), check=check,
     3360                                           embedding=embedding, implementation=implementation)
     3361        else:
     3362            return NumberField_relative(self, poly, str(name), check=check,
     3363                                        embedding=embedding, implementation=implementation)
    33583364
    33593365    def factor(self, n):
    33603366        r"""
     
    34703476            if self.__polynomial != None:
    34713477                X = self.__polynomial.parent().gen()
    34723478            else:
     3479                from sage.rings.all import PolynomialRing
    34733480                X = PolynomialRing(rational_field.RationalField()).gen()
    34743481            self.__gen = self._element_class(self, X)
    34753482            return self.__gen
     
    47884795        """
    47894796        return self.pari_nf().dirzetak(n)
    47904797
     4798    def multi_polynomial_quotient_ring(self):
     4799        r"""
     4800        Return a polynomial quotient ring `R/I`, and maps `f` and `t`,
     4801        where `f: R/I \to K` and `t:K \to R/I` are isomorphisms, where
     4802        `K` is self.
     4803
     4804        OUTPUT:
     4805            - `Q` -- quotient of a polynomial ring
     4806            - `f` -- homomorphism Q to self
     4807            - `t` -- homomorphism self to Q
     4808
     4809        EXAMPLES::
     4810
     4811        An absolute extension::
     4812       
     4813            sage: K.<a> = NumberField(x^3 + x + 3); Q, f, t = K.multi_polynomial_quotient_ring(); Q
     4814            Quotient of Multivariate Polynomial Ring in x over Rational Field by the ideal (x^3 + x + 3)
     4815            sage: f(Q.0)
     4816            a
     4817            sage: t(a)
     4818            a
     4819
     4820        A relative extension::
     4821       
     4822            sage: K.<a> = NumberField(x^3 + x + 3); R.<y> = K[]; L.<b> = K.extension(y^2 + a*y + a^2)
     4823            sage: Q, f, t = L.multi_polynomial_quotient_ring();  alpha = L.random_element(); alpha
     4824            (-12*a^2 - 36*a - 3/2)*b - 71/2*a^2 + 1141/95*a + 3043/95
     4825            sage: Q
     4826            Quotient of Multivariate Polynomial Ring in y, x over Rational Field by the ideal (x^3 + x + 3, y^2 + y*x + x^2)
     4827            sage: Q.gens()
     4828            (b, a)
     4829            sage: t(alpha)
     4830            -12*b*a^2 - 36*b*a - 71/2*a^2 - 3/2*b + 1141/95*a + 3043/95
     4831            sage: f(t(alpha))
     4832             (-12*a^2 - 36*a - 3/2)*b - 71/2*a^2 + 1141/95*a + 3043/95
     4833            sage: f(t(alpha))== alpha
     4834            True
     4835        """
     4836        from sage.rings.all import PolynomialRing, QQ
     4837        p = self.defining_polynomial()
     4838        var = p.variable_name()
     4839        if self.is_absolute():
     4840            R = PolynomialRing(QQ, 1, names=self.variable_name())
     4841            p2 = R(p.change_variable_name(self.variable_name()))
     4842            Q = R.quotient(p2, names=self.variable_name())
     4843            f = Q.hom([self.gen()])
     4844            t = self.hom([Q.gen()])
     4845            return Q, f, t
     4846        else:
     4847            B = self.base_field()
     4848            Q0, f0, t0 = B.multi_polynomial_quotient_ring()
     4849            R = PolynomialRing(QQ, Q0.ngens()+1, self.variable_names())
     4850            phi = Q0.cover_ring().hom(R.gens()[1:])
     4851            x = R.gen(0)
     4852            p2 = sum(phi(t0(a).lift())*x**i for i, a in enumerate(p.list()))
     4853            I = R.ideal([phi(g) for g in Q0.defining_ideal().gens()] + [p2])
     4854            Q = R.quotient(I, names = self.variable_names())
     4855            t = maps.MapRelativeNumberFieldToMPolynomialQuotient(self, Q, f0, t0)
     4856            f = t.inverse()
     4857            return Q, f, t
     4858
     4859    def polynomial_quotient_tower(self):
     4860        """
     4861        EXAMPLES::
     4862
     4863        An absolute extension::
     4864       
     4865            sage: K.<a> = NumberField(x^2 + 3)
     4866            sage: Q, f, t = K.polynomial_quotient_tower(); Q
     4867            Univariate Quotient Polynomial Ring in a over Rational Field with modulus x^2 + 3
     4868            sage: f(Q.0^2+3)
     4869            0
     4870            sage: f(Q.0-2/3)
     4871            a - 2/3
     4872            sage: t(a-2/3)
     4873            a - 2/3
     4874
     4875        A relative extension::
     4876
     4877            sage: K.<a,b> = NumberField([x^17 + 7, x^3 + 2])
     4878            sage: Q, f, t = K.polynomial_quotient_tower()
     4879            sage: Q
     4880            Univariate Quotient Polynomial Ring in a over Univariate Quotient Polynomial Ring in b over Rational Field with modulus x^3 + 2 with modulus x^17 + 7
     4881            sage: f
     4882            Isomorphism map:
     4883              From: Univariate Quotient Polynomial Ring in a ...
     4884              To:   Number Field in a with defining polynomial x^17 + 7...
     4885            sage: t
     4886            Isomorphism map:
     4887              From: Number Field in a with defining polynomial x^17 + 7...
     4888              To:   Univariate Quotient Polynomial Ring in a ...
     4889
     4890
     4891        A more complicated relative extension::
     4892
     4893            sage: K.<a> = NumberField(x^3 + x + 3); R.<y> = K[]
     4894            sage: L.<b> = K.extension(y^2 + a*y + a^2); L
     4895            Number Field in b with defining polynomial y^2 + a*y + a^2 over its base field
     4896            sage: Q, f, t = L.polynomial_quotient_tower(); Q
     4897            Univariate Quotient Polynomial Ring in b over Univariate Quotient Polynomial Ring in a over Rational Field with modulus x^3 + x + 3 with modulus y^2 + a*y + a^2
     4898            sage: f(Q.0)
     4899            b
     4900            sage: t(L.0)
     4901            b
     4902            sage: r = L.random_element(); r
     4903            (-12*a^2 - 36*a - 3/2)*b - 71/2*a^2 + 1141/95*a + 3043/95
     4904            sage: t(r)
     4905            (-12*a^2 - 36*a - 3/2)*b - 71/2*a^2 + 1141/95*a + 3043/95
     4906            sage: f(t(r))
     4907            (-12*a^2 - 36*a - 3/2)*b - 71/2*a^2 + 1141/95*a + 3043/95
     4908            sage: f(t(r)) == r
     4909            True
     4910        """
     4911        p = self.defining_polynomial()
     4912        if self.is_absolute():
     4913            R = p.parent()
     4914            Q = R.quotient(p, names=self.variable_name())
     4915            f = Q.hom([self.gen()])
     4916            t = self.hom([Q.gen()])
     4917            return Q, f, t
     4918        else:
     4919            B = self.base_field()
     4920            Q0, f0, t0 = B.polynomial_quotient_tower()
     4921            R = Q0[p.variable_name()]
     4922            q = R([t0(z).lift() for z in p.list()])
     4923            Q = R.quotient(q, names = self.variable_name())
     4924            t = maps.MapRelativeNumberFieldToPolynomialQuotientTower(self, Q, f0, t0)
     4925            f = t.inverse()
     4926            return Q, f, t
     4927       
    47914928
    47924929class NumberField_absolute(NumberField_generic):
    47934930
     
    48404977            self._zero_element = self(0)
    48414978            self._one_element =  self(1)
    48424979
     4980    def _mpoly_ideal(self):
     4981        """
     4982        Return the multivariate polynomial ring ideal that we use to
     4983        implement arithmetic in the relative extension defined by the
     4984        given polynomial.
     4985
     4986        OUTPUT:
     4987            - an ideal in a multivariate polynomial ring
     4988
     4989        EXAMPLES::
     4990
     4991            sage: K.<a> = NumberField(x^3 + 7)
     4992            sage: K._mpoly_ideal()
     4993            Ideal (x^3 + 7) of Multivariate Polynomial Ring in x over Rational Field
     4994            sage: R.<T> = QQ[]
     4995            sage: K.<alpha> = NumberField(T^3 - 5/3)
     4996            sage: K._mpoly_ideal()
     4997            Ideal (T^3 - 5/3) of Multivariate Polynomial Ring in T over Rational Field
     4998        """
     4999        polynomial = self.polynomial()
     5000        from sage.rings.all import PolynomialRing, QQ
     5001        R = PolynomialRing(QQ,1,names=polynomial.variable_name())
     5002        I = R.ideal([polynomial])
     5003        return I
     5004
    48435005    def _coerce_from_other_number_field(self, x):
    48445006        """
    48455007        Coerce a number field element x into this number field.
     
    49005062            TypeError: <type 'sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX'>
    49015063
    49025064        One can also coerce an element of the polynomial quotient ring
    4903         that's isomorphic to the number field:
     5065        that's isomorphic to the number field::
     5066       
    49045067            sage: K.<a> = NumberField(x^3 + 17)
    49055068            sage: b = K.polynomial_quotient_ring().random_element()
    49065069            sage: K(b)
  • sage/rings/number_field/number_field_element_libsingular.pxd

    diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/number_field_element_libsingular.pxd
    a b  
    3535cdef void nfelt_mul(nfelt_t rop, nfelt_t op1, nfelt_t op2, nf_t K)
    3636cdef void nfelt_add(nfelt_t rop, nfelt_t op1, nfelt_t op2, nf_t K)
    3737cdef void nfelt_sub(nfelt_t rop, nfelt_t op1, nfelt_t op2, nf_t K)
     38cdef void nfelt_neg(nfelt_t rop, nfelt_t op, nf_t K)
    3839cdef void nfelt_div(nfelt_t q, nfelt_t n, nfelt_t d, nf_t K)
    39 cdef void nfelt_div(nfelt_t q, nfelt_t n, nfelt_t d, nf_t K)
     40cdef void nfelt_pow_ui(nfelt_t rop, nfelt_t op, unsigned long exp, nf_t K)
    4041
    4142cdef void nfelt_canonicalize(nfelt_t rop, nf_t K)
    4243cdef object nfelt_pystr(nfelt_t op, nf_t K)
     
    5859    cdef nfelt_t poly
    5960    cdef _new(self)
    6061    cdef MPolynomialRing_libsingular mpoly_ring(self)
     62    cdef MPolynomial_libsingular coerce(self, x)
    6163    cdef imp(self)
    6264
    6365   
  • sage/rings/number_field/number_field_element_libsingular.pyx

    diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/number_field_element_libsingular.pyx
    a b  
    2828    int unlikely(int)
    2929    int likely(int)
    3030
     31# We do this to force compilation of the file using C++.  Once this is
     32# moved to a library, there will be a different solution to including
     33# fmpq_poly.
     34cdef extern from "../../libs/flint/fmpq_poly.c":
     35    pass
     36
    3137include "../../ext/stdsage.pxi"
    3238
    3339from sage.structure.element cimport RingElement, ModuleElement, Element
    3440from number_field_base cimport NumberField
    3541
    3642from sage.libs.singular.decl cimport (
    37     p_Copy, p_Delete, p_ISet,
     43    p_Copy, p_Delete, p_GetCoeff, p_ISet, p_Init, p_SetCoeff,
     44    p_GetExp, p_SetExp, pNext, p_Setm, p_Add_q,
    3845    currRing, rChangeCurrRing,
    3946    redNF, redtailBba,
    40     IDELEMS, idInit, idLift, id_Delete)
     47    IDELEMS, idInit, idLift, id_Delete,
     48    number, nlInit2gmp,
     49    pTakeOutComp1)
     50
     51from sage.libs.gmp.mpq cimport (
     52    mpq_t, mpq_init, mpq_clear,
     53    mpq_numref, mpq_denref, mpq_sgn)
     54
     55from sage.libs.gmp.mpz cimport (
     56    mpz_t, mpz_init_set_si, mpz_clear)
     57
     58from sage.libs.flint.fmpq_poly cimport (
     59    fmpq_poly_t,
     60    fmpq_poly_get_coeff_mpq, fmpq_poly_degree)
    4161
    4262# singular poly arith
    4363from sage.libs.singular.polynomial cimport (
    4464    singular_polynomial_call, singular_polynomial_cmp,
    45     singular_polynomial_add, singular_polynomial_sub,
     65    singular_polynomial_add, singular_polynomial_sub, singular_polynomial_neg,
    4666    singular_polynomial_neg, singular_polynomial_rmul, singular_polynomial_mul,
    4767    singular_polynomial_div_coeff, singular_polynomial_pow,
    4868    singular_polynomial_str, singular_polynomial_latex,
    4969    singular_polynomial_str_with_changed_varnames,
    5070    singular_polynomial_deg, singular_polynomial_length_bounded)
    5171
    52 from implementation cimport ArithmeticImplementation_libsingular
     72from sage.rings.integer cimport Integer
     73from sage.rings.rational cimport Rational
     74
     75from implementation cimport ArithmeticImplementation
     76
     77cdef class ArithmeticImplementation_libsingular(ArithmeticImplementation):
     78    cdef object nf_t_wrap
     79    cdef object ideal
     80    cdef object ring
     81    cdef object field_to_ring
     82    cdef object base_field
     83    def __init__(self, ideal, field_to_ring, base_field):
     84        """
     85        EXAMPLES::
     86
     87            sage: sage.rings.number_field.implementation.ArithmeticImplementation_libsingular()
     88            Arithmetic implementation 'singular'
     89        """
     90        ArithmeticImplementation.__init__(self, 'singular')
     91        self.nf_t_wrap = nf_t_wrap(ideal)
     92        self.ideal = ideal
     93        self.ring = ideal.ring()
     94        self.field_to_ring = field_to_ring
     95        self.base_field = base_field
     96
     97from number_field_element_flint cimport NumberFieldElement_flint
    5398
    5499cdef class NumberFieldElement_libsingular(NumberFieldElement):
    55100
     
    127172
    128173    #### end BENCHMARKING CODE
    129174
    130     def __init__(self, parent, f):
     175    def __init__(self, parent, x):
     176        """
     177        You can coerce the following types in:
     178
     179            - MPolynomial_libsingular -- in which case x is supposed to be in the
     180              multivariate polynomial ring corresponding to the parent.
     181            - NumberFieldElement_libsingular -- in which case x is assumed to be
     182              in either the base field or in parent.
     183            - NumberFieldElement_flint -- in which x must be in the base field of self.
     184            - Integer
     185
     186        The above stated assumptions need not be checked.
     187       
     188        EXAMPLES::
     189        """
     190        cdef poly *p, *q, *mon
     191        cdef number* c
     192        cdef ring *R_p, *R_q
     193        cdef long exponent
     194        cdef fmpq_poly_t f
     195        cdef mpq_t t
     196        cdef mpz_t z, z2
     197       
    131198        self._parent = parent
    132         #cdef MPolynomial_libsingular g = self.mpoly_ring()(f)
    133         cdef MPolynomial_libsingular g = self.mpoly_ring().gen()
    134         nfelt_init_set_poly(self.poly, g._poly, imp(self).nf)
     199        if PY_TYPE_CHECK(x, MPolynomial_libsingular):
     200            #print "MPolynomial_libsingular --> "
     201            # Directly set the pointer.  Note we are assuming here
     202            # that the ring containing x is correct.
     203            p = (<MPolynomial_libsingular>x)._poly
     204           
     205        elif PY_TYPE_CHECK(x, NumberFieldElement_libsingular):
     206            #print "NumberFieldElement_libsingular --> "
     207            # x is an element of the base field, and the base field is
     208            # a relative extension.  We construct a multivariate
     209            # polynomial from x in the bigger ring (with one more
     210            # variable adjoined).
     211
     212            # Get a pointer to the underlying libsingular polynomial
     213            q = (<NumberFieldElement_libsingular>x).poly.poly
     214
     215            # Get the libsingular rings for both p and q, which are
     216            # stored in their implementation nf objects.
     217            R_q = imp(x).nf.ring
     218            R_p = imp(self).nf.ring
     219
     220            # Initialize p (which will be the image of q) to 0.
     221            p = p_ISet(0, R_p)
     222
     223            # Now we iterate over each coefficient of q, grabbing
     224            # the corresponding monomial.
     225            while q:
     226                # Switch to the ring R_q and grab the leading coefficient
     227                rChangeCurrRing(R_q)
     228                c = p_GetCoeff(q, R_q)
     229
     230                # If the coefficient is nonzero, add the corresponding
     231                # coefficient*monomial to p.
     232                if c:
     233                    rChangeCurrRing(R_p)
     234                    mon = p_Init(R_p)      # make a new unitialized monomial (pointer to a poly)
     235                    p_SetCoeff(mon, c, R_p)
     236                    # iterate over the variables, getting the exponents
     237                    for j in range(1, R_p.N): 
     238                        exponent = p_GetExp(q, j, R_q)
     239                        if exponent:
     240                            # We set the exponent of the (j+1)th variable, because the map
     241                            # from the smaller field to this one is:
     242                            #    Q[y,z] \---> Q[x,y,z], i.e., the first variable is the new one.
     243                            p_SetExp(mon, j+1, exponent, R_p)
     244                    # Finalize the change (having set p_SetExp).
     245                    p_Setm(mon, R_p)
     246                    # Replace p by p plus the monomial (with coefficient).
     247                    p = p_Add_q(p, mon, R_p)
     248                # Move to the next monomial of q.
     249                q = pNext(q)
     250
     251        elif PY_TYPE_CHECK(x, NumberFieldElement_flint):
     252            #print "NumberFieldElement_flint --> "
     253           
     254            # Now x is represented by a flint polynomial.
     255            # We iterate through its coefficient, setting
     256            # the corresponding monomial of p.
     257
     258            # Get the ring for self, and initialize p to 0.
     259            R_p = imp(self).nf.ring
     260            p = p_ISet(0, R_p)
     261
     262            mpq_init(t)
     263
     264            # Get C-level access to underlying flint polynomial.
     265            f[0] = ((<NumberFieldElement_flint>x).f)[0]
     266            #print "    degree =", fmpq_poly_degree(f)
     267            for exponent in range(fmpq_poly_degree(f)+1):
     268                # Get the i-th coefficient as a GMP integer
     269                fmpq_poly_get_coeff_mpq(t, f, exponent)
     270                if mpq_sgn(t) != 0:   # if the coefficient is nonzero
     271                    # Make a Singular number.
     272                    c = nlInit2gmp(mpq_numref(t), mpq_denref(t))
     273                    # Set the coefficient, then exponent of the variable.
     274                    mon = p_Init(R_p)
     275                    p_SetCoeff(mon, c, R_p)
     276                    # It must be the last variable, since FLINT is always at bottom of tower
     277                    p_SetExp(mon, R_p.N, exponent, R_p)
     278                    # Finalize the change (having set p_SetExp).
     279                    p_Setm(mon, R_p)
     280                    # Now add the monomial to p.
     281                    p = p_Add_q(p, mon, R_p)
     282                   
     283            mpq_clear(t)
     284
     285        elif PY_TYPE_CHECK(x, Integer):
     286
     287            # Get the ring for self, and initialize p to 0.
     288            R_p = imp(self).nf.ring
     289            # Initialize p to 0
     290            p = p_Init(R_p)
     291            # Create the GMP integer 1, for the denominator below.
     292            mpz_init_set_si(z, 1)
     293            # Create a singular number from x.
     294            c = nlInit2gmp((<Integer>x).value, z)
     295            # Set p to that number.
     296            p_SetCoeff(p, c, R_p)
     297            p_Setm(p, R_p)   # and finalize
     298            mpz_clear(z)
     299           
     300        elif PY_TYPE_CHECK(x, Rational):
     301
     302            # Get the ring for self, and initialize p to 0.
     303            R_p = imp(self).nf.ring
     304            # Initialize p to 0
     305            p = p_Init(R_p)
     306            # Create the GMP integer 1, for the denominator below.
     307            # Create a singular number from x.
     308            c = nlInit2gmp(mpq_numref((<Rational>x).value), mpq_denref((<Rational>x).value))
     309            # Set p to that number.
     310            p_SetCoeff(p, c, R_p)
     311            p_Setm(p, R_p)   # and finalize
     312            mpz_clear(z)
     313
     314        elif PY_TYPE_CHECK(x, int):
     315
     316            # TODO -- surely there is a vastly better way to do this.
     317            R_p = imp(self).nf.ring
     318            p = p_Init(R_p)
     319            mpz_init_set_si(z, 1)
     320            mpz_init_set_si(z2, x)
     321            c = nlInit2gmp(z2, z)
     322            p_SetCoeff(p, c, R_p)
     323            p_Setm(p, R_p)   
     324            mpz_clear(z)
     325            mpz_clear(z2)
     326           
     327        else:
     328            raise TypeError
     329
     330        # Set self to the result of the above.
     331        nfelt_init_set_poly(self.poly, p, imp(self).nf)
     332
     333    def __dealloc__(self):
     334        nfelt_clear(self.poly, imp(self).nf)
    135335
    136336    cdef imp(self):
    137337        cdef ArithmeticImplementation_libsingular A
    138338        A = <ArithmeticImplementation_libsingular> (<NumberField>self._parent)._implementation
    139339        return A
    140340
     341    cdef MPolynomial_libsingular coerce(self, x):
     342        print x, type(x)
     343        if isinstance(x, MPolynomial_libsingular): return x
     344        cdef ArithmeticImplementation_libsingular A
     345        A = <ArithmeticImplementation_libsingular> (<NumberField>self._parent)._implementation
     346        # TODO: having to lift here is stupid; but fixing this is going to require even
     347        # more maps in maps.py... ugh.
     348        return A.field_to_ring(x).lift()
     349
    141350    cdef inline MPolynomialRing_libsingular mpoly_ring(self):
    142351        cdef ArithmeticImplementation_libsingular A
    143352        A = <ArithmeticImplementation_libsingular> (<NumberField>self._parent)._implementation
     
    171380        nfelt_sub(rop.poly, self.poly, (<NumberFieldElement_libsingular>right).poly, imp(self).nf)
    172381        return rop
    173382
     383    def __neg__(self):
     384        cdef NumberFieldElement_libsingular rop = self._new()
     385        nfelt_neg(rop.poly, self.poly, imp(self).nf)
     386        return rop
     387
    174388    cpdef RingElement _div_(self, RingElement right):
    175389        if nfelt_is_zero((<NumberFieldElement_libsingular>right).poly):
    176390            raise ZeroDivisionError
     
    185399        nfelt_invert(rop.poly, self.poly, imp(self).nf)
    186400        return rop
    187401
     402    def __pow__(NumberFieldElement_libsingular self, long exp, dummy):
     403        """
     404        EXAMPLES::
     405        """
     406        if exp < 0:
     407            return self.__invert__().__pow__(-exp)
     408        cdef NumberFieldElement_libsingular rop = self._new()
     409        nfelt_pow_ui(rop.poly, self.poly, exp, imp(self).nf)
     410        return rop
     411
    188412    def __richcmp__(left, right, int op):
    189413        return (<Element>left)._richcmp(right, op)
    190414
     
    274498    nfelt_clear(rop, K)
    275499    singular_polynomial_sub(&(rop.poly), op1.poly, op2.poly, K.ring)
    276500   
     501cdef void nfelt_neg(nfelt_t rop, nfelt_t op, nf_t K):
     502    nfelt_clear(rop, K)
     503    singular_polynomial_neg(&(rop.poly), op.poly, K.ring)
     504
    277505cdef void nfelt_div(nfelt_t q, nfelt_t n, nfelt_t d, nf_t K):
    278506    cdef ideal *I, *nI, *res
     507
     508    # TODO: I did benchmarks, and in some examples this is easily
     509    # way slower than magma, say by a factor of 10 or more.  Not good.
     510    # E.g., comparing this in Sage:
     511    #   K.<a,b> = NumberField([x^6 + 2*x^3 + 7, x^10 +17*x + 152])
     512    # with some simple divides to this in Magma
     513    #   R<x> := PolynomialRing(RationalField());
     514    #   K<a,b> := NumberField([x^6 + 2*x^3 + 7, x^10 +17*x + 152]);
    279515   
    280516    # Initialize the ideal generated by n.
    281517    nI = idInit(1, 1)
    282518    nI.m[0] = p_Copy(n.poly, K.ring)
    283519
    284520    # Initialize the ideal with generators [d] + K.ideal.gens()
    285     I = idInit(IDELEMS(K.ideal)+1, 1)
     521    I = idInit(IDELEMS(K.ideal) + 1, 1)
    286522    I.m[0] = p_Copy(d.poly, K.ring)
    287     for i in range(1, IDELEMS(K.ideal)+1):
     523    for i in range(1, IDELEMS(K.ideal) + 1):
    288524        I.m[i] = p_Copy(K.ideal.m[i-1], K.ring)
    289525
    290526    # Now compute the lift of nI
    291527    res = idLift(I, nI, NULL, 0, 0, 0)
     528
     529    # The answer is the first entry in the lift.
    292530    nfelt_clear(q, K)
    293     q.poly = p_Copy(res.m[0], K.ring)
     531    #q.poly = p_Copy(res.m[0], K.ring)
     532    q.poly = pTakeOutComp1(&res.m[0], 1)
     533
     534    # Clean up.
    294535    id_Delete(&nI, K.ring)
    295536    id_Delete(&I, K.ring)
     537    id_Delete(&res, K.ring)
     538
     539cdef void nfelt_pow_ui(nfelt_t rop, nfelt_t op, unsigned long exp, nf_t K):
     540    nfelt_clear(rop, K)
     541    singular_polynomial_pow(&(rop.poly), op.poly, exp, K.ring)
     542    nfelt_canonicalize(rop, K)
    296543
    297544cdef void nfelt_canonicalize(nfelt_t op, nf_t K):
    298545    if unlikely(K.ring != currRing): rChangeCurrRing(K.ring)
    299546    cdef int max_ind
    300     op.poly = redNF(p_Copy(op.poly, K.ring), max_ind, 0, K.strategy)
     547    op.poly = redNF(op.poly, max_ind, 0, K.strategy)
    301548    if likely(op.poly != NULL):
    302549        op.poly = redtailBba(op.poly, max_ind, K.strategy)
    303550
     
    310557cdef nf_t_wrap imp(NumberFieldElement_libsingular x):
    311558    return (<ArithmeticImplementation_libsingular>(x.imp())).nf_t_wrap
    312559
    313 
    314560cdef class nf_t_wrap:
    315561    def __init__(self, ideal):
    316562        self.ideal = ideal
    317563        nf_init_sage_ideal(self.nf, ideal)
     564
    318565       
     566       
  • new file sage/rings/number_field/number_field_fast.pyx

    diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/number_field_fast.pyx
    - +  
     1include "../../ext/stdsage.pxi"
     2
     3import number_field_rel
     4from sage.rings.integer cimport Integer
     5from sage.rings.rational cimport Rational
     6from number_field_element_libsingular import NumberFieldElement_libsingular
     7
     8class NumberField_libsingular(number_field_rel.NumberField_libsingular):
     9    def _element_constructor_(self, x):
     10        if PY_TYPE_CHECK(x, Integer):
     11            return NumberFieldElement_libsingular(self, x)           
     12        if PY_TYPE_CHECK(x, Rational):
     13            return NumberFieldElement_libsingular(self, x)           
     14        return super(NumberField_libsingular, self)._element_constructor_(x)
     15
  • sage/rings/number_field/number_field_morphisms.pyx

    diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/number_field_morphisms.pyx
    a b  
    103103
    104104    def __init__(self, K, L, ambient_field=None):
    105105        """
    106         EXAMPLES:
     106        EXAMPLES: :
     107       
    107108            sage: from sage.rings.number_field.number_field_morphisms import EmbeddedNumberFieldMorphism
    108109            sage: K.<a> = NumberField(x^2-17, embedding=4.1)
    109110            sage: L.<b> = NumberField(x^4-17, embedding=2.0)
     
    124125              To:   Cyclotomic Field of order 36 and degree 12
    125126              Defn: zeta12 -> zeta36^3
    126127           
    127         The embeddings must be compatible:
     128        The embeddings must be compatible::
     129       
    128130            sage: F1 = NumberField(x^3 + 2, 'a', embedding=2)
    129131            sage: F2 = NumberField(x^3 + 2, 'a', embedding=CC.0)
    130132            sage: F1.gen() + F2.gen()
     
    143145   
    144146    def section(self):
    145147        """
    146         EXAMPLES:
     148        EXAMPLES::
     149       
    147150            sage: from sage.rings.number_field.number_field_morphisms import EmbeddedNumberFieldMorphism
    148151            sage: K.<a> = NumberField(x^2-700, embedding=25)
    149152            sage: L.<b> = NumberField(x^6-700, embedding=3)
  • sage/rings/number_field/number_field_rel.py

    diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/number_field_rel.py
    a b  
    276276            polynomial = polynomial.change_ring(base)
    277277
    278278        #########################################
     279        # Trivial initialization that must be done
     280        # before constructing implementation object
     281        # below.
     282        #########################################       
     283        self.__base_field = base
     284        self.__relative_polynomial = polynomial
     285       
     286        #########################################
     287        # Compute the generators of this field,
     288        # going down the tower and coercing in
     289        # each generator.
     290        #########################################       
     291        self.__gens = [None]
     292        v = [None]
     293        K = base
     294        names = [name]
     295        while K != QQ:
     296            names.append(K.variable_name())
     297            v.append(K.gen())
     298            K = K.base_field()
     299        self._assign_names(tuple(names), normalize=False)
     300
     301        #########################################
    279302        # Set the implementation object
    280         #########################################       
     303        #########################################
     304        # TODO
     305        implementation = 'singular'
     306       
    281307        if implementation == 'default':
    282308            implementation = number_field.DEFAULT_IMPLEMENTATION['relative']
    283309           
     
    295321            import number_field_element_libsingular
    296322            self._element_class = number_field_element_libsingular.NumberFieldElement_libsingular
    297323            self._order_element_class = number_field_element_libsingular.OrderElement_libsingular
    298             ring, ideal = self._libsingular_ring(polynomial)
    299             self._set_implementation(arithmetic_implementation.ArithmeticImplementation_libsingular(ideal))
     324            Q,_,to_Q = self.multi_polynomial_quotient_ring()
     325            ideal = Q.defining_ideal()
     326            self._set_implementation(number_field_element_libsingular.ArithmeticImplementation_libsingular(
     327                ideal, to_Q, base))
    300328        else:
    301329            raise ValueError, "invalid relative number field implementation '%s'"%implementation
    302330        assert self.implementation() is not None
     
    318346            from_abs_base = maps.IdentityMap(base)
    319347            to_abs_base = maps.IdentityMap(base)
    320348        self.__absolute_base_field = abs_base, from_abs_base, to_abs_base
    321         self.__base_field = base
    322         self.__relative_polynomial = polynomial
    323349
    324350        # Check that defining polynomial for this field is irreducible.
    325351        if check:
     
    330356                # polynomials over number fields -- see ticket #4724
    331357                raise ValueError, "defining polynomial (%s) must be irreducible"%polynomial
    332358
    333         #########################################
    334         # Compute the generators of this field,
    335         # going down the tower and coercing in
    336         # each generator.
    337         #########################################       
    338         self.__gens = [None]
    339         v = [None]
    340         K = base
    341         names = [name]
    342         while K != QQ:
    343             names.append(K.variable_name())
    344             v.append(K.gen())
    345             K = K.base_field()
    346359
    347360        #########################################
    348361        # Generic initialization
    349362        #########################################       
    350         self._assign_names(tuple(names), normalize=False)
    351363        NumberField_generic.__init__(self, self.absolute_polynomial(), name=None,
    352364                                     latex_name=latex_name, check=False,
    353365                                     embedding=embedding)
     
    356368        # Now we can finish our gens initialization
    357369        #########################################       
    358370        v[0] = self._gen_relative()
     371        self.__gens = tuple(v)
    359372        v = [self(x) for x in v]
    360373        self.__gens = tuple(v)
    361374        self._zero_element = self(0)
    362375        self._one_element =  self(1)
    363376
    364     def _libsingular_ring(self, polynomial):
    365         """
    366         Return the libsingular ring that we use to implement arithmetic in
    367         the relative extension defined by the given polynomial.
    368 
    369         INPUT:
    370             - ``polynomial`` -- a polynomial over a number field
    371 
    372         OUTPUT:
    373             - a singular multivariate polynomial ring
    374             - an ideal
    375         """
    376         from sage.rings.all import PolynomialRing, QQ
    377         ring = PolynomialRing(QQ, 2, names=('x','y'))
    378         x,y = ring.gens()
    379         ideal = ring.ideal([x**3+7,y**3+2])
    380         return ring, ideal
    381 
    382377    def change_names(self, names):
    383378        r"""
    384379        Return relative number field isomorphic to self but with the
     
    776771            sage: type(K.Hom(K))
    777772            <class 'sage.rings.number_field.morphism.RelativeNumberFieldHomset_with_category'>
    778773        """
    779 
    780774        from number_field import is_NumberFieldHomsetCodomain
    781775        if is_NumberFieldHomsetCodomain(codomain):
    782776            import morphism
     
    819813        """
    820814        if x.parent() is self.base_ring() or x.parent() == self.base_ring():
    821815            return self.__base_inclusion(x)
     816           
    822817        f = x.polynomial()
    823818        if f.degree() <= 0:
    824819            return self._element_class(self, f[0])
     
    14651460        if self.implementation().use_absolute_polynomials():
    14661461            f = self._absolute_pari_polynomial()
    14671462        else:
    1468             f = self.polynomial_ring().gen()
     1463            f = self.multi_polynomial_quotient_ring()[0].gen(0).lift()
    14691464        return self._element_class(self, f)
    14701465
    14711466    @cached_method
     
    24242419    return NumberField_relative(base_field, poly, name, latex_name, check=False, embedding=canonical_embedding)
    24252420
    24262421NumberField_extension_v1 = NumberField_relative_v1  # historical reasons only
     2422
     2423
     2424
     2425#####################
     2426
     2427import number_field_element
     2428import sage.modules.free_module_element
     2429
     2430class NumberField_libsingular(NumberField_relative):
     2431    def _coerce_from_other_number_field(self, x):
     2432        K = self.base_field()
     2433        if x.parent() != K: x = K(x)
     2434        return self._element_class(self, x)
     2435
     2436    def _coerce_non_number_field_element_in(self, x):
     2437        return self._element_class(self, self.base_field()(x))
     2438
     2439    def _element_constructor_(self, x):
     2440        if isinstance(x, integer.Integer):
     2441            return self._element_class(self, x)
     2442       
     2443        if number_field_element.is_NumberFieldElement(x):
     2444            K = x.parent()
     2445            if K is self:
     2446                return x
     2447            elif K == self:
     2448                return self._element_class(self, x.polynomial())
     2449            elif number_field_element.is_OrderElement(x):
     2450                L = K.number_field()
     2451                if L == self:
     2452                    return self._element_class(self, x)
     2453                x = L(x)
     2454            return self._coerce_from_other_number_field(x)
     2455        elif isinstance(x,str):
     2456            return self._coerce_from_str(x)
     2457        elif isinstance(x, (tuple, list)) or \
     2458                (isinstance(x, sage.modules.free_module_element.FreeModuleElement) and
     2459                 self.base_ring().has_coerce_map_from(x.parent().base_ring())):
     2460            if len(x) != self.relative_degree():
     2461                raise ValueError, "Length must be equal to the degree of this number field"
     2462            result = x[0]
     2463            for i in xrange(1,self.relative_degree()):
     2464                result += x[i]*self.gen(0)**i
     2465            return result
     2466        return self._coerce_non_number_field_element_in(x)
     2467       
  • sage/rings/number_field/todo.txt

    diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/todo.txt
    a b  
    3838   [x] make sure the _cmp_c_impl's are compatible across number field element implementations.
    3939   [x] make default implementation computation be centralized somehow??
    4040
     41   [x] isomorphisms between number fields and univariate poly tower
     42
     43   [x] isomorphisms between number fields and multi poly ring
     44
     45   [x] add loads/dumps doctests to all of maps.py, along with __cmp__ methods
     46
     47   [x] optimize coercion in
     48
     49   [x] fix division for singular nf elts
     50
     51
     52   [ ] fix construction of towers with more than 2 fields in them.
     53   [ ] make it so creation of relative number fields doesn't require computing
     54       some stupid absolute polynomial, which takes forever.  that's stupid.
     55
     56-------------------------------------
     57
     58
     59   [ ] loads/dumps in maps.py broken due to non-uniqueness of homsets -- see rings/homset.py
     60       I tried for about an hour to make this unique in various ways, but got ass kicked.
     61   
     62   [ ] move the arithmetic implementation objects to the relevant element files, and make
     63       sure module_list.py is maximally conservative
     64
    4165   [ ] libsingular elements:
    4266       [ ] constructing the corresponding ring
    4367
    44 
    4568   [ ] implement OrderElement_singular
    4669
    4770   [ ] write general implementation of algorithm for computing absolute_field