Ticket #23218: 23218_over_23471.diff

File 23218_over_23471.diff, 130.7 KB (added by roed, 20 months ago)

Diff against #23471

  • src/module_list.py

    diff --git a/src/module_list.py b/src/module_list.py
    index 8015e17391..6271bb30bb 100644
    a b ext_modules = [ 
    14511451              libraries = ["gmp", "ntl"],
    14521452              language='c++'),
    14531453
     1454    Extension('sage.rings.padics.pow_computer_relative',
     1455              sources = ['sage/rings/padics/pow_computer_relative.pyx'],
     1456              libraries = ["ntl", "gmp", "m"],
     1457              language='c++'),
     1458
    14541459    Extension('sage.rings.padics.qadic_flint_CR',
    14551460              sources = ['sage/rings/padics/qadic_flint_CR.pyx']),
    14561461
    ext_modules = [ 
    14641469              sources = ['sage/rings/padics/qadic_flint_FP.pyx'],
    14651470              libraries = ["flint"]),
    14661471
     1472    Extension('sage.rings.padics.relative_ramified_FM',
     1473              sources = ['sage/rings/padics/relative_ramified_FM.pyx']),
     1474
    14671475    ################################
    14681476    ##
    14691477    ## sage.rings.polynomial
  • new file src/sage/libs/linkages/padics/Polynomial_ram.pxi

    diff --git a/src/sage/libs/linkages/padics/Polynomial_ram.pxi b/src/sage/libs/linkages/padics/Polynomial_ram.pxi
    new file mode 100644
    index 0000000000..e858e5bce0
    - +  
     1# -*- coding: utf-8 -*-
     2r"""
     3This linkage file implements the padics API for ramified extensions using Sage
     4Polynomials.
     5
     6It contains the bits that are specific for ramified extensions. Everything that
     7is independent of ramification is in Polynomial_shared.pxi.
     8
     9.. NOTE::
     10
     11    There are no doctests in this file since the functions here can not be
     12    called directly from Python. Testing of this function is necessarily
     13    indirect and mostly done through arithmetic black-box tests that are part
     14    of the test suites of the `p`-adic parents.
     15
     16AUTHORS:
     17
     18- David Roe, Julian Rüth (2017-06-11): initial version
     19
     20"""
     21#*****************************************************************************
     22#       Copyright (C) 2017 David Roe <roed.math@gmail.com>
     23#                     2017 Julian Rüth <julian.rueth@fsfe.org>
     24#
     25#  Distributed under the terms of the GNU General Public License (GPL)
     26#  as published by the Free Software Foundation; either version 2 of
     27#  the License, or (at your option) any later version.
     28#
     29#                  http://www.gnu.org/licenses/
     30#*****************************************************************************
     31from sage.rings.integer cimport Integer
     32from sage.ext.stdsage cimport PY_NEW
     33from sage.libs.gmp.mpz cimport *
     34
     35include "sage/libs/linkages/padics/Polynomial_shared.pxi"
     36
     37cdef inline bint creduce(celement out, celement a, long prec, PowComputer_ prime_pow) except -1:
     38    r"""
     39    Reduce ``a`` modulo a power of the maximal ideal.
     40
     41    INPUT:
     42
     43    - ``out`` -- a ``celement`` to store the reduction
     44
     45    - ``a`` -- the ``celement`` to be reduced
     46
     47    - ``prec`` -- a ``long``, the precision to reduce modulo
     48
     49    - ``prime_pow`` -- the ``PowComputer`` for the ring
     50
     51    OUTPUT:
     52
     53    ``True`` if the reduction is zero, ``False`` otherwise
     54
     55    """
     56    out.__coeffs = (<celement?>(a % prime_pow.modulus)).__coeffs
     57    cdef long coeff_prec = prec / prime_pow.e + 1
     58    cdef long break_pt = prec % prime_pow.e
     59    if break_pt > len(out.__coeffs):
     60        break_pt = len(out.__coeffs)
     61    for i in range(break_pt):
     62        out.__coeffs[i] %= prime_pow.base_ring.uniformizer_pow(coeff_prec)
     63    coeff_prec -= 1
     64    for i in range(break_pt, len(out.__coeffs)):
     65        out.__coeffs[i] %= prime_pow.base_ring.uniformizer_pow(coeff_prec)
     66    out.__normalize()
     67    return out == 0
     68
     69cdef inline bint creduce_small(celement out, celement a, long prec, PowComputer_ prime_pow) except -1:
     70    r"""
     71    Reduce ``a`` modulo a power of the maximal ideal.
     72
     73    Similar to ``creduce`` but this function assumes that at most one
     74    addition/subtraction has happened on reduced inputs.  For integral inputs
     75    this translates to the assumption that `-p^\mathrm{prec} < a < 2p^\mathrm{prec}`.
     76
     77    INPUT:
     78
     79    - ``out`` -- a ``celement`` to store the reduction
     80
     81    - ``a`` -- the ``celement`` to be reduced
     82
     83    - ``prec`` -- a ``long``, the precision to reduce modulo
     84
     85    - ``prime_pow`` -- the ``PowComputer`` for the ring
     86
     87    OUTPUT:
     88
     89    ``True`` if the reduction is zero, ``False`` otherwise
     90
     91    """
     92    return creduce(out, a, prec, prime_pow)
     93
     94cdef inline long cvaluation(celement a, long prec, PowComputer_ prime_pow) except -1:
     95    r"""
     96    Return the maximum power of the uniformizer dividing ``a``.
     97
     98    This function differs from :meth:`cremove` in that the unit is discarded.
     99
     100    INPUT:
     101
     102    - ``a`` -- the element whose valuation is desired
     103
     104    - ``prec`` -- a ``long``; if the valuation of ``a`` exceeds ``prec``, this
     105      function returns ``prec``. In particular, ``prec`` is returned if ``a``
     106      is zero.
     107
     108    - ``prec`` -- a ``long``, the return value if ``a`` is zero
     109
     110    - ``prime_pow`` -- the ``PowComputer`` for the ring
     111
     112    OUTPUT:
     113
     114    The number of times the uniformizer divides ``a``, or ``prec`` if that is
     115    higher.
     116
     117    """
     118    cdef long ret = prec
     119
     120    for i,c in enumerate(a.__coeffs):
     121        if i >= prec:
     122            break
     123        ret = min(ret, c.valuation()*prime_pow.e + i)
     124
     125    return ret
     126
     127cdef inline int cshift(celement out, celement a, long n, long prec, PowComputer_ prime_pow, bint reduce_afterward) except -1:
     128    r"""
     129    Multiply ``a`` with an ``n``-th power of the uniformizer.
     130
     131    This function shifts the `\pi`-adic expansion of ``a`` by ``n``, i.e., it
     132    multiplies ``a`` by the `n`-th power of the uniformizer and drops any terms
     133    with negative powers of the uniformizer in the `\pi`-adic expansion.
     134
     135    INPUT:
     136
     137    - ``out`` -- a ``celement`` to store the result
     138
     139    - ``a`` -- the ``celement`` to shift
     140
     141    - ``n`` -- a ``long``, the amount to shift by
     142
     143    - ``prec`` -- a ``long``, a precision modulo which to reduce if
     144      ``reduce_afterward`` is set
     145
     146    - ``prime_pow`` -- the ``PowComputer`` for the ring
     147
     148    - ``reduce_afterward`` -- whether to :meth:`creduce` ``out`` before
     149      returning
     150
     151    """
     152    cdef long q, r
     153
     154    if n > 0:
     155        a *= prime_pow.uniformizer_pow(n)
     156    elif n < 0:
     157        q = -n / prime_pow.e # ≥ 0
     158        r = -n % prime_pow.e # ≥ 0
     159        # As 0 > n = -q*e - r, π^n = p^-q * (p/π^e)^q * π^-r
     160        if q:
     161            # Multiply with p^-q: this kills the digits in the π-adic expansion
     162            # that belong to terms below π^(q*e).
     163            a = a.map_coefficients(lambda c: c>>q)
     164            # Multiply with (p/π^e)^q.
     165            a *= prime_pow.pxe_pow(q)
     166        if r:
     167            # Multiply with (p/x^r)
     168            a *= prime_pow.px_pow(r)
     169            a %= prime_pow.modulus()
     170            # Divide by p
     171            a = a.map_coefficients(lambda c: c>>1)
     172
     173    if reduce_afterward:
     174        creduce(out, a, prec, prime_pow)
     175    else:
     176        out.__coeffs = a.__coeffs
     177
     178cdef inline int cshift_notrunc(celement out, celement a, long n, long prec, PowComputer_ prime_pow) except -1:
     179    r"""
     180    Multiply ``a`` with an ``n``-th power of the uniformizer.
     181
     182    This method is identical to :meth:`cshift` but assumes that the valuation
     183    of ``a`` is at least ``-n``.
     184
     185    INPUT:
     186
     187    - ``out`` -- a ``celement`` to store the result
     188
     189    - ``a`` -- the ``celement`` to shift
     190
     191    - ``n`` -- a ``long``, the amount to shift by
     192
     193    - ``prec`` -- a ``long``, a precision modulo which to reduce if
     194      ``reduce_afterward`` is set
     195
     196    - ``prime_pow`` -- the ``PowComputer`` for the ring
     197
     198    """
     199    cshift(out, a, n, prec, prime_pow, True)
     200
     201cdef inline int cinvert(celement out, celement a, long prec, PowComputer_ prime_pow) except -1:
     202    r"""
     203    Compute the inverse of ``a``.
     204
     205    INPUT:
     206
     207    - ``out`` -- a ``celement`` to store the inverse
     208
     209    - ``a`` -- a ``celement``, the element to be inverted
     210
     211    - ``prec`` -- a ``long``, ``out`` is reduced to this precision
     212
     213    - ``prime_pow`` -- the ``PowComputer`` for the ring
     214
     215    """
     216    out.__coeffs = prime_pow.invert(a, prec).__coeffs
     217    creduce(out, out, prec, prime_pow)
     218
     219cdef inline int cdivunit(celement out, celement a, celement b, long prec, PowComputer_ prime_pow) except -1:
     220    r"""
     221    Divide ``a`` by ``b``.
     222
     223    This function computes ``a*(1/b)`` where the inverse of ``b`` is determined
     224    to precision ``prec``. No reduction is performed after the product.
     225
     226    INPUT:
     227
     228    - ``out`` -- a ``celement`` to store the quotient
     229
     230    - ``a`` -- a ``celement``, the dividend
     231
     232    - ``b`` -- a ``celement``, the divisor, an element of valuation zero
     233
     234    - ``prec`` -- a ``long``, the precision to which the inverse of ``b`` is
     235      determined
     236
     237    - ``prime_pow`` -- the ``PowComputer`` for the ring
     238
     239    """
     240    cinvert(out, b, prec, prime_pow)
     241    cmul(out, out, a, prec, prime_pow)
     242
     243cdef inline int cpow(celement out, celement a, mpz_t n, long prec, PowComputer_ prime_pow) except -1:
     244    r"""
     245    Raise ``a`` to the ``n``-th power.
     246
     247    INPUT:
     248
     249    - ``out`` -- a ``celement`` in which to store the result
     250
     251    - ``a`` -- a ``celement``, the base
     252
     253    - ``n`` -- an ``mpz_t``, the exponent
     254
     255    - ``prec`` -- a ``long``, the working absolute precision
     256
     257    - ``prime_pow`` -- the ``PowComputer`` for the ring
     258
     259    """
     260    cdef Integer zn = PY_NEW(Integer)
     261    mpz_set(zn.value, n)
     262
     263    csetone(out, prime_pow)
     264    if zn == 0:
     265        return 0
     266
     267    cmul(out, out, a, prec, prime_pow)
     268
     269    for digit in zn.binary()[1:]:
     270        cmul(out, out, out, prec, prime_pow)
     271        if digit == '1':
     272            cmul(out, out, a, prec, prime_pow)
     273        # we should probably not creduce that frequently to increase the performance
     274        creduce(out, out, prec, prime_pow)
     275
     276# The element is filled in for zero in the output of clist if necessary.
     277# This WON'T work if the absolute inertia degree is 1.
     278_list_zero = []
     279
     280cdef clist(celement a, long prec, bint pos, PowComputer_ prime_pow):
     281    r"""
     282    Return a list of digits in the series expansion.
     283
     284    This function is used in printing, and expresses ``a`` as a series
     285    in the standard uniformizer `\pi`.  Note that for extension
     286    elements, the coefficients in the series could be lists themselves.
     287
     288    INPUT:
     289
     290    - ``a`` -- a ``celement`` for which to determine the list expansion
     291
     292    - ``prec`` -- a ``long``, the number of digits desired
     293
     294    - ``pos`` -- if ``True``, then representatives in the range 0…p-1 are used;
     295      otherwise, in the range `-\lfloor p/2\rlfloor … \lceil p/2\rceil`
     296
     297    - ``prime_pow`` -- a ``PowComputer`` for the ring
     298
     299    OUTPUT:
     300
     301    A list of p-adic digits `[a_0, a_1, \ldots]` so that `a = a_0 + a_1\pi +
     302    \cdots` modulo `\pi^\mathrm{prec}`
     303
     304    """
     305    # This is not very efficient, but there's no clear better way.
     306    # We assume this is only called on two-step extensions (for more general
     307    # extensions, convert to the absolute field).
     308    R = a.base_ring()
     309    if R.degree() == 1:
     310        raise NotImplementedError("Absolute extensions using Sage polynomials not completely supported")
     311    if R.base_ring().degree() != 1:
     312        raise TypeError("clist only allowed on towers of height 2")
     313    cdef long j
     314    ans = []
     315    p = a.base_ring().prime()
     316    p2 = (p-1)//2
     317    ccopy(prime_pow.tmp_clist, a, prime_pow)
     318    for j in range(prec):
     319        # the following is specific to the ramified over unramified case.
     320        const_term = prime_pow.tmp_clist[0]
     321        if const_term._is_exact_zero():
     322            term = []
     323        else:
     324            flint_rep = const_term._flint_rep_abs()[0]
     325            term = [c % p for c in flint_rep.list()]
     326            while term and not term[-1]:
     327                del term[-1]
     328            if not pos:
     329                term = [c - p if c > p2 else c for c in term]
     330        ans.append(term)
     331        if j != prec-1:
     332            cshift(prime_pow.tmp_clist, prime_pow.tmp_clist, -1, prec-j, prime_pow, False)
     333        if not prime_pow.tmp_clist:
     334            break
     335    return ans
     336
     337cdef int cteichmuller(celement out, celement value, long prec, PowComputer_ prime_pow) except -1:
     338    r"""
     339    Compute a Teichmüller representative congruent to ``value``.
     340
     341    INPUT:
     342
     343    - ``out`` -- a ``celement`` which is set to a `q-1`-th root of unity
     344      congruent to ``value`` modulo `\pi`; or 0 if `a \equiv 0 \pmod{\pi}`.
     345
     346    - ``value`` -- n ``celement``, the element mod `\pi` to lift
     347
     348    - ``prec`` -- a ``long``, the precision to which to lift
     349
     350    - ``prime_pow`` -- the ``PowComputer`` of the ring
     351
     352    """
     353    if value[0].valuation() > 0:
     354        out.__coeffs = []
     355    else:
     356        out.__coeffs = [value[0].parent().teichmuller(value[0])]
  • new file src/sage/libs/linkages/padics/Polynomial_shared.pxi

    diff --git a/src/sage/libs/linkages/padics/Polynomial_shared.pxi b/src/sage/libs/linkages/padics/Polynomial_shared.pxi
    new file mode 100644
    index 0000000000..9e81b84342
    - +  
     1r"""
     2This linkage file implements the padics API using Sage Polynomials.
     3
     4It is included into Polynomial_ram.pxi and Polynomial_unram.pxi,
     5where functions that depend on the ramification of the defining polynomial are placed.
     6
     7.. NOTE::
     8
     9    There are no doctests in this file since the functions here can not be
     10    called directly from Python. Testing of this function is necessarily
     11    indirect and mostly done through arithmetic black-box tests that are part
     12    of the test suites of the `p`-adic parents.
     13
     14AUTHORS:
     15
     16- David Roe, Julian Rüth (2017-06-11): initial version
     17
     18"""
     19#*****************************************************************************
     20#       Copyright (C) 2017 David Roe <roed.math@gmail.com>
     21#                     2017 Julian Rüth <julian.rueth@fsfe.org>
     22#
     23#  Distributed under the terms of the GNU General Public License (GPL)
     24#  as published by the Free Software Foundation; either version 2 of
     25#  the License, or (at your option) any later version.
     26#
     27#                  http://www.gnu.org/licenses/
     28#*****************************************************************************
     29from cpython.list cimport *
     30from sage.rings.integer cimport Integer
     31from sage.rings.rational cimport Rational
     32from sage.rings.all import ZZ, QQ
     33from sage.ext.stdsage cimport PY_NEW
     34from copy import copy
     35from sage.rings.padics.common_conversion cimport cconv_mpz_t_out_shared, cconv_mpz_t_shared, cconv_mpq_t_out_shared, cconv_mpq_t_shared, cconv_shared
     36
     37cdef inline int cconstruct(celement value, PowComputer_ prime_pow) except -1:
     38    r"""
     39    Construct a new element.
     40
     41    INPUT:
     42
     43    - ``value`` -- a ``celement`` to be initialized
     44
     45    - ``prime_pow`` -- the ``PowComputer`` for the ring
     46
     47    .. NOTE::
     48
     49        For Polynomial elements, this function calls the ``__init__`` method of
     50        ``celement``. When creating ``celement`` instances, we use ``__new__`` which
     51        does not call ``__init__``, because of the metaclass that we are using.
     52
     53    """
     54    value.__init__(prime_pow.poly_ring)
     55
     56cdef inline int cdestruct(celement value, PowComputer_ prime_pow) except -1:
     57    r"""
     58    Deallocate ``value``.
     59
     60    INPUT:
     61
     62    - ``value`` -- a ``celement`` to be cleared
     63
     64    - ``prime_pow`` -- the ``PowComputer`` for the ring
     65
     66    .. NOTE::
     67
     68        This function has no effect for polynomials. There is no manual garbage
     69        collection necessary, as ``celement`` is a managed Python type.
     70
     71    """
     72    pass
     73
     74cdef inline int ccmp(celement a, celement b, long prec, bint reduce_a, bint reduce_b, PowComputer_ prime_pow) except -2:
     75    r"""
     76    Return the comparison of ``a`` and ``b``.
     77
     78    This function returns -1, 0, or 1 for use with ``cmp`` of Python 2. In
     79    particular, this function return 0 if ``a`` and ``b`` differ by an element
     80    of valuation at least ``prec``.
     81
     82    .. NOTE::
     83
     84        You should not rely on whether this function returns -1 or 1 as this
     85        might not be consistent.
     86
     87    INPUT:
     88
     89    - ``a`` -- a ``celement``
     90
     91    - ``b`` -- a ``celement``
     92
     93    - ``prec`` -- a ``long``, the precision to which the comparison should be
     94      performed
     95
     96    - ``reduce_a`` -- whether ``a`` is already reduced with respect to ``prec``
     97
     98    - ``reduce_b`` -- whether ``b`` is already reduced with respect to ``prec``
     99
     100    - ``prime_pow`` -- the ``PowComputer`` for the ring
     101
     102    """
     103    if not (reduce_a or reduce_b):
     104        return 0 if a == b else 1
     105    ccopy(prime_pow.tmp_ccmp_a, a, prime_pow)
     106    ccopy(prime_pow.tmp_ccmp_b, b, prime_pow)
     107
     108    if reduce_a:
     109        creduce(prime_pow.tmp_ccmp_a, prime_pow.tmp_ccmp_a, prec, prime_pow)
     110    if reduce_b:
     111        creduce(prime_pow.tmp_ccmp_b, prime_pow.tmp_ccmp_b, prec, prime_pow)
     112
     113    return 0 if prime_pow.tmp_ccmp_a == prime_pow.tmp_ccmp_b else 1
     114
     115cdef inline long cremove(celement out, celement a, long prec, PowComputer_ prime_pow) except -1:
     116    r"""
     117    Extract the maximum power of the uniformizer dividing ``a``.
     118
     119    INPUT:
     120
     121    - ``out`` -- a ``celement`` to store the unit part
     122
     123    - ``a`` -- the ``celement`` whose valuation and unit are desired
     124
     125    - ``prec`` -- a ``long``, the return value if ``a`` is zero
     126
     127    - ``prime_pow`` -- the ``PowComputer`` for the ring
     128
     129    OUTPUT:
     130
     131    The number of times the uniformizer divides ``a``, or ``prec`` if ``a`` is
     132    zero.
     133
     134    """
     135    if a == 0:
     136        return prec
     137    cdef long v = cvaluation(a, prec, prime_pow)
     138    cshift(out, a, -v, prec, prime_pow, True)
     139    return v
     140
     141cdef inline bint cisunit(celement a, PowComputer_ prime_pow) except -1:
     142    r"""
     143    Return whether ``a`` has valuation zero.
     144
     145    INPUT:
     146
     147    - ``a`` -- the ``celement`` to test
     148
     149    - ``prime_pow`` -- the ``PowComputer`` for the ring
     150
     151    """
     152    return cvaluation(a, 1, prime_pow) == 0
     153
     154cdef inline int cneg(celement out, celement a, long prec, PowComputer_ prime_pow) except -1:
     155    r"""
     156    Set ``out`` to the negative of ``a``.
     157
     158    Note that no reduction is performed.
     159
     160    INPUT:
     161
     162    - ``out`` -- a ``celement`` to store the negation
     163
     164    - ``a`` -- a ``celement`` to be negated
     165
     166    - ``prec`` -- a ``long``, the precision
     167
     168    - ``prime_pow`` -- the ``PowComputer`` for the ring
     169
     170    """
     171    out.__coeffs = (<celement?>(-a)).__coeffs
     172
     173cdef inline int cadd(celement out, celement a, celement b, long prec, PowComputer_ prime_pow) except -1:
     174    r"""
     175    Set ``out`` to the sum of ``a + b``.
     176
     177    Note that no reduction is performed.
     178
     179    INPUT:
     180
     181    - ``out`` -- a ``celement`` to store the sum
     182
     183    - ``a`` -- a ``celement``, the first summand
     184
     185    - ``b`` -- a ``celement``, the second summand
     186
     187    - ``prec`` -- a ``long``, the precision
     188
     189    - ``prime_pow`` -- the ``PowComputer`` for the ring
     190
     191    """
     192    out.__coeffs = (<celement?>(a + b)).__coeffs
     193
     194cdef inline int csub(celement out, celement a, celement b, long prec, PowComputer_ prime_pow) except -1:
     195    r"""
     196    Set ``out`` to the difference of ``a - b``.
     197
     198    Note that no reduction is performed.
     199
     200    INPUT:
     201
     202    - ``out`` -- a ``celement`` to store the difference
     203
     204    - ``a`` -- a ``celement``, the first input
     205
     206    - ``b`` -- a ``celement``, the second input
     207
     208    - ``prec`` -- a ``long``, the precision
     209
     210    - ``prime_pow`` -- the ``PowComputer`` for the ring
     211
     212    """
     213    out.__coeffs = (<celement?>(a - b)).__coeffs
     214
     215cdef inline int cmul(celement out, celement a, celement b, long prec, PowComputer_ prime_pow) except -1:
     216    r"""
     217    Set ``out`` to the product of ``a*b``.
     218
     219    Note that no reduction is performed.
     220
     221    INPUT:
     222
     223    - ``out`` -- a ``celement`` to store the product
     224
     225    - ``a`` -- a ``celement``, the first input
     226
     227    - ``b`` -- a ``celement``, the second input
     228
     229    - ``prec`` -- a ``long``, the precision
     230
     231    - ``prime_pow`` -- the ``PowComputer`` for the ring
     232
     233    """
     234    out.__coeffs = (<celement?>(a*b)).__coeffs
     235
     236cdef inline int csetone(celement out, PowComputer_ prime_pow) except -1:
     237    r"""
     238    Set ``out`` to 1.
     239
     240    INPUT:
     241
     242    - ``out`` -- the ``celement`` in which to store 1
     243
     244    - ``prime_pow`` -- the ``PowComputer`` for the ring
     245
     246    """
     247    out.__coeffs = [prime_pow.base_ring(1)]
     248
     249cdef inline int csetzero(celement out, PowComputer_ prime_pow) except -1:
     250    r"""
     251    Set ``out`` to 0.
     252
     253    INPUT:
     254
     255    - ``out`` -- the ``celement`` in which to store 0
     256
     257    - ``prime_pow`` -- the ``PowComputer`` for the ring
     258
     259    """
     260    out.__coeffs = []
     261
     262cdef inline bint cisone(celement a, PowComputer_ prime_pow) except -1:
     263    r"""
     264    Return whether ``a`` is equal to 1.
     265
     266    INPUT:
     267
     268    - ``a`` -- the element to test
     269
     270    - ``prime_pow`` -- the ``PowComputer`` for the ring
     271
     272    """
     273    return a.is_one()
     274
     275cdef inline bint ciszero(celement a, PowComputer_ prime_pow) except -1:
     276    r"""
     277    Return whether ``a`` is equal to 0.
     278
     279    INPUT:
     280
     281    - ``a`` -- the element to test
     282
     283    - ``prime_pow`` -- the ``PowComputer`` for the ring
     284
     285    """
     286    return a.is_zero()
     287
     288cdef inline int ccopy(celement out, celement a, PowComputer_ prime_pow) except -1:
     289    r"""
     290    Copy ``a`` into ``out``.
     291
     292    INPUT:
     293
     294    - ``out`` -- the ``celement`` to store the result
     295
     296    - ``a`` -- the element from which to copy
     297
     298    - ``prime_pow`` -- the ``PowComputer`` for the ring
     299
     300    """
     301    out.__coeffs = a.__coeffs[:]
     302
     303cdef inline cpickle(celement a, PowComputer_ prime_pow):
     304    r"""
     305    Return a representation of ``a`` for pickling.
     306
     307    INPUT:
     308
     309    - ``a`` the element to pickle
     310
     311    - ``prime_pow`` the ``PowComputer`` for the ring
     312
     313    """
     314    return a.__coeffs
     315
     316cdef inline int cunpickle(celement out, x, PowComputer_ prime_pow) except -1:
     317    r"""
     318    Reconstruct from the output of :meth:`cpickle`.
     319
     320    INPUT:
     321
     322    - ``out`` -- the ``celement`` in which to store the result
     323
     324    - ``x`` -- the result of `meth`:cpickle
     325
     326    - ``prime_pow`` -- the ``PowComputer`` for the ring
     327
     328    """
     329    out.__coeffs = x
     330
     331cdef inline long chash(celement a, long ordp, long prec, PowComputer_ prime_pow) except -1:
     332    r"""
     333    Return a hash value for ``a``.
     334
     335    INPUT:
     336
     337    - ``a`` -- the element to hash
     338
     339    - ``ordp`` -- the valuation as a ``long``
     340
     341    - ``prec`` -- the precision as a ``long``
     342
     343    - ``prime_pow`` -- the ``PowComputer`` for the ring
     344
     345    """
     346    if ciszero(a, prime_pow):
     347        return 0
     348
     349    return hash((a._cache_key(), ordp, prec))
     350
     351cdef list ccoefficients(celement x, long valshift, long prec, PowComputer_ prime_pow):
     352    """
     353    Return a list of coefficients, as elements that can be converted into the base ring.
     354
     355    INPUT:
     356
     357    - ``x`` -- a ``celement`` giving the underlying `p`-adic element, or possibly its unit part.
     358    - ``valshift`` -- a long giving the power of the uniformizer to shift `x` by.
     359    - ``prec`` -- a long, the (relative) precision desired, used in rational reconstruction
     360    - ``prime_pow`` -- the Powcomputer of the ring
     361    """
     362    return x.list()
     363
     364cdef int cconv(celement out, x, long prec, long valshift, PowComputer_ prime_pow) except -2:
     365    r"""
     366    Convert ``x`` to a `p`-adic element and store it in ``out``.
     367
     368    INPUT:
     369
     370    - ``out`` -- a ``celement`` to store the output
     371
     372    - ``x`` -- a Sage element that can be converted to a `p`-adic element
     373
     374    - ``prec`` -- a ``long``, giving the precision desired: absolute if `valshift =
     375      0`, relative if `valshift > 0`
     376
     377    - ``valshift`` -- the power of the uniformizer to divide by before storing
     378      the result in ``out``
     379
     380    - ``prime_pow`` -- a ``PowComputer`` for the ring
     381
     382    """
     383    out.__coeffs = (<celement?>prime_pow.poly_ring(x)).__coeffs
     384    creduce(out, out, prec, prime_pow)
     385    cshift(out, out, valshift, prec, prime_pow, True)
     386
     387cdef inline long cconv_mpz_t(celement out, mpz_t x, long prec, bint absolute, PowComputer_ prime_pow) except -2:
     388    r"""
     389    Set ``out`` to the integer ``x``.
     390
     391    This function provides a fast pathway for conversion of integers that
     392    doesn't require precomputation of the valuation.
     393
     394    INPUT:
     395
     396    - ``out`` -- a ``celement`` to store the output
     397
     398    - ``x`` -- n ``mpz_t`` giving the integer to be converted
     399
     400    - ``prec`` -- a ``long``, giving the precision desired: absolute or relative
     401      depending on the ``absolute`` input
     402
     403    - ``absolute`` -- if ``False`` then extracts the valuation and returns it,
     404      storing the unit in ``out``; if ``True`` then just reduces ``x`` modulo
     405      the precision.
     406
     407    - ``prime_pow`` -- a ``PowComputer`` for the ring
     408
     409    OUTPUT:
     410
     411    If ``absolute`` is ``False``, the valuation that was extracted (``maxordp``
     412    when `x = 0`).
     413
     414    """
     415    cdef long valuation = maxordp
     416
     417    cdef Integer n = PY_NEW(Integer)
     418    mpz_set(n.value, x)
     419
     420    if n:
     421        out.__coeffs = [prime_pow.base_ring(n)]
     422        if not absolute:
     423            valuation = cremove(out, out, prec, prime_pow)
     424    else:
     425        out.__coeffs = []
     426
     427    return valuation
     428
     429cdef inline int cconv_mpz_t_out(mpz_t out, celement x, long valshift, long prec, PowComputer_ prime_pow) except -1:
     430    r"""
     431    Set ``out`` to the integer approximated by ``x``.
     432
     433    INPUT:
     434
     435    - ``out`` -- stores the resulting integer as an integer between 0 and
     436      `p^{\mathrm{prec} + \mathrm{valshift}}`
     437
     438    - ``x`` -- a ``celement`` giving the underlying `p`-adic element
     439
     440    - ``valshift`` -- a ``long`` giving the power of the uniformizer to shift ``x`` by
     441
     442    -` ``prec`` -- a ``long``, the precision of ``x`` and ``out``
     443
     444    - ``prime_pow`` -- a ``PowComputer`` for the ring
     445
     446    """
     447    cdef Integer n
     448
     449    if valshift:
     450        cshift(prime_pow.powhelper_cconv_out, x, valshift, prec, prime_pow, True)
     451    else:
     452        prime_pow.powhelper_cconv_out = x
     453
     454    if len(prime_pow.powhelper_cconv_out.__coeffs) == 0:
     455        mpz_set_ui(out, 0)
     456    elif len(prime_pow.powhelper_cconv_out.__coeffs) == 1:
     457        # recursively let the underlying polynomial convert the constant
     458        # coefficient to an integer (if possible)
     459        n = ZZ(prime_pow.powhelper_cconv_out.__coeffs[0])
     460        mpz_set(out, n.value)
     461    else:
     462        raise ValueError("cannot convert to integer")
     463
     464cdef inline long cconv_mpq_t(celement out, mpq_t x, long prec, bint absolute, PowComputer_ prime_pow) except? -10000:
     465    r"""
     466    Set ``out`` to the rational ``x``.
     467
     468    A fast pathway for conversion of rationals that doesn't require
     469    precomputation of the valuation.
     470
     471    INPUT:
     472
     473    - ``out`` -- a ``celement`` to store the output
     474
     475    - ``x`` -- an ``mpq_t`` giving the rational to be converted
     476
     477    - ``prec`` -- a ``long``, giving the precision desired: absolute or relative
     478      depending on ``absolute``
     479
     480    - ``absolute`` -- if ``False`` then extracts the valuation and returns it,
     481      storing the unit in ``out``; if ``True`` then just reduces ``x`` modulo the
     482      precision.
     483
     484    - ``prime_pow`` -- a ``PowComputer`` for the ring
     485
     486    OUTPUT:
     487
     488    If ``absolute`` is ``False``, the valuation that was extracted (``maxordp``
     489    when `x = 0`)
     490
     491    """
     492    cdef Rational r = PY_NEW(Rational)
     493    mpq_set(r.value, x)
     494    out.__coeffs = [prime_pow.base_ring(r)]
     495
     496    if absolute:
     497        creduce(out, out, prec, prime_pow)
     498    else:
     499        return cremove(out, out, prec, prime_pow)
     500
     501cdef inline int cconv_mpq_t_out(mpq_t out, celement x, long valshift, long prec, PowComputer_ prime_pow) except -1:
     502    r"""
     503    Set ``out`` to the rational approximated by ``x``.
     504
     505    INPUT:
     506
     507    - ``out`` -- set to a rational approximating the input.  Currently uses
     508      rational reconstruction but may change in the future to use a more naive
     509      method.
     510
     511    - ``x`` -- a ``celement``, the element to convert
     512
     513    - ``valshift`` -- a ``long`` giving the power of the uniformizer to shift `x`
     514      by before converting
     515
     516    - ``prec`` -- a long, the precision of ``x``; ignored
     517
     518    - ``prime_pow`` -- a ``PowComputer`` for the ring
     519
     520    """
     521    cdef Rational c
     522
     523    if valshift:
     524        cshift(prime_pow.powhelper_cconv_out, x, valshift, prec, prime_pow, True)
     525    else:
     526        prime_pow.powhelper_cconv_out = x
     527
     528    if len(prime_pow.powhelper_cconv_out.__coeffs) == 0:
     529        mpq_set_ui(out, 0, 1)
     530    elif len(prime_pow.powhelper_cconv_out.__coeffs) == 1:
     531        # recursively let the underlying polynomial convert the constant
     532        # coefficient to a rational (if possible)
     533        c = QQ(prime_pow.powhelper_cconv_out.__coeffs[0])
     534        mpq_set(out, c.value)
     535    else:
     536        raise ValueError("cannot convert to ratioal")
  • src/sage/misc/cachefunc.pyx

    diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx
    index 2f70a5ba3d..d6f30ef01d 100644
    a b attribute ``__cached_methods`` of type ``<dict>``. Since 
    9090:trac:`11115`, this is the case for all classes inheriting from
    9191:class:`~sage.structure.parent.Parent`. See below for a more explicit
    9292example. By :trac:`12951`, cached methods of extension classes can
    93 be defined by simply using the decorater. However, an indirect
     93be defined by simply using the decorator. However, an indirect
    9494approach is still needed for cpdef methods::
    9595
    9696    sage: cython_code = ['cpdef test_meth(self,x):',
  • src/sage/rings/finite_rings/finite_field_base.pyx

    diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx
    index b93eeacef3..f7546c31b3 100644
    a b cdef class FiniteField(Field): 
    10651065                elif (R.degree().divides(self.degree())
    10661066                      and hasattr(self, '_prefix') and hasattr(R, '_prefix')):
    10671067                    return R.hom((self.gen() ** ((self.order() - 1)//(R.order() - 1)),))
     1068        from sage.rings.padics.padic_generic import pAdicGeneric, ResidueReductionMap
     1069        if isinstance(R, pAdicGeneric) and not R.is_field() and R.residue_field() is self:
     1070            return ResidueReductionMap(R, self)
     1071
     1072    def _convert_map_from_(self, R):
     1073        from sage.rings.padics.padic_generic import pAdicGeneric, ResidueReductionMap
     1074        if isinstance(R, pAdicGeneric) and R.residue_field() is self:
     1075            return ResidueReductionMap(R, self)
    10681076
    10691077    def construction(self):
    10701078        """
  • src/sage/rings/finite_rings/finite_field_prime_modn.py

    diff --git a/src/sage/rings/finite_rings/finite_field_prime_modn.py b/src/sage/rings/finite_rings/finite_field_prime_modn.py
    index 0db8bf5cec..2a325d1a4f 100644
    a b class FiniteField_prime_modn(FiniteField_generic, integer_mod_ring.IntegerModRin 
    141141                    return integer_mod.IntegerMod_to_IntegerMod(S, self)
    142142                except TypeError:
    143143                    pass
     144        from sage.rings.padics.padic_generic import pAdicGeneric, ResidueReductionMap
     145        if isinstance(S, pAdicGeneric) and not S.is_field() and S.residue_field() is self:
     146            return ResidueReductionMap(S, self)
    144147        to_ZZ = ZZ._internal_coerce_map_from(S)
    145148        if to_ZZ is not None:
    146149            return integer_mod.Integer_to_IntegerMod(self) * to_ZZ
    147150
     151    def _convert_map_from_(self, R):
     152        from sage.rings.padics.padic_generic import pAdicGeneric, ResidueReductionMap
     153        if isinstance(R, pAdicGeneric) and R.residue_field() is self:
     154            return ResidueReductionMap(R, self)
     155
    148156    def construction(self):
    149157        """
    150158        Returns the construction of this finite field (for use by sage.categories.pushout)
  • src/sage/rings/padics/CA_template.pxi

    diff --git a/src/sage/rings/padics/CA_template.pxi b/src/sage/rings/padics/CA_template.pxi
    index 9fae4335ce..59cd794217 100644
    a b cdef class CAElement(pAdicTemplateElement): 
    7777            4*5^2 + 2*5^3 + O(5^5)
    7878        """
    7979        cconstruct(self.value, self.prime_pow)
    80         cdef long rprec = comb_prec(relprec, self.prime_pow.prec_cap)
    81         cdef long aprec = comb_prec(absprec, min(self.prime_pow.prec_cap, xprec))
     80        cdef long rprec = comb_prec(relprec, self.prime_pow.ram_prec_cap)
     81        cdef long aprec = comb_prec(absprec, min(self.prime_pow.ram_prec_cap, xprec))
    8282        if aprec <= val:
    8383            csetzero(self.value, self.prime_pow)
    8484            self.absprec = aprec
    cdef class CAElement(pAdicTemplateElement): 
    117117            ...
    118118            PrecisionError: Precision higher than allowed by the precision cap.
    119119        """
    120         if self.absprec > self.prime_pow.prec_cap:
     120        if self.absprec > self.prime_pow.ram_prec_cap:
    121121            raise PrecisionError("Precision higher than allowed by the precision cap.")
    122122
    123123    def __copy__(self):
    cdef class CAElement(pAdicTemplateElement): 
    260260        cdef CAElement right = _right
    261261        cdef CAElement ans = self._new_c()
    262262        cdef long vals, valr
    263         if self.absprec == self.prime_pow.prec_cap and right.absprec == self.prime_pow.prec_cap:
     263        if self.absprec == self.prime_pow.ram_prec_cap and right.absprec == self.prime_pow.ram_prec_cap:
    264264            ans.absprec = self.absprec
    265265        else:
    266266            vals = self.valuation_c()
    267267            valr = right.valuation_c()
    268             ans.absprec = min(vals + valr + min(self.absprec - vals, right.absprec - valr), self.prime_pow.prec_cap)
     268            ans.absprec = min(vals + valr + min(self.absprec - vals, right.absprec - valr), self.prime_pow.ram_prec_cap)
    269269        cmul(ans.value, self.value, right.value, ans.absprec, ans.prime_pow)
    270270        creduce(ans.value, ans.value, ans.absprec, ans.prime_pow)
    271271        return ans
    cdef class CAElement(pAdicTemplateElement): 
    449449        elif shift == 0:
    450450            return self
    451451        cdef CAElement ans = self._new_c()
    452         if shift >= self.prime_pow.prec_cap:
     452        if shift >= self.prime_pow.ram_prec_cap:
    453453            csetzero(ans.value, ans.prime_pow)
    454             ans.absprec = self.prime_pow.prec_cap
     454            ans.absprec = self.prime_pow.ram_prec_cap
    455455        else:
    456             ans.absprec = min(self.absprec + shift, self.prime_pow.prec_cap)
     456            ans.absprec = min(self.absprec + shift, self.prime_pow.ram_prec_cap)
    457457            cshift(ans.value, self.value, shift, ans.absprec, ans.prime_pow, False)
    458458        return ans
    459459
    cdef class CAElement(pAdicTemplateElement): 
    712712        """
    713713        cdef CAElement ans
    714714        if absprec == maxordp:
    715             absprec = self.prime_pow.prec_cap
     715            absprec = self.prime_pow.ram_prec_cap
    716716        if absprec <= self.absprec:
    717717            return self
    718718        ans = self._new_c()
    cdef class CAElement(pAdicTemplateElement): 
    971971        """
    972972        if self.valuation_c() > 0:
    973973            csetzero(self.value, self.prime_pow)
    974             self.absprec = self.prime_pow.prec_cap
     974            self.absprec = self.prime_pow.ram_prec_cap
    975975        elif self.absprec == 0:
    976976            raise ValueError("not enough precision")
    977977        else:
    cdef class pAdicCoercion_ZZ_CA(RingHomomorphism): 
    12091209        if mpz_sgn((<Integer>x).value) == 0:
    12101210            return self._zero
    12111211        cdef CAElement ans = self._zero._new_c()
    1212         ans.absprec = ans.prime_pow.prec_cap
     1212        ans.absprec = ans.prime_pow.ram_prec_cap
    12131213        cconv_mpz_t(ans.value, (<Integer>x).value, ans.absprec, True, ans.prime_pow)
    12141214        return ans
    12151215
    cdef class pAdicCoercion_ZZ_CA(RingHomomorphism): 
    12431243        cdef CAElement ans
    12441244        _process_args_and_kwds(&aprec, &rprec, args, kwds, True, self._zero.prime_pow)
    12451245        if mpz_sgn((<Integer>x).value) == 0:
    1246             if aprec >= self._zero.prime_pow.prec_cap:
     1246            if aprec >= self._zero.prime_pow.ram_prec_cap:
    12471247                return self._zero
    12481248            ans = self._zero._new_c()
    12491249            csetzero(ans.value, ans.prime_pow)
    cdef class pAdicConvert_QQ_CA(Morphism): 
    14001400        if mpq_sgn((<Rational>x).value) == 0:
    14011401            return self._zero
    14021402        cdef CAElement ans = self._zero._new_c()
    1403         cconv_mpq_t(ans.value, (<Rational>x).value, ans.prime_pow.prec_cap, True, ans.prime_pow)
    1404         ans.absprec = ans.prime_pow.prec_cap
     1403        cconv_mpq_t(ans.value, (<Rational>x).value, ans.prime_pow.ram_prec_cap, True, ans.prime_pow)
     1404        ans.absprec = ans.prime_pow.ram_prec_cap
    14051405        return ans
    14061406
    14071407    cpdef Element _call_with_args(self, x, args=(), kwds={}):
    cdef class pAdicConvert_QQ_CA(Morphism): 
    14361436        cdef CAElement ans
    14371437        _process_args_and_kwds(&aprec, &rprec, args, kwds, True, self._zero.prime_pow)
    14381438        if mpq_sgn((<Rational>x).value) == 0:
    1439             if aprec >= self._zero.prime_pow.prec_cap:
     1439            if aprec >= self._zero.prime_pow.ram_prec_cap:
    14401440                return self._zero
    14411441            ans = self._zero._new_c()
    14421442            csetzero(ans.value, ans.prime_pow)
  • src/sage/rings/padics/CR_template.pxi

    diff --git a/src/sage/rings/padics/CR_template.pxi b/src/sage/rings/padics/CR_template.pxi
    index 33ab3b8c59..974a88d930 100644
    a b cdef class CRElement(pAdicTemplateElement): 
    134134            2 + 3*5 + O(5^5)
    135135        """
    136136        cconstruct(self.unit, self.prime_pow)
    137         cdef long rprec = comb_prec(relprec, self.prime_pow.prec_cap)
     137        cdef long rprec = comb_prec(relprec, self.prime_pow.ram_prec_cap)
    138138        cdef long aprec = comb_prec(absprec, xprec)
    139139        if aprec <= val: # this may also hit an exact zero, if aprec == val == maxordp
    140140            self._set_inexact_zero(aprec)
    cdef class CRElement(pAdicTemplateElement): 
    203203            ...
    204204            PrecisionError: Precision higher than allowed by the precision cap.
    205205        """
    206         if self.relprec > self.prime_pow.prec_cap:
     206        if self.relprec > self.prime_pow.ram_prec_cap:
    207207            raise PrecisionError("Precision higher than allowed by the precision cap.")
    208208
    209209    def __copy__(self):
    cdef class CRElement(pAdicTemplateElement): 
    11481148                ans._set_exact_zero()
    11491149                return ans
    11501150            else:
    1151                 absprec = self.ordp + self.prime_pow.prec_cap
     1151                absprec = self.ordp + self.prime_pow.ram_prec_cap
    11521152        cdef long relprec = absprec - self.ordp
    11531153        if relprec <= self.relprec:
    11541154            return self
    cdef class pAdicCoercion_ZZ_CR(RingHomomorphism): 
    17501750        if mpz_sgn((<Integer>x).value) == 0:
    17511751            return self._zero
    17521752        cdef CRElement ans = self._zero._new_c()
    1753         ans.relprec = ans.prime_pow.prec_cap
     1753        ans.relprec = ans.prime_pow.ram_prec_cap
    17541754        ans.ordp = cconv_mpz_t(ans.unit, (<Integer>x).value, ans.relprec, False, ans.prime_pow)
    17551755        return ans
    17561756
    cdef class pAdicCoercion_QQ_CR(RingHomomorphism): 
    19701970        if mpq_sgn((<Rational>x).value) == 0:
    19711971            return self._zero
    19721972        cdef CRElement ans = self._zero._new_c()
    1973         ans.relprec = ans.prime_pow.prec_cap
     1973        ans.relprec = ans.prime_pow.ram_prec_cap
    19741974        ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, ans.relprec, False, self._zero.prime_pow)
    19751975        return ans
    19761976
    cdef class pAdicConvert_QQ_CR(Morphism): 
    21682168        if mpq_sgn((<Rational>x).value) == 0:
    21692169            return self._zero
    21702170        cdef CRElement ans = self._zero._new_c()
    2171         ans.relprec = ans.prime_pow.prec_cap
     2171        ans.relprec = ans.prime_pow.ram_prec_cap
    21722172        ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, ans.relprec, False, self._zero.prime_pow)
    21732173        if ans.ordp < 0:
    21742174            raise ValueError("p divides the denominator")
  • src/sage/rings/padics/FM_template.pxi

    diff --git a/src/sage/rings/padics/FM_template.pxi b/src/sage/rings/padics/FM_template.pxi
    index 14cd3cacb8..b5391c4cf4 100644
    a b cdef class FMElement(pAdicTemplateElement): 
    8585        if isinstance(x,FMElement) and x.parent() is self.parent():
    8686            cshift(self.value, (<FMElement>x).value, 0, 0, self.prime_pow, False)
    8787        else:
    88             cconv(self.value, x, self.prime_pow.prec_cap, 0, self.prime_pow)
     88            cconv(self.value, x, self.prime_pow.ram_prec_cap, 0, self.prime_pow)
    8989
    9090    cdef FMElement _new_c(self):
    9191        """
    cdef class FMElement(pAdicTemplateElement): 
    169169            6*7 + 6*7^2 + 6*7^3 + O(7^4)
    170170        """
    171171        cdef FMElement ans = self._new_c()
    172         cneg(ans.value, self.value, ans.prime_pow.prec_cap, ans.prime_pow)
    173         creduce_small(ans.value, ans.value, ans.prime_pow.prec_cap, ans.prime_pow)
     172        cneg(ans.value, self.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
     173        creduce_small(ans.value, ans.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    174174        return ans
    175175
    176176    cpdef _add_(self, _right):
    cdef class FMElement(pAdicTemplateElement): 
    189189        """
    190190        cdef FMElement right = _right
    191191        cdef FMElement ans = self._new_c()
    192         cadd(ans.value, self.value, right.value, ans.prime_pow.prec_cap, ans.prime_pow)
    193         creduce_small(ans.value, ans.value, ans.prime_pow.prec_cap, ans.prime_pow)
     192        cadd(ans.value, self.value, right.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
     193        creduce_small(ans.value, ans.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    194194        return ans
    195195
    196196    cpdef _sub_(self, _right):
    cdef class FMElement(pAdicTemplateElement): 
    209209        """
    210210        cdef FMElement right = _right
    211211        cdef FMElement ans = self._new_c()
    212         csub(ans.value, self.value, right.value, ans.prime_pow.prec_cap, ans.prime_pow)
    213         creduce_small(ans.value, ans.value, ans.prime_pow.prec_cap, ans.prime_pow)
     212        csub(ans.value, self.value, right.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
     213        creduce_small(ans.value, ans.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    214214        return ans
    215215
    216216    def __invert__(self):
    cdef class FMElement(pAdicTemplateElement): 
    235235        if not cisunit(self.value, self.prime_pow):
    236236            raise ValueError("cannot invert non-unit")
    237237        cdef FMElement ans = self._new_c()
    238         cinvert(ans.value, self.value, ans.prime_pow.prec_cap, ans.prime_pow)
     238        cinvert(ans.value, self.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    239239        return ans
    240240
    241241    cpdef _mul_(self, _right):
    cdef class FMElement(pAdicTemplateElement): 
    252252        """
    253253        cdef FMElement right = _right
    254254        cdef FMElement ans = self._new_c()
    255         cmul(ans.value, self.value, right.value, ans.prime_pow.prec_cap, ans.prime_pow)
    256         creduce(ans.value, ans.value, ans.prime_pow.prec_cap, ans.prime_pow)
     255        cmul(ans.value, self.value, right.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
     256        creduce(ans.value, ans.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    257257        return ans
    258258
    259259    cpdef _div_(self, _right):
    cdef class FMElement(pAdicTemplateElement): 
    279279        cdef FMElement ans = self._new_c()
    280280        if not cisunit(right.value, self.prime_pow):
    281281            raise ValueError("cannot invert non-unit")
    282         cdivunit(ans.value, self.value, right.value, ans.prime_pow.prec_cap, ans.prime_pow)
    283         creduce(ans.value, ans.value, ans.prime_pow.prec_cap, ans.prime_pow)
     282        cdivunit(ans.value, self.value, right.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
     283        creduce(ans.value, ans.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    284284        return ans
    285285
    286     def __pow__(FMElement self, _right, dummy): # NOTE: dummy ignored, always use self.prime_pow.prec_cap
     286    def __pow__(FMElement self, _right, dummy): # NOTE: dummy ignored, always use self.prime_pow.ram_prec_cap
    287287        """
    288288        Exponentiation by an integer
    289289
    cdef class FMElement(pAdicTemplateElement): 
    313313        if right < 0:
    314314            self = ~self
    315315            mpz_neg(right.value, right.value)
    316         cpow(ans.value, self.value, right.value, self.prime_pow.prec_cap, self.prime_pow)
     316        cpow(ans.value, self.value, right.value, self.prime_pow.ram_prec_cap, self.prime_pow)
    317317        return ans
    318318
    319319    cdef pAdicTemplateElement _lshift_c(self, long shift):
    cdef class FMElement(pAdicTemplateElement): 
    357357        elif shift == 0:
    358358            return self
    359359        cdef FMElement ans = self._new_c()
    360         if shift >= self.prime_pow.prec_cap:
     360        if shift >= self.prime_pow.ram_prec_cap:
    361361            csetzero(ans.value, ans.prime_pow)
    362362        else:
    363             cshift(ans.value, self.value, shift, ans.prime_pow.prec_cap, ans.prime_pow, False)
     363            cshift(ans.value, self.value, shift, ans.prime_pow.ram_prec_cap, ans.prime_pow, False)
    364364        return ans
    365365
    366366    cdef pAdicTemplateElement _rshift_c(self, long shift):
    cdef class FMElement(pAdicTemplateElement): 
    391391        elif shift == 0:
    392392            return self
    393393        cdef FMElement ans = self._new_c()
    394         if shift >= self.prime_pow.prec_cap:
     394        if shift >= self.prime_pow.ram_prec_cap:
    395395            csetzero(ans.value, ans.prime_pow)
    396396        else:
    397             cshift(ans.value, self.value, -shift, ans.prime_pow.prec_cap, ans.prime_pow, False)
     397            cshift(ans.value, self.value, -shift, ans.prime_pow.ram_prec_cap, ans.prime_pow, False)
    398398        return ans
    399399
    400400    def add_bigoh(self, absprec):
    cdef class FMElement(pAdicTemplateElement): 
    421421            if not isinstance(absprec, Integer):
    422422                absprec = Integer(absprec)
    423423            aprec = mpz_get_si((<Integer>absprec).value)
    424         if aprec >= self.prime_pow.prec_cap:
     424        if aprec >= self.prime_pow.ram_prec_cap:
    425425            return self
    426426        cdef FMElement ans = self._new_c()
    427427        creduce(ans.value, self.value, aprec, ans.prime_pow)
    cdef class FMElement(pAdicTemplateElement): 
    476476            return iszero
    477477        if not isinstance(absprec, Integer):
    478478            absprec = Integer(absprec)
    479         if mpz_cmp_si((<Integer>absprec).value, self.prime_pow.prec_cap) >= 0:
     479        if mpz_cmp_si((<Integer>absprec).value, self.prime_pow.ram_prec_cap) >= 0:
    480480            return iszero
    481481        cdef long val = self.valuation_c()
    482482        return mpz_cmp_si((<Integer>absprec).value, val) <= 0
    cdef class FMElement(pAdicTemplateElement): 
    528528            right = self.parent()(_right)
    529529        if absprec is None:
    530530            # The default absolute precision is given by the precision cap
    531             aprec = self.prime_pow.prec_cap
     531            aprec = self.prime_pow.ram_prec_cap
    532532        else:
    533533            if not isinstance(absprec, Integer):
    534534                absprec = Integer(absprec)
    cdef class FMElement(pAdicTemplateElement): 
    538538                return True
    539539            # If absprec is bigger than the precision cap, we use it
    540540            # instead.
    541             if mpz_cmp_si((<Integer>absprec).value, self.prime_pow.prec_cap) >= 0:
    542                 aprec = self.prime_pow.prec_cap
     541            if mpz_cmp_si((<Integer>absprec).value, self.prime_pow.ram_prec_cap) >= 0:
     542                aprec = self.prime_pow.ram_prec_cap
    543543            else:
    544544                aprec = mpz_get_si((<Integer>absprec).value)
    545545        return ccmp(self.value,
    546546                    right.value,
    547547                    aprec,
    548                     aprec < self.prime_pow.prec_cap,
    549                     aprec < right.prime_pow.prec_cap,
     548                    aprec < self.prime_pow.ram_prec_cap,
     549                    aprec < right.prime_pow.ram_prec_cap,
    550550                    self.prime_pow) == 0
    551551
    552552    cdef int _cmp_units(self, pAdicGenericElement _right) except -2:
    cdef class FMElement(pAdicTemplateElement): 
    563563            True
    564564        """
    565565        cdef FMElement right = _right
    566         return ccmp(self.value, right.value, self.prime_pow.prec_cap, False, False, self.prime_pow)
     566        return ccmp(self.value, right.value, self.prime_pow.ram_prec_cap, False, False, self.prime_pow)
    567567
    568568    cdef pAdicTemplateElement lift_to_precision_c(self, long absprec):
    569569        """
    cdef class FMElement(pAdicTemplateElement): 
    664664            else:
    665665                return self.teichmuller_expansion(n - self.valuation_c())
    666666        elif lift_mode == 'simple':
    667             vlist = clist(self.value, self.prime_pow.prec_cap, True, self.prime_pow)
     667            vlist = clist(self.value, self.prime_pow.ram_prec_cap, True, self.prime_pow)
    668668        elif lift_mode == 'smallest':
    669             vlist = clist(self.value, self.prime_pow.prec_cap, False, self.prime_pow)
     669            vlist = clist(self.value, self.prime_pow.ram_prec_cap, False, self.prime_pow)
    670670        else:
    671671            raise ValueError("unknown lift_mode")
    672672        if n is None:
    cdef class FMElement(pAdicTemplateElement): 
    708708            ans = PyList_New(0)
    709709            if ciszero(self.value, self.prime_pow):
    710710                return ans
    711         elif ciszero(self.value, self.prime_pow) or n < 0 or n >= self.prime_pow.prec_cap:
     711        elif ciszero(self.value, self.prime_pow) or n < 0 or n >= self.prime_pow.ram_prec_cap:
    712712            list_elt = self._new_c()
    713713            csetzero(list_elt.value, self.prime_pow)
    714714            return list_elt
    cdef class FMElement(pAdicTemplateElement): 
    716716            # We only need one list_elt
    717717            list_elt = self._new_c()
    718718        self = self.unit_part()
    719         cdef long curpower = self.prime_pow.prec_cap
    720         cdef long prec_cap = self.prime_pow.prec_cap
     719        cdef long curpower = self.prime_pow.ram_prec_cap
     720        cdef long prec_cap = self.prime_pow.ram_prec_cap
    721721        cdef long goal
    722722        if n is not None: goal = prec_cap - n
    723723        cdef FMElement tmp = self._new_c()
    cdef class FMElement(pAdicTemplateElement): 
    769769            O(17^5)
    770770        """
    771771        if cisunit(self.value, self.prime_pow):
    772             cteichmuller(self.value, self.value, self.prime_pow.prec_cap, self.prime_pow)
     772            cteichmuller(self.value, self.value, self.prime_pow.ram_prec_cap, self.prime_pow)
    773773        else:
    774774            csetzero(self.value, self.prime_pow)
    775775
    cdef class FMElement(pAdicTemplateElement): 
    813813            4
    814814        """
    815815        cdef Integer ans = Integer.__new__(Integer)
    816         mpz_set_si(ans.value, self.prime_pow.prec_cap)
     816        mpz_set_si(ans.value, self.prime_pow.ram_prec_cap)
    817817        return ans
    818818
    819819    def precision_relative(self):
    cdef class FMElement(pAdicTemplateElement): 
    828828            0
    829829        """
    830830        cdef Integer ans = Integer.__new__(Integer)
    831         mpz_set_si(ans.value, self.prime_pow.prec_cap - self.valuation_c())
     831        mpz_set_si(ans.value, self.prime_pow.ram_prec_cap - self.valuation_c())
    832832        return ans
    833833
    834834    cpdef pAdicTemplateElement unit_part(FMElement self):
    cdef class FMElement(pAdicTemplateElement): 
    853853            3 + O(5^5)
    854854        """
    855855        cdef FMElement ans = (<FMElement>self)._new_c()
    856         cremove(ans.value, (<FMElement>self).value, (<FMElement>self).prime_pow.prec_cap, (<FMElement>self).prime_pow)
     856        cremove(ans.value, (<FMElement>self).value, (<FMElement>self).prime_pow.ram_prec_cap, (<FMElement>self).prime_pow)
    857857        return ans
    858858
    859859    cdef long valuation_c(self):
    cdef class FMElement(pAdicTemplateElement): 
    885885            2
    886886        """
    887887        # for backward compatibility
    888         return cvaluation(self.value, self.prime_pow.prec_cap, self.prime_pow)
     888        return cvaluation(self.value, self.prime_pow.ram_prec_cap, self.prime_pow)
    889889
    890890    cpdef val_unit(self):
    891891        """
    cdef class FMElement(pAdicTemplateElement): 
    905905        """
    906906        cdef FMElement unit = self._new_c()
    907907        cdef Integer valuation = Integer.__new__(Integer)
    908         mpz_set_si(valuation.value, cremove(unit.value, self.value, self.prime_pow.prec_cap, self.prime_pow))
     908        mpz_set_si(valuation.value, cremove(unit.value, self.value, self.prime_pow.ram_prec_cap, self.prime_pow))
    909909        return valuation, unit
    910910
    911911    def __hash__(self):
    cdef class FMElement(pAdicTemplateElement): 
    918918            sage: hash(R(3)) == hash(3)
    919919            True
    920920        """
    921         return chash(self.value, 0, self.prime_pow.prec_cap, self.prime_pow)
     921        return chash(self.value, 0, self.prime_pow.ram_prec_cap, self.prime_pow)
    922922
    923923cdef class pAdicCoercion_ZZ_FM(RingHomomorphism):
    924924    """
    cdef class pAdicCoercion_ZZ_FM(RingHomomorphism): 
    10021002        if mpz_sgn((<Integer>x).value) == 0:
    10031003            return self._zero
    10041004        cdef FMElement ans = self._zero._new_c()
    1005         cconv_mpz_t(ans.value, (<Integer>x).value, ans.prime_pow.prec_cap, True, ans.prime_pow)
     1005        cconv_mpz_t(ans.value, (<Integer>x).value, ans.prime_pow.ram_prec_cap, True, ans.prime_pow)
    10061006        return ans
    10071007
    10081008    cpdef Element _call_with_args(self, x, args=(), kwds={}):
    cdef class pAdicCoercion_ZZ_FM(RingHomomorphism): 
    10411041        if mpz_sgn((<Integer>x).value) == 0:
    10421042            return self._zero
    10431043        cdef FMElement ans = self._zero._new_c()
    1044         cconv_mpz_t(ans.value, (<Integer>x).value, ans.prime_pow.prec_cap, True, ans.prime_pow)
     1044        cconv_mpz_t(ans.value, (<Integer>x).value, ans.prime_pow.ram_prec_cap, True, ans.prime_pow)
    10451045        return ans
    10461046
    10471047    def section(self):
    cdef class pAdicConvert_FM_ZZ(RingMap): 
    11051105        """
    11061106        cdef Integer ans = Integer.__new__(Integer)
    11071107        cdef FMElement x = _x
    1108         cconv_mpz_t_out(ans.value, x.value, 0, x.prime_pow.prec_cap, x.prime_pow)
     1108        cconv_mpz_t_out(ans.value, x.value, 0, x.prime_pow.ram_prec_cap, x.prime_pow)
    11091109        return ans
    11101110
    11111111cdef class pAdicConvert_QQ_FM(Morphism):
    cdef class pAdicConvert_QQ_FM(Morphism): 
    11831183        if mpq_sgn((<Rational>x).value) == 0:
    11841184            return self._zero
    11851185        cdef FMElement ans = self._zero._new_c()
    1186         cconv_mpq_t(ans.value, (<Rational>x).value, ans.prime_pow.prec_cap, True, ans.prime_pow)
     1186        cconv_mpq_t(ans.value, (<Rational>x).value, ans.prime_pow.ram_prec_cap, True, ans.prime_pow)
    11871187        return ans
    11881188
    11891189    cpdef Element _call_with_args(self, x, args=(), kwds={}):
    cdef class pAdicConvert_QQ_FM(Morphism): 
    12221222        if mpq_sgn((<Rational>x).value) == 0:
    12231223            return self._zero
    12241224        cdef FMElement ans = self._zero._new_c()
    1225         cconv_mpq_t(ans.value, (<Rational>x).value, ans.prime_pow.prec_cap, True, ans.prime_pow)
     1225        cconv_mpq_t(ans.value, (<Rational>x).value, ans.prime_pow.ram_prec_cap, True, ans.prime_pow)
    12261226        return ans
    12271227
    12281228def unpickle_fme_v2(cls, parent, value):
    12291229    """
    1230     Unpickles a capped relative element.
     1230    Unpickles a fixed mod element.
    12311231
    12321232    EXAMPLES::
    12331233
  • src/sage/rings/padics/FP_template.pxi

    diff --git a/src/sage/rings/padics/FP_template.pxi b/src/sage/rings/padics/FP_template.pxi
    index 6a01848453..daca07e2a6 100644
    a b cdef class FPElement(pAdicTemplateElement): 
    138138            if isinstance(x,FPElement) and x.parent() is self.parent():
    139139                ccopy(self.unit, (<FPElement>x).unit, self.prime_pow)
    140140            else:
    141                 cconv(self.unit, x, self.prime_pow.prec_cap, val, self.prime_pow)
     141                cconv(self.unit, x, self.prime_pow.ram_prec_cap, val, self.prime_pow)
    142142
    143143    cdef int _set_exact_zero(self) except -1:
    144144        """
    cdef class FPElement(pAdicTemplateElement): 
    226226        elif very_neg_val(self.ordp):
    227227            self._set_infinity()
    228228        else:
    229             is_zero = creduce(self.unit, self.unit, self.prime_pow.prec_cap, self.prime_pow)
     229            is_zero = creduce(self.unit, self.unit, self.prime_pow.ram_prec_cap, self.prime_pow)
    230230            if is_zero:
    231231                self.ordp = maxordp
    232232            else:
    233                 diff = cremove(self.unit, self.unit, self.prime_pow.prec_cap, self.prime_pow)
     233                diff = cremove(self.unit, self.unit, self.prime_pow.ram_prec_cap, self.prime_pow)
    234234                self.ordp += diff
    235235                if very_pos_val(self.ordp):
    236236                    self._set_exact_zero()
    cdef class FPElement(pAdicTemplateElement): 
    293293        if huge_val(self.ordp): # zero or infinity
    294294            ccopy(ans.unit, self.unit, ans.prime_pow)
    295295        else:
    296             cneg(ans.unit, self.unit, ans.prime_pow.prec_cap, ans.prime_pow)
    297             creduce_small(ans.unit, ans.unit, ans.prime_pow.prec_cap, ans.prime_pow)
     296            cneg(ans.unit, self.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
     297            creduce_small(ans.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    298298        return ans
    299299
    300300    cpdef _add_(self, _right):
    cdef class FPElement(pAdicTemplateElement): 
    320320            if huge_val(ans.ordp):
    321321                ccopy(ans.unit, self.unit, ans.prime_pow)
    322322            else:
    323                 cadd(ans.unit, self.unit, right.unit, ans.prime_pow.prec_cap, ans.prime_pow)
     323                cadd(ans.unit, self.unit, right.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    324324                ans._normalize() # safer than trying to leave unnormalized
    325325        else:
    326326            if self.ordp > right.ordp:
    327327                # Addition is commutative, swap so self.ordp < right.ordp
    328328                ans = right; right = self; self = ans
    329329            tmpL = right.ordp - self.ordp
    330             if tmpL > self.prime_pow.prec_cap:
     330            if tmpL > self.prime_pow.ram_prec_cap:
    331331                return self
    332332            ans = self._new_c()
    333333            ans.ordp = self.ordp
    334334            if huge_val(ans.ordp):
    335335                ccopy(ans.unit, self.unit, ans.prime_pow)
    336336            else:
    337                 cshift(ans.unit, right.unit, tmpL, ans.prime_pow.prec_cap, ans.prime_pow, False)
    338                 cadd(ans.unit, ans.unit, self.unit, ans.prime_pow.prec_cap, ans.prime_pow)
    339                 creduce(ans.unit, ans.unit, ans.prime_pow.prec_cap, ans.prime_pow)
     337                cshift(ans.unit, right.unit, tmpL, ans.prime_pow.ram_prec_cap, ans.prime_pow, False)
     338                cadd(ans.unit, ans.unit, self.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
     339                creduce(ans.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    340340        return ans
    341341
    342342    cpdef _sub_(self, _right):
    cdef class FPElement(pAdicTemplateElement): 
    362362            if huge_val(ans.ordp):
    363363                ccopy(ans.unit, self.unit, ans.prime_pow)
    364364            else:
    365                 csub(ans.unit, self.unit, right.unit, ans.prime_pow.prec_cap, ans.prime_pow)
     365                csub(ans.unit, self.unit, right.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    366366                ans._normalize() # safer than trying to leave unnormalized
    367367        elif self.ordp < right.ordp:
    368368            tmpL = right.ordp - self.ordp
    369             if tmpL > self.prime_pow.prec_cap:
     369            if tmpL > self.prime_pow.ram_prec_cap:
    370370                return self
    371371            ans = self._new_c()
    372372            ans.ordp = self.ordp
    373373            if huge_val(ans.ordp):
    374374                ccopy(ans.unit, self.unit, ans.prime_pow)
    375375            else:
    376                 cshift(ans.unit, right.unit, tmpL, ans.prime_pow.prec_cap, ans.prime_pow, False)
    377                 csub(ans.unit, self.unit, ans.unit, ans.prime_pow.prec_cap, ans.prime_pow)
    378                 creduce(ans.unit, ans.unit, ans.prime_pow.prec_cap, ans.prime_pow)
     376                cshift(ans.unit, right.unit, tmpL, ans.prime_pow.ram_prec_cap, ans.prime_pow, False)
     377                csub(ans.unit, self.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
     378                creduce(ans.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    379379        else:
    380380            tmpL = self.ordp - right.ordp
    381             if tmpL > self.prime_pow.prec_cap:
     381            if tmpL > self.prime_pow.ram_prec_cap:
    382382                return right._neg_()
    383383            ans = self._new_c()
    384384            ans.ordp = right.ordp
    385385            if huge_val(ans.ordp):
    386386                ccopy(ans.unit, self.unit, ans.prime_pow)
    387387            else:
    388                 cshift(ans.unit, self.unit, tmpL, ans.prime_pow.prec_cap, ans.prime_pow, False)
    389                 csub(ans.unit, ans.unit, right.unit, ans.prime_pow.prec_cap, ans.prime_pow)
    390                 creduce(ans.unit, ans.unit, ans.prime_pow.prec_cap, ans.prime_pow)
     388                cshift(ans.unit, self.unit, tmpL, ans.prime_pow.ram_prec_cap, ans.prime_pow, False)
     389                csub(ans.unit, ans.unit, right.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
     390                creduce(ans.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    391391        return ans
    392392
    393393    def __invert__(self):
    cdef class FPElement(pAdicTemplateElement): 
    415415        elif very_neg_val(ans.ordp):
    416416            csetzero(ans.unit, ans.prime_pow)
    417417        else:
    418             cinvert(ans.unit, self.unit, ans.prime_pow.prec_cap, ans.prime_pow)
     418            cinvert(ans.unit, self.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    419419        return ans
    420420
    421421    cpdef _mul_(self, _right):
    cdef class FPElement(pAdicTemplateElement): 
    447447        ans.ordp = self.ordp + right.ordp
    448448        if overunderflow(&ans.ordp, ans.unit, ans.prime_pow):
    449449            return ans
    450         cmul(ans.unit, self.unit, right.unit, ans.prime_pow.prec_cap, ans.prime_pow)
    451         creduce(ans.unit, ans.unit, ans.prime_pow.prec_cap, ans.prime_pow)
     450        cmul(ans.unit, self.unit, right.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
     451        creduce(ans.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    452452        return ans
    453453
    454454    cpdef _div_(self, _right):
    cdef class FPElement(pAdicTemplateElement): 
    485485            ans.ordp = self.ordp - right.ordp
    486486            if overunderflow(&ans.ordp, ans.unit, ans.prime_pow):
    487487                return ans
    488             cdivunit(ans.unit, self.unit, right.unit, ans.prime_pow.prec_cap, ans.prime_pow)
    489             creduce(ans.unit, ans.unit, ans.prime_pow.prec_cap, ans.prime_pow)
     488            cdivunit(ans.unit, self.unit, right.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
     489            creduce(ans.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    490490        return ans
    491491
    492     def __pow__(FPElement self, _right, dummy): # NOTE: dummy ignored, always use self.prime_pow.prec_cap
     492    def __pow__(FPElement self, _right, dummy): # NOTE: dummy ignored, always use self.prime_pow.ram_prec_cap
    493493        """
    494494        Exponentiation by an integer
    495495
    cdef class FPElement(pAdicTemplateElement): 
    540540        ans = self._new_c()
    541541        if exact_exp:
    542542            # exact_pow_helper is defined in padic_template_element.pxi
    543             right = exact_pow_helper(&dummyL, self.prime_pow.prec_cap, _right, self.prime_pow)
     543            right = exact_pow_helper(&dummyL, self.prime_pow.ram_prec_cap, _right, self.prime_pow)
    544544            mpz_init(tmp)
    545545            try:
    546546                mpz_mul_si(tmp, right.value, self.ordp)
    cdef class FPElement(pAdicTemplateElement): 
    550550                    ans.ordp = mpz_get_si(tmp)
    551551            finally:
    552552                mpz_clear(tmp)
    553             cpow(ans.unit, self.unit, right.value, ans.prime_pow.prec_cap, ans.prime_pow)
     553            cpow(ans.unit, self.unit, right.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
    554554        else:
    555555            # padic_pow_helper is defined in padic_template_element.pxi
    556             dummyL = padic_pow_helper(ans.unit, self.unit, self.ordp, self.prime_pow.prec_cap,
    557                                       pright.unit, pright.ordp, pright.prime_pow.prec_cap, self.prime_pow)
     556            dummyL = padic_pow_helper(ans.unit, self.unit, self.ordp, self.prime_pow.ram_prec_cap,
     557                                      pright.unit, pright.ordp, pright.prime_pow.ram_prec_cap, self.prime_pow)
    558558            ans.ordp = 0
    559559        return ans
    560560
    cdef class FPElement(pAdicTemplateElement): 
    656656                ccopy(ans.unit, self.unit, ans.prime_pow)
    657657        else:
    658658            diff = shift - self.ordp
    659             if diff >= self.prime_pow.prec_cap:
     659            if diff >= self.prime_pow.ram_prec_cap:
    660660                ans._set_exact_zero()
    661661            else:
    662662                ans.ordp = 0
    663                 cshift(ans.unit, self.unit, -diff, ans.prime_pow.prec_cap, ans.prime_pow, False)
     663                cshift(ans.unit, self.unit, -diff, ans.prime_pow.ram_prec_cap, ans.prime_pow, False)
    664664                ans._normalize()
    665665        return ans
    666666
    cdef class FPElement(pAdicTemplateElement): 
    718718                aprec = minusmaxordp
    719719            else:
    720720                aprec = mpz_get_si((<Integer>absprec).value)
    721         if aprec >= self.ordp + self.prime_pow.prec_cap:
     721        if aprec >= self.ordp + self.prime_pow.ram_prec_cap:
    722722            return self
    723723        cdef FPElement ans = self._new_c()
    724724        if aprec <= self.ordp:
    cdef class FPElement(pAdicTemplateElement): 
    839839            return False
    840840        if absprec is None or absprec is infinity:
    841841            return ((self.ordp == right.ordp) and
    842                     (ccmp(self.unit, right.unit, self.prime_pow.prec_cap, False, False, self.prime_pow) == 0))
     842                    (ccmp(self.unit, right.unit, self.prime_pow.ram_prec_cap, False, False, self.prime_pow) == 0))
    843843        if not isinstance(absprec, Integer):
    844844            absprec = Integer(absprec)
    845845        if mpz_cmp_si((<Integer>absprec).value, self.ordp) <= 0:
    cdef class FPElement(pAdicTemplateElement): 
    851851        if self.ordp != right.ordp:
    852852            return False
    853853        if mpz_cmp_si((<Integer>absprec).value, maxordp) >= 0:
    854             return ccmp(self.unit, right.unit, self.prime_pow.prec_cap, False, False, self.prime_pow) == 0
     854            return ccmp(self.unit, right.unit, self.prime_pow.ram_prec_cap, False, False, self.prime_pow) == 0
    855855        aprec = mpz_get_si((<Integer>absprec).value)
    856856        rprec = aprec - self.ordp
    857         if rprec > self.prime_pow.prec_cap:
    858             rprec = self.prime_pow.prec_cap
     857        if rprec > self.prime_pow.ram_prec_cap:
     858            rprec = self.prime_pow.ram_prec_cap
    859859        return ccmp(self.unit,
    860860                    right.unit,
    861861                    rprec,
    862                     rprec < self.prime_pow.prec_cap,
    863                     rprec < right.prime_pow.prec_cap,
     862                    rprec < self.prime_pow.ram_prec_cap,
     863                    rprec < right.prime_pow.ram_prec_cap,
    864864                    self.prime_pow) == 0
    865865
    866866    cdef int _cmp_units(self, pAdicGenericElement _right) except -2:
    cdef class FPElement(pAdicTemplateElement): 
    877877            True
    878878        """
    879879        cdef FPElement right = _right
    880         return ccmp(self.unit, right.unit, self.prime_pow.prec_cap, False, False, self.prime_pow)
     880        return ccmp(self.unit, right.unit, self.prime_pow.ram_prec_cap, False, False, self.prime_pow)
    881881
    882882    cdef pAdicTemplateElement lift_to_precision_c(self, long absprec):
    883883        """
    cdef class FPElement(pAdicTemplateElement): 
    10281028            else:
    10291029                return self.teichmuller_expansion(n - self.ordp)
    10301030        elif lift_mode == 'simple':
    1031             ulist = clist(self.unit, self.prime_pow.prec_cap, True, self.prime_pow)
     1031            ulist = clist(self.unit, self.prime_pow.ram_prec_cap, True, self.prime_pow)
    10321032        elif lift_mode == 'smallest':
    1033             ulist = clist(self.unit, self.prime_pow.prec_cap, False, self.prime_pow)
     1033            ulist = clist(self.unit, self.prime_pow.ram_prec_cap, False, self.prime_pow)
    10341034        else:
    10351035            raise ValueError("unknown lift_mode")
    10361036        if n is not None:
    cdef class FPElement(pAdicTemplateElement): 
    10841084        else:
    10851085            # We only need one list_elt
    10861086            list_elt = self._new_c()
    1087         cdef long prec_cap = self.prime_pow.prec_cap
     1087        cdef long prec_cap = self.prime_pow.ram_prec_cap
    10881088        cdef long goal
    10891089        if n is not None: goal = prec_cap - n
    10901090        cdef long curpower = prec_cap
    cdef class FPElement(pAdicTemplateElement): 
    11431143        elif self.ordp < 0:
    11441144            raise ValueError("cannot set negative valuation element to Teichmuller representative.")
    11451145        else:
    1146             cteichmuller(self.unit, self.unit, self.prime_pow.prec_cap, self.prime_pow)
     1146            cteichmuller(self.unit, self.unit, self.prime_pow.ram_prec_cap, self.prime_pow)
    11471147
    11481148    def polynomial(self, var='x'):
    11491149        """
    cdef class FPElement(pAdicTemplateElement): 
    11911191        elif very_neg_val(self.ordp):
    11921192            return -infinity
    11931193        cdef Integer ans = PY_NEW(Integer)
    1194         mpz_set_si(ans.value, self.ordp + self.prime_pow.prec_cap)
     1194        mpz_set_si(ans.value, self.ordp + self.prime_pow.ram_prec_cap)
    11951195        return ans
    11961196
    11971197    def precision_relative(self):
    cdef class FPElement(pAdicTemplateElement): 
    12111211        if huge_val(self.ordp):
    12121212            mpz_set_si(ans.value, 0)
    12131213        else:
    1214             mpz_set_si(ans.value, self.prime_pow.prec_cap)
     1214            mpz_set_si(ans.value, self.prime_pow.ram_prec_cap)
    12151215        return ans
    12161216
    12171217    cpdef pAdicTemplateElement unit_part(FPElement self):
    cdef class FPElement(pAdicTemplateElement): 
    13241324            return 0
    13251325        if very_neg_val(self.ordp):
    13261326            return 314159
    1327         return chash(self.unit, self.ordp, self.prime_pow.prec_cap, self.prime_pow) ^ self.ordp
     1327        return chash(self.unit, self.ordp, self.prime_pow.ram_prec_cap, self.prime_pow) ^ self.ordp
    13281328
    13291329cdef class pAdicCoercion_ZZ_FP(RingHomomorphism):
    13301330    """
    cdef class pAdicCoercion_ZZ_FP(RingHomomorphism): 
    14081408        if mpz_sgn((<Integer>x).value) == 0:
    14091409            return self._zero
    14101410        cdef FPElement ans = self._zero._new_c()
    1411         ans.ordp = cconv_mpz_t(ans.unit, (<Integer>x).value, ans.prime_pow.prec_cap, False, ans.prime_pow)
     1411        ans.ordp = cconv_mpz_t(ans.unit, (<Integer>x).value, ans.prime_pow.ram_prec_cap, False, ans.prime_pow)
    14121412        return ans
    14131413
    14141414    cpdef Element _call_with_args(self, x, args=(), kwds={}):
    cdef class pAdicConvert_FP_ZZ(RingMap): 
    15331533        elif very_neg_val(x.ordp):
    15341534            raise ValueError("Infinity cannot be converted to a rational")
    15351535        else:
    1536             cconv_mpz_t_out(ans.value, x.unit, x.ordp, x.prime_pow.prec_cap, x.prime_pow)
     1536            cconv_mpz_t_out(ans.value, x.unit, x.ordp, x.prime_pow.ram_prec_cap, x.prime_pow)
    15371537        return ans
    15381538
    15391539cdef class pAdicCoercion_QQ_FP(RingHomomorphism):
    cdef class pAdicCoercion_QQ_FP(RingHomomorphism): 
    16341634        if mpq_sgn((<Rational>x).value) == 0:
    16351635            return self._zero
    16361636        cdef FPElement ans = self._zero._new_c()
    1637         ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, ans.prime_pow.prec_cap, False, self._zero.prime_pow)
     1637        ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, ans.prime_pow.ram_prec_cap, False, self._zero.prime_pow)
    16381638        return ans
    16391639
    16401640    cpdef Element _call_with_args(self, x, args=(), kwds={}):
    cdef class pAdicConvert_FP_QQ(RingMap): 
    17411741        elif very_neg_val(x.ordp):
    17421742            raise ValueError("Infinity cannot be converted to a rational")
    17431743        else:
    1744             cconv_mpq_t_out(ans.value, x.unit, x.ordp, x.prime_pow.prec_cap, x.prime_pow)
     1744            cconv_mpq_t_out(ans.value, x.unit, x.ordp, x.prime_pow.ram_prec_cap, x.prime_pow)
    17451745        return ans
    17461746
    17471747cdef class pAdicConvert_QQ_FP(Morphism):
    cdef class pAdicConvert_QQ_FP(Morphism): 
    18181818        if mpq_sgn((<Rational>x).value) == 0:
    18191819            return self._zero
    18201820        cdef FPElement ans = self._zero._new_c()
    1821         ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, ans.prime_pow.prec_cap, False, ans.prime_pow)
     1821        ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, ans.prime_pow.ram_prec_cap, False, ans.prime_pow)
    18221822        if ans.ordp < 0:
    18231823            raise ValueError("p divides the denominator")
    18241824        return ans
    cdef class pAdicCoercion_FP_frac_field(RingHomomorphism): 
    19191919        cdef FPElement x = _x
    19201920        cdef FPElement ans = self._zero._new_c()
    19211921        ans.ordp = x.ordp
    1922         cshift(ans.unit, x.unit, 0, ans.prime_pow.prec_cap, x.prime_pow, False)
     1922        cshift(ans.unit, x.unit, 0, ans.prime_pow.ram_prec_cap, x.prime_pow, False)
    19231923        return ans
    19241924
    19251925    cpdef Element _call_with_args(self, _x, args=(), kwds={}):
    cdef class pAdicCoercion_FP_frac_field(RingHomomorphism): 
    19611961        if aprec <= x.ordp:
    19621962            ans._set_exact_zero()
    19631963        else:
    1964             if rprec < ans.prime_pow.prec_cap:
     1964            if rprec < ans.prime_pow.ram_prec_cap:
    19651965                reduce = True
    19661966            else:
    1967                 rprec = ans.prime_pow.prec_cap
     1967                rprec = ans.prime_pow.ram_prec_cap
    19681968            if aprec < rprec + x.ordp:
    19691969                rprec = aprec - x.ordp
    19701970                reduce = True
    cdef class pAdicConvert_FP_frac_field(Morphism): 
    20862086        if x.ordp < 0: raise ValueError("negative valuation")
    20872087        cdef FPElement ans = self._zero._new_c()
    20882088        ans.ordp = x.ordp
    2089         cshift(ans.unit, x.unit, 0, ans.prime_pow.prec_cap, ans.prime_pow, False)
     2089        cshift(ans.unit, x.unit, 0, ans.prime_pow.ram_prec_cap, ans.prime_pow, False)
    20902090        return ans
    20912091
    20922092    cpdef Element _call_with_args(self, _x, args=(), kwds={}):
    cdef class pAdicConvert_FP_frac_field(Morphism): 
    21292129        if aprec <= x.ordp:
    21302130            ans._set_exact_zero()
    21312131        else:
    2132             if rprec < ans.prime_pow.prec_cap:
     2132            if rprec < ans.prime_pow.ram_prec_cap:
    21332133                reduce = True
    21342134            else:
    2135                 rprec = ans.prime_pow.prec_cap
     2135                rprec = ans.prime_pow.ram_prec_cap
    21362136            if aprec < rprec + x.ordp:
    21372137                rprec = aprec - x.ordp
    21382138                reduce = True
  • src/sage/rings/padics/eisenstein_extension_generic.py

    diff --git a/src/sage/rings/padics/eisenstein_extension_generic.py b/src/sage/rings/padics/eisenstein_extension_generic.py
    index e67a67073a..5aaca9ac6c 100644
    a b class EisensteinExtensionGeneric(pAdicExtensionGeneric): 
    162162        """
    163163        return self.ground_ring().residue_class_field()
    164164
     165    def residue_ring(self, n):
     166        if n == 1:
     167            return self.ground_ring().residue_ring(1)
     168        else:
     169            raise NotImplementedError
     170
    165171    #def discriminant(self, K=None):
    166172    #    if K is self:
    167173    #        return 1
  • src/sage/rings/padics/factory.py

    diff --git a/src/sage/rings/padics/factory.py b/src/sage/rings/padics/factory.py
    index 6034161d06..f126ae0e5a 100644
    a b from . import padic_printing 
    4242######################################################
    4343
    4444from .padic_extension_leaves import *
     45from .relative_extension_leaves import *
    4546from functools import reduce
    4647#This imports all of the classes used in the ext_table below.
    4748
    ext_table['u', pAdicRingFixedMod] = UnramifiedExtensionRingFixedMod 
    6869ext_table['u', pAdicRingFloatingPoint] = UnramifiedExtensionRingFloatingPoint
    6970ext_table['u', pAdicFieldFloatingPoint] = UnramifiedExtensionFieldFloatingPoint
    7071#ext_table['u', pAdicRingLazy] = UnramifiedExtensionRingLazy
     72ext_table['re', pAdicRingFixedMod] = RelativeRamifiedExtensionRingFixedMod
    7173
    7274def _default_show_prec(type, print_mode):
    7375    """
    class pAdicExtension_class(UniqueFactory): 
    24502452            if ram_name is None:
    24512453                ram_name = base._printer._uniformizer_name()
    24522454            names = (names, res_name, unram_name, ram_name)
    2453             polytype = 'u'
     2455            if base.degree() == 1:
     2456                polytype = 'u'
     2457            else:
     2458                polytype = 'ru'
    24542459            if prec is None:
    24552460                prec = min([c.precision_absolute() for c in approx_modulus.list()] + [base.precision_cap()])
    24562461            elif prec > base.precision_cap():
    class pAdicExtension_class(UniqueFactory): 
    24622467            res_name = None
    24632468            if ram_name is None:
    24642469                ram_name = names
     2470            if base.degree() == 1:
     2471                unram_name = None
     2472                polytype = 'e'
     2473            else:
     2474                unram_name = base.variable_name()
     2475                polytype = 're'
    24652476            names = (names, res_name, unram_name, ram_name)
    2466             polytype = 'e'
    24672477            e = approx_modulus.degree()
    24682478            if prec is None:
    24692479                prec = min([c.precision_absolute() for c in approx_modulus.list() if not c._is_exact_zero()] + [base.precision_cap()]) * e
    class pAdicExtension_class(UniqueFactory): 
    25162526            (polytype, base, exact_modulus, names, prec, print_mode, print_pos,
    25172527             print_sep, print_alphabet, print_max_ram_terms, print_max_unram_terms,
    25182528             print_max_terse_terms, show_prec, implementation) = key
    2519             if polytype == 'e':
     2529            if polytype in ('e', 're'):
    25202530                unif = exact_modulus.base_ring()(base.uniformizer())
    25212531                shift_seed = (-exact_modulus[:exact_modulus.degree()] / unif).change_ring(base)
    25222532            if not krasner_check(exact_modulus, prec):
  • src/sage/rings/padics/padic_capped_absolute_element.pyx

    diff --git a/src/sage/rings/padics/padic_capped_absolute_element.pyx b/src/sage/rings/padics/padic_capped_absolute_element.pyx
    index b39a2e98a9..55d1a62f2e 100644
    a b cdef class pAdicCappedAbsoluteElement(CAElement): 
    167167        """
    168168        return self.lift_c()
    169169
    170     def residue(self, absprec=1):
     170    def residue(self, absprec=1, field=None):
    171171        r"""
    172172        Reduces ``self`` modulo `p^\mathrm{absprec}`.
    173173
    cdef class pAdicCappedAbsoluteElement(CAElement): 
    175175
    176176        - ``absprec`` - a non-negative integer (default: 1)
    177177
     178        - ``field`` -- boolean (default ``None``).  Whether to return an element of GF(p) or Zmod(p).
     179
    178180        OUTPUT:
    179181
    180182        This element reduced modulo `p^\mathrm{absprec}` as an element of
    cdef class pAdicCappedAbsoluteElement(CAElement): 
    229231            raise PrecisionError("not enough precision known in order to compute residue.")
    230232        elif mpz_sgn((<Integer>absprec).value) < 0:
    231233            raise ValueError("cannot reduce modulo a negative power of p.")
     234        if field is None:
     235            field = (absprec == 1)
     236        elif field and absprec != 1:
     237            raise ValueError("field keyword may only be set at precision 1")
    232238        cdef long aprec = mpz_get_ui((<Integer>absprec).value)
    233239        cdef Integer modulus = Integer.__new__(Integer)
    234240        mpz_set(modulus.value, self.prime_pow.pow_mpz_t_tmp(aprec))
    235241        cdef Integer selfvalue = Integer.__new__(Integer)
    236242        mpz_set(selfvalue.value, self.value)
    237         return Mod(selfvalue, modulus)
     243        if field:
     244            from sage.rings.finite_rings.all import GF
     245            return GF(self.parent().prime())(selfvalue)
     246        else:
     247            return Mod(selfvalue, modulus)
    238248
    239249    def multiplicative_order(self):
    240250        r"""
  • src/sage/rings/padics/padic_capped_relative_element.pyx

    diff --git a/src/sage/rings/padics/padic_capped_relative_element.pyx b/src/sage/rings/padics/padic_capped_relative_element.pyx
    index ac9567e52c..dffa0ec167 100644
    a b cdef class pAdicCappedRelativeElement(CRElement): 
    249249            raise ValueError("Cannot form an integer out of a p-adic field element with negative valuation")
    250250        return self.lift_c()
    251251
    252     def residue(self, absprec=1):
     252    def residue(self, absprec=1, field=None):
    253253        """
    254254        Reduces this element modulo `p^{\mathrm{absprec}}`.
    255255
    256256        INPUT:
    257257
    258         - ``absprec`` - a non-negative integer (default: ``1``)
     258        - ``absprec`` -- a non-negative integer (default: ``1``)
     259
     260        - ``field`` -- boolean (default ``None``).  Whether to return an element of GF(p) or Zmod(p).
    259261
    260262        OUTPUT:
    261263
    cdef class pAdicCappedRelativeElement(CRElement): 
    328330        aprec = mpz_get_ui((<Integer>absprec).value)
    329331        if self.ordp < 0:
    330332            raise ValueError("element must have non-negative valuation in order to compute residue.")
     333        if field is None:
     334            field = (absprec == 1)
     335        elif field and absprec != 1:
     336            raise ValueError("field keyword may only be set at precision 1")
    331337        modulus = PY_NEW(Integer)
    332338        mpz_set(modulus.value, self.prime_pow.pow_mpz_t_tmp(aprec))
    333339        selfvalue = PY_NEW(Integer)
    cdef class pAdicCappedRelativeElement(CRElement): 
    336342        else:
    337343            # Need to do this better.
    338344            mpz_mul(selfvalue.value, self.prime_pow.pow_mpz_t_tmp(self.ordp), self.unit)
    339         return Mod(selfvalue, modulus)
     345        if field:
     346            from sage.rings.finite_rings.all import GF
     347            return GF(self.parent().prime())(selfvalue)
     348        else:
     349            return Mod(selfvalue, modulus)
    340350
    341351    def _log_binary_splitting(self, aprec, mina=0):
    342352        r"""
  • 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 cbcd63ddd8..418232db94 100644
    a b class pAdicExtensionGeneric(pAdicGeneric): 
    5656        print_mode['var_name'] = names[0]
    5757        names = names[0]
    5858        pAdicGeneric.__init__(self, R, R.prime(), prec, print_mode, names, element_class)
    59         self._populate_coercion_lists_(coerce_list=[R], element_constructor=element_class)
    60 
    61 #     def __reduce__(self):
    62 #         """
    63 #         For pickling.
    64 
    65 #         This function is provided because prime_pow needs to be set before _printer, so the standard unpickling fails.
    66 #         """
    67 #         from sage.rings.padics.factory import ExtensionFactory
    68 #         return ExtensionFactory, (self.base_ring(), self._exact_modulus, self.precision_cap(), self.print_mode(), None, self.variable_name())
     59        self._populate_coercion_lists_(element_constructor=element_class)
    6960
    7061    def _coerce_map_from_(self, R):
    7162        """
    class pAdicExtensionGeneric(pAdicGeneric): 
    8071            sage: w + R(5,2)
    8172            w + w^5 + O(w^10)
    8273        """
    83         # Far more functionality needs to be added here later.
    84         if isinstance(R, pAdicExtensionGeneric) and R.fraction_field() is self:
    85             if self._implementation == 'NTL':
    86                 return True
    87             elif R._prec_type() == 'capped-abs':
    88                 from sage.rings.padics.qadic_flint_CA import pAdicCoercion_CA_frac_field as coerce_map
    89             elif R._prec_type() == 'capped-rel':
    90                 from sage.rings.padics.qadic_flint_CR import pAdicCoercion_CR_frac_field as coerce_map
    91             elif R._prec_type() == 'floating-point':
    92                 from sage.rings.padics.qadic_flint_FP import pAdicCoercion_FP_frac_field as coerce_map
    93             return coerce_map(R, self)
     74        if R is self.base_ring():
     75            return True
    9476
    9577    def _convert_map_from_(self, R):
    9678        """
  • src/sage/rings/padics/padic_extension_leaves.py

    diff --git a/src/sage/rings/padics/padic_extension_leaves.py b/src/sage/rings/padics/padic_extension_leaves.py
    index 7709447de5..e1413aee9c 100644
    a b class UnramifiedExtensionFieldCappedRelative(UnramifiedExtensionGeneric, pAdicCa 
    204204            self.register_coercion(pAdicCoercion_ZZ_CR(self))
    205205            self.register_coercion(pAdicCoercion_QQ_CR(self))
    206206
     207    def _coerce_map_from_(self, R):
     208        r"""
     209        Return a coercion from ``R`` into this ring or ``True`` if the default
     210        conversion map can be used to perform a coercion.
     211
     212        EXAMPLES::
     213
     214            sage: R.<a> = QqCR(27)
     215            sage: R.coerce_map_from(ZqCR(27)) # indirect doctest
     216            sage: R.coerce_map_from(ZqCA(27)) # indirect doctest
     217        """
     218        if isinstance(R, UnramifiedExtensionRingCappedRelative) and R.fraction_field() is self:
     219           from sage.rings.padics.qadic_flint_CR import pAdicCoercion_CR_frac_field
     220           return pAdicCoercion_CR_frac_field(R, self)
     221        if isinstance(R, UnramifiedExtensionRingCappedAbsolute) and R.fraction_field() is self:
     222           from sage.rings.padics.qadic_flint_CR import pAdicCoercion_CA_frac_field
     223           return pAdicCoercion_CA_frac_field(R, self)
     224
     225        return super(UnramifiedExtensionFieldCappedRelative, self)._coerce_map_from_(R)
     226
    207227class UnramifiedExtensionRingCappedAbsolute(UnramifiedExtensionGeneric, pAdicCappedAbsoluteRingGeneric):
    208228    """
    209229    TESTS::
    class UnramifiedExtensionRingFloatingPoint(UnramifiedExtensionGeneric, pAdicFloa 
    381401        self.register_coercion(pAdicCoercion_ZZ_FP(self))
    382402        self.register_conversion(pAdicConvert_QQ_FP(self))
    383403
     404
    384405class UnramifiedExtensionFieldFloatingPoint(UnramifiedExtensionGeneric, pAdicFloatingPointFieldGeneric):
    385406    """
    386407    TESTS::
    class UnramifiedExtensionFieldFloatingPoint(UnramifiedExtensionGeneric, pAdicFlo 
    430451        self.register_coercion(pAdicCoercion_ZZ_FP(self))
    431452        self.register_coercion(pAdicCoercion_QQ_FP(self))
    432453
     454    def _coerce_map_from_(self, R):
     455        r"""
     456        Return a coercion from ``R`` into this ring or ``True`` if the default
     457        conversion map can be used to perform a coercion.
     458
     459        EXAMPLES::
     460
     461            sage: R.<a> = QqFP(27)
     462            sage: R.coerce_map_from(ZqFP(27)) # indirect doctest
     463           
     464        """
     465        if isinstance(R, UnramifiedExtensionRingFloatingPoint) and R.fraction_field() is self:
     466            from sage.rings.padics.qadic_flint_FP import pAdicCoercion_FP_frac_field
     467            return pAdicCoercion_FP_frac_field(R, self)
     468
     469        return super(UnramifiedExtensionFieldFloatingPoint, self)._coerce_map_from_(R)
     470
    433471class EisensteinExtensionRingCappedRelative(EisensteinExtensionGeneric, pAdicCappedRelativeRingGeneric):
    434472    """
    435473    TESTS::
  • src/sage/rings/padics/padic_fixed_mod_element.pyx

    diff --git a/src/sage/rings/padics/padic_fixed_mod_element.pyx b/src/sage/rings/padics/padic_fixed_mod_element.pyx
    index 7516e45ea1..14c61c4614 100644
    a b cdef class pAdicFixedModElement(FMElement): 
    244244        """
    245245        return self.lift_c()
    246246
    247     def residue(self, absprec=1):
     247    def residue(self, absprec=1, field=None):
    248248        r"""
    249249        Reduce ``self`` modulo `p^\mathrm{absprec}`.
    250250
    cdef class pAdicFixedModElement(FMElement): 
    252252
    253253        - ``absprec`` -- an integer (default: ``1``)
    254254
     255        - ``field`` -- boolean (default ``None``).  Whether to return an element of GF(p) or Zmod(p).
     256
    255257        OUTPUT:
    256258
    257259        This element reduced modulo `p^\mathrm{absprec}` as an element of
    cdef class pAdicFixedModElement(FMElement): 
    303305            raise PrecisionError("Not enough precision known in order to compute residue.")
    304306        elif absprec < 0:
    305307            raise ValueError("Cannot reduce modulo a negative power of p.")
     308        if field is None:
     309            field = (absprec == 1)
     310        elif field and absprec != 1:
     311            raise ValueError("field keyword may only be set at precision 1")
    306312        cdef long aprec = mpz_get_ui((<Integer>absprec).value)
    307313        modulus = PY_NEW(Integer)
    308314        mpz_set(modulus.value, self.prime_pow.pow_mpz_t_tmp(aprec))
    309315        selfvalue = PY_NEW(Integer)
    310316        mpz_set(selfvalue.value, self.value)
    311         return Mod(selfvalue, modulus)
     317        if field:
     318            from sage.rings.finite_rings.all import GF
     319            return GF(self.parent().prime())(selfvalue)
     320        else:
     321            return Mod(selfvalue, modulus)
    312322
    313323    def multiplicative_order(self):
    314324        r"""
  • src/sage/rings/padics/padic_floating_point_element.pyx

    diff --git a/src/sage/rings/padics/padic_floating_point_element.pyx b/src/sage/rings/padics/padic_floating_point_element.pyx
    index 6e604477ae..0e711811f2 100644
    a b cdef class pAdicFloatingPointElement(FPElement): 
    237237            raise ValueError("Cannot form an integer out of a p-adic field element with negative valuation")
    238238        return self.lift_c()
    239239
    240     def residue(self, absprec=1):
     240    def residue(self, absprec=1, field=None):
    241241        """
    242242        Reduces this element modulo `p^{\mathrm{absprec}}`.
    243243
    cdef class pAdicFloatingPointElement(FPElement): 
    245245
    246246        - ``absprec`` - a non-negative integer (default: ``1``)
    247247
     248        - ``field`` -- boolean (default ``None``).  Whether to return an element of GF(p) or Zmod(p).
     249
    248250        OUTPUT:
    249251
    250252        This element reduced modulo `p^\mathrm{absprec}` as an element of
    cdef class pAdicFloatingPointElement(FPElement): 
    298300        aprec = mpz_get_ui((<Integer>absprec).value)
    299301        if self.ordp < 0:
    300302            raise ValueError("element must have non-negative valuation in order to compute residue.")
     303        if field is None:
     304            field = (absprec == 1)
     305        elif field and absprec != 1:
     306            raise ValueError("field keyword may only be set at precision 1")
    301307        modulus = PY_NEW(Integer)
    302308        mpz_set(modulus.value, self.prime_pow.pow_mpz_t_tmp(aprec))
    303309        selfvalue = PY_NEW(Integer)
    cdef class pAdicFloatingPointElement(FPElement): 
    306312        else:
    307313            # Need to do this better.
    308314            mpz_mul(selfvalue.value, self.prime_pow.pow_mpz_t_tmp(self.ordp), self.unit)
    309         return Mod(selfvalue, modulus)
     315        if field:
     316            from sage.rings.finite_rings.all import GF
     317            return GF(self.parent().prime())(selfvalue)
     318        else:
     319            return Mod(selfvalue, modulus)
    310320
    311321    def _exp_binary_splitting(self, aprec):
    312322        """
    cdef class pAdicFloatingPointElement(FPElement): 
    429439        sig_off()
    430440
    431441        return ans
    432 
  • src/sage/rings/padics/padic_generic.py

    diff --git a/src/sage/rings/padics/padic_generic.py b/src/sage/rings/padics/padic_generic.py
    index c43c74e6aa..c3dfda2b03 100644
    a b from sage.misc.prandom import sample 
    3030from sage.misc.misc import some_tuples
    3131
    3232from sage.categories.principal_ideal_domains import PrincipalIdealDomains
     33from sage.categories.morphism import Morphism
     34from sage.categories.sets_with_partial_maps import SetsWithPartialMaps
    3335from sage.categories.fields import Fields
    3436from sage.rings.infinity import infinity
    3537from .local_generic import LocalGeneric
    class pAdicGeneric(PrincipalIdealDomain, LocalGeneric): 
    337339        """
    338340        return self.residue_class_field()
    339341
     342    def residue_ring(self, n):
     343        """
     344        Returns the quotient of the ring of integers by the `n`th power of the maximal ideal.
     345
     346        EXAMPLES::
     347
     348            sage: R = Zp(11)
     349            sage: R.residue_ring(3)
     350            Ring of integers modulo 1331
     351        """
     352        from sage.rings.finite_rings.integer_mod_ring import Zmod
     353        return Zmod(self.prime()**n)
     354
    340355    def residue_system(self):
    341356        """
    342357        Returns a list of elements representing all the residue classes.
    class pAdicGeneric(PrincipalIdealDomain, LocalGeneric): 
    906921        """
    907922        pass
    908923
     924class ResidueReductionMap(Morphism):
     925    """
     926    Reduction map from a p-adic ring or field to its residue field or ring.
     927    """
     928    def __init__(self, R, k):
     929        if R.is_field():
     930            cat = SetsWithPartialMaps()
     931        else:
     932            from sage.categories.rings import Rings
     933            cat = Rings()
     934        from sage.categories.homset import Hom
     935        Morphism.__init__(self, Hom(R, k, cat))
     936        kfield = R.residue_field()
     937        q = kfield.cardinality()
     938        N = k.cardinality()
     939        self._n = N.exact_log(q)
     940        if q**self._n != N:
     941            raise ValueError("Codomain does not have cardinality a power of q")
     942        if kfield is k:
     943            self._field = True
     944        else:
     945            self._field = False
     946
     947    def is_surjective(self):
     948        return True
     949
     950    def is_injective(self):
     951        return False
     952
     953    def _call_(self, x):
     954        return x.residue(self._n, field=self._field)
     955
     956    def section(self):
     957        return ResidueLiftingMap(self.codomain(), self.domain())
     958
     959class ResidueLiftingMap(Morphism):
     960    def __init__(self, k, R):
     961        from sage.categories.sets_cat import Sets
     962        from sage.categories.homset import Hom
     963        Morphism.__init__(self, Hom(k, R, Sets()))
     964
     965    def _call_(self, x):
     966        R = self.codomain()
     967        A = R.base_ring()
     968        if R is A:
     969            return R._element_constructor(x) # fall back on common_conversion code
     970        if R.f() == 1:
     971            return R([A(x)])
     972        elif R.e() == 1:
     973            return R(x.polynomial().list())
     974        else:
     975            raise NotImplementedError
     976
    909977def local_print_mode(obj, print_options, pos = None, ram_name = None):
    910978    r"""
    911979    Context manager for safely temporarily changing the print_mode
  • src/sage/rings/padics/padic_printing.pyx

    diff --git a/src/sage/rings/padics/padic_printing.pyx b/src/sage/rings/padics/padic_printing.pyx
    index dbfaffdf1c..4cadce2686 100644
    a b cdef class pAdicPrinter_class(SageObject): 
    10781078                    poly, k = elt._flint_rep_abs()
    10791079                    L = [repr(a) for a in poly.coefficients(sparse=False)]
    10801080                    ZZ_pEX = 1
     1081                elif elt.parent()._implementation == 'Polynomial':
     1082                    poly = elt._poly_rep()
     1083                    if do_latex:
     1084                        L = [a._latex_() for a in poly.coefficients(sparse=False)]
     1085                    else:
     1086                        L = [repr(a) for a in poly.coefficients(sparse=False)]
     1087                    L, ellipsis = self._truncate_list(L, self.max_terse_terms, '0')
     1088                    s = ''
     1089                    for i, a in enumerate(L):
     1090                        if a == '0':
     1091                            continue
     1092                        if (i > 0) and ('+' in a or '-' in a[1:]):
     1093                            a = '(' + a + ')'
     1094                        if a[0] == '-':
     1095                            if s:
     1096                                s += ' - '
     1097                            else:
     1098                                s = '-'
     1099                            if a[1:] == '1':
     1100                                s += self._var(self.var_name, i, do_latex)
     1101                            else:
     1102                                s += a[1:] + self._dot_var(self.var_name, i, do_latex)
     1103                        else:
     1104                            if s:
     1105                                s += ' + '
     1106                            if a == '1':
     1107                                s += self._var(self.var_name, i, do_latex)
     1108                            else:
     1109                                s += a + self._dot_var(self.var_name, i, do_latex)
     1110                    if ellipsis:
     1111                        s += self._plus_ellipsis(do_latex)
     1112                    if paren and ' ' in s:
     1113                        s = '(' + s + ')'
     1114                    return s
    10811115                else:
    10821116                    if elt.parent().is_capped_relative():
    10831117                        poly, k = elt._ntl_rep_abs()
  • src/sage/rings/padics/padic_template_element.pxi

    diff --git a/src/sage/rings/padics/padic_template_element.pxi b/src/sage/rings/padics/padic_template_element.pxi
    index cc6aa440f4..f82da3b8e0 100644
    a b cdef class pAdicTemplateElement(pAdicGenericElement): 
    121121                x = Rational(x)
    122122        elif isinstance(x, pAdicGenericElement):
    123123            if not ((<pAdicGenericElement>x)._is_base_elt(self.prime_pow.prime) or x.parent() is self.parent()):
    124                 raise NotImplementedError("conversion between padic extensions not implemented")
     124                if x.parent().modulus().change_ring(self.base_ring()) == self.parent().modulus():
     125                    x = x.polynomial().change_ring(self.base_ring()).list()
     126                else:
     127                    raise NotImplementedError("conversion from %r to %r not implemented"%(x.parent(), self.parent()))
    125128        elif sage.rings.finite_rings.integer_mod.is_IntegerMod(x):
    126129            if not Integer(self.prime_pow.prime).divides(x.parent().order()):
    127130                raise TypeError("p does not divide modulus %s"%x.parent().order())
    cdef class pAdicTemplateElement(pAdicGenericElement): 
    453456        """
    454457        return self.prime_pow
    455458
    456     def residue(self, absprec=1):
     459    def residue(self, absprec=1, field=None):
    457460        r"""
    458461        Reduce this element modulo `p^\mathrm{absprec}`.
    459462
    cdef class pAdicTemplateElement(pAdicGenericElement): 
    461464
    462465        - ``absprec`` -- ``0`` or ``1``.
    463466
     467        - ``field`` -- boolean (default ``None``).  For precision 1, whether to return
     468          an element of the residue field or a residue ring.  Currently unused.
     469
    464470        OUTPUT:
    465471
    466472        This element reduced modulo `p^\mathrm{absprec}` as an element of the
    cdef class pAdicTemplateElement(pAdicGenericElement): 
    502508            Traceback (most recent call last):
    503509            ...
    504510            ValueError: element must have non-negative valuation in order to compute residue.
    505            
    506511        """
    507512        if absprec < 0:
    508513            raise ValueError("cannot reduce modulo a negative power of the uniformizer.")
    cdef class pAdicTemplateElement(pAdicGenericElement): 
    510515            raise ValueError("element must have non-negative valuation in order to compute residue.")
    511516        if absprec > self.precision_absolute():
    512517            raise PrecisionError("insufficient precision to reduce modulo p^%s."%absprec)
     518        if field and absprec != 1:
     519            raise ValueError("field keyword may only be set at precision 1")
    513520        if absprec == 0:
    514521            from sage.rings.all import IntegerModRing
    515522            return IntegerModRing(1).zero()
    cdef long padic_pow_helper(celement result, celement base, long base_val, long b 
    603610    if base_val != 0:
    604611        raise ValueError("in order to raise to a p-adic exponent, base must be a unit")
    605612    ####### NOTE:  this function needs to be updated for extension elements. #######
    606     cdef celement oneunit, teichdiff
    607613    cdef long loga_val, loga_aprec, bloga_val, bloga_aprec
    608614    cdef Integer expcheck, right
     615    cteichmuller(prime_pow.powhelper_oneunit, base, base_relprec, prime_pow)
     616    cdivunit(prime_pow.powhelper_oneunit, base, prime_pow.powhelper_oneunit, base_relprec, prime_pow)
     617    csetone(prime_pow.powhelper_teichdiff, prime_pow)
     618    csub(prime_pow.powhelper_teichdiff, prime_pow.powhelper_oneunit, prime_pow.powhelper_teichdiff, base_relprec, prime_pow)
     619    ## For extension elements in ramified extensions, the computation of the
     620    ## valuation and precision of log(a) is more complicated)
     621    loga_val = cvaluation(prime_pow.powhelper_teichdiff, base_relprec, prime_pow)
     622    loga_aprec = base_relprec
     623    # valuation of b*log(a)
     624    bloga_val = loga_val + right_val
     625    bloga_aprec = bloga_val + min(right_relprec, loga_aprec - loga_val)
     626    if bloga_aprec > prime_pow.ram_prec_cap:
     627        bloga_aprec = prime_pow.ram_prec_cap
     628    expcheck = PY_NEW(Integer)
     629    mpz_sub_ui(expcheck.value, prime_pow.prime.value, 1)
     630    mpz_mul_si(expcheck.value, expcheck.value, bloga_val)
     631    if mpz_cmp_ui(expcheck.value, prime_pow.e) <= 0:
     632        raise ValueError("exponential does not converge")
     633    right = PY_NEW(Integer)
    609634    try:
    610         cconstruct(oneunit, prime_pow)
    611         cconstruct(teichdiff, prime_pow)
    612         cteichmuller(oneunit, base, base_relprec, prime_pow)
    613         cdivunit(oneunit, base, oneunit, base_relprec, prime_pow)
    614         csetone(teichdiff, prime_pow)
    615         csub(teichdiff, oneunit, teichdiff, base_relprec, prime_pow)
    616         ## For extension elements in ramified extensions, the computation of the
    617         ## valuation and precision of log(a) is more complicated)
    618         loga_val = cvaluation(teichdiff, base_relprec, prime_pow)
    619         loga_aprec = base_relprec
    620         # valuation of b*log(a)
    621         bloga_val = loga_val + right_val
    622         bloga_aprec = bloga_val + min(right_relprec, loga_aprec - loga_val)
    623         if bloga_aprec > prime_pow.ram_prec_cap:
    624             bloga_aprec = prime_pow.ram_prec_cap
    625         expcheck = PY_NEW(Integer)
    626         mpz_sub_ui(expcheck.value, prime_pow.prime.value, 1)
    627         mpz_mul_si(expcheck.value, expcheck.value, bloga_val)
    628         if mpz_cmp_ui(expcheck.value, prime_pow.e) <= 0:
    629             raise ValueError("exponential does not converge")
    630         right = PY_NEW(Integer)
    631         try:
    632             cconv_mpz_t_out(right.value, right_unit, right_val, right_relprec, prime_pow)
    633         except ValueError:
    634             # Here we need to use the exp(b log(a)) definition,
    635             # since we can't convert the exponent to an integer
    636             raise NotImplementedError("exponents with negative valuation not yet supported")
    637         ## For extension elements in ramified extensions
    638         ## the following precision might need to be changed.
    639         cpow(result, oneunit, right.value, bloga_aprec, prime_pow)
    640     finally:
    641         cdestruct(oneunit, prime_pow)
    642         cdestruct(teichdiff, prime_pow)
     635        cconv_mpz_t_out(right.value, right_unit, right_val, right_relprec, prime_pow)
     636    except ValueError:
     637        # Here we need to use the exp(b log(a)) definition,
     638        # since we can't convert the exponent to an integer
     639        raise NotImplementedError("exponents with negative valuation not yet supported")
     640    ## For extension elements in ramified extensions
     641    ## the following precision might need to be changed.
     642    cpow(result, prime_pow.powhelper_oneunit, right.value, bloga_aprec, prime_pow)
    643643    return bloga_aprec
  • src/sage/rings/padics/pow_computer.pxd

    diff --git a/src/sage/rings/padics/pow_computer.pxd b/src/sage/rings/padics/pow_computer.pxd
    index 7d754e8a28..ddd9450102 100644
    a b cdef class PowComputer_class(SageObject): 
    88    cdef int __allocated
    99    cdef public object _prec_type
    1010
    11     # the following three should be set by the subclasses
    1211    cdef long ram_prec_cap # = prec_cap * e
     12
     13    # the following constants should be set by the subclasses
     14    # the relative degree of the p-adic ring over its base
    1315    cdef long deg
     16    # the ramification index of the p-adic ring over its base
    1417    cdef long e
     18    # the residual degree of the p-adic ring over its base
    1519    cdef long f
    1620
    1721    cdef unsigned long cache_limit
    cdef class PowComputer_class(SageObject): 
    2529cdef class PowComputer_base(PowComputer_class):
    2630    cdef mpz_t* small_powers
    2731    cdef mpz_t top_power
     32    cdef mpz_t powhelper_oneunit
     33    cdef mpz_t powhelper_teichdiff
    2834    cdef object __weakref__
  • src/sage/rings/padics/pow_computer.pyx

    diff --git a/src/sage/rings/padics/pow_computer.pyx b/src/sage/rings/padics/pow_computer.pyx
    index 5c6073ee0e..b26f309c95 100644
    a b cdef class PowComputer_base(PowComputer_class): 
    441441            try:
    442442                mpz_init(self.top_power)
    443443                try:
    444                     for i in range(cache_limit + 1):
     444                    mpz_init(self.powhelper_oneunit)
     445                    try:
     446                        mpz_init(self.powhelper_teichdiff)
    445447                        try:
    446                             mpz_init(self.small_powers[i])
     448                            for i in range(cache_limit + 1):
     449                                try:
     450                                    mpz_init(self.small_powers[i])
     451                                except BaseException:
     452                                    while i:
     453                                        i-=1
     454                                        mpz_clear(self.small_powers[i])
     455                                    raise
    447456                        except BaseException:
    448                             while i:
    449                                 i-=1
    450                                 mpz_clear(self.small_powers[i])
     457                            mpz_clear(self.powhelper_teichdiff)
    451458                            raise
     459                    except BaseException:
     460                        mpz_clear(self.powhelper_oneunit)
     461                        raise
    452462                except BaseException:
    453463                    mpz_clear(self.top_power)
    454464                    raise
    cdef class PowComputer_base(PowComputer_class): 
    504514            for i in range(self.cache_limit + 1):
    505515                mpz_clear(self.small_powers[i])
    506516            mpz_clear(self.top_power)
     517            mpz_clear(self.powhelper_oneunit)
     518            mpz_clear(self.powhelper_teichdiff)
    507519            mpz_clear(self.temp_m)
    508520            sig_free(self.small_powers)
    509521
  • src/sage/rings/padics/pow_computer_flint.pxd

    diff --git a/src/sage/rings/padics/pow_computer_flint.pxd b/src/sage/rings/padics/pow_computer_flint.pxd
    index 6126da0ff7..7d5c54b109 100644
    a b cdef class PowComputer_flint(PowComputer_class): 
    1818cdef class PowComputer_flint_1step(PowComputer_flint):
    1919    cdef fmpz_t q
    2020    cdef fmpz_poly_t modulus
     21    cdef fmpz_poly_t powhelper_oneunit
     22    cdef fmpz_poly_t powhelper_teichdiff
    2123    cdef fmpz_poly_t* _moduli
    2224    cdef fmpz_poly_t* get_modulus(self, unsigned long n)
    2325    cdef fmpz_poly_t* get_modulus_capdiv(self, unsigned long n)
  • src/sage/rings/padics/pow_computer_flint.pyx

    diff --git a/src/sage/rings/padics/pow_computer_flint.pyx b/src/sage/rings/padics/pow_computer_flint.pyx
    index d5542626d5..2b8166eac4 100644
    a b cdef class PowComputer_flint_1step(PowComputer_flint): 
    219219            try:
    220220                fmpz_poly_init2(self.modulus, length)
    221221                try:
    222                     for i in range(1,cache_limit+2):
     222                    fmpz_poly_init2(self.powhelper_oneunit, length)
     223                    try:
     224                        fmpz_poly_init2(self.powhelper_teichdiff, length)
    223225                        try:
    224                             fmpz_poly_init2(self._moduli[i], length)
     226                            for i in range(1,cache_limit+2):
     227                                try:
     228                                    fmpz_poly_init2(self._moduli[i], length)
     229                                except BaseException:
     230                                    i-=1
     231                                    while i:
     232                                        fmpz_poly_clear(self._moduli[i])
     233                                        i-=1
     234                                    raise
    225235                        except BaseException:
    226                             i-=1
    227                             while i:
    228                                 fmpz_poly_clear(self._moduli[i])
    229                                 i-=1
     236                            fmpz_poly_clear(self.powhelper_teichdiff)
    230237                            raise
     238                    except BaseException:
     239                        fmpz_poly_clear(self.powhelper_oneunit)
     240                        raise
    231241                except BaseException:
    232242                    fmpz_poly_clear(self.modulus)
    233243                    raise
    cdef class PowComputer_flint_1step(PowComputer_flint): 
    285295        if self.__allocated >= 8:
    286296            fmpz_clear(self.q)
    287297            fmpz_poly_clear(self.modulus)
     298            fmpz_poly_clear(self.powhelper_oneunit)
     299            fmpz_poly_clear(self.powhelper_teichdiff)
    288300            for i in range(1, self.cache_limit + 1):
    289301                fmpz_poly_clear(self._moduli[i])
    290302            sig_free(self._moduli)
  • new file src/sage/rings/padics/pow_computer_relative.pxd

    diff --git a/src/sage/rings/padics/pow_computer_relative.pxd b/src/sage/rings/padics/pow_computer_relative.pxd
    new file mode 100644
    index 0000000000..d1c66b8a0a
    - +  
     1# -*- coding: utf-8 -*-
     2from sage.rings.padics.pow_computer cimport PowComputer_class
     3from sage.rings.polynomial.polynomial_element cimport Polynomial_generic_dense
     4
     5cdef class PowComputer_relative(PowComputer_class):
     6    # p-adic elements are represented by polynomials in this ring
     7    cdef public object poly_ring
     8    # the p-adic ring is an extension of this base ring
     9    cdef public object base_ring
     10    # the modulus of the extension
     11    cdef public Polynomial_generic_dense modulus
     12    # storage for temporary variables used in the linkage files
     13    cdef Polynomial_generic_dense tmp_cconv_out
     14    cdef Polynomial_generic_dense tmp_clist
     15    cdef Polynomial_generic_dense tmp_ccmp_a
     16    cdef Polynomial_generic_dense tmp_ccmp_b
     17    # allow cached methods
     18    cdef public dict __cached_methods
     19
     20    cdef unsigned long capdiv(self, unsigned long n)
     21
     22cdef class PowComputer_relative_eis(PowComputer_relative):
     23    # (x^e - modulus)/p
     24    cdef public Polynomial_generic_dense _shift_seed
     25    cdef Polynomial_generic_dense invert(self, Polynomial_generic_dense element, long prec)
  • new file src/sage/rings/padics/pow_computer_relative.pyx

    diff --git a/src/sage/rings/padics/pow_computer_relative.pyx b/src/sage/rings/padics/pow_computer_relative.pyx
    new file mode 100644
    index 0000000000..7fc23f6686
    - +  
     1# -*- coding: utf-8 -*-
     2r"""
     3A ``PowComputer`` for relative extensions
     4
     5This module provides helper classes for the various kinds of relative `p`-adic
     6extensions. You should never have to access these directly, unless you are
     7working on linkages or other low-level `p`-adics code within the Sage library.
     8
     9AUTHORS:
     10
     11- David Roe, Julian Rüth (2017-06-11): initial version
     12
     13"""
     14#*****************************************************************************
     15#       Copyright (C) 2017 David Roe <roed.math@gmail.com>
     16#                     2017 Julian Rüth <julian.rueth@fsfe.org>
     17#
     18#  Distributed under the terms of the GNU General Public License (GPL)
     19#  as published by the Free Software Foundation; either version 2 of
     20#  the License, or (at your option) any later version.
     21#
     22#                  http://www.gnu.org/licenses/
     23#*****************************************************************************
     24from __future__ import absolute_import
     25
     26from cysignals.memory cimport sig_malloc, sig_free
     27from cysignals.signals cimport sig_on, sig_off
     28
     29from sage.libs.gmp.mpz cimport mpz_init, mpz_clear, mpz_pow_ui
     30
     31from cpython.object cimport Py_EQ, Py_NE
     32from sage.structure.richcmp cimport richcmp_not_equal
     33from sage.rings.integer cimport Integer
     34from sage.rings.all import ZZ
     35from sage.misc.cachefunc import cached_method
     36
     37cdef class PowComputer_relative(PowComputer_class):
     38    r"""
     39    Base class for a ``PowComputer`` for use in `p`-adics implemented by Sage
     40    Polynomials.
     41
     42    For a description of inputs see :func:`PowComputer_relative_maker`.
     43
     44    EXAMPLES::
     45
     46        sage: from sage.rings.padics.pow_computer_relative import PowComputer_relative_maker
     47        sage: R.<a> = ZqFM(25)
     48        sage: S.<x> = R[]
     49        sage: f = x^3 - 5*x - 5*a
     50        sage: PC = PowComputer_relative_maker(3, 20, 20, 60, False, f, 'fixed-mod')
     51
     52    TESTS::
     53
     54        sage: from sage.rings.padics.pow_computer_relative import PowComputer_relative
     55        sage: isinstance(PC, PowComputer_relative)
     56
     57    """
     58    def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed):
     59        r"""
     60        TESTS::
     61
     62            sage: from sage.rings.padics.pow_computer_relative import PowComputer_relative_maker
     63            sage: PC = PowComputer_relative_maker(3, 20, 20, 60, False, f, 'fixed-mod')
     64
     65        """
     66        self.__allocated = 4
     67
     68    def __init__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed):
     69        r"""
     70        TESTS::
     71
     72            sage: from sage.rings.padics.pow_computer_relative import PowComputer_relative_maker
     73            sage: R.<a> = ZqFM(25)
     74            sage: S.<x> = R[]; f = x^3 - 5*x - 5*a
     75            sage: PC = PowComputer_relative_maker(5, 20, 20, 60, False, f, 'fixed-mod') # indirect doctest
     76            sage: TestSuite(PC).run()
     77
     78        """
     79        PowComputer_class.__init__(self, prime, cache_limit, prec_cap, ram_prec_cap, in_field, poly, shift_seed)
     80        self.e = poly.degree()
     81        self.f = 1
     82
     83        self.modulus = poly
     84
     85        self.tmp_cconv_out = poly.parent()()
     86        self.tmp_clist = poly.parent()()
     87        self.tmp_ccmp_a = poly.parent()()
     88        self.tmp_ccmp_b = poly.parent()()
     89
     90        self.base_ring = poly.base_ring()
     91        self.poly_ring = poly.parent()
     92
     93    def __dealloc__(self):
     94        r"""
     95        TESTS::
     96
     97            sage: from sage.rings.padics.pow_computer_relative import PowComputer_relative_maker
     98            sage: R.<a> = ZqFM(25)
     99            sage: S.<x> = R[]
     100            sage: f = x^3 - 5*x - 5*a
     101            sage: PC = PowComputer_relative_maker(5, 20, 20, 60, False, f, 'fixed-mod')
     102            sage: del PC
     103
     104        """
     105
     106    def __reduce__(self):
     107        r"""
     108        Return a picklable representation of this ``PowComputer``.
     109
     110        TESTS::
     111
     112            sage: from sage.rings.padics.pow_computer_relative import PowComputer_relative_maker
     113            sage: R.<a> = ZqFM(25)
     114            sage: S.<x> = R[]
     115            sage: f = x^3 - 5*x - 5*a
     116            sage: PC = PowComputer_relative_maker(5, 20, 20, 60, False, f, 'fixed-mod') # indirect doctest
     117            sage: loads(dumps(PC)) == PC
     118
     119        """
     120        return PowComputer_relative_maker, (self.prime, self.cache_limit, self.prec_cap, self.ram_prec_cap, self.in_field, self.polynomial(), self._prec_type)
     121
     122    def _repr_(self):
     123        r"""
     124        Return a string representation of this ``PowComputer``.
     125
     126        EXAMPLES::
     127
     128            sage: from sage.rings.padics.pow_computer_relative import PowComputer_relative_maker
     129            sage: R.<a> = ZqFM(25)
     130            sage: S.<x> = R[]
     131            sage: f = x^3 - 5*x - 5*a
     132            sage: PowComputer_relative_maker(5, 20, 20, 60, False, f, 'fixed-mod') # indirect doctest
     133            Relative PowComputer for modulus x^3 - 5*x - 5*a
     134
     135        """
     136        return "Relative PowComputer for modulus %s"%(self.modulus,)
     137
     138    cdef unsigned long capdiv(self, unsigned long n):
     139        r"""
     140        Return `\lceil n/e \rceil`.
     141        """
     142        if self.e == 1: return n
     143        if n == 0: return 0
     144        return (n - 1)/self.e + 1
     145
     146    def polynomial(self, n=None, var='x'):
     147        r"""
     148        Return the modulus of the `p`-adic extension that is handled by this
     149        ``PowComputer``.
     150
     151        EXAMPLES::
     152
     153            sage: from sage.rings.padics.pow_computer_relative import PowComputer_relative_maker
     154            sage: R.<a> = ZqFM(25)
     155            sage: S.<x> = R[]; f = x^3 - 5*x - 5*a
     156            sage: PC = PowComputer_relative_maker(5, 20, 20, 60, False, f, 'fixed-mod') # indirect doctest
     157            sage: PC.polynomial() is f
     158            True
     159
     160        """
     161        return self.modulus
     162
     163
     164cdef class PowComputer_relative_eis(PowComputer_relative):
     165    r"""
     166    A ``PowComputer`` for a relative extension defined by an Eisenstein polynomial
     167
     168    For a description of inputs see :func:`PowComputer_relative_maker`.
     169
     170    EXAMPLES::
     171
     172        sage: from sage.rings.padics.pow_computer_relative import PowComputer_relative_eis
     173        sage: R.<x> = ZZ[]
     174        sage: f = x^3 - 25*x + 5
     175        sage: PC = PowComputer_relative_eis(5, 20, 20, 60, False, f)
     176
     177    TESTS::
     178
     179        sage: from sage.rings.padics.pow_computer_relative import PowComputer_relative_eis
     180        sage: isinstance(PC, PowComputer_relative_eis)
     181
     182    """
     183    def __init__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed):
     184        r"""
     185        TESTS::
     186
     187            sage: from sage.rings.padics.pow_computer_relative import PowComputer_relative_eis
     188            sage: R.<x> = ZZ[]
     189            sage: f = x^3 - 25*x + 5
     190            sage: A = PowComputer_relative_eis(5, 20, 20, 60, False, f)
     191            sage: TestSuite(A).run()
     192
     193        """
     194        PowComputer_relative.__init__(self, prime, cache_limit, prec_cap, ram_prec_cap, in_field, poly, shift_seed)
     195
     196        self.e = self.modulus.degree()
     197        self.f = 1
     198        self._shift_seed = shift_seed
     199
     200    cdef Polynomial_generic_dense invert(self, Polynomial_generic_dense a, long prec):
     201        r"""
     202        Return the inverse of ``a``.
     203
     204        INPUT:
     205
     206        - ``a`` -- a `p`-adic element, represented as a reduced
     207          Polynomial in ``poly_ring``
     208
     209        - ```prec`` -- a ``long``, the required precision
     210
     211        OUTPUT:
     212
     213        A polynomial ``b`` such that ``a*b`` is one modulo `π^\mathrm{prec}`
     214
     215        EXAMPLES::
     216
     217            sage: TODO: invert something
     218
     219        """
     220        # TODO: At the moment, we use an xgcd. We should use Newton iterations
     221        # instead to make this faster.
     222        K = self.base_ring.fraction_field()
     223        Qpmodulus = self.modulus.change_ring(K)
     224        one, _, b = Qpmodulus.xgcd(a)
     225        if not one.is_one():
     226            raise ValueError("element has no inverse")
     227        return b.change_ring(self.base_ring)
     228
     229    @cached_method
     230    def px_pow(self, r):
     231        r"""
     232        Return `p/π^r` where π is the uniformizer and `p` is the uniformizer of
     233        the base ring (not necessarily an integer.)
     234
     235        INPUT:
     236
     237        - ``r`` -- a non-negative integer
     238
     239        OUTPUT:
     240
     241        A reduced polynomial in π
     242
     243        EXAMPLES::
     244
     245            sage: TODO
     246
     247        """
     248        if r < 0:
     249            raise ValueError("r must be non-negative")
     250        elif r == 0:
     251            return self.poly_ring(self.base_ring.uniformizer())
     252        elif r < self.e:
     253            # Split modulus in half:
     254            # modulus = -p*c + π^r*d, where c and d are integral polynomials, and c has unit const term.
     255            # Then p/π^r = d/c.
     256            R = self.modulus.parent()
     257            c = R(self._shift_seed.list()[:r])
     258            d = R(self.modulus.list()[r:])
     259            c_inverse = self.invert(c, self.ram_prec_cap)
     260            return (d*c_inverse) % self.modulus
     261        elif r == self.e:
     262            return self.invert(self._shift_seed, self.ram_prec_cap)
     263        else:
     264            raise NotImplementedError
     265
     266    @cached_method
     267    def pxe_pow(self, r):
     268        r"""
     269        Return the ``r``-th power of the unit `p/π^e` where `e` is the relative
     270        ramification index and `p` is the uniformizer of the base ring (not necessarily an integer.)
     271
     272        INPUT:
     273
     274        - ``r`` -- a non-negative integer
     275
     276        OUTPUT:
     277
     278        A reduced polynomial in π
     279
     280        EXAMPLES::
     281
     282            sage: TODO
     283
     284        """
     285        if r < 0:
     286            raise ValueError("r must be non-negative")
     287        elif r == 0:
     288            return self.poly_ring.one()
     289        elif r == 1:
     290            return self.px_pow(self.e)
     291        elif r%2:
     292            return (self.pxe_pow(r-1) * self.pxe_pow(1)) % self.modulus
     293        else:
     294            return (self.pxe_pow(r//2)*self.pxe_pow(r//2)) % self.modulus
     295
     296    @cached_method
     297    def uniformizer_pow(self, r):
     298        r"""
     299        Return the ``r``-th power of the uniformizer.
     300
     301        INPUT:
     302
     303        - ``r`` -- a non-negative integer
     304
     305        OUTPUT:
     306
     307        A reduced polynomial in π
     308
     309        EXAMPLES::
     310
     311            sage: TODO
     312
     313        """
     314        if r < 0:
     315            raise ValueError("r must be non-negative")
     316        elif r == 0:
     317            return self.poly_ring.one()
     318        elif r < self.e:
     319            return self.poly_ring.one() << r
     320        elif r%2:
     321            return (self.uniformizer_pow(r-1) << 1) % self.modulus
     322        else:
     323            return (self.uniformizer_pow(r//2) * self.uniformizer_pow(r//2)) % self.modulus
     324
     325def PowComputer_relative_maker(prime, cache_limit, prec_cap, ram_prec_cap, in_field, poly, shift_seed, prec_type):
     326    r"""
     327    Create a ``PowComputer``.
     328
     329    INPUT:
     330
     331    - ``prime`` -- a uniformizer in the base ring
     332
     333    - ``cache_limit`` -- a non-negative integer, controlling the caching. The
     334      ``PowComputer`` caches frequently used things like powers of ``prime``.
     335      This parameter, e.g., controls up to which power these are cached.
     336
     337    - ``prec_cap`` -- the power of ``prime`` modulo which elements of largest
     338      precision are defined
     339
     340    - ``ram_prec_cap`` -- approximately ``e*prec_cap``, where ``e`` is
     341      the relative ramification degree of the extension.  For a ramified
     342      extension this is what Sage calls the precision cap of the ring.  In
     343      fact, it's possible to have rings with precision cap not a multiple of
     344      `e`, in which case the actual relationship between ``ram_prec_cap`` and
     345      ``prec_cap`` is that ``prec_cap = ceil(n/e)``
     346
     347    - ``in_field`` -- a boolean; whether the associated ring is actually a
     348      field
     349
     350    - ``poly`` -- the polynomial defining the extension
     351
     352    - `prec_type`` -- one of ``"capped-rel"``, ``"capped-abs"`` or
     353      ``"fixed-mod"``, ``"floating-point"``, the precision type of the ring
     354
     355    .. NOTE::
     356
     357        Because of the way templates work, this function imports the class of
     358        its return value from the appropriate element files.  This means that
     359        the returned PowComputer will have the appropriate compile-time-type
     360        for Cython.
     361
     362    EXAMPLES::
     363
     364        sage: TODO
     365
     366    """
     367    PC = PowComputer_relative_eis(prime, cache_limit, prec_cap, ram_prec_cap, in_field, poly, shift_seed)
     368    PC._prec_type = prec_type
     369    return PC
  • src/sage/rings/padics/qadic_flint_FP.pyx

    diff --git a/src/sage/rings/padics/qadic_flint_FP.pyx b/src/sage/rings/padics/qadic_flint_FP.pyx
    index 0137a9f2da..d27981fadb 100644
    a b cdef class qAdicFloatingPointElement(FPElement): 
    8383            sage: (1+a)*(41*a^2+40*a+42)
    8484            1
    8585        """
     86        if self._is_exact_zero():
     87            raise ValueError("Zero does not have a flint rep")
    8688        return self.prime_pow._new_fmpz_poly(self.unit, var)
    8789
    8890    def _flint_rep_abs(self, var='x'):
    cdef class qAdicFloatingPointElement(FPElement): 
    101103        """
    102104        if self.ordp < 0:
    103105            return self._flint_rep(var), Integer(self.ordp)
     106        if self._is_exact_zero():
     107            raise ValueError("Zero does not have a flint rep")
    104108        cshift(self.prime_pow.poly_flint_rep, self.unit, self.ordp, self.ordp + self.prime_pow.prec_cap, self.prime_pow, False)
    105109        return self.prime_pow._new_fmpz_poly(self.prime_pow.poly_flint_rep, var), Integer(0)
    106110
  • new file src/sage/rings/padics/relative_extension_leaves.py

    diff --git a/src/sage/rings/padics/relative_extension_leaves.py b/src/sage/rings/padics/relative_extension_leaves.py
    new file mode 100644
    index 0000000000..6a7580d261
    - +  
     1"""
     2Relative extensions of `p`-adic rings
     3"""
     4
     5#*****************************************************************************
     6#       Copyright (C) 2017 David Roe <roed.math@gmail.com>
     7#
     8#  Distributed under the terms of the GNU General Public License (GPL)
     9#  as published by the Free Software Foundation; either version 2 of
     10#  the License, or (at your option) any later version.
     11#
     12#                  http://www.gnu.org/licenses/
     13#*****************************************************************************
     14
     15from sage.categories.morphism import Morphism
     16from sage.categories.homset import Hom
     17from .generic_nodes import pAdicFixedModRingGeneric
     18from .eisenstein_extension_generic import EisensteinExtensionGeneric
     19from .relative_ramified_FM import RelativeRamifiedFixedModElement
     20from .pow_computer_relative import PowComputer_relative_maker
     21
     22class RelativeRamifiedExtensionRingFixedMod(EisensteinExtensionGeneric, pAdicFixedModRingGeneric):
     23    def __init__(self, exact_modulus, approx_modulus, prec, print_mode, shift_seed, names, implementation):
     24        self._exact_modulus = exact_modulus
     25        unram_prec = (prec + approx_modulus.degree() - 1) // approx_modulus.degree()
     26        KFP = approx_modulus.base_ring().change(type='floating-point')
     27        self.prime_pow = PowComputer_relative_maker(approx_modulus.base_ring().prime(), max(min(unram_prec - 1, 30), 1), unram_prec, prec, False, exact_modulus.change_ring(KFP), shift_seed.change_ring(KFP), 'fixed-mod')
     28        self._implementation = 'Polynomial'
     29        EisensteinExtensionGeneric.__init__(self, approx_modulus, prec, print_mode, names, RelativeRamifiedFixedModElement)
     30        from .relative_ramified_FM import pAdicCoercion_ZZ_FM, pAdicConvert_QQ_FM
     31        self.register_coercion(pAdicCoercion_ZZ_FM(self))
     32        self.register_coercion(pAdicRelativeBaseringInjection(approx_modulus.base_ring(), self))
     33        self.register_conversion(pAdicConvert_QQ_FM(self))
     34
     35class pAdicRelativeBaseringInjection(Morphism):
     36    def __init__(self, R, S):
     37        if not R.is_field() or S.is_field():
     38            Morphism.__init__(self, Hom(R, S, R.category()))
     39        else:
     40            from sage.categories.sets_with_partial_maps import SetsWithPartialMaps
     41            Morphism.__init__(self, Hom(R, S, SetsWithPartialMaps()))
     42
     43    def _call_(self, x):
     44        return self.codomain()([x])
     45
     46    def _call_with_extra_args(self, x, args=(), kwds={}):
     47        return self.codomain()([x], *args, **kwds)
  • new file src/sage/rings/padics/relative_ramified_FM.pxd

    diff --git a/src/sage/rings/padics/relative_ramified_FM.pxd b/src/sage/rings/padics/relative_ramified_FM.pxd
    new file mode 100644
    index 0000000000..a4861ee39d
    - +  
     1from sage.rings.polynomial.polynomial_element cimport Polynomial_generic_dense_inexact as celement
     2from sage.rings.padics.pow_computer_relative cimport PowComputer_relative_eis as PowComputer_
     3
     4include "FM_template_header.pxi"
     5
     6cdef class RelativeRamifiedFixedModElement(FMElement):
     7    pass
  • new file src/sage/rings/padics/relative_ramified_FM.pyx

    diff --git a/src/sage/rings/padics/relative_ramified_FM.pyx b/src/sage/rings/padics/relative_ramified_FM.pyx
    new file mode 100644
    index 0000000000..01a5fe3c40
    - +  
     1#from types import MethodType
     2
     3include "sage/libs/linkages/padics/Polynomial_ram.pxi"
     4include "FM_template.pxi"
     5
     6cdef class RelativeRamifiedFixedModElement(FMElement):
     7    #frobenius = MethodType(frobenius_unram, None, qAdicFixedModElement)
     8    #trace = MethodType(trace_unram, None, qAdicFixedModElement)
     9    #norm = MethodType(norm_unram, None, qAdicFixedModElement)
     10
     11    def __cinit__(self, parent=None, x=None, absprec=infinity, relprec=infinity):
     12        # It's not possible to set self.value in cconstruct (because of the calling syntax)
     13        # so we do it here.
     14        cdef type t
     15        if parent is not None: # This will break the pickling function
     16            t = type((<PowComputer_?>parent.prime_pow).modulus)
     17            self.value = t.__new__(t)
     18
     19    cdef FMElement _new_c(self):
     20        """
     21        Creates a new element in this ring.
     22
     23        This is meant to be the fastest way to create such an element; much
     24        faster than going through the usual mechanisms which involve
     25        ``__init__``.
     26
     27        TESTS::
     28
     29            sage: R = ZpFM(5); R(6) * R(7) #indirect doctest
     30            2 + 3*5 + 5^2 + O(5^20)
     31
     32        """
     33        cdef type t = type(self)
     34        cdef type polyt = type(self.prime_pow.modulus)
     35        cdef FMElement ans = t.__new__(t)
     36        ans._parent = self._parent
     37        ans.prime_pow = self.prime_pow
     38        ans.value = polyt.__new__(polyt)
     39        cconstruct(ans.value, ans.prime_pow)
     40        return ans
     41
     42    def __reduce__(self):
     43        """
     44        Return a tuple of a function and data that can be used to unpickle this
     45        element.
     46
     47        EXAMPLES::
     48
     49            sage: R.<a> = ZqFM(9)
     50            sage: S.<x> = ZZ[]
     51            sage: W.<w> = R.extension(x^2 - 3)
     52            sage: loads(dumps(w)) == w
     53            True
     54        """
     55        return unpickle_fme_rel_v2, (self.__class__, self.parent(), cpickle(self.value, self.prime_pow))
     56
     57    def _poly_rep(self):
     58        return self.value
     59
     60    #def matrix_mod_pn(self):
     61    #    """
     62    #    Returns the matrix of right multiplication by the element on
     63    #    the power basis `1, x, x^2, \ldots, x^{d-1}` for this
     64    #    extension field.  Thus the *rows* of this matrix give the
     65    #    images of each of the `x^i`.  The entries of the matrices are
     66    #    IntegerMod elements, defined modulo ``p^(self.absprec() / e)``.
     67
     68    #    EXAMPLES::
     69
     70    #        sage: R.<a> = ZqFM(5^5,5)
     71    #        sage: b = (5 + 15*a)^3
     72    #        sage: b.matrix_mod_pn()
     73    #        [ 125 1125  250  250    0]
     74    #        [   0  125 1125  250  250]
     75    #        [2375 2125  125 1125  250]
     76    #        [2375 1375 2125  125 1125]
     77    #        [2875 1000 1375 2125  125]
     78
     79    #        sage: M = R(0,3).matrix_mod_pn(); M == 0
     80    #        True
     81    #        sage: M.base_ring()
     82    #        Ring of integers modulo 3125
     83    #    """
     84    #    return cmatrix_mod_pn(self.value, self.prime_pow.prec_cap, 0, self.prime_pow)
     85
     86    #def _flint_rep(self, var='x'):
     87    #    """
     88    #    Replacement for _ntl_rep for use in printing and debugging.
     89
     90    #    EXAMPLES::
     91
     92    #        sage: R.<a> = ZqFM(27, 4)
     93    #        sage: (1+a).inverse_of_unit()._flint_rep()
     94    #        41*x^2 + 40*x + 42
     95    #        sage: (1+a)*(41*a^2+40*a+42)
     96    #        1 + O(3^4)
     97    #    """
     98    #    return self.prime_pow._new_fmpz_poly(self.value, var)
     99
     100    #def _flint_rep_abs(self, var='x'):
     101    #    """
     102    #    Replacement for _ntl_rep_abs for use in printing and debugging.
     103
     104    #    EXAMPLES::
     105
     106    #        sage: R.<a> = ZqFM(27, 4)
     107    #        sage: (3+3*a)._flint_rep_abs()
     108    #        (3*x + 3, 0)
     109    #    """
     110    #    return self._flint_rep(var), Integer(0)
     111
     112def unpickle_fme_rel_v2(cls, parent, value):
     113    """
     114    Unpickles a fixed mod element.
     115
     116    EXAMPLES::
     117
     118        sage: from sage.rings.padics.relative_ramified_FM import RelativeRamifiedFixedModElement, unpickle_fme_rel_v2
     119        sage: R.<a> = ZqFM(9)
     120        sage: S.<x> = ZZ[]
     121        sage: W.<w> = R.extension(x^2 - 3)
     122        sage: u = unpickle_fme_rel_v2(RelativeRamifiedFixedModElement, W, [a, 1]); u
     123        sage: u.parent() is W
     124        True
     125    """
     126    cdef RelativeRamifiedFixedModElement ans = cls.__new__(cls)
     127    ans._parent = parent
     128    ans.prime_pow = <PowComputer_?>parent.prime_pow
     129    cdef type polyt = type(ans.prime_pow.modulus)
     130    ans.value = polyt.__new__(polyt)
     131    cconstruct(ans.value, ans.prime_pow)
     132    cunpickle(ans.value, value, ans.prime_pow)
     133    return ans
  • src/sage/rings/padics/unramified_extension_generic.py

    diff --git a/src/sage/rings/padics/unramified_extension_generic.py b/src/sage/rings/padics/unramified_extension_generic.py
    index 7a23baf3fc..5263d5bbe8 100644
    a b class UnramifiedExtensionGeneric(pAdicExtensionGeneric): 
    136136        #coercion base.
    137137        return self._res_field
    138138
     139    def residue_ring(self, n):
     140        if n == 1:
     141            return self._res_field
     142        else:
     143            raise NotImplementedError
     144
    139145    def discriminant(self, K=None):
    140146        """
    141147        Returns the discriminant of self over the subring K.
  • src/sage/rings/polynomial/polynomial_element.pxd

    diff --git a/src/sage/rings/polynomial/polynomial_element.pxd b/src/sage/rings/polynomial/polynomial_element.pxd
    index a30609da93..044b80c8a4 100644
    a b cdef class Polynomial(CommutativeAlgebraElement): 
    3131    cdef get_unsafe(self, Py_ssize_t i)
    3232    cpdef long number_of_terms(self)
    3333
     34    # See 23227
     35    cpdef _add_(self, right)
     36    cpdef _mul_(self, right)
     37    cpdef _floordiv_(self, right)
     38
    3439    cdef public dict __cached_methods
    3540
    3641cdef class Polynomial_generic_dense(Polynomial):