(a, d, DE, z=None, conds='piecewise')
return (ret, i, b)
Integration of hyperexponential functions.

    Given a hyperexponential monomial t over k and f in k(t), return g
    elementary over k(t), i in k(t), and a bool b in {True, False} such that
    i = f - Dg is in k if b is True or i = f - Dg does not have an elementary
    integral over k(t) if b is False.

    This function returns a Basic expression for the first argument.  If b is
    True, the second argument is Basic expression in k to recursively integrate.
    If b is False, the second argument is an unevaluated Integral, which has
    been proven to be nonelementary.
Integration of hyperexponential functions.
Integration of hyperexponential functions .
def integrate_hyperexponential(a, d, DE, z=None, conds='piecewise'):
    """
    Integration of hyperexponential functions.

    Given a hyperexponential monomial t over k and f in k(t), return g
    elementary over k(t), i in k(t), and a bool b in {True, False} such that
    i = f - Dg is in k if b is True or i = f - Dg does not have an elementary
    integral over k(t) if b is False.

    This function returns a Basic expression for the first argument.  If b is
    True, the second argument is Basic expression in k to recursively integrate.
    If b is False, the second argument is an unevaluated Integral, which has
    been proven to be nonelementary.
    """
    # XXX: a and d must be canceled, or this might return incorrect results
    z = z or Dummy("z")
    s = list(zip(reversed(DE.T), reversed([f(DE.x) for f in DE.Tfuncs])))

    g1, h, r = hermite_reduce(a, d, DE)
    g2, b = residue_reduce(h[0], h[1], DE, z=z)
    if not b:
        i = cancel(a.as_expr()/d.as_expr() - (g1[1]*derivation(g1[0], DE) -
            g1[0]*derivation(g1[1], DE)).as_expr()/(g1[1]**2).as_expr() -
            residue_reduce_derivation(g2, DE, z))
        i = NonElementaryIntegral(cancel(i.subs(s)), DE.x)
        return ((g1[0].as_expr()/g1[1].as_expr()).subs(s) +
            residue_reduce_to_basic(g2, DE, z), i, b)

    # p should be a polynomial in t and 1/t, because Sirr == k[t, 1/t]
    # h - Dg2 + r
    p = cancel(h[0].as_expr()/h[1].as_expr() - residue_reduce_derivation(g2,
        DE, z) + r[0].as_expr()/r[1].as_expr())
    pp = as_poly_1t(p, DE.t, z)

    qa, qd, b = integrate_hyperexponential_polynomial(pp, DE, z)

    i = pp.nth(0, 0)

    ret = ((g1[0].as_expr()/g1[1].as_expr()).subs(s) \
        + residue_reduce_to_basic(g2, DE, z))

    qas = qa.as_expr().subs(s)
    qds = qd.as_expr().subs(s)
    if conds == 'piecewise' and DE.x not in qds.free_symbols:
        # We have to be careful if the exponent is S.Zero!

        # XXX: Does qd = 0 always necessarily correspond to the exponential
        # equaling 1?
        ret += Piecewise(
                (integrate((p - i).subs(DE.t, 1).subs(s), DE.x), Eq(qds, 0)),
                (qas/qds, True)
            )
    else:
        ret += qas/qds

    if not b:
        i = p - (qd*derivation(qa, DE) - qa*derivation(qd, DE)).as_expr()/\
            (qd**2).as_expr()
        i = NonElementaryIntegral(cancel(i).subs(s), DE.x)
    return (ret, i, b)
def integrate_hyperexponential ( a , d , DE , z = None , conds = 'piecewise' ) : # XXX: a and d must be canceled, or this might return incorrect results z = z or Dummy ( "z" ) s = list ( zip ( reversed ( DE . T ) , reversed ( [ f ( DE . x ) for f in DE . Tfuncs ] ) ) ) g1 , h , r = hermite_reduce ( a , d , DE ) g2 , b = residue_reduce ( h [ 0 ] , h [ 1 ] , DE , z = z ) if not b : i = cancel ( a . as_expr ( ) / d . as_expr ( ) - ( g1 [ 1 ] * derivation ( g1 [ 0 ] , DE ) - g1 [ 0 ] * derivation ( g1 [ 1 ] , DE ) ) . as_expr ( ) / ( g1 [ 1 ] ** 2 ) . as_expr ( ) - residue_reduce_derivation ( g2 , DE , z ) ) i = NonElementaryIntegral ( cancel ( i . subs ( s ) ) , DE . x ) return ( ( g1 [ 0 ] . as_expr ( ) / g1 [ 1 ] . as_expr ( ) ) . subs ( s ) + residue_reduce_to_basic ( g2 , DE , z ) , i , b ) # p should be a polynomial in t and 1/t, because Sirr == k[t, 1/t] # h - Dg2 + r p = cancel ( h [ 0 ] . as_expr ( ) / h [ 1 ] . as_expr ( ) - residue_reduce_derivation ( g2 , DE , z ) + r [ 0 ] . as_expr ( ) / r [ 1 ] . as_expr ( ) ) pp = as_poly_1t ( p , DE . t , z ) qa , qd , b = integrate_hyperexponential_polynomial ( pp , DE , z ) i = pp . nth ( 0 , 0 ) ret = ( ( g1 [ 0 ] . as_expr ( ) / g1 [ 1 ] . as_expr ( ) ) . subs ( s ) + residue_reduce_to_basic ( g2 , DE , z ) ) qas = qa . as_expr ( ) . subs ( s ) qds = qd . as_expr ( ) . subs ( s ) if conds == 'piecewise' and DE . x not in qds . free_symbols : # We have to be careful if the exponent is S.Zero! # XXX: Does qd = 0 always necessarily correspond to the exponential # equaling 1? ret += Piecewise ( ( integrate ( ( p - i ) . subs ( DE . t , 1 ) . subs ( s ) , DE . x ) , Eq ( qds , 0 ) ) , ( qas / qds , True ) ) else : ret += qas / qds if not b : i = p - ( qd * derivation ( qa , DE ) - qa * derivation ( qd , DE ) ) . as_expr ( ) / ( qd ** 2 ) . as_expr ( ) i = NonElementaryIntegral ( cancel ( i ) . subs ( s ) , DE . x ) return ( ret , i , b )