(a, d, F, n, DE)
return (delta_a, delta_d, H_list)
Contribution of F to the full partial fraction decomposition of A/D

    Given a field K of characteristic 0 and A,D,F in K[x] with D monic,
    nonzero, coprime with A, and F the factor of multiplicity n in the square-
    free factorization of D, return the principal parts of the Laurent series of
    A/D at all the zeros of F.
Contribution of F to the full partial fraction decomposition of A/D
Contribution of F to the full partial fraction decomposition of A / D
def laurent_series(a, d, F, n, DE):
    """
    Contribution of F to the full partial fraction decomposition of A/D

    Given a field K of characteristic 0 and A,D,F in K[x] with D monic,
    nonzero, coprime with A, and F the factor of multiplicity n in the square-
    free factorization of D, return the principal parts of the Laurent series of
    A/D at all the zeros of F.
    """
    if F.degree()==0:
        return 0
    Z = _symbols('z', n)
    Z.insert(0, z)
    delta_a = Poly(0, DE.t)
    delta_d = Poly(1, DE.t)

    E = d.quo(F**n)
    ha, hd = (a, E*Poly(z**n, DE.t))
    dF = derivation(F,DE)
    B, G = gcdex_diophantine(E, F, Poly(1,DE.t))
    C, G = gcdex_diophantine(dF, F, Poly(1,DE.t))

    # initialization
    F_store = F
    V, DE_D_list, H_list= [], [], []

    for j in range(0, n):
    # jth derivative of z would be substituted with dfnth/(j+1) where dfnth =(d^n)f/(dx)^n
        F_store = derivation(F_store, DE)
        v = (F_store.as_expr())/(j + 1)
        V.append(v)
        DE_D_list.append(Poly(Z[j + 1],Z[j]))

    DE_new = DifferentialExtension(extension = {'D': DE_D_list}) #a differential indeterminate
    for j in range(0, n):
        zEha = Poly(z**(n + j), DE.t)*E**(j + 1)*ha
        zEhd = hd
        Pa, Pd = cancel((zEha, zEhd))[1], cancel((zEha, zEhd))[2]
        Q = Pa.quo(Pd)
        for i in range(0, j + 1):
            Q = Q.subs(Z[i], V[i])
        Dha = hd*derivation(ha, DE, basic=True) + ha*derivation(hd, DE, basic=True)
        Dha += hd*derivation(ha, DE_new, basic=True) + ha*derivation(hd, DE_new, basic=True)
        Dhd = Poly(j + 1, DE.t)*hd**2
        ha, hd = Dha, Dhd

        Ff, Fr = F.div(gcd(F, Q))
        F_stara, F_stard = frac_in(Ff, DE.t)
        if F_stara.degree(DE.t) - F_stard.degree(DE.t) > 0:
            QBC = Poly(Q, DE.t)*B**(1 + j)*C**(n + j)
            H = QBC
            H_list.append(H)
            H = (QBC*F_stard).rem(F_stara)
            alphas = real_roots(F_stara)
            for alpha in list(alphas):
                delta_a = delta_a*Poly((DE.t - alpha)**(n - j), DE.t) + Poly(H.eval(alpha), DE.t)
                delta_d = delta_d*Poly((DE.t - alpha)**(n - j), DE.t)
    return (delta_a, delta_d, H_list)
def laurent_series ( a , d , F , n , DE ) : if F . degree ( ) == 0 : return 0 Z = _symbols ( 'z' , n ) Z . insert ( 0 , z ) delta_a = Poly ( 0 , DE . t ) delta_d = Poly ( 1 , DE . t ) E = d . quo ( F ** n ) ha , hd = ( a , E * Poly ( z ** n , DE . t ) ) dF = derivation ( F , DE ) B , G = gcdex_diophantine ( E , F , Poly ( 1 , DE . t ) ) C , G = gcdex_diophantine ( dF , F , Poly ( 1 , DE . t ) ) # initialization F_store = F V , DE_D_list , H_list = [ ] , [ ] , [ ] for j in range ( 0 , n ) : # jth derivative of z would be substituted with dfnth/(j+1) where dfnth =(d^n)f/(dx)^n F_store = derivation ( F_store , DE ) v = ( F_store . as_expr ( ) ) / ( j + 1 ) V . append ( v ) DE_D_list . append ( Poly ( Z [ j + 1 ] , Z [ j ] ) ) DE_new = DifferentialExtension ( extension = { 'D' : DE_D_list } ) #a differential indeterminate for j in range ( 0 , n ) : zEha = Poly ( z ** ( n + j ) , DE . t ) * E ** ( j + 1 ) * ha zEhd = hd Pa , Pd = cancel ( ( zEha , zEhd ) ) [ 1 ] , cancel ( ( zEha , zEhd ) ) [ 2 ] Q = Pa . quo ( Pd ) for i in range ( 0 , j + 1 ) : Q = Q . subs ( Z [ i ] , V [ i ] ) Dha = hd * derivation ( ha , DE , basic = True ) + ha * derivation ( hd , DE , basic = True ) Dha += hd * derivation ( ha , DE_new , basic = True ) + ha * derivation ( hd , DE_new , basic = True ) Dhd = Poly ( j + 1 , DE . t ) * hd ** 2 ha , hd = Dha , Dhd Ff , Fr = F . div ( gcd ( F , Q ) ) F_stara , F_stard = frac_in ( Ff , DE . t ) if F_stara . degree ( DE . t ) - F_stard . degree ( DE . t ) > 0 : QBC = Poly ( Q , DE . t ) * B ** ( 1 + j ) * C ** ( n + j ) H = QBC H_list . append ( H ) H = ( QBC * F_stard ) . rem ( F_stara ) alphas = real_roots ( F_stara ) for alpha in list ( alphas ) : delta_a = delta_a * Poly ( ( DE . t - alpha ) ** ( n - j ) , DE . t ) + Poly ( H . eval ( alpha ) , DE . t ) delta_d = delta_d * Poly ( ( DE . t - alpha ) ** ( n - j ) , DE . t ) return ( delta_a , delta_d , H_list )