Ejemplo n.º 1
0
    def newton_polygon(self):
        r"""
        Returns a list of vertices of the Newton polygon of this polynomial.

        .. NOTE::

            If some coefficients have not enough precision an error is raised.

        EXAMPLES::

            sage: K = Qp(5)
            sage: R.<t> = K[]
            sage: f = 5 + 3*t + t^4 + 25*t^10
            sage: f.newton_polygon()
            Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2)

            sage: g = f + K(0,0)*t^4; g
            (5^2 + O(5^22))*t^10 + (O(5^0))*t^4 + (3 + O(5^20))*t + (5 + O(5^21))
            sage: g.newton_polygon()
            Traceback (most recent call last):
            ...
            PrecisionError: The coefficient of t^4 has not enough precision

        TESTS:

        Check that :trac:`22936` is fixed::

            sage: S.<x> = PowerSeriesRing(GF(5))
            sage: R.<y> = S[]
            sage: p = x^2+y+x*y^2
            sage: p.newton_polygon()
            Finite Newton polygon with 3 vertices: (0, 2), (1, 0), (2, 1)

        AUTHOR:

        - Xavier Caruso (2013-03-20)
        """
        d = self.degree()
        from sage.geometry.newton_polygon import NewtonPolygon
        polygon = NewtonPolygon([(x, self[x].valuation()) for x in range(d+1)])
        polygon_prec = NewtonPolygon([ (x, self[x].precision_absolute()) for x in range(d+1) ])
        vertices = polygon.vertices(copy=False)
        vertices_prec = polygon_prec.vertices(copy=False)
        if len(vertices_prec) > 0:
            if vertices[0][0] > vertices_prec[0][0]:
                raise PrecisionError("first term with non-infinite valuation must have determined valuation")
            elif vertices[-1][0] < vertices_prec[-1][0]:
                raise PrecisionError("last term with non-infinite valuation must have determined valuation")
            else:
                for (x, y) in vertices:
                    if polygon_prec(x) <= y:
                         raise PrecisionError("The coefficient of %s^%s has not enough precision" % (self.parent().variable_name(), x))
        return polygon
Ejemplo n.º 2
0
    def newton_polygon(self):
        r"""
        Returns a list of vertices of the Newton polygon of this polynomial.

        .. NOTE::

            If some coefficients have not enough precision an error is raised.

        EXAMPLES::

            sage: K = Qp(5)
            sage: R.<t> = K[]
            sage: f = 5 + 3*t + t^4 + 25*t^10
            sage: f.newton_polygon()
            Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2)

            sage: g = f + K(0,0)*t^4; g
            (5^2 + O(5^22))*t^10 + (O(5^0))*t^4 + (3 + O(5^20))*t + (5 + O(5^21))
            sage: g.newton_polygon()
            Traceback (most recent call last):
            ...
            PrecisionError: The coefficient of t^4 has not enough precision

        TESTS:

        Check that :trac:`22936` is fixed::

            sage: S.<x> = PowerSeriesRing(GF(5))
            sage: R.<y> = S[]
            sage: p = x^2+y+x*y^2
            sage: p.newton_polygon()
            Finite Newton polygon with 3 vertices: (0, 2), (1, 0), (2, 1)

        AUTHOR:

        - Xavier Caruso (2013-03-20)
        """
        d = self.degree()
        from sage.geometry.newton_polygon import NewtonPolygon
        polygon = NewtonPolygon([(x, self[x].valuation()) for x in range(d+1)])
        polygon_prec = NewtonPolygon([ (x, self[x].precision_absolute()) for x in range(d+1) ])
        vertices = polygon.vertices(copy=False)
        vertices_prec = polygon_prec.vertices(copy=False)
        if len(vertices_prec) > 0:
            if vertices[0][0] > vertices_prec[0][0]:
                raise PrecisionError("first term with non-infinite valuation must have determined valuation")
            elif vertices[-1][0] < vertices_prec[-1][0]:
                raise PrecisionError("last term with non-infinite valuation must have determined valuation")
            else:
                for (x, y) in vertices:
                    if polygon_prec(x) <= y:
                         raise PrecisionError("The coefficient of %s^%s has not enough precision" % (self.parent().variable_name(), x))
        return polygon
