Ticket #15422: 15422_factorpadic.patch

File 15422_factorpadic.patch, 51.9 KB (added by jdemeyer, 8 years ago)
  • sage/misc/classgraph.py

    # HG changeset patch
    # User Jeroen Demeyer <jdemeyer@cage.ugent.be>
    # Date 1385718102 -3600
    # Node ID f3185fb2a16984a691df7be3d086d79286c58854
    # Parent  f9d6bda1ed496ffcb74233d389f6499535f56539
    Fix p-adic factorizations for non-squarefree polynomials
    
    diff --git a/sage/misc/classgraph.py b/sage/misc/classgraph.py
    a b  
    3434
    3535        sage: from sage.rings.polynomial.padics import polynomial_padic_capped_relative_dense, polynomial_padic_flat
    3636        sage: G = class_graph(sage.rings.polynomial.padics); G
    37         Digraph on 4 vertices
     37        Digraph on 6 vertices
    3838        sage: G.vertices()
    39         ['Polynomial_generic_dense', 'Polynomial_generic_domain', 'Polynomial_padic_capped_relative_dense', 'Polynomial_padic_flat']
     39        ['Polynomial', 'Polynomial_generic_dense', 'Polynomial_generic_domain', 'Polynomial_padic', 'Polynomial_padic_capped_relative_dense', 'Polynomial_padic_flat']
    4040        sage: G.edges(labels=False)
    41         [('Polynomial_padic_capped_relative_dense', 'Polynomial_generic_domain'), ('Polynomial_padic_flat', 'Polynomial_generic_dense')]
     41        [('Polynomial_padic', 'Polynomial'), ('Polynomial_padic_capped_relative_dense', 'Polynomial_generic_domain'), ('Polynomial_padic_capped_relative_dense', 'Polynomial_padic'), ('Polynomial_padic_flat', 'Polynomial_generic_dense'), ('Polynomial_padic_flat', 'Polynomial_padic')]
    4242
    4343    We construct the inheritance graph of a given class::
    4444
     
    5555       can be emulated by setting the option ``as_graph`` to ``False``::
    5656
    5757        sage: class_graph(sage.rings.polynomial.padics, depth=2, as_graph=False)
    58         {'Polynomial_padic_capped_relative_dense': ['Polynomial_generic_domain'],
    59         'Polynomial_padic_flat': ['Polynomial_generic_dense']}
    60 
     58        {'Polynomial_padic': ['Polynomial'],
     59        'Polynomial_padic_capped_relative_dense': ['Polynomial_generic_domain', 'Polynomial_padic'],
     60        'Polynomial_padic_flat': ['Polynomial_generic_dense', 'Polynomial_padic']}
    6161
    6262    .. note:: the ``classes`` and ``as_graph`` options are mostly
    6363       intended for internal recursive use.
     
    6767    TESTS::
    6868
    6969        sage: G = class_graph(sage.rings.polynomial.padics, depth=2); G
    70         Digraph on 4 vertices
     70        Digraph on 6 vertices
    7171    """
    7272    # This function descends recursively down the submodules of the
    7373    # top module (if ``top`` is a module) and then down the hierarchy
  • sage/rings/padics/factory.py

    diff --git a/sage/rings/padics/factory.py b/sage/rings/padics/factory.py
    a b  
    16031603
    16041604        sage: P.<x> = ZZ[]
    16051605        sage: R.<a> = Zq(27, modulus = x^3 + 2*x + 1); R.modulus()
    1606         (1 + O(3^20))*x^3 + (2 + O(3^20))*x + (1 + O(3^20))
     1606        (1 + O(3^20))*x^3 + (O(3^20))*x^2 + (2 + O(3^20))*x + (1 + O(3^20))
    16071607        sage: P.<x> = QQ[]
    16081608        sage: S.<a> = Zq(27, modulus = x^3 + 2/7*x + 1)
    16091609        sage: P.<x> = Zp(3)[]
     
    16381638
    16391639        sage: x = var('x')
    16401640        sage: X.<a> = Zq(27, modulus = x^3 + 2*x + 1); X.modulus()
    1641         (1 + O(3^20))*x^3 + (2 + O(3^20))*x + (1 + O(3^20))
     1641        (1 + O(3^20))*x^3 + (O(3^20))*x^2 + (2 + O(3^20))*x + (1 + O(3^20))
    16421642        sage: X == R
    16431643        True
    16441644
     
    16481648        sage: GF(125, 'a').modulus()
    16491649        x^3 + 3*x + 3
    16501650        sage: Y.<a> = Zq(125); Y.modulus()
    1651         (1 + O(5^20))*x^3 + (3 + O(5^20))*x + (3 + O(5^20))
     1651        (1 + O(5^20))*x^3 + (O(5^20))*x^2 + (3 + O(5^20))*x + (3 + O(5^20))
    16521652
    16531653    However, you can choose another polynomial if desired (as long as
    16541654    the reduction to `\mathbb{F}_p[x]` is irreducible).::
  • sage/rings/padics/local_generic.py

    diff --git a/sage/rings/padics/local_generic.py b/sage/rings/padics/local_generic.py
    a b  
    242242        EXAMPLES::
    243243       
    244244            sage: R = Zp(3, 3, 'fixed-mod'); R.defining_polynomial('foo')
    245             (1 + O(3^3))*foo
     245            (1 + O(3^3))*foo + (O(3^3))
    246246        """
    247247        from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
    248248        return PolynomialRing(self, var).gen()
  • sage/rings/padics/padic_ZZ_pX_CA_element.pyx

    diff --git a/sage/rings/padics/padic_ZZ_pX_CA_element.pyx b/sage/rings/padics/padic_ZZ_pX_CA_element.pyx
    a b  
    7070    sage: S.<x> = ZZ[]
    7171    sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5
    7272    sage: W.<w> = R.ext(f); W
    73     Eisenstein Extension of 5-adic Ring with capped absolute precision 5 in w defined by (1 + O(5^5))*x^5 + (3*5^2 + O(5^5))*x^3 + (2*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))*x^2 + (5^3 + O(5^5))*x + (4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))
     73    Eisenstein Extension of 5-adic Ring with capped absolute precision 5 in w defined by (1 + O(5^5))*x^5 + (O(5^5))*x^4 + (3*5^2 + O(5^5))*x^3 + (2*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))*x^2 + (5^3 + O(5^5))*x + (4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))
    7474    sage: z = (1+w)^5; z
    7575    1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
    7676    sage: y = z >> 1; y
  • sage/rings/padics/padic_ZZ_pX_FM_element.pyx

    diff --git a/sage/rings/padics/padic_ZZ_pX_FM_element.pyx b/sage/rings/padics/padic_ZZ_pX_FM_element.pyx
    a b  
    6161    sage: S.<x> = R[]
    6262    sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5
    6363    sage: W.<w> = R.ext(f); W
    64     Eisenstein Extension of 5-adic Ring of fixed modulus 5^5 in w defined by (1 + O(5^5))*x^5 + (3*5^2 + O(5^5))*x^3 + (2*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))*x^2 + (5^3 + O(5^5))*x + (4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))
     64    Eisenstein Extension of 5-adic Ring of fixed modulus 5^5 in w defined by (1 + O(5^5))*x^5 + (O(5^5))*x^4 + (3*5^2 + O(5^5))*x^3 + (2*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))*x^2 + (5^3 + O(5^5))*x + (4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))
    6565    sage: z = (1+w)^5; z
    6666    1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
    6767    sage: y = z >> 1; y
     
    501501            sage: y = ~z; y # indirect doctest
    502502            1 + 4*w^5 + 4*w^6 + 3*w^7 + w^8 + 2*w^10 + w^11 + w^12 + 2*w^14 + 3*w^16 + 3*w^17 + 4*w^18 + 4*w^19 + 2*w^20 + 2*w^21 + 4*w^22 + 3*w^23 + 3*w^24 + O(w^25)
    503503            sage: y.parent()
    504             Eisenstein Extension of 5-adic Ring of fixed modulus 5^5 in w defined by (1 + O(5^5))*x^5 + (3*5^2 + O(5^5))*x^3 + (2*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))*x^2 + (5^3 + O(5^5))*x + (4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))
     504            Eisenstein Extension of 5-adic Ring of fixed modulus 5^5 in w defined by (1 + O(5^5))*x^5 + (O(5^5))*x^4 + (3*5^2 + O(5^5))*x^3 + (2*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))*x^2 + (5^3 + O(5^5))*x + (4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))
    505505            sage: z = z - 1
    506506            sage: ~z
    507507            Traceback (most recent call last):
     
    527527            sage: y = ~z; y # indirect doctest
    528528            1 + 4*w^5 + 4*w^6 + 3*w^7 + w^8 + 2*w^10 + w^11 + w^12 + 2*w^14 + 3*w^16 + 3*w^17 + 4*w^18 + 4*w^19 + 2*w^20 + 2*w^21 + 4*w^22 + 3*w^23 + 3*w^24 + O(w^25)
    529529            sage: y.parent()
    530             Eisenstein Extension of 5-adic Ring of fixed modulus 5^5 in w defined by (1 + O(5^5))*x^5 + (3*5^2 + O(5^5))*x^3 + (2*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))*x^2 + (5^3 + O(5^5))*x + (4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))
     530            Eisenstein Extension of 5-adic Ring of fixed modulus 5^5 in w defined by (1 + O(5^5))*x^5 + (O(5^5))*x^4 + (3*5^2 + O(5^5))*x^3 + (2*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))*x^2 + (5^3 + O(5^5))*x + (4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5))
    531531            sage: z = z - 1
    532532            sage: ~z
    533533            Traceback (most recent call last):
  • sage/rings/padics/padic_extension_leaves.py

    diff --git a/sage/rings/padics/padic_extension_leaves.py b/sage/rings/padics/padic_extension_leaves.py
    a b  
    177177        EXAMPLES::
    178178
    179179            sage: R.<a> = ZqCA(27,10000); R #indirect doctest
    180             Unramified Extension of 3-adic Ring with capped absolute precision 10000 in a defined by (1 + O(3^10000))*x^3 + (2 + O(3^10000))*x + (1 + O(3^10000))
     180            Unramified Extension of 3-adic Ring with capped absolute precision 10000 in a defined by (1 + O(3^10000))*x^3 + (O(3^10000))*x^2 + (2 + O(3^10000))*x + (1 + O(3^10000))
    181181
    182182            sage: R.<a> = ZqCA(next_prime(10^30)^3, 3); R.prime()
    183183            1000000000000000000000000000057
     
    226226        EXAMPLES::
    227227
    228228            sage: R.<a> = ZqFM(27,10000); R #indirect doctest
    229             Unramified Extension of 3-adic Ring of fixed modulus 3^10000 in a defined by (1 + O(3^10000))*x^3 + (2 + O(3^10000))*x + (1 + O(3^10000))
     229            Unramified Extension of 3-adic Ring of fixed modulus 3^10000 in a defined by (1 + O(3^10000))*x^3 + (O(3^10000))*x^2 + (2 + O(3^10000))*x + (1 + O(3^10000))
    230230
    231231            sage: R.<a> = ZqFM(next_prime(10^30)^3, 3); R.prime()
    232232            1000000000000000000000000000057
     
    406406
    407407            sage: R = ZpCA(3, 10000, print_pos=False); S.<x> = ZZ[]; f = x^3 + 9*x - 3
    408408            sage: W.<w> = R.ext(f); W #indirect doctest
    409             Eisenstein Extension of 3-adic Ring with capped absolute precision 10000 in w defined by (1 + O(3^10000))*x^3 + (3^2 + O(3^10000))*x + (-3 + 3^10000 + O(3^10000))
     409            Eisenstein Extension of 3-adic Ring with capped absolute precision 10000 in w defined by (1 + O(3^10000))*x^3 + (O(3^10000))*x^2 + (3^2 + O(3^10000))*x + (-3 + 3^10000 + O(3^10000))
    410410            sage: W.precision_cap()
    411411            30000
    412412
     
    463463
    464464            sage: R = ZpFM(3, 10000, print_pos=False); S.<x> = ZZ[]; f = x^3 + 9*x - 3
    465465            sage: W.<w> = R.ext(f); W #indirect doctest
    466             Eisenstein Extension of 3-adic Ring of fixed modulus 3^10000 in w defined by (1 + O(3^10000))*x^3 + (3^2 + O(3^10000))*x + (-3 + 3^10000 + O(3^10000))
     466            Eisenstein Extension of 3-adic Ring of fixed modulus 3^10000 in w defined by (1 + O(3^10000))*x^3 + (O(3^10000))*x^2 + (3^2 + O(3^10000))*x + (-3 + 3^10000 + O(3^10000))
    467467            sage: W.precision_cap()
    468468            30000
    469469
  • sage/rings/padics/tutorial.py

    diff --git a/sage/rings/padics/tutorial.py b/sage/rings/padics/tutorial.py
    a b  
    310310
    311311    sage: R.<c> = Zq(125, prec = 20); R
    312312    Unramified Extension of 5-adic Ring with capped absolute precision 20
    313     in c defined by (1 + O(5^20))*x^3 + (3 + O(5^20))*x + (3 + O(5^20))
     313    in c defined by (1 + O(5^20))*x^3 + (O(5^20))*x^2 + (3 + O(5^20))*x + (3 + O(5^20))
    314314
    315315Eisenstein Extensions
    316316---------------------
  • sage/rings/padics/unramified_extension_generic.py

    diff --git a/sage/rings/padics/unramified_extension_generic.py b/sage/rings/padics/unramified_extension_generic.py
    a b  
    5757        EXAMPLES::
    5858
    5959            sage: R.<a> = Zq(125); R #indirect doctest
    60             Unramified Extension of 5-adic Ring with capped absolute precision 20 in a defined by (1 + O(5^20))*x^3 + (3 + O(5^20))*x + (3 + O(5^20))
     60            Unramified Extension of 5-adic Ring with capped absolute precision 20 in a defined by (1 + O(5^20))*x^3 + (O(5^20))*x^2 + (3 + O(5^20))*x + (3 + O(5^20))
    6161            sage: latex(R) #indirect doctest
    6262            \mathbf{Z}_{5^{3}}
    6363        """
  • new file sage/rings/polynomial/padics/polynomial_padic.py

    diff --git a/sage/rings/polynomial/padics/polynomial_padic.py b/sage/rings/polynomial/padics/polynomial_padic.py
    new file mode 100644
    - +  
     1"""
     2Base class for generic `p`-adic polynomials
     3
     4This provides common functionality for all `p`-adic polynomials, such
     5as printing and factoring.
     6
     7AUTHORS:
     8
     9- Jeroen Demeyer (2013-11-22): initial version, split off from other
     10  files, made Polynomial_padic the common base class for all p-adic
     11  polynomials.
     12
     13"""
     14
     15#*****************************************************************************
     16#       Copyright (C) 2007 David Roe <roed.math@gmail.com>
     17#       Copyright (C) 2013 Jeroen Demeyer <jdemeyer@cage.ugent.be>
     18#
     19#  Distributed under the terms of the GNU General Public License (GPL)
     20#  as published by the Free Software Foundation; either version 2 of
     21#  the License, or (at your option) any later version.
     22#                  http://www.gnu.org/licenses/
     23#*****************************************************************************
     24
     25from sage.rings.padics.precision_error import PrecisionError
     26from sage.rings.polynomial.polynomial_element import Polynomial
     27from sage.rings.infinity import infinity
     28
     29class Polynomial_padic(Polynomial):
     30    def __init__(self, parent, x=None, check=True, is_gen=False, construct=False):
     31        Polynomial.__init__(self, parent, is_gen, construct)
     32
     33    def _repr(self, name=None):
     34        r"""
     35        EXAMPLES::
     36       
     37            sage: R.<w> = PolynomialRing(Zp(5, prec=5, type = 'capped-abs', print_mode = 'val-unit'))
     38            sage: f = 24 + R(4/3)*w + w^4
     39            sage: f._repr()
     40            '(1 + O(5^5))*w^4 + (O(5^5))*w^3 + (O(5^5))*w^2 + (1043 + O(5^5))*w + (24 + O(5^5))'
     41            sage: f._repr(name='z')
     42            '(1 + O(5^5))*z^4 + (O(5^5))*z^3 + (O(5^5))*z^2 + (1043 + O(5^5))*z + (24 + O(5^5))'
     43
     44        TESTS::
     45
     46            sage: k = Qp(5,10)
     47            sage: R.<x> = k[]
     48            sage: f = R([k(0,-3), 0, k(0,-1)]); f
     49            (O(5^-1))*x^2 + (O(5^-3))
     50            sage: f + f
     51            (O(5^-1))*x^2 + (O(5^-3))
     52
     53        AUTHOR:
     54
     55        - David Roe (2007-03-03), based on Polynomial_generic_dense._repr()
     56        """
     57        s = ""
     58        coeffs = self.list()
     59        if name is None:
     60            name = self.parent().variable_name()
     61        for n in reversed(xrange(len(coeffs))):
     62            x = coeffs[n]
     63            if x.valuation() != infinity:
     64                if s:
     65                    s += " + "
     66                x = "(%s)"%repr(x)
     67                if n > 1:
     68                    var = "*%s^%s"%(name,n)
     69                elif n==1:
     70                    var = "*%s"%name
     71                else:
     72                    var = ""
     73                s += (x + var)
     74        return s or "0"
     75
     76    def factor(self):
     77        """
     78        Return the factorization of this polynomial.
     79
     80        EXAMPLES::
     81
     82            sage: R.<t> = PolynomialRing(Qp(3,3,print_mode='terse',print_pos=False))
     83            sage: pol = t^8 - 1
     84            sage: for p,e in pol.factor(): print e, p
     85            1 (1 + O(3^3))*t + (1 + O(3^3))
     86            1 (1 + O(3^3))*t + (-1 + O(3^3))
     87            1 (1 + O(3^3))*t^2 + (5 + O(3^3))*t + (-1 + O(3^3))
     88            1 (1 + O(3^3))*t^2 + (-5 + O(3^3))*t + (-1 + O(3^3))
     89            1 (1 + O(3^3))*t^2 + (1 + O(3^3))
     90            sage: R.<t> = PolynomialRing(Qp(5,6,print_mode='terse',print_pos=False))
     91            sage: pol = 100 * (5*t - 1) * (t - 5)
     92            sage: pol
     93            (500 + O(5^9))*t^2 + (-2600 + O(5^8))*t + (500 + O(5^9))
     94            sage: pol.factor()
     95            (500 + O(5^9)) * ((1 + O(5^5))*t + (-1/5 + O(5^5))) * ((1 + O(5^6))*t + (-5 + O(5^6)))
     96            sage: pol.factor().value()
     97            (500 + O(5^8))*t^2 + (-2600 + O(5^8))*t + (500 + O(5^8))
     98
     99        The same factorization over `\ZZ_p`. In this case, the "unit"
     100        part is a `p`-adic unit and the power of `p` is considered to be
     101        a factor::
     102
     103            sage: R.<t> = PolynomialRing(Zp(5,6,print_mode='terse',print_pos=False))
     104            sage: pol = 100 * (5*t - 1) * (t - 5)
     105            sage: pol
     106            (500 + O(5^9))*t^2 + (-2600 + O(5^8))*t + (500 + O(5^9))
     107            sage: pol.factor()
     108            (4 + O(5^6)) * ((5 + O(5^7)))^2 * ((1 + O(5^6))*t + (-5 + O(5^6))) * ((5 + O(5^6))*t + (-1 + O(5^6)))
     109            sage: pol.factor().value()
     110            (500 + O(5^8))*t^2 + (-2600 + O(5^8))*t + (500 + O(5^8))
     111           
     112        In the following example, the discriminant is zero, so the `p`-adic
     113        factorization is not well defined::
     114
     115            sage: factor(t^2)
     116            Traceback (most recent call last):
     117            ...
     118            PrecisionError: p-adic factorization not well-defined since the discriminant is zero up to the requestion p-adic precision
     119
     120        More examples over `\ZZ_p`::
     121
     122            sage: R.<w> = PolynomialRing(Zp(5, prec=6, type = 'capped-abs', print_mode = 'val-unit'))
     123            sage: f = w^5-1
     124            sage: f.factor()
     125            ((1 + O(5^6))*w + (3124 + O(5^6))) * ((1 + O(5^6))*w^4 + (12501 + O(5^6))*w^3 + (9376 + O(5^6))*w^2 + (6251 + O(5^6))*w + (3126 + O(5^6)))
     126
     127        See :trac:`4038`::
     128
     129            sage: E = EllipticCurve('37a1')
     130            sage: K =Qp(7,10)                 
     131            sage: EK = E.base_extend(K)
     132            sage: E = EllipticCurve('37a1')
     133            sage: K = Qp(7,10)             
     134            sage: EK = E.base_extend(K)   
     135            sage: g = EK.division_polynomial_0(3)
     136            sage: g.factor()
     137            (3 + O(7^10)) * ((1 + O(7^10))*x + (1 + 2*7 + 4*7^2 + 2*7^3 + 5*7^4 + 7^5 + 5*7^6 + 3*7^7 + 5*7^8 + 3*7^9 + O(7^10))) * ((1 + O(7^10))*x^3 + (6 + 4*7 + 2*7^2 + 4*7^3 + 7^4 + 5*7^5 + 7^6 + 3*7^7 + 7^8 + 3*7^9 + O(7^10))*x^2 + (6 + 3*7 + 5*7^2 + 2*7^4 + 7^5 + 7^6 + 2*7^8 + 3*7^9 + O(7^10))*x + (2 + 5*7 + 4*7^2 + 2*7^3 + 6*7^4 + 3*7^5 + 7^6 + 4*7^7 + O(7^10)))
     138
     139        TESTS:
     140
     141        Check that :trac:`13293` is fixed::
     142
     143            sage: R.<T> = Qp(3)[]
     144            sage: f = 1926*T^2 + 312*T + 387
     145            sage: f.factor()
     146            (3^2 + 2*3^3 + 2*3^4 + 3^5 + 2*3^6 + O(3^22)) * ((1 + O(3^19))*T + (2*3^-1 + 3 + 3^2 + 2*3^5 + 2*3^6 + 2*3^7 + 3^8 + 3^9 + 2*3^11 + 3^15 + 3^17 + O(3^19))) * ((1 + O(3^20))*T + (2*3 + 3^2 + 3^3 + 3^5 + 2*3^6 + 2*3^7 + 3^8 + 3^10 + 3^11 + 2*3^12 + 2*3^14 + 2*3^15 + 2*3^17 + 2*3^18 + O(3^20)))
     147        """
     148        if self == 0:
     149            raise ArithmeticError("factorization of 0 not defined")
     150        # Scale self such that 0 is the lowest valuation
     151        # amongst the coefficients
     152        try:
     153            val = self.valuation(val_of_var=0)
     154        except TypeError:
     155            val = min([c.valuation() for c in self])
     156        self_normal = self / self.base_ring().uniformizer_pow(val)
     157
     158        absprec = min([x.precision_absolute() for x in self_normal])
     159        if self_normal.discriminant().valuation() >= absprec:
     160            raise PrecisionError(
     161                "p-adic factorization not well-defined since the discriminant is zero up to the requestion p-adic precision")
     162        G = self_normal._pari_().factorpadic(self.base_ring().prime(), absprec)
     163        return _pari_padic_factorization_to_sage(G, self.parent(), self.leading_coefficient())
     164
     165def _pari_padic_factorization_to_sage(G, R, leading_coeff):
     166    """
     167    Given a PARI factorization matrix `G` representing a factorization
     168    of some polynomial in the `p`-adic polynomial ring `R`,
     169    return the corresponding Sage factorization. All factors in `G`
     170    are assumed to have content 1 (this is how PARI returns its
     171    factorizations).
     172
     173    INPUT:
     174
     175    - ``G`` -- PARI factorization matrix, returned by ``factorpadic``.
     176
     177    - ``R`` -- polynomial ring to be used as parent ring of the factors
     178
     179    - ``leading_coeff`` -- leading coefficient of the polynomial which
     180      was factored. This can belong to any ring which can be coerced
     181      into ``R.base_ring()``.
     182
     183    OUTPUT:
     184
     185    - A Sage :class:`Factorization`.
     186
     187    """
     188    B = R.base_ring()
     189    p = B.prime()
     190    leading_coeff = B(leading_coeff)
     191
     192    pols = [R(f, absprec=f.padicprec(p)) for f in G[0]]
     193    exps = [int(e) for e in G[1]]
     194       
     195    # Determine unit part (which is discarded by PARI)
     196    if B.is_field():
     197        # When the base ring is a field, we normalize
     198        # the irreducible factors so they have leading
     199        # coefficient 1.
     200        for i in xrange(len(pols)):
     201            lc = pols[i].leading_coefficient()
     202            lc = lc.lift_to_precision()  # Ensure we don't lose precision
     203            pols[i] *= ~lc
     204    else:
     205        # When the base ring is not a field, we normalize
     206        # the irreducible factors so that the leading term
     207        # is a power of p.
     208        c, leading_coeff = leading_coeff.val_unit()
     209        for i in xrange(len(pols)):
     210            v, upart = pols[i].leading_coefficient().val_unit()
     211            upart = upart.lift_to_precision()  # Ensure we don't lose precision
     212            pols[i] *= ~upart
     213            c -= exps[i] * v
     214        if c:
     215            # Add factor p^c
     216            pols.append(R(p))
     217            exps.append(c)
     218
     219    from sage.structure.factorization import Factorization
     220    return Factorization(zip(pols, exps), leading_coeff)
  • sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py

    diff --git a/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py b/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py
    a b  
    22p-adic Capped Relative Dense Polynomials
    33"""
    44
     5#*****************************************************************************
     6#  Distributed under the terms of the GNU General Public License (GPL)
     7#  as published by the Free Software Foundation; either version 2 of
     8#  the License, or (at your option) any later version.
     9#                  http://www.gnu.org/licenses/
     10#*****************************************************************************
     11
    512import sage.rings.polynomial.polynomial_element_generic
    613from sage.rings.polynomial.polynomial_element import Polynomial
     14from sage.rings.polynomial.padics.polynomial_padic import Polynomial_padic
    715import sage.rings.polynomial.polynomial_integer_dense_ntl
    816import sage.rings.integer
    917import sage.rings.integer_ring
     
    1422
    1523from sage.libs.all import pari, pari_gen
    1624from sage.libs.ntl.all import ZZX
    17 from sage.structure.factorization import Factorization
    1825from sage.rings.infinity import infinity
    1926
    2027min = misc.min
     
    2431Polynomial_generic_domain = sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_domain
    2532Polynomial_integer_dense = sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl
    2633
    27 class Polynomial_padic_capped_relative_dense(Polynomial_generic_domain):
     34class Polynomial_padic_capped_relative_dense(Polynomial_generic_domain, Polynomial_padic):
    2835    def __init__(self, parent, x=None, check=True, is_gen=False, construct = False, absprec = infinity, relprec = infinity):
    2936        """
    3037        TESTS::
     
    303310            self._comp_list()
    304311        return list(self._list)
    305312
    306     def _repr(self, name=None):
    307         """
    308         TESTS::
    309 
    310             sage: k = Qp(5,10)
    311             sage: R.<x> = k[]
    312             sage: f = R([k(0,-3), 0, k(0,-1)]); f
    313             (O(5^-1))*x^2 + (O(5^-3))
    314             sage: f + f
    315             (O(5^-1))*x^2 + (O(5^-3))
    316         """
    317         # TODO: what is new here (that doesn't come from parent class)?
    318         s = " "
    319         coeffs = self.list()
    320         m = len(coeffs)
    321         while m > 0 and coeffs[m-1].valuation() == infinity:
    322             m -= 1
    323         r = reversed(xrange(m))
    324         if name is None:
    325             name = self.parent().variable_name()
    326         for n in r:
    327             x = coeffs[n]
    328             if x.valuation() < infinity:
    329                 if n != m-1:
    330                     s += " + "
    331                 x = "(%s)"%x
    332                 if n > 1:
    333                     var = "*%s^%s"%(name,n)
    334                 elif n==1:
    335                     var = "*%s"%name
    336                 else:
    337                     var = ""
    338                 s += "%s%s"%(x,var)
    339         if s==" ":
    340             return "0"
    341         return s[1:]
    342 
    343313    def content(self):
    344314        """
    345315        Returns the content of self.
     
    11241094            raise PrecisionError, "Polynomial is not known to high enough precision"
    11251095        return self._poly.factor_mod(self.base_ring().prime())
    11261096
    1127     def factor(self):
    1128         # This will eventually be improved.
    1129         if self == 0:
    1130             raise ValueError, "Factorization of the zero polynomial not defined"
    1131         from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
    1132         from sage.rings.padics.factory import ZpCA
    1133         base = self.base_ring()
    1134         #print self.list()
    1135         m = min([x.precision_absolute() for x in self.list()])
    1136         #print m
    1137         R = ZpCA(base.prime(), prec = m)
    1138         S = PolynomialRing(R, self.parent().variable_name())
    1139         F = S(self).factor()
    1140         return Factorization([(self.parent()(a), b) for (a, b) in F], base(F.unit()))
    1141 
    11421097def _extend_by_infinity(L, n):
    11431098    return L + [infinity] * (n - len(L))
    11441099
  • sage/rings/polynomial/padics/polynomial_padic_flat.py

    diff --git a/sage/rings/polynomial/padics/polynomial_padic_flat.py b/sage/rings/polynomial/padics/polynomial_padic_flat.py
    a b  
    1 from sage.rings.integer import Integer
     1"""
     2p-adic Flat Polynomials
     3"""
     4
     5#*****************************************************************************
     6#  Distributed under the terms of the GNU General Public License (GPL)
     7#  as published by the Free Software Foundation; either version 2 of
     8#  the License, or (at your option) any later version.
     9#                  http://www.gnu.org/licenses/
     10#*****************************************************************************
     11
    212from sage.rings.polynomial.polynomial_element import Polynomial_generic_dense, Polynomial
     13from sage.rings.polynomial.padics.polynomial_padic import Polynomial_padic
    314from sage.rings.infinity import infinity
    415from sage.libs.all import pari_gen
    5 from sage.structure.factorization import Factorization
    616import sage.rings.padics.misc
    717
    8 class Polynomial_padic_flat(Polynomial_generic_dense):
     18class Polynomial_padic_flat(Polynomial_generic_dense, Polynomial_padic):
    919    def __init__(self, parent, x=None, check=True, is_gen=False, construct=False, absprec=None):
    1020        """
    11         Initialization function for the class  Polynomial_padic_flat.
     21        Initialization function for the class Polynomial_padic_flat.
    1222        """
    13        
    1423        if x is None:
    15             Polynomial_generic_dense.__init__(self, parent, x = None, is_gen = is_gen)
     24            Polynomial_generic_dense.__init__(self, parent, x, check, is_gen, construct)
    1625            return
    1726        R = parent.base_ring()
    1827        if sage.rings.fraction_field_element.is_FractionFieldElement(x):
     
    5261            absprec = infinity
    5362        m = min([a.precision_absolute() for a in x] + [absprec])
    5463        Polynomial_generic_dense.__init__(self, parent, x, absprec = m)
    55 
    56     def _mul_(self, right):
    57         """
    58         Returns the product of this Polynomial_padic_flat by right.
    59         """
    60         return self._mul_generic(right)
    61 
    62     def _repr(self, name=None):
    63         r"""
    64         EXAMPLES:
    65             sage: R.<w> = PolynomialRing(Zp(5, prec=5, type = 'capped-abs', print_mode = 'val-unit'))
    66             sage: f = 24 + R(4/3)*w + w^4
    67             sage: f._repr()
    68             '(1 + O(5^5))*w^4 + (1043 + O(5^5))*w + (24 + O(5^5))'
    69             sage: f._repr(name='z')
    70             '(1 + O(5^5))*z^4 + (1043 + O(5^5))*z + (24 + O(5^5))'
    71 
    72         AUTHOR:
    73             -- David Roe (2007-03-03), based on Polynomial_generic_dense._repr()
    74         """
    75         s = " "
    76         n = m = self.degree()
    77         if name is None:
    78             name = self.parent().variable_name()
    79         #atomic_repr = self.parent().base_ring()._repr_option('element_is_atomic')
    80         coeffs = self.list()
    81         for x in reversed(coeffs):
    82             if x != 0:
    83                 if n != m:
    84                     s += " + "
    85                 #x = repr(x)
    86                 x = "(%s)"%x
    87                 if n > 1:
    88                     var = "*%s^%s"%(name,n)
    89                 elif n==1:
    90                     var = "*%s"%name
    91                 else:
    92                     var = ""
    93                 s += "%s%s"%(x,var)
    94             n -= 1
    95         if s==" ":
    96             return "0"
    97         return s[1:]
    98 
    99     def factor(self, absprec = None):
    100         r"""
    101         Returns the factorization of this Polynomial_padic_flat.
    102 
    103         EXAMPLES:
    104             sage: R.<w> = PolynomialRing(Zp(5, prec=5, type = 'capped-abs', print_mode = 'val-unit'))
    105             sage: f = w^5-1
    106             sage: f.factor()
    107             ((1 + O(5^5))*w + (624 + O(5^5))) * ((1 + O(5^5))*w^4 + (2501 + O(5^5))*w^3 + (1876 + O(5^5))*w^2 + (1251 + O(5^5))*w + (626 + O(5^5)))
    108 
    109         See \#4038:
    110             sage: E = EllipticCurve('37a1')
    111             sage: K =Qp(7,10)                 
    112             sage: EK = E.base_extend(K)
    113             sage: E = EllipticCurve('37a1')
    114             sage: K = Qp(7,10)             
    115             sage: EK = E.base_extend(K)   
    116             sage: g = EK.division_polynomial_0(3)
    117             sage: g.factor()
    118             (3 + O(7^10)) * ((1 + O(7^10))*x + (1 + 2*7 + 4*7^2 + 2*7^3 + 5*7^4 + 7^5 + 5*7^6 + 3*7^7 + 5*7^8 + 3*7^9 + O(7^10))) * ((1 + O(7^10))*x^3 + (6 + 4*7 + 2*7^2 + 4*7^3 + 7^4 + 5*7^5 + 7^6 + 3*7^7 + 7^8 + 3*7^9 + O(7^10))*x^2 + (6 + 3*7 + 5*7^2 + 2*7^4 + 7^5 + 7^6 + 2*7^8 + 3*7^9 + O(7^10))*x + (2 + 5*7 + 4*7^2 + 2*7^3 + 6*7^4 + 3*7^5 + 7^6 + 4*7^7 + O(7^10)))
    119 
    120         TESTS:
    121 
    122         Check that :trac:`13293` is fixed::
    123 
    124             sage: R.<T>=Qp(3)[]
    125             sage: f=1926*T^2 + 312*T + 387
    126             sage: f.factor()
    127             (1 + 2*3 + 2*3^2 + 3^3 + 2*3^4 + O(3^20)) * ((3 + O(3^21))) * ((1 + O(3^20))*T + (2*3 + 3^2 + 3^3 + 3^5 + 2*3^6 + 2*3^7 + 3^8 + 3^10 + 3^11 + 2*3^12 + 2*3^14 + 2*3^15 + 2*3^17 + 2*3^18 + 3^20 + O(3^21))) * ((3 + O(3^21))*T + (2 + 3^2 + 3^3 + 2*3^6 + 2*3^7 + 2*3^8 + 3^9 + 3^10 + 2*3^12 + 3^16 + 3^18 + O(3^20)))
    128         """
    129         if self == 0:
    130             raise ValueError, "Factorization of 0 not defined"
    131         if absprec is None:
    132             absprec = min([x.precision_absolute() for x in self.list()])
    133         else:
    134             absprec = Integer(absprec)
    135         if absprec <= 0:
    136             raise ValueError, "absprec must be positive"
    137         G = self._pari_().factorpadic(self.base_ring().prime(), absprec)
    138         pols = G[0]
    139         exps = G[1]
    140         F = []
    141         R = self.parent()
    142         for i in xrange(len(pols)):
    143             f = R(pols[i], absprec = absprec)
    144             e = int(exps[i])
    145             F.append((f,e))
    146            
    147         #if R.base_ring().is_field():
    148         #    # When the base ring is a field we normalize
    149         #    # the irreducible factors so they have leading
    150         #    # coefficient 1.
    151         #    for i in range(len(F)):
    152         #        cur = F[i][0].leading_coefficient()
    153         #        if cur != 1:
    154         #            F[i] = (F[i][0].monic(), F[i][1])
    155         #    return Factorization(F, self.leading_coefficient())
    156         #else:
    157         #    # When the base ring is not a field, we normalize
    158         #    # the irreducible factors so that the leading term
    159         #    # is a power of p.  We also ensure that the gcd of
    160         #    # the coefficients of each term is 1.
    161         c = self.leading_coefficient().valuation()
    162         u = self.base_ring()(1)
    163         for i in range(len(F)):
    164             upart = F[i][0].leading_coefficient().unit_part().lift_to_precision(absprec)
    165             lval = F[i][0].leading_coefficient().valuation()
    166             if upart != 1:
    167                 F[i] = (F[i][0] / upart, F[i][1])
    168                 u *= upart ** F[i][1]
    169             c -= lval * F[i][1]
    170         if c != 0:
    171             F.append((self.parent()(self.base_ring().prime_pow(c)), 1))
    172             u = u.add_bigoh(absprec - c)
    173         return Factorization(F, u)
  • sage/rings/polynomial/polynomial_element.pyx

    diff --git a/sage/rings/polynomial/polynomial_element.pyx b/sage/rings/polynomial/polynomial_element.pyx
    a b  
    7474from sage.rings.rational_field import QQ, is_RationalField
    7575from sage.rings.integer_ring import ZZ, is_IntegerRing
    7676from sage.rings.fraction_field import is_FractionField
     77from sage.rings.padics.generic_nodes import is_pAdicRing, is_pAdicField
    7778
    7879from sage.rings.integral_domain import is_IntegralDomain
    7980from sage.structure.parent_gens cimport ParentWithGens
     
    46364637            newself = bigring(self)
    46374638            newother = bigring(other)
    46384639            return self.parent().base_ring()(newself.resultant(newother,bigring(self.parent().gen())))
    4639         # Main variable is "x": we can use PARI to compute the resultant
    4640         res = self._pari_with_name().polresultant(other._pari_with_name(), variable)
     4640        # Single-variable polynomial or main variable is "x": we can use PARI to compute the resultant
     4641        res = self._pari_with_name().polresultant(other._pari_with_name())
    46414642        return self.parent().base_ring()(res)
    46424643
    46434644    def discriminant(self):
     
    47334734            54
    47344735            sage: ZZ.quo(9)[x](2*x^3 + x^2 + x).discriminant()
    47354736            2
     4737
     4738        This was fixed by :trac:`15422`::
     4739
     4740            sage: R.<s> = PolynomialRing(Qp(2))
     4741            sage: (s^2).discriminant()
     4742            0
    47364743        """
    47374744        if self.is_zero():
    47384745            return self.parent().zero_element()
     
    53065313            Traceback (most recent call last):
    53075314            ...
    53085315            TypeError: Cannot evaluate symbolic expression to a numeric value.
     5316
     5317        We can find roots of polynomials defined over `\ZZ` or `\QQ`
     5318        over the `p`-adics, see :trac:`15422`::
     5319
     5320            sage: R.<x> = ZZ[]
     5321            sage: pol = (x - 1)^2
     5322            sage: pol.roots(Qp(3,5))
     5323            [(1 + O(3^5), 2)]
     5324
     5325        This doesn't work if we first change coefficients to `\QQ_p`::
     5326
     5327            sage: pol.change_ring(Qp(3,5)).roots()
     5328            Traceback (most recent call last):
     5329            ...
     5330            PrecisionError: p-adic factorization not well-defined since the discriminant is zero up to the requestion p-adic precision
     5331
     5332            sage: (pol - 3^6).roots(Qp(3,5))
     5333            [(1 + 2*3^3 + 2*3^4 + O(3^5), 1), (1 + 3^3 + O(3^5), 1)]
     5334            sage: r = pol.roots(Zp(3,5), multiplicities=False); r
     5335            [1 + O(3^5)]
     5336            sage: parent(r[0])
     5337            3-adic Ring with capped relative precision 5
    53095338        """
    53105339        K = self.parent().base_ring()
    53115340        if hasattr(K, '_roots_univariate_polynomial'):
    53125341            return K._roots_univariate_polynomial(self, ring=ring, multiplicities=multiplicities, algorithm=algorithm)
    53135342       
    5314         seq = []
    53155343        L = K if ring is None else ring
    53165344
    53175345        late_import()
     
    54015429
    54025430        if L != K or is_AlgebraicField_common(L):
    54035431            # So far, the only "special" implementations are for real
    5404             # and complex root isolation.
     5432            # and complex root isolation and for p-adic factorization
    54055433            if (is_IntegerRing(K) or is_RationalField(K)
    54065434                or is_AlgebraicRealField(K)) and \
    54075435                (is_AlgebraicRealField(L) or is_RealIntervalField(L)):
     
    54605488                    real_field = RealField(L.prec())
    54615489
    54625490                return self.change_ring(real_field).roots(ring=L, multiplicities=multiplicities, algorithm=algorithm)
    5463             else:
    5464                 return self.change_ring(L).roots(multiplicities=multiplicities, algorithm=algorithm)
     5491            elif is_pAdicRing(L) or is_pAdicField(L):
     5492                p = L.prime()
     5493                n = L.precision_cap()
     5494                try:
     5495                    F = self.factor_padic(p, n)
     5496                except AttributeError:
     5497                    pass
     5498                else:
     5499                    return self.change_ring(L)._roots_from_factorization(F, multiplicities)
     5500
     5501            return self.change_ring(L).roots(multiplicities=multiplicities, algorithm=algorithm)
    54655502
    54665503        try:
    54675504            if K.is_integral_domain():
     
    54745511                        self = self//c
    54755512                    except AttributeError:
    54765513                        pass
    5477                 rts = self.factor()
     5514                return self._roots_from_factorization(self.factor(), multiplicities)
    54785515            else:
    54795516                raise NotImplementedError
    54805517        except NotImplementedError:
     
    54865523               
    54875524            raise NotImplementedError("root finding for this polynomial not implemented")
    54885525
    5489         for fac in rts:
     5526    def _roots_from_factorization(self, F, multiplicities):
     5527        """
     5528        Given a factorization ``F`` of the polynomial ``self``, return
     5529        the roots of ``self``.
     5530
     5531        EXAMPLES::
     5532
     5533            sage: R.<x> = ZZ[]
     5534            sage: pol = 20*x^3 - 50*x^2 + 20*x
     5535            sage: F = pol.factor(); F
     5536            2 * 5 * (x - 2) * x * (2*x - 1)
     5537            sage: pol._roots_from_factorization(F, multiplicities=True)
     5538            [(2, 1), (0, 1)]
     5539            sage: pol.change_ring(QQ)._roots_from_factorization(F, multiplicities=False)
     5540            [2, 0, 1/2]
     5541        """
     5542        seq = []
     5543        K = self.parent().base_ring()
     5544        for fac in F:
    54905545            g = fac[0]                                                       
    54915546            if g.degree() == 1:
    54925547                rt = -g[0]/g[1]
  • sage/rings/polynomial/polynomial_element_generic.py

    diff --git a/sage/rings/polynomial/polynomial_element_generic.py b/sage/rings/polynomial/polynomial_element_generic.py
    a b  
    2121    x^2 + (-z^2 - 1)*x
    2222"""
    2323
    24 ################################################################################
     24#*****************************************************************************
    2525#       Copyright (C) 2007 William Stein <wstein@gmail.com>
    2626#
    2727#  Distributed under the terms of the GNU General Public License (GPL)
    28 #
     28#  as published by the Free Software Foundation; either version 2 of
     29#  the License, or (at your option) any later version.
    2930#                  http://www.gnu.org/licenses/
    30 ################################################################################
     31#*****************************************************************************
    3132
    3233from sage.rings.polynomial.polynomial_element import Polynomial, Polynomial_generic_dense
    3334from sage.structure.element import IntegralDomainElement, EuclideanDomainElement
    3435
    3536from sage.rings.polynomial.polynomial_singular_interface import Polynomial_singular_repr
    3637
    37 
    3838from sage.libs.pari.all import pari_gen
    39 from sage.structure.factorization import Factorization
    4039from sage.structure.element import coerce_binop
    4140
    4241from sage.rings.infinity import infinity
    4342from sage.rings.integer_ring import ZZ
    44 import sage.rings.integer as integer
    4543
    46 import sage.rings.polynomial.polynomial_ring
    4744
    48                
    4945class Polynomial_generic_sparse(Polynomial):
    5046    """
    5147    A generic sparse polynomial.
     
    732728register_unpickle_override( \
    733729    'sage.rings.polynomial.polynomial_element_generic', \
    734730    'Polynomial_rational_dense', Polynomial_rational_flint)
    735 
    736 class Polynomial_padic_generic_dense(Polynomial_generic_dense, Polynomial_generic_domain):
    737     def __init__(self, parent, x=None, check=True, is_gen = False, construct=False, absprec=None):
    738         Polynomial_generic_dense.__init__(self, parent, x, check, is_gen, absprec=absprec)
    739 
    740     def _mul_(self, right):
    741         return self._mul_generic(right)
    742 
    743     def __pow__(self, right):
    744         #computing f^p in this way loses precision
    745         return self._pow(right)
    746 
    747     def clear_zeros(self):
    748         """
    749         This function replaces coefficients of the polynomial that evaluate as equal to 0 with the zero element of the base ring that has the maximum possible precision.
    750        
    751         WARNING: this function mutates the underlying polynomial.
    752         """
    753         coeffs = self._Polynomial_generic_dense__coeffs
    754         for n in range(len(coeffs)):
    755             if not coeffs[n]:
    756                 self._Polynomial_generic_dense__coeffs[n] = self.base_ring()(0)
    757 
    758     def _repr(self, name=None):
    759         r"""
    760         EXAMPLES::
    761 
    762             sage: R.<w> = PolynomialRing(Zp(5, prec=5, type = 'capped-abs', print_mode = 'val-unit'))
    763             sage: f = 24 + R(4/3)*w + w^4
    764             sage: f._repr()
    765             '(1 + O(5^5))*w^4 + (1043 + O(5^5))*w + (24 + O(5^5))'
    766             sage: f._repr(name='z')
    767             '(1 + O(5^5))*z^4 + (1043 + O(5^5))*z + (24 + O(5^5))'
    768 
    769         AUTHOR:
    770         - David Roe (2007-03-03), based on Polynomial_generic_dense._repr()
    771         """
    772         s = " "
    773         n = m = self.degree()
    774         if name is None:
    775             name = self.parent().variable_name()
    776         coeffs = self.list()
    777         for x in reversed(coeffs):
    778             if x.valuation() != infinity:
    779                 if n != m:
    780                     s += " + "
    781                 x = repr(x)
    782                 x = "(%s)"%x
    783                 if n > 1:
    784                     var = "*%s^%s"%(name,n)
    785                 elif n==1:
    786                     var = "*%s"%name
    787                 else:
    788                     var = ""
    789                 s += "%s%s"%(x,var)
    790             n -= 1
    791         if s==" ":
    792             return "0"
    793         return s[1:]
    794 
    795 
    796     def factor(self, absprec = None):
    797         if self == 0:
    798             raise ValueError, "Factorization of 0 not defined"
    799         if absprec is None:
    800             absprec = min([x.precision_absolute() for x in self.list()])
    801         else:
    802             absprec = integer.Integer(absprec)
    803         if absprec <= 0:
    804             raise ValueError, "absprec must be positive"
    805         G = self._pari_().factorpadic(self.base_ring().prime(), absprec)
    806         pols = G[0]
    807         exps = G[1]
    808         F = []
    809         R = self.parent()
    810         for i in xrange(len(pols)):
    811             f = R(pols[i], absprec = absprec)
    812             e = int(exps[i])
    813             F.append((f,e))
    814            
    815         if R.base_ring().is_field():
    816             # When the base ring is a field we normalize
    817             # the irreducible factors so they have leading
    818             # coefficient 1.
    819             for i in range(len(F)):
    820                 cur = F[i][0].leading_coefficient()
    821                 if cur != 1:
    822                     F[i] = (F[i][0].monic(), F[i][1])
    823             return Factorization(F, self.leading_coefficient())
    824         else:
    825             # When the base ring is not a field, we normalize
    826             # the irreducible factors so that the leading term
    827             # is a power of p.  We also ensure that the gcd of
    828             # the coefficients of each term is 1.
    829             c = self.leading_coefficient().valuation()
    830             u = self.base_ring()(1)
    831             for i in range(len(F)):
    832                 upart = F[i][0].leading_coefficient().unit_part()
    833                 lval = F[i][0].leading_coefficient().valuation()
    834                 if upart != 1:
    835                     F[i] = (F[i][0] // upart, F[i][1])
    836                     u *= upart ** F[i][1]
    837                 c -= lval
    838             if c != 0:
    839                 F.append((self.parent()(self.base_ring().prime_pow(c)), 1))
    840             return Factorization(F, u)
    841 
    842 class Polynomial_padic_ring_dense(Polynomial_padic_generic_dense):
    843     def content(self):
    844         if self == 0:
    845             return self.base_ring()(0)
    846         else:
    847             return self.base_ring()(self.base_ring().prime_pow(min([x.valuation() for x in self.list()])))
    848 
    849 class Polynomial_padic_field_dense(Polynomial_padic_generic_dense, Polynomial_generic_dense_field):
    850     def content(self):
    851         if self != 0:
    852             return self.base_ring()(1)
    853         else:
    854             return self.base_ring()(0)
    855 
    856 class Polynomial_padic_ring_lazy_dense(Polynomial_padic_ring_dense):
    857     pass
    858 
    859 class Polynomial_padic_field_lazy_dense(Polynomial_padic_field_dense):
    860     pass
    861 
  • sage/rings/polynomial/polynomial_integer_dense_flint.pyx

    diff --git a/sage/rings/polynomial/polynomial_integer_dense_flint.pyx b/sage/rings/polynomial/polynomial_integer_dense_flint.pyx
    a b  
    12671267        Return `p`-adic factorization of self to given precision.
    12681268
    12691269        INPUT:
    1270        
     1270
    12711271        - ``p`` -- prime
     1272
    12721273        - ``prec`` -- integer; the precision
    12731274
    12741275        OUTPUT:
    12751276
    1276         factorization of self reduced modulo p.
     1277        - factorization of ``self`` over the completion at `p`.
    12771278
    12781279        EXAMPLES::
    12791280
     
    12811282            sage: f = x^2 + 1
    12821283            sage: f.factor_padic(5, 4)
    12831284            ((1 + O(5^4))*x + (2 + 5 + 2*5^2 + 5^3 + O(5^4))) * ((1 + O(5^4))*x + (3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4)))
    1284            
     1285
     1286        A more difficult example::
     1287
     1288            sage: f = 100 * (5*x + 1)^2 * (x + 5)^2
     1289            sage: f.factor_padic(5, 10)
     1290            (4 + O(5^10)) * ((5 + O(5^11)))^2 * ((1 + O(5^10))*x + (5 + O(5^10)))^2 * ((5 + O(5^10))*x + (1 + O(5^10)))^2
     1291
    12851292        """
    12861293        from sage.rings.padics.factory import Zp
     1294
    12871295        p = Integer(p)
    1288         if not p.is_prime():
    1289             raise ValueError, "p must be prime"
    12901296        prec = Integer(prec)
    1291         if prec <= 0:
    1292             raise ValueError, "prec must be positive"
    1293         K = Zp(p, prec, type='capped-abs')
     1297
     1298        # Parent field for coefficients and polynomial
     1299        K = Zp(p, prec, type='capped-rel')
    12941300        R = K[self.parent().variable_name()]
    1295         return R(self).factor()
    1296      
     1301       
     1302        # Factor the *exact* polynomial using factorpadic()
     1303        G = self._pari_with_name().factorpadic(p, prec)
     1304
     1305        from sage.rings.polynomial.padics.polynomial_padic import _pari_padic_factorization_to_sage
     1306        return _pari_padic_factorization_to_sage(G, R, self.leading_coefficient())
    12971307
    12981308    def list(self):
    12991309        """
  • sage/rings/polynomial/polynomial_integer_dense_ntl.pyx

    diff --git a/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx b/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx
    a b  
    989989
    990990    def factor_padic(self, p, prec=10):
    991991        """
    992         Return p-adic factorization of self to given precision.
     992        Return `p`-adic factorization of self to given precision.
    993993
    994994        INPUT:
    995995
    996996        - ``p`` -- prime
     997
    997998        - ``prec`` -- integer; the precision
    998999
    999         OUTPUT: factorization of self reduced modulo p.
     1000        OUTPUT:
     1001
     1002        - factorization of ``self`` over the completion at `p`.
    10001003
    10011004        EXAMPLES::
    10021005
     
    10041007            sage: f = x^2 + 1
    10051008            sage: f.factor_padic(5, 4)
    10061009            ((1 + O(5^4))*x + (2 + 5 + 2*5^2 + 5^3 + O(5^4))) * ((1 + O(5^4))*x + (3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4)))
    1007            
     1010
     1011        A more difficult example::
     1012
     1013            sage: f = 100 * (5*x + 1)^2 * (x + 5)^2
     1014            sage: f.factor_padic(5, 10)
     1015            (4 + O(5^10)) * ((5 + O(5^11)))^2 * ((1 + O(5^10))*x + (5 + O(5^10)))^2 * ((5 + O(5^10))*x + (1 + O(5^10)))^2
     1016
    10081017        """
    10091018        from sage.rings.padics.factory import Zp
     1019
    10101020        p = Integer(p)
    1011         if not p.is_prime():
    1012             raise ValueError, "p must be prime"
    10131021        prec = Integer(prec)
    1014         if prec <= 0:
    1015             raise ValueError, "prec must be positive"
    1016         K = Zp(p, prec, type='capped-abs')
     1022
     1023        # Parent field for coefficients and polynomial
     1024        K = Zp(p, prec, type='capped-rel')
    10171025        R = K[self.parent().variable_name()]
    1018         return R(self).factor()
    1019      
     1026       
     1027        # Factor the *exact* polynomial using factorpadic()
     1028        G = self._pari_with_name().factorpadic(p, prec)
     1029
     1030        from sage.rings.polynomial.padics.polynomial_padic import _pari_padic_factorization_to_sage
     1031        return _pari_padic_factorization_to_sage(G, R, self.leading_coefficient())
    10201032
    10211033    def list(self):
    10221034        """
  • sage/rings/polynomial/polynomial_rational_flint.pyx

    diff --git a/sage/rings/polynomial/polynomial_rational_flint.pyx b/sage/rings/polynomial/polynomial_rational_flint.pyx
    a b  
    15501550   
    15511551    def factor_padic(self, p, prec=10):
    15521552        """
    1553         Returns the ``p``-adic factorization of this polynomial to the given
     1553        Return the `p`-adic factorization of this polynomial to the given
    15541554        precision.
    1555        
     1555
    15561556        INPUT:
    1557        
     1557
    15581558        -  ``p`` - Prime number
     1559
    15591560        -  ``prec`` - Integer; the precision
    1560        
     1561
    15611562        OUTPUT:
    1562        
    1563         -  Factorization of ``self`` viewed as a ``p``-adic polynomial
    1564        
     1563
     1564        - factorization of ``self`` viewed as a `p`-adic polynomial
     1565
    15651566        EXAMPLES::
    1566        
     1567
    15671568            sage: R.<x> = QQ[]
    15681569            sage: f = x^3 - 2
    15691570            sage: f.factor_padic(2)
    1570             (1 + O(2^10))*x^3 + (O(2^10))*x^2 + (O(2^10))*x + (2 + 2^2 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^8 + 2^9 + O(2^10))
     1571            (1 + O(2^10))*x^3 + (2 + 2^2 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^8 + 2^9 + O(2^10))
    15711572            sage: f.factor_padic(3)
    1572             (1 + O(3^10))*x^3 + (O(3^10))*x^2 + (O(3^10))*x + (1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + O(3^10))
     1573            (1 + O(3^10))*x^3 + (1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + O(3^10))
    15731574            sage: f.factor_padic(5)
    15741575            ((1 + O(5^10))*x + (2 + 4*5 + 2*5^2 + 2*5^3 + 5^4 + 3*5^5 + 4*5^7 + 2*5^8 + 5^9 + O(5^10))) * ((1 + O(5^10))*x^2 + (3 + 2*5^2 + 2*5^3 + 3*5^4 + 5^5 + 4*5^6 + 2*5^8 + 3*5^9 + O(5^10))*x + (4 + 5 + 2*5^2 + 4*5^3 + 4*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 4*5^9 + O(5^10)))
     1576
     1577        The input polynomial is considered to have "infinite" precision,
     1578        therefore the `p`-adic factorization of the polynomial is not
     1579        the same as first coercing to `Q_p` and then factoring
     1580        (see also :trac:`15422`)::
     1581
     1582            sage: f = x^2 - 3^6
     1583            sage: f.factor_padic(3,5)
     1584            ((1 + O(3^5))*x + (3^3 + O(3^5))) * ((1 + O(3^5))*x + (2*3^3 + 2*3^4 + O(3^5)))
     1585            sage: f.change_ring(Qp(3,5)).factor()
     1586            Traceback (most recent call last):
     1587            ...
     1588            PrecisionError: p-adic factorization not well-defined since the discriminant is zero up to the requestion p-adic precision
     1589
     1590        A more difficult example::
     1591
     1592            sage: f = 100 * (5*x + 1)^2 * (x + 5)^2
     1593            sage: f.factor_padic(5, 10)
     1594            (4*5^4 + O(5^14)) * ((1 + O(5^9))*x + (5^-1 + O(5^9)))^2 * ((1 + O(5^10))*x + (5 + O(5^10)))^2
     1595
     1596        Try some bogus inputs::
     1597
     1598            sage: f.factor_padic(3,-1)
     1599            Traceback (most recent call last):
     1600            ...
     1601            ValueError: prec_cap must be non-negative.
     1602            sage: f.factor_padic(6,10)
     1603            Traceback (most recent call last):
     1604            ...
     1605            ValueError: p must be prime
     1606            sage: f.factor_padic('hello', 'world')
     1607            Traceback (most recent call last):
     1608            ...
     1609            TypeError: unable to convert x (=hello) to an integer
    15751610        """
    15761611        from sage.rings.padics.factory import Qp
    1577        
     1612
    15781613        p = Integer(p)
    1579         if not p.is_prime():
    1580             raise ValueError, "p must be prime"
    15811614        prec = Integer(prec)
    1582         if prec <= 0:
    1583             raise ValueError, "prec must be positive"
    1584        
     1615
     1616        # Parent field for coefficients and polynomial
    15851617        K = Qp(p, prec, type='capped-rel')
    15861618        R = K[self.parent().variable_name()]
    1587         return R(self).factor()  # absprec = prec
    1588    
     1619
     1620        # Factor the *exact* polynomial using factorpadic()
     1621        G = self._pari_with_name().factorpadic(p, prec)
     1622
     1623        from sage.rings.polynomial.padics.polynomial_padic import _pari_padic_factorization_to_sage
     1624        return _pari_padic_factorization_to_sage(G, R, self.leading_coefficient())
     1625
    15891626    def hensel_lift(self, p, e):
    15901627        r"""
    15911628        Assuming that this polynomial factors modulo `p` into distinct
  • sage/tests/french_book/polynomes.py

    diff --git a/sage/tests/french_book/polynomes.py b/sage/tests/french_book/polynomes.py
    a b  
    162162  sage: p.roots(QQ)
    163163  [(2, 2), (1/2, 2)]
    164164  sage: p.roots(Zp(19, print_max_terms=3))
    165   [(2 + 6*19^10 + 9*19^11 + ... + O(19^20), 1),
    166   (7 + 16*19 + 17*19^2 + ... + O(19^20), 1),
    167   (10 + 9*19 + 9*19^2 + ... + O(19^20), 1),
    168   (10 + 9*19 + 9*19^2 + ... + O(19^20), 1),
     165  [(7 + 16*19 + 17*19^2 + ... + O(19^20), 1),
    169166  (12 + 2*19 + 19^2 + ... + O(19^20), 1),
    170   (2 + 13*19^10 + 9*19^11 + ... + O(19^20), 1)]
     167  (10 + 9*19 + 9*19^2 + ... + O(19^20), 2),
     168  (2 + O(19^20), 2)]
    171169
    172170Sage example in ./polynomes.tex, line 623::
    173171