(a, d, DE)
return ((ga, gd), (r, d), (rra, rrd))
Hermite Reduction - Mack's Linear Version.

    Given a derivation D on k(t) and f = a/d in k(t), returns g, h, r in
    k(t) such that f = Dg + h + r, h is simple, and r is reduced.
Hermite Reduction - Mack's Linear Version.
Hermite Reduction - Mack s Linear Version .
def hermite_reduce(a, d, DE):
    """
    Hermite Reduction - Mack's Linear Version.

    Given a derivation D on k(t) and f = a/d in k(t), returns g, h, r in
    k(t) such that f = Dg + h + r, h is simple, and r is reduced.

    """
    # Make d monic
    l = Poly(1/d.LC(), DE.t)
    a, d = a.mul(l), d.mul(l)

    fp, fs, fn = canonical_representation(a, d, DE)
    a, d = fn
    l = Poly(1/d.LC(), DE.t)
    a, d = a.mul(l), d.mul(l)

    ga = Poly(0, DE.t)
    gd = Poly(1, DE.t)

    dd = derivation(d, DE)
    dm = gcd(d, dd).as_poly(DE.t)
    ds, r = d.div(dm)

    while dm.degree(DE.t)>0:

        ddm = derivation(dm, DE)
        dm2 = gcd(dm, ddm)
        dms, r = dm.div(dm2)
        ds_ddm = ds.mul(ddm)
        ds_ddm_dm, r = ds_ddm.div(dm)

        b, c = gcdex_diophantine(-ds_ddm_dm.as_poly(DE.t), dms.as_poly(DE.t), a.as_poly(DE.t))
        b, c = b.as_poly(DE.t), c.as_poly(DE.t)

        db = derivation(b, DE).as_poly(DE.t)
        ds_dms, r = ds.div(dms)
        a = c.as_poly(DE.t) - db.mul(ds_dms).as_poly(DE.t)

        ga = ga*dm + b*gd
        gd = gd*dm
        ga, gd = ga.cancel(gd, include=True)
        dm = dm2

    d = ds
    q, r = a.div(d)
    ga, gd = ga.cancel(gd, include=True)

    r, d = r.cancel(d, include=True)
    rra = q*fs[1] + fp*fs[1] + fs[0]
    rrd = fs[1]
    rra, rrd = rra.cancel(rrd, include=True)

    return ((ga, gd), (r, d), (rra, rrd))
def hermite_reduce ( a , d , DE ) : # Make d monic l = Poly ( 1 / d . LC ( ) , DE . t ) a , d = a . mul ( l ) , d . mul ( l ) fp , fs , fn = canonical_representation ( a , d , DE ) a , d = fn l = Poly ( 1 / d . LC ( ) , DE . t ) a , d = a . mul ( l ) , d . mul ( l ) ga = Poly ( 0 , DE . t ) gd = Poly ( 1 , DE . t ) dd = derivation ( d , DE ) dm = gcd ( d , dd ) . as_poly ( DE . t ) ds , r = d . div ( dm ) while dm . degree ( DE . t ) > 0 : ddm = derivation ( dm , DE ) dm2 = gcd ( dm , ddm ) dms , r = dm . div ( dm2 ) ds_ddm = ds . mul ( ddm ) ds_ddm_dm , r = ds_ddm . div ( dm ) b , c = gcdex_diophantine ( - ds_ddm_dm . as_poly ( DE . t ) , dms . as_poly ( DE . t ) , a . as_poly ( DE . t ) ) b , c = b . as_poly ( DE . t ) , c . as_poly ( DE . t ) db = derivation ( b , DE ) . as_poly ( DE . t ) ds_dms , r = ds . div ( dms ) a = c . as_poly ( DE . t ) - db . mul ( ds_dms ) . as_poly ( DE . t ) ga = ga * dm + b * gd gd = gd * dm ga , gd = ga . cancel ( gd , include = True ) dm = dm2 d = ds q , r = a . div ( d ) ga , gd = ga . cancel ( gd , include = True ) r , d = r . cancel ( d , include = True ) rra = q * fs [ 1 ] + fp * fs [ 1 ] + fs [ 0 ] rrd = fs [ 1 ] rra , rrd = rra . cancel ( rrd , include = True ) return ( ( ga , gd ) , ( r , d ) , ( rra , rrd ) )