Ejemplo n.º 3
0
def component_jumps(xi0, xi1):
    r""" Helper function for ``permanent_completion``.

    """
    from sage.geometry.newton_polygon import NewtonPolygon
    from mclf.berkovich.berkovich_line import valuations_from_inequality
    from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
    from mclf.berkovich.berkovich_line import TypeIIPointOnBerkovichLine

    assert xi0.is_leq(xi1), "xi0 has to be an ancestor of xi1"
    X = xi0.berkovich_line()
    vK = X.base_valuation()

    v0 = xi0.pseudovaluation_on_polynomial_ring()
    v1 = xi1.pseudovaluation_on_polynomial_ring()
    y = xi1.parameter()
    if hasattr(v1, "phi"):
        phi = v1.phi()
        # v1 is an inductive valuation
    else:
        phi = v1._G
        # v1 is a limit valuation
    assert v0(phi) < v1(phi), "xi0 is not an ancestor of xi1!"
    R = phi.parent()
    x = R.gen()
    S = PolynomialRing(R, 'T')
    T = S.gen()
    G = phi(x + T)
    NP = NewtonPolygon([(i, v1(G[i])) for i in range(G.degree() + 1)])
    V = []
    vertices = NP.vertices()
    for k in range(len(vertices) - 1):
        i, ai = vertices[k]
        j, aj = vertices[k + 1]
        a0 = aj - j * (ai - aj) / (i - j)
        # print("a0 = ", a0)
        V += valuations_from_inequality(vK, phi, a0, v0)
    ret = [TypeIIPointOnBerkovichLine(X, (v, y)) for v in V]
    """
    if xi1.is_in_unit_disk():
        ret = [X.point_from_polynomial_pseudovaluation(v) for v in V]
    else:
        ret = [X.point_from_polynomial_pseudovaluation(v, in_unit_disk=False) for v in V]
    """
    return [xi for xi in ret if (xi0.is_leq(xi) and xi.is_leq(xi1))]
Ejemplo n.º 4
0
    def is_approximate_irreducible_factor(self, g, f, v=None):
        r"""
        Check whether ``g`` is an approximate irreducible factor of ``f``.

        INPUT:

        - ``g``: univariate polynomial over the underlying number field `K_0`
        - ``f``: univariate polynomial over `K_0`
        - ``v``: a MacLane valuation on `K_0[x]` approximating ``g``, or ``None``;
          here *approximating* means that ``LimitValuation(v, g)`` is well-defined.

        Output: True if ``g`` is an approximate irreducible factor of f, i.e.
        if g is irreducible over `K` and Krasner's condition is satified,
        If true, the stem field of ``g`` over `K` is a subfield of the
        splitting field of ``f`` over `K`.

        Her we say that *Krasner's Condition* holds if for some root `\alpha`
        of `g` there exists a root `\beta` of `f` such that `\alpha` is `p`-adically
        closer to `\beta` than to any other root of `g`.

        Note that if `\deg(g)=1` then the condition is nontrivial, even though
        the conclusion from Krasner's Lemma is trivial.

        """
        K = self.number_field()
        vK = self.valuation()
        assert K.has_coerce_map_from(f.parent().base_ring())
        f = f.change_ring(K)
        R = f.parent()
        assert K.has_coerce_map_from(g.parent().base_ring())
        g = R(g)
        assert g.is_monic(), 'g has to be monic'
        f = f.monic()
        if g == f:
            return True
        x = R.gen()

        if g.degree() == 1:             # the case deg(g)=1 is different
            alpha = -g[0]               # the unique root of g
            F = f(x+alpha)
            if F[0] == 0:               # alpha is an exact root of f
                return True
            np_f = NewtonPolygon([(i, vK(F[i])) for i in range(F.degree()+1)])
            # the slopes correspond to vK(alpha-beta), beta the roots of f
            return ( len(np_f.vertices())>1 and np_f.vertices()[1][0]==1 and
                    np_f.slopes()[0]<0 )

        # now deg(g)>1
        if v == None:
            V = vK.mac_lane_approximants(g)
            if len(V) != 1:
                return False   # g is not irreducible
            v = V[0]
        v = LimitValuation(v, g)
        # if v(f) == Infinity:
        if (v._G).divides(f):
            return True
        # the valuation v has the property
        #        v(h)=vK(h(alpha))
        # for all h in K[x], where alpha is a root of g

        S = PolynomialRing(R, 'T')
        G = g(x + S.gen()).shift(-1)
        np_g = NewtonPolygon([(i, v(G[i])) for i in range(G.degree()+1)])
        # the slopes of np_g correspond to the valuations of
        # alpha-alpha_i, where alpha_i runs over all roots of
        # g distinct from alpha

        F = f(x + S.gen())
        np_f = NewtonPolygon([(i, v(F[i])) for i in range(F.degree()+1)])
        # the slopes of np_f correspond to the valuations of
        # alpha-beta, where beta runs over all roots of f

        result = min(np_g.slopes()) > min(np_f.slopes())
        # this is true if there is a root beta of f
        # such that vK(alpha-beta)>vK(alpha-alpha_i) for all i
        return result
