(eq)
return Pow(exp(logcombine(Mul(*add))), e*Mul(*other))
Denest powers.

    This is a helper function for powdenest that performs the actual
    transformation.
Denest powers.
Denest powers .
def _denest_pow(eq):
    """
    Denest powers.

    This is a helper function for powdenest that performs the actual
    transformation.
    """
    b, e = eq.as_base_exp()

    # denest exp with log terms in exponent
    if b is S.Exp1 and e.is_Mul:
        logs = []
        other = []
        for ei in e.args:
            if any(ai.func is C.log for ai in Add.make_args(ei)):
                logs.append(ei)
            else:
                other.append(ei)
        logs = logcombine(Mul(*logs))
        return Pow(exp(logs), Mul(*other))

    _, be = b.as_base_exp()
    if be is S.One and not (b.is_Mul or
                            b.is_Rational and b.q != 1 or
                            b.is_positive):
        return eq

    # denest eq which is either pos**e or Pow**e or Mul**e or
    # Mul(b1**e1, b2**e2)

    # handle polar numbers specially
    polars, nonpolars = [], []
    for bb in Mul.make_args(b):
        if bb.is_polar:
            polars.append(bb.as_base_exp())
        else:
            nonpolars.append(bb)
    if len(polars) == 1 and not polars[0][0].is_Mul:
        return Pow(polars[0][0], polars[0][1]*e)*powdenest(Mul(*nonpolars)**e)
    elif polars:
        return Mul(*[powdenest(bb**(ee*e)) for (bb, ee) in polars]) \
            *powdenest(Mul(*nonpolars)**e)

    # see if there is a positive, non-Mul base at the very bottom
    exponents = []
    kernel = eq
    while kernel.is_Pow:
        kernel, ex = kernel.as_base_exp()
        exponents.append(ex)
    if kernel.is_positive:
        e = Mul(*exponents)
        if kernel.is_Mul:
            b = kernel
        else:
            if kernel.is_Integer:
                # use log to see if there is a power here
                logkernel = expand_log(log(kernel))
                if logkernel.is_Mul:
                    c, logk = logkernel.args
                    e *= c
                    kernel = logk.args[0]
            return Pow(kernel, e)

    # if any factor is an atom then there is nothing to be done
    # but the kernel check may have created a new exponent
    if any(s.is_Atom for s in Mul.make_args(b)):
        if exponents:
            return b**e
        return eq

    # let log handle the case of the base of the argument being a mul, e.g.
    # sqrt(x**(2*i)*y**(6*i)) -> x**i*y**(3**i) if x and y are positive; we
    # will take the log, expand it, and then factor out the common powers that
    # now appear as coefficient. We do this manually since terms_gcd pulls out
    # fractions, terms_gcd(x+x*y/2) -> x*(y + 2)/2 and we don't want the 1/2;
    # gcd won't pull out numerators from a fraction: gcd(3*x, 9*x/2) -> x but
    # we want 3*x. Neither work with noncommutatives.

    def nc_gcd(aa, bb):
        a, b = [i.as_coeff_Mul() for i in [aa, bb]]
        c = gcd(a[0], b[0]).as_numer_denom()[0]
        g = Mul(*(a[1].args_cnc(cset=True)[0] & b[1].args_cnc(cset=True)[0]))
        return _keep_coeff(c, g)

    glogb = expand_log(log(b))
    if glogb.is_Add:
        args = glogb.args
        g = reduce(nc_gcd, args)
        if g != 1:
            cg, rg = g.as_coeff_Mul()
            glogb = _keep_coeff(cg, rg*Add(*[a/g for a in args]))

    # now put the log back together again
    if glogb.func is C.log or not glogb.is_Mul:
        if glogb.args[0].is_Pow or glogb.args[0].func is exp:
            glogb = _denest_pow(glogb.args[0])
            if (abs(glogb.exp) < 1) == True:
                return Pow(glogb.base, glogb.exp*e)
        return eq

    # the log(b) was a Mul so join any adds with logcombine
    add = []
    other = []
    for a in glogb.args:
        if a.is_Add:
            add.append(a)
        else:
            other.append(a)
    return Pow(exp(logcombine(Mul(*add))), e*Mul(*other))
