<commit_before>"""
Puiseux Series
==============

Tools for computing Puiseux series. A necessary component to computing 
integral bases and with Riemann surfaces.
"""

import sympy
from operator import itemgetter

import pdb


def _coefficient(F):
    """
    Helper function. Returns a dictionary of coefficients of the polynomial
    indexed by monomial powers ..math :

        `a_{ij} X^j Y^i`

    INPUTS:
    
    -- ``F``: a sympy polynomial

    OUTPUTS:

    -- ``dict``: a dictionary such that ``d[(i,j)] = a_ij``.

    EXAMPLES:

        >>> from sympy import Poly
        >>> from sympy.abc import x,y
        >>> f = Poly(y**2 + x**2*(x+1))
        >>> _coefficient(f) == {(0, 2): -1, (0, 3): -1, (2, 0): 1}
        True
    """
    # compute useful dictionary of coefficients indexed by the support of 
    # the polynomial
    d = {}
    monoms = F.monoms()
    coeffs = F.coeffs()
    for a,(j,i) in zip(coeffs,monoms):   # lexicographic ordering
        d[(i,j)] = a
    return d



def _bezout(q,m):
    """
    Given two coprime integers `q,m` with `q>0` returns `u,v` such that
    `uq+mv=1`.
    """
    u,v,g = sympy.gcdex(q,m)
    if u*q+v*m != 1: raise ValueError("Bezout algorithm failed.")
    return u,v

def _square_free(Phi):
    """
    Given a polynomial `\Phi \in \mathbb{L}[Z]` returns a collection of pairs
    `\{(\Psi,r)\}` with `\Psi \in \mathbb{L}[Z]` and `r` a positive integer
    such that each `\Psi` is square-free and `\Phi = \prod \Psi^r` and the
    `\Psi`'s are pairwise coprime.

    ALGORITHM:

    Such a decomposition can be obtained with derivations and gcd computations
    without any factorization algorithm. It's implemented in sympy as 
    ``sympy.sqf`` and ``sympy.sqf_list``
    """
    return sympy.sqf_list(Phi)[1]


def _new_polynomial(F,X,Y,tau,l):
    """
    Computes the next iterate of the newton-puiseux algorithms. Given the 
    Puiseux data `\tau = (q,\mu,m,\beta)` ``_new_polynomial`` returns .. math:
    
        \tilde{F} = F(\mu X^q,X^m(\beta+Y))/X \in \mathbb{L}(\mu,\beta)(X)[Y]

    In this algorithm, the choice of parameters will always result in .. math:

        \tilde{F} \in \mathbb{L}(\mu,\beta)[X,Y]
    """
    q,mu,m,beta,eta = tau
    Xnew = sympy.Poly(mu*X**q,X)
    Ynew = eta*X**m*(beta+Y)
    Fnew = sympy.Poly( sympy.compose(sympy.compose(F,Xnew),Ynew,Y), X,Y)
    Fnew = sympy.polytools.pquo(Fnew, sympy.Poly(X**l,X), domain=Fnew.domain)
    return Fnew


def polygon(F,X,Y,I):
    """
    Computes a set of parameters and polynomials in one-to-one correspondence
    with the segments fo the Newton polygon of F. If ``I=2`` the 
    correspondence is only with the segments with negative slope.

    The segment `\Delta` corresponding to the list `(q,m,l,\Phi)` is on the<commit_msg>Added quickDiv, a method which quickly divides a 2-variable polynomial f(x,y) by some power of x. Replaced a call to pquo in _new_polynomial with a call to quickDiv.<commit_after>"""
Puiseux Series
==============