Ejemplo n.º 5
0
    def newton_polygon(self):
        r"""
        Returns the Newton polygon of this polynomial.

        .. NOTE::

            If some coefficients have not enough precision an error is raised.

        OUTPUT:

        - a Newton polygon

        EXAMPLES::

            sage: K = Qp(2, prec=5)
            sage: P.<x> = K[]
            sage: f = x^4 + 2^3*x^3 + 2^13*x^2 + 2^21*x + 2^37
            sage: f.newton_polygon()
            Finite Newton polygon with 4 vertices: (0, 37), (1, 21), (3, 3), (4, 0)

            sage: K = Qp(5)
            sage: R.<t> = K[]
            sage: f = 5 + 3*t + t^4 + 25*t^10
            sage: f.newton_polygon()
            Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2)

        Here is an example where the computation fails because precision is
        not sufficient::

            sage: g = f + K(0,0)*t^4; g
            (5^2 + O(5^22))*t^10 + (O(5^0))*t^4 + (3 + O(5^20))*t + (5 + O(5^21))
            sage: g.newton_polygon()
            Traceback (most recent call last):
            ...
            PrecisionError: The coefficient of t^4 has not enough precision

        TESTS::

            sage: (5*f).newton_polygon()
            Finite Newton polygon with 4 vertices: (0, 2), (1, 1), (4, 1), (10, 3)

        AUTHOR:

        - Xavier Caruso (2013-03-20)
        """
        if self._valaddeds is None:
            self._comp_valaddeds()
        from sage.geometry.newton_polygon import NewtonPolygon
        valbase = self._valbase
        polygon = NewtonPolygon([(x, val + valbase)
                                 for x, val in enumerate(self._valaddeds)])
        polygon_prec = NewtonPolygon([(x, val + valbase)
                                      for x, val in enumerate(self._relprecs)])
        vertices = polygon.vertices(copy=False)
        vertices_prec = polygon_prec.vertices(copy=False)

        # The two following tests should always fail (i.e. the corresponding errors
        # should never be raised). However, it's probably safer to keep them.
        if vertices[0][0] > vertices_prec[0][0]:
            raise PrecisionError("The constant coefficient has not enough precision")
        if vertices[-1][0] < vertices_prec[-1][0]:
            raise PrecisionError("The leading coefficient has not enough precision")

        for (x, y) in vertices:
            if polygon_prec(x) <= y:
                raise PrecisionError("The coefficient of %s^%s has not enough precision" % (self.parent().variable_name(), x))
        return polygon
Ejemplo n.º 6
0
class NewtonBigOh_polynomial(BigOh_polynomial):
    def _init_(self, parent, prec, check=True):
        from sage.geometry.newton_polygon import NewtonPolygon, NewtonPolygon_element

        if isinstance(prec, NewtonPolygon_element):
            self._polygon = prec
        else:
            if not isinstance(prec, list):
                prec = [prec]
                # raise TypeError("prec must be either a Newton polygon, a list of coordinates (x,y) or a list of precisions")
            dimension = parent.dimension()
            vertices = []
            if len(prec) > 0:
                if isinstance(prec[0], tuple):
                    for p in prec:
                        if isinstance(p, tuple) and (len(p) == 2):
                            if (p[0] < 0) or (p[0] >= dimension):
                                raise IndexError
                            val = p[1]
                            if isinstance(val, Integer) or val is Infinity:
                                vertices.append((p[0], val))
                            else:
                                try:
                                    val = self._baseprec(val).flat_below()
                                except TypeError:
                                    raise TypeError(
                                        "prec must be either a Newton polygon, a list of coordinates (x,y) or a list of precisions"
                                    )
                                vertices.append((p[0], val))
                        else:
                            raise TypeError(
                                "prec must be either a Newton polygon, a list of coordinates (x,y) or a list of precisions"
                            )
                else:
                    if len(prec) > dimension:
                        raise ValueError("list too long")
                    for i in range(len(prec)):
                        val = prec[i]
                        if isinstance(val, Integer) or val is Infinity:
                            vertices.append((i, val))
                        else:
                            try:
                                val = self._baseprec(val).flat_below()
                            except TypeError:
                                raise TypeError(
                                    "prec must be either a Newton polygon, a list of coordinates (x,y) or a list of precisions"
                                )
                            vertices.append((i, val))
            self._polygon = NewtonPolygon(vertices)

    def _convert_(self, parent, prec):
        vertices = []
        for i in range(prec.last()):
            vertices.append((i, prec[i].flat_below()))
        from sage.geometry.newton_polygon import NewtonPolygon

        self._polygon = NewtonPolygon(vertices)

    def is_exact(self):
        return len(self._polygon.vertices()) == 0

    def _getitem_by_num(self, i):
        from sage.functions.other import ceil

        val = self._polygon(i)
        if val is Infinity:
            return self._base_exactprec
        else:
            return self._baseprec(ceil(val))

    def _add_(self, other):
        return self.__class__(self.parent(), self._polygon + other._polygon)

    def _mul_(self, other):
        return self.__class__(self.parent(), self._polygon * other._polygon)

    def _lmul_(self, coeff):
        return self.__class__(self.parent(), self._polygon.__lshift__(coeff.flat_below()))

    def _rmul_(self, coeff):
        return self.__class__(self.parent(), self._polygon.__lshift__(coeff.flat_below()))

    def __pow__(self, exp, ignored=None):
        return self.__class__(self.parent(), self._polygon ** exp)

    def first(self):
        vertices = self._polygon.vertices()
        if len(vertices) == 0:
            return self.parent().dimension()
        else:
            return vertices[0][0]

    def last(self):
        vertices = self._polygon.vertices()
        if len(vertices) == 0:
            return 0
        else:
            return vertices[-1][0] + 1

    def __lshift__(self, i):
        return self.__class__(self.parent(), self._polygon.__lshift__(i))

    def __rshift__(self, i):
        return self.__class__(self.parent(), self._polygon.__rshift__(i))

    def flat_below(self):
        vertices = self._polygon.vertices()
        if len(vertices) == 0:
            return Infinity
        else:
            return min([v[1] for v in vertices])

    def to_workprec(self, last=None):
        vertices = self._polygon.vertices()
        if len(vertices) == 0:
            return Infinity
        last_x = vertices[-1][0] + 1
        if last is None:
            last = last_x
        if last > len(vertices):
            return Infinity
        elif last < len(vertices):
            raise ValueError("still inexact BigOh's after last")  # is it really an error?
        else:
            return max([v[1] for v in vertices])

    def equals(self, other):
        return self._polygon == other._polygon

    def contains(self, other):
        return self._polygon <= other._polygon

    def _repr_(self, model):
        return BigOh_polynomial._repr_(self, model)