Ticket #23471: 23471_over_14825.diff

File 23471_over_14825.diff, 11.8 KB (added by roed, 2 years ago)

Diff against #14825 for ease of review

  • src/sage/rings/number_field/number_field.py

    diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py
    index d224a344db..4750f84d30 100644
    a b class NumberField_generic(WithEqualityById, number_field_base.NumberField): 
    13621362            else:
    13631363                parent, x = embedding.parent(), embedding
    13641364            embedding = number_field_morphisms.NumberFieldEmbedding(self, parent, x)
    1365         self._populate_coercion_lists_(embedding=embedding)
     1365        self._populate_coercion_lists_(embedding=embedding, convert_method_name='_number_field_')
    13661366
    13671367    def _convert_map_from_(self, other):
    13681368        r"""
  • src/sage/rings/number_field/order.py

    diff --git a/src/sage/rings/number_field/order.py b/src/sage/rings/number_field/order.py
    index 8cd3a8240a..c426e54fd7 100644
    a b class AbsoluteOrder(Order): 
    10911091        Quadratic elements have a special optimized type:
    10921092
    10931093        """
    1094         Order.__init__(self, K, is_maximal=is_maximal)
    1095 
    10961094        if K.degree() == 2:
    10971095            self._element_type = OrderElement_quadratic
    10981096            # adding the following attribute makes the comparison of elements
    class AbsoluteOrder(Order): 
    11021100            self._element_type = OrderElement_absolute
    11031101
    11041102        self._module_rep = module_rep
    1105         V, from_v, to_v = self._K.vector_space()
     1103        V, from_v, to_v = K.vector_space()
     1104        Order.__init__(self, K, is_maximal=is_maximal)
     1105
    11061106        if check:
    11071107            if not K.is_absolute():
    11081108                raise ValueError("AbsoluteOrder must be called with an absolute number field.")
    class RelativeOrder(Order): 
    14731473            sage: loads(dumps(O)) == O
    14741474            True
    14751475        """
    1476         Order.__init__(self, K, is_maximal=is_maximal)
    14771476        self._absolute_order = absolute_order
    14781477        self._module_rep = absolute_order._module_rep
     1478        Order.__init__(self, K, is_maximal=is_maximal)
    14791479
    14801480    def _element_constructor_(self, x):
    14811481        """
  • src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx

    diff --git a/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx
    index 3cef23ab83..aee6f1f813 100644
    a b cdef class pAdicZZpXCAElement(pAdicZZpXElement): 
    17031703        """
    17041704        R = self.base_ring()
    17051705        S = R[var]
    1706         if self.absprec == 0:
     1706        if self.is_zero():
    17071707            return S([])
    17081708        e = self.parent().e()
    17091709        L = [Integer(c) for c in self._ntl_rep().list()]
  • src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx

    diff --git a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx
    index f3c6f8e1f6..2029b2497e 100644
    a b cdef class pAdicZZpXCRElement(pAdicZZpXElement): 
    25242524        """
    25252525        R = self.base_ring()
    25262526        S = R[var]
    2527         if self.relprec == 0:
     2527        if self.is_zero():
    25282528            return S([])
    25292529        prec = self.relprec + self.ordp
    25302530        e = self.parent().e()
  • src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx

    diff --git a/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx
    index 5de71b11b1..7fd5b19d84 100644
    a b cdef class pAdicZZpXFMElement(pAdicZZpXElement): 
    11521152        """
    11531153        R = self.base_ring()
    11541154        S = R[var]
     1155        if self.is_zero():
     1156            return S([])
    11551157        return S([Integer(c) for c in self._ntl_rep().list()])
    11561158
    11571159    cdef ZZ_p_c _const_term(self):
  • src/sage/rings/padics/padic_extension_generic.py

    diff --git a/src/sage/rings/padics/padic_extension_generic.py b/src/sage/rings/padics/padic_extension_generic.py
    index fa317a30ab..39270fbf75 100644
    a b from __future__ import absolute_import 
    2222
    2323from .padic_generic import pAdicGeneric
    2424from .padic_base_generic import pAdicBaseGeneric
     25from sage.rings.number_field.number_field_base import NumberField
     26from sage.rings.number_field.order import Order
     27from sage.rings.rational_field import QQ
    2528from sage.structure.richcmp import op_EQ
    2629from functools import reduce
    27 
     30from sage.categories.morphism import Morphism
     31from sage.categories.sets_with_partial_maps import SetsWithPartialMaps
     32from sage.categories.integral_domains import IntegralDomains
     33from sage.categories.fields import Fields
     34from sage.categories.homset import Hom
    2835
    2936class pAdicExtensionGeneric(pAdicGeneric):
    3037    def __init__(self, poly, prec, print_mode, names, element_class):
    class pAdicExtensionGeneric(pAdicGeneric): 
    6269
    6370    def _coerce_map_from_(self, R):
    6471        """
    65         Returns True if there is a coercion map from R to self.
     72        Finds coercion maps from R to this ring.
    6673
    6774        EXAMPLES::
    6875
    class pAdicExtensionGeneric(pAdicGeneric): 
    8592                from sage.rings.padics.qadic_flint_FP import pAdicCoercion_FP_frac_field as coerce_map
    8693            return coerce_map(R, self)
    8794
     95    def _convert_map_from_(self, R):
     96        """
     97        Finds conversion maps from R to this ring.
     98
     99        Currently, a conversion exists if the defining polynomial is the same.
     100
     101        EXAMPLES::
     102
     103            sage: R.<a> = Zq(125)
     104            sage: S = R.change(type='capped-abs', prec=40, print_mode='terse', print_pos=False)
     105            sage: S(a - 15)
     106            -15 + a + O(5^20)
     107
     108        We get conversions from the exact field::
     109
     110            sage: K = R.exact_field(); K
     111            Number Field in a with defining polynomial x^3 + 3*x + 3
     112            sage: R(K.gen())
     113            a + O(5^20)
     114
     115        and its maximal order::
     116
     117            sage: OK = K.maximal_order()
     118            sage: R(OK.gen(1))
     119            a + O(5^20)
     120        """
     121        cat = None
     122        if self._implementation == 'NTL' and R == QQ:
     123            # Want to use DefaultConvertMap
     124            return None
     125        if isinstance(R, pAdicExtensionGeneric) and R.defining_polynomial(exact=True) == self.defining_polynomial(exact=True):
     126            if R.is_field() and not self.is_field():
     127                cat = SetsWithPartialMaps()
     128            else:
     129                cat = R.category()
     130        elif isinstance(R, Order) and R.number_field().defining_polynomial() == self.defining_polynomial():
     131            cat = IntegralDomains()
     132        elif isinstance(R, NumberField) and R.defining_polynomial() == self.defining_polynomial():
     133            if self.is_field():
     134                cat = Fields()
     135            else:
     136                cat = SetsWithPartialMaps()
     137        if cat is not None:
     138            H = Hom(R, self, cat)
     139            return H.__make_element_class__(DefPolyConversion)(H)
     140
    88141    def __eq__(self, other):
    89142        """
    90143        Return ``True`` if ``self == other`` and ``False`` otherwise.
    class pAdicExtensionGeneric(pAdicGeneric): 
    448501    #def zeta_order(self):
    449502    #    raise NotImplementedError
    450503
     504class DefPolyConversion(Morphism):
     505    """
     506    Conversion map between p-adic rings/fields with the same defining polynomial.
     507
     508    INPUT:
     509
     510    - ``R`` -- a p-adic extension ring or field.
     511    - ``S`` -- a p-adic extension ring or field with the same defining polynomial.
     512
     513    EXAMPLES::
     514
     515        sage: R.<a> = Zq(125, print_mode='terse')
     516        sage: S = R.change(prec = 15, type='floating-point')
     517        sage: a - 1
     518        95367431640624 + a + O(5^20)
     519        sage: S(a - 1)
     520        30517578124 + a + O(5^15)
     521
     522    ::
     523
     524        sage: R.<a> = Zq(125, print_mode='terse')
     525        sage: S = R.change(prec = 15, type='floating-point')
     526        sage: f = S.convert_map_from(R)
     527        sage: TestSuite(f).run()
     528    """
     529    def _call_(self, x):
     530        """
     531        Use the polynomial associated to the element to do the conversion.
     532
     533        EXAMPLES::
     534
     535            sage: S.<x> = ZZ[]
     536            sage: W.<w> = Zp(3).extension(x^4 + 9*x^2 + 3*x - 3)
     537            sage: z = W.random_element()
     538            sage: repr(W.change(print_mode='digits')(z))
     539            '...20112102111011011200001212210222202220100111100200011222122121202100210120010120'
     540        """
     541        S = self.codomain()
     542        Sbase = S.base_ring()
     543        L = x.polynomial().list()
     544        if L and not (len(L) == 1 and L[0].is_zero()):
     545            return S([Sbase(c) for c in L])
     546        # Inexact zeros need to be handled separately
     547        elif isinstance(x.parent(), pAdicExtensionGeneric):
     548            return S(0, x.precision_absolute())
     549        else:
     550            return S(0)
     551
     552    def _call_with_args(self, x, args=(), kwds={}):
     553        """
     554        Use the polynomial associated to the element to do the conversion,
     555        passing arguments along to the codomain.
     556
     557        EXAMPLES::
     558
     559            sage: S.<x> = ZZ[]
     560            sage: W.<w> = Zp(3).extension(x^4 + 9*x^2 + 3*x - 3)
     561            sage: z = W.random_element()
     562            sage: repr(W.change(print_mode='digits')(z, absprec=8))
     563            '...20010120'
     564        """
     565        S = self.codomain()
     566        Sbase = S.base_ring()
     567        L = x.polynomial().list()
     568        if L and not (len(L) == 1 and L[0].is_zero()):
     569            return S([Sbase(c) for c in L], *args, **kwds)
     570        # Inexact zeros need to be handled separately
     571        elif isinstance(x.parent(), pAdicExtensionGeneric):
     572            if args:
     573                if 'absprec' in kwds:
     574                    raise TypeError("_call_with_args() got multiple values for keyword argument 'absprec'")
     575                absprec = args[0]
     576                args = args[1:]
     577            else:
     578                absprec = kwds.pop('absprec',x.precision_absolute())
     579            absprec = min(absprec, x.precision_absolute())
     580            return S(0, absprec, *args, **kwds)
     581        else:
     582            return S(0, *args, **kwds)
  • src/sage/rings/padics/padic_generic_element.pyx

    diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx
    index 890a846630..6d59043d50 100644
    a b cdef class pAdicGenericElement(LocalGenericElement): 
    15881588            p = self.parent().prime()
    15891589            return Rational(p**self.valuation() * self.unit_part().lift())
    15901590
     1591    def _number_field_(self, K):
     1592        r"""
     1593        Return an element of K approximating this p-adic number.
     1594
     1595        INPUT:
     1596
     1597        - ``K`` -- a number field
     1598
     1599        EXAMPLES::
     1600
     1601            sage: R.<a> = Zq(125)
     1602            sage: K = R.exact_field()
     1603            sage: a._number_field_(K)
     1604            a
     1605        """
     1606        Kbase = K.base_ring()
     1607        if K.defining_polynomial() != self.parent().defining_polynomial(exact=True):
     1608            # Might convert to K's base ring.
     1609            return Kbase(self)
     1610        L = [Kbase(c) for c in self.polynomial().list()]
     1611        if len(L) < K.degree():
     1612            L += [Kbase(0)] * (K.degree() - len(L))
     1613        return K(L)
     1614
    15911615    def _log_generic(self, aprec, mina=0):
    15921616        r"""
    15931617        Return ``\log(self)`` for ``self`` equal to 1 in the residue field
    cdef class pAdicGenericElement(LocalGenericElement): 
    20432067
    20442068            sage: R = ZpFM(2, prec=5)
    20452069            sage: R(180).log(p_branch=0) == R(30).log(p_branch=0) + R(6).log(p_branch=0)
    2046             False           
     2070            False
    20472071
    20482072        Check that log is the inverse of exp::
    20492073
    cdef class pAdicGenericElement(LocalGenericElement): 
    21412165        - Julian Rueth (2013-02-14): Added doctests, some changes for
    21422166          capped-absolute implementations.
    21432167
    2144         - Xavier Caruso (2017-06): Added binary splitting type algorithms 
     2168        - Xavier Caruso (2017-06): Added binary splitting type algorithms
    21452169          over Qp
    21462170
    21472171        """