def _denest_pow ( eq ) : b , e = eq . as_base_exp ( ) # denest exp with log terms in exponent if b is S . Exp1 and e . is_Mul : logs = [ ] other = [ ] for ei in e . args : if any ( ai . func is C . log for ai in Add . make_args ( ei ) ) : logs . append ( ei ) else : other . append ( ei ) logs = logcombine ( Mul ( * logs ) ) return Pow ( exp ( logs ) , Mul ( * other ) ) _ , be = b . as_base_exp ( ) if be is S . One and not ( b . is_Mul or b . is_Rational and b . q != 1 or b . is_positive ) : return eq # denest eq which is either pos**e or Pow**e or Mul**e or # Mul(b1**e1, b2**e2) # handle polar numbers specially polars , nonpolars = [ ] , [ ] for bb in Mul . make_args ( b ) : if bb . is_polar : polars . append ( bb . as_base_exp ( ) ) else : nonpolars . append ( bb ) if len ( polars ) == 1 and not polars [ 0 ] [ 0 ] . is_Mul : return Pow ( polars [ 0 ] [ 0 ] , polars [ 0 ] [ 1 ] * e ) * powdenest ( Mul ( * nonpolars ) ** e ) elif polars : return Mul ( * [ powdenest ( bb ** ( ee * e ) ) for ( bb , ee ) in polars ] ) * powdenest ( Mul ( * nonpolars ) ** e ) # see if there is a positive, non-Mul base at the very bottom exponents = [ ] kernel = eq while kernel . is_Pow : kernel , ex = kernel . as_base_exp ( ) exponents . append ( ex ) if kernel . is_positive : e = Mul ( * exponents ) if kernel . is_Mul : b = kernel else : if kernel . is_Integer : # use log to see if there is a power here logkernel = expand_log ( log ( kernel ) ) if logkernel . is_Mul : c , logk = logkernel . args e *= c kernel = logk . args [ 0 ] return Pow ( kernel , e ) # if any factor is an atom then there is nothing to be done # but the kernel check may have created a new exponent if any ( s . is_Atom for s in Mul . make_args ( b ) ) : if exponents : return b ** e return eq # let log handle the case of the base of the argument being a mul, e.g. # sqrt(x**(2*i)*y**(6*i)) -> x**i*y**(3**i) if x and y are positive; we # will take the log, expand it, and then factor out the common powers that # now appear as coefficient. We do this manually since terms_gcd pulls out # fractions, terms_gcd(x+x*y/2) -> x*(y + 2)/2 and we don't want the 1/2; # gcd won't pull out numerators from a fraction: gcd(3*x, 9*x/2) -> x but # we want 3*x. Neither work with noncommutatives. def nc_gcd ( aa , bb ) : a , b = [ i . as_coeff_Mul ( ) for i in [ aa , bb ] ] c = gcd ( a [ 0 ] , b [ 0 ] ) . as_numer_denom ( ) [ 0 ] g = Mul ( * ( a [ 1 ] . args_cnc ( cset = True ) [ 0 ] & b [ 1 ] . args_cnc ( cset = True ) [ 0 ] ) ) return _keep_coeff ( c , g ) glogb = expand_log ( log ( b ) ) if glogb . is_Add : args = glogb . args g = reduce ( nc_gcd , args ) if g != 1 : cg , rg = g . as_coeff_Mul ( ) glogb = _keep_coeff ( cg , rg * Add ( * [ a / g for a in args ] ) ) # now put the log back together again if glogb . func is C . log or not glogb . is_Mul : if glogb . args [ 0 ] . is_Pow or glogb . args [ 0 ] . func is exp : glogb = _denest_pow ( glogb . args [ 0 ] ) if ( abs ( glogb . exp ) < 1 ) == True : return Pow ( glogb . base , glogb . exp * e ) return eq # the log(b) was a Mul so join any adds with logcombine add = [ ] other = [ ] for a in glogb . args : if a . is_Add : add . append ( a ) else : other . append ( a ) return Pow ( exp ( logcombine ( Mul ( * add ) ) ) , e * Mul ( * other ) )