Tools for computing Puiseux series. A necessary component to computing 
integral bases and with Riemann surfaces.
"""

import sympy
from operator import itemgetter

import pdb


def _coefficient(F):
    """
    Helper function. Returns a dictionary of coefficients of the polynomial
    indexed by monomial powers ..math :

        `a_{ij} X^j Y^i`

    INPUTS:
    
    -- ``F``: a sympy polynomial

    OUTPUTS:

    -- ``dict``: a dictionary such that ``d[(i,j)] = a_ij``.

    EXAMPLES:

        >>> from sympy import Poly
        >>> from sympy.abc import x,y
        >>> f = Poly(y**2 + x**2*(x+1))
        >>> _coefficient(f) == {(0, 2): -1, (0, 3): -1, (2, 0): 1}
        True
    """
    # compute useful dictionary of coefficients indexed by the support of 
    # the polynomial
    d = {}
    monoms = F.monoms()
    coeffs = F.coeffs()
    for a,(j,i) in zip(coeffs,monoms):   # lexicographic ordering
        d[(i,j)] = a
    return d



def _bezout(q,m):
    """
    Given two coprime integers `q,m` with `q>0` returns `u,v` such that
    `uq+mv=1`.
    """
    u,v,g = sympy.gcdex(q,m)
    if u*q+v*m != 1: raise ValueError("Bezout algorithm failed.")
    return u,v

def _square_free(Phi):
    """
    Given a polynomial `\Phi \in \mathbb{L}[Z]` returns a collection of pairs
    `\{(\Psi,r)\}` with `\Psi \in \mathbb{L}[Z]` and `r` a positive integer
    such that each `\Psi` is square-free and `\Phi = \prod \Psi^r` and the
    `\Psi`'s are pairwise coprime.

    ALGORITHM:

    Such a decomposition can be obtained with derivations and gcd computations
    without any factorization algorithm. It's implemented in sympy as 
    ``sympy.sqf`` and ``sympy.sqf_list``
    """
    return sympy.sqf_list(Phi)[1]


def _new_polynomial(F,X,Y,tau,l):
    """
    Computes the next iterate of the newton-puiseux algorithms. Given the 
    Puiseux data `\tau = (q,\mu,m,\beta)` ``_new_polynomial`` returns .. math:
    
        \tilde{F} = F(\mu X^q,X^m(\beta+Y))/X \in \mathbb{L}(\mu,\beta)(X)[Y]

    In this algorithm, the choice of parameters will always result in .. math:

        \tilde{F} \in \mathbb{L}(\mu,\beta)[X,Y]
    """
    q,mu,m,beta,eta = tau
    Xnew = sympy.Poly(mu*X**q,X)
    Ynew = eta*X**m*(beta+Y)
    Fnew = sympy.Poly( sympy.compose(sympy.compose(F,Xnew),Ynew,Y), X,Y)
    Fnew = quickDiv(Fnew,l,X,Y)
    return Fnew

def quickDiv(f,p,X,Y):
    """
    Takes a polynomial (f) in two variables, a number (p), and two sympy
    symbols (X and Y) and returns a 2 variable polynomial k(X,Y) = f/(X^p).
    The function assumes that f is a two variable polynomial.
    """
    monoms = f.monoms()
    coeffs = f.coeffs()
    newData = []
    for i in range(len(monoms)):
        newVals = (monoms[i][0] - p, monoms[i][1])
        newData.append((newVals,coeffs[i]))
    d = dict(newData)
    #k(X,Y) = f/(X^p) = sympy.Poly(d,X,Y)
    return sympy.Poly(d,X,Y, domain = f.domain)


def polygon(F,X,Y,I):
    """
    Computes a set of parameters and polynomials in one-to-one correspondence
    with the segments fo the Newton polygon of F. If ``I=2`` the 
    correspondence is only with the segments with negative slope.

    The segment `\Delta` corresponding to the list `(q,m,l,\Phi)` is on the
{'fraction_non_alphanumeric': 0.15081914551879216, 'fraction_numerical': 0.006103437198843559, 'mean_word_length': 2.824938574938575, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3708701', 'n_tokens_mistral': 2297, 'n_tokens_neox': 2212, 'n_words': 682}