(self, **hints)
return rv
(a*b)**n -> a**n * b**n
(a*b)**n -> a**n * b**n
( a * b ) ** n - > a ** n * b ** n
def _eval_expand_power_base(self, **hints):
        """(a*b)**n -> a**n * b**n"""
        force = hints.get('force', False)

        b = self.base
        e = self.exp
        if not b.is_Mul:
            return self

        cargs, nc = b.args_cnc(split_1=False)

        # expand each term - this is top-level-only
        # expansion but we have to watch out for things
        # that don't have an _eval_expand method
        if nc:
            nc = [i._eval_expand_power_base(**hints)
                if hasattr(i, '_eval_expand_power_base') else i
                for i in nc]

            if e.is_Integer:
                if e.is_positive:
                    rv = Mul(*nc*e)
                else:
                    rv = 1/Mul(*nc*-e)
                if cargs:
                    rv *= Mul(*cargs)**e
                return rv

            if not cargs:
                return self.func(Mul(*nc), e, evaluate=False)

            nc = [Mul(*nc)]

        # sift the commutative bases
        def pred(x):
            if x is S.ImaginaryUnit:
                return S.ImaginaryUnit
            polar = x.is_polar
            if polar:
                return True
            if polar is None:
                return fuzzy_bool(x.is_nonnegative)
        sifted = sift(cargs, pred)
        nonneg = sifted[True]
        other = sifted[None]
        neg = sifted[False]
        imag = sifted[S.ImaginaryUnit]
        if imag:
            I = S.ImaginaryUnit
            i = len(imag) % 4
            if i == 0:
                pass
            elif i == 1:
                other.append(I)
            elif i == 2:
                if neg:
                    nonn = -neg.pop()
                    if nonn is not S.One:
                        nonneg.append(nonn)
                else:
                    neg.append(S.NegativeOne)
            else:
                if neg:
                    nonn = -neg.pop()
                    if nonn is not S.One:
                        nonneg.append(nonn)
                else:
                    neg.append(S.NegativeOne)
                other.append(I)
            del imag

        # bring out the bases that can be separated from the base

        if force or e.is_integer:
            # treat all commutatives the same and put nc in other
            cargs = nonneg + neg + other
            other = nc
        else:
            # this is just like what is happening automatically, except
            # that now we are doing it for an arbitrary exponent for which
            # no automatic expansion is done

            assert not e.is_Integer

            # handle negatives by making them all positive and putting
            # the residual -1 in other
            if len(neg) > 1:
                o = S.One
                if not other and neg[0].is_Number:
                    o *= neg.pop(0)
                if len(neg) % 2:
                    o = -o
                for n in neg:
                    nonneg.append(-n)
                if o is not S.One:
                    other.append(o)
            elif neg and other:
                if neg[0].is_Number and neg[0] is not S.NegativeOne:
                    other.append(S.NegativeOne)
                    nonneg.append(-neg[0])
                else:
                    other.extend(neg)
            else:
                other.extend(neg)
            del neg

            cargs = nonneg
            other += nc

        rv = S.One
        if cargs:
            rv *= Mul(*[self.func(b, e, evaluate=False) for b in cargs])
        if other:
            rv *= self.func(Mul(*other), e, evaluate=False)
        return rv
def _eval_expand_power_base ( self , * * hints ) : force = hints . get ( 'force' , False ) b = self . base e = self . exp if not b . is_Mul : return self cargs , nc = b . args_cnc ( split_1 = False ) # expand each term - this is top-level-only # expansion but we have to watch out for things # that don't have an _eval_expand method if nc : nc = [ i . _eval_expand_power_base ( * * hints ) if hasattr ( i , '_eval_expand_power_base' ) else i for i in nc ] if e . is_Integer : if e . is_positive : rv = Mul ( * nc * e ) else : rv = 1 / Mul ( * nc * - e ) if cargs : rv *= Mul ( * cargs ) ** e return rv if not cargs : return self . func ( Mul ( * nc ) , e , evaluate = False ) nc = [ Mul ( * nc ) ] # sift the commutative bases def pred ( x ) : if x is S . ImaginaryUnit : return S . ImaginaryUnit polar = x . is_polar if polar : return True if polar is None : return fuzzy_bool ( x . is_nonnegative ) sifted = sift ( cargs , pred ) nonneg = sifted [ True ] other = sifted [ None ] neg = sifted [ False ] imag = sifted [ S . ImaginaryUnit ] if imag : I = S . ImaginaryUnit i = len ( imag ) % 4 if i == 0 : pass elif i == 1 : other . append ( I ) elif i == 2 : if neg : nonn = - neg . pop ( ) if nonn is not S . One : nonneg . append ( nonn ) else : neg . append ( S . NegativeOne ) else : if neg : nonn = - neg . pop ( ) if nonn is not S . One : nonneg . append ( nonn ) else : neg . append ( S . NegativeOne ) other . append ( I ) del imag # bring out the bases that can be separated from the base if force or e . is_integer : # treat all commutatives the same and put nc in other cargs = nonneg + neg + other other = nc else : # this is just like what is happening automatically, except # that now we are doing it for an arbitrary exponent for which # no automatic expansion is done assert not e . is_Integer # handle negatives by making them all positive and putting # the residual -1 in other if len ( neg ) > 1 : o = S . One if not other and neg [ 0 ] . is_Number : o *= neg . pop ( 0 ) if len ( neg ) % 2 : o = - o for n in neg : nonneg . append ( - n ) if o is not S . One : other . append ( o ) elif neg and other : if neg [ 0 ] . is_Number and neg [ 0 ] is not S . NegativeOne : other . append ( S . NegativeOne ) nonneg . append ( - neg [ 0 ] ) else : other . extend ( neg ) else : other . extend ( neg ) del neg cargs = nonneg other += nc rv = S . One if cargs : rv *= Mul ( * [ self . func ( b , e , evaluate = False ) for b in cargs ] ) if other : rv *= self . func ( Mul ( * other ) , e , evaluate = False ) return rv