(self, exps, dummy=True)
return new_extension
Try to build an exponential extension.

        Returns True if there was a new extension, False if there was no new
        extension but it was able to rewrite the given exponentials in terms
        of the existing extension, and None if the entire extension building
        process should be restarted.  If the process fails because there is no
        way around an algebraic extension (e.g., exp(log(x)/2)), it will raise
        NotImplementedError.
Try to build an exponential extension.
Try to build an exponential extension .
def _exp_part(self, exps, dummy=True):
        """
        Try to build an exponential extension.

        Returns True if there was a new extension, False if there was no new
        extension but it was able to rewrite the given exponentials in terms
        of the existing extension, and None if the entire extension building
        process should be restarted.  If the process fails because there is no
        way around an algebraic extension (e.g., exp(log(x)/2)), it will raise
        NotImplementedError.
        """
        from sympy.integrals.prde import is_log_deriv_k_t_radical

        new_extension = False
        restart = False
        expargs = [i.exp for i in exps]
        ip = integer_powers(expargs)
        for arg, others in ip:
            # Minimize potential problems with algebraic substitution
            others.sort(key=lambda i: i[1])

            arga, argd = frac_in(arg, self.t)
            A = is_log_deriv_k_t_radical(arga, argd, self)

            if A is not None:
                ans, u, n, const = A
                # if n is 1 or -1, it's algebraic, but we can handle it
                if n == -1:
                    # This probably will never happen, because
                    # Rational.as_numer_denom() returns the negative term in
                    # the numerator.  But in case that changes, reduce it to
                    # n == 1.
                    n = 1
                    u **= -1
                    const *= -1
                    ans = [(i, -j) for i, j in ans]

                if n == 1:
                    # Example: exp(x + x**2) over QQ(x, exp(x), exp(x**2))
                    self.newf = self.newf.xreplace({exp(arg): exp(const)*Mul(*[
                        u**power for u, power in ans])})
                    self.newf = self.newf.xreplace(dict([(exp(p*exparg),
                        exp(const*p) * Mul(*[u**power for u, power in ans]))
                        for exparg, p in others]))
                    # TODO: Add something to backsubs to put exp(const*p)
                    # back together.

                    continue

                else:
                    # Bad news: we have an algebraic radical.  But maybe we
                    # could still avoid it by choosing a different extension.
                    # For example, integer_powers() won't handle exp(x/2 + 1)
                    # over QQ(x, exp(x)), but if we pull out the exp(1), it
                    # will.  Or maybe we have exp(x + x**2/2), over
                    # QQ(x, exp(x), exp(x**2)), which is exp(x)*sqrt(exp(x**2)),
                    # but if we use QQ(x, exp(x), exp(x**2/2)), then they will
                    # all work.
                    #
                    # So here is what we do: If there is a non-zero const, pull
                    # it out and retry.  Also, if len(ans) > 1, then rewrite
                    # exp(arg) as the product of exponentials from ans, and
                    # retry that.  If const == 0 and len(ans) == 1, then we
                    # assume that it would have been handled by either
                    # integer_powers() or n == 1 above if it could be handled,
                    # so we give up at that point.  For example, you can never
                    # handle exp(log(x)/2) because it equals sqrt(x).

                    if const or len(ans) > 1:
                        rad = Mul(*[term**(power/n) for term, power in ans])
                        self.newf = self.newf.xreplace(dict((exp(p*exparg),
                            exp(const*p)*rad) for exparg, p in others))
                        self.newf = self.newf.xreplace(dict(list(zip(reversed(self.T),
                            reversed([f(self.x) for f in self.Tfuncs])))))
                        restart = True
                        break
                    else:
                        # TODO: give algebraic dependence in error string
                        raise NotImplementedError("Cannot integrate over "
                            "algebraic extensions.")

            else:
                arga, argd = frac_in(arg, self.t)
                darga = (argd*derivation(Poly(arga, self.t), self) -
                    arga*derivation(Poly(argd, self.t), self))
                dargd = argd**2
                darga, dargd = darga.cancel(dargd, include=True)
                darg = darga.as_expr()/dargd.as_expr()
                self.t = next(self.ts)
                self.T.append(self.t)
                self.E_args.append(arg)
                self.E_K.append(len(self.T) - 1)
                self.D.append(darg.as_poly(self.t, expand=False)*Poly(self.t,
                    self.t, expand=False))
                if dummy:
                    i = Dummy("i")
                else:
                    i = Symbol('i')
                self.Tfuncs = self.Tfuncs + [Lambda(i, exp(arg.subs(self.x, i)))]
                self.newf = self.newf.xreplace(
                        dict((exp(exparg), self.t**p) for exparg, p in others))
                new_extension = True

        if restart:
            return None
        return new_extension
def _exp_part ( self , exps , dummy = True ) : from sympy . integrals . prde import is_log_deriv_k_t_radical new_extension = False restart = False expargs = [ i . exp for i in exps ] ip = integer_powers ( expargs ) for arg , others in ip : # Minimize potential problems with algebraic substitution others . sort ( key = lambda i : i [ 1 ] ) arga , argd = frac_in ( arg , self . t ) A = is_log_deriv_k_t_radical ( arga , argd , self ) if A is not None : ans , u , n , const = A # if n is 1 or -1, it's algebraic, but we can handle it if n == - 1 : # This probably will never happen, because # Rational.as_numer_denom() returns the negative term in # the numerator.  But in case that changes, reduce it to # n == 1. n = 1 u **= - 1 const *= - 1 ans = [ ( i , - j ) for i , j in ans ] if n == 1 : # Example: exp(x + x**2) over QQ(x, exp(x), exp(x**2)) self . newf = self . newf . xreplace ( { exp ( arg ) : exp ( const ) * Mul ( * [ u ** power for u , power in ans ] ) } ) self . newf = self . newf . xreplace ( dict ( [ ( exp ( p * exparg ) , exp ( const * p ) * Mul ( * [ u ** power for u , power in ans ] ) ) for exparg , p in others ] ) ) # TODO: Add something to backsubs to put exp(const*p) # back together. continue else : # Bad news: we have an algebraic radical.  But maybe we # could still avoid it by choosing a different extension. # For example, integer_powers() won't handle exp(x/2 + 1) # over QQ(x, exp(x)), but if we pull out the exp(1), it # will.  Or maybe we have exp(x + x**2/2), over # QQ(x, exp(x), exp(x**2)), which is exp(x)*sqrt(exp(x**2)), # but if we use QQ(x, exp(x), exp(x**2/2)), then they will # all work. # # So here is what we do: If there is a non-zero const, pull # it out and retry.  Also, if len(ans) > 1, then rewrite # exp(arg) as the product of exponentials from ans, and # retry that.  If const == 0 and len(ans) == 1, then we # assume that it would have been handled by either # integer_powers() or n == 1 above if it could be handled, # so we give up at that point.  For example, you can never # handle exp(log(x)/2) because it equals sqrt(x). if const or len ( ans ) > 1 : rad = Mul ( * [ term ** ( power / n ) for term , power in ans ] ) self . newf = self . newf . xreplace ( dict ( ( exp ( p * exparg ) , exp ( const * p ) * rad ) for exparg , p in others ) ) self . newf = self . newf . xreplace ( dict ( list ( zip ( reversed ( self . T ) , reversed ( [ f ( self . x ) for f in self . Tfuncs ] ) ) ) ) ) restart = True break else : # TODO: give algebraic dependence in error string raise NotImplementedError ( "Cannot integrate over " "algebraic extensions." ) else : arga , argd = frac_in ( arg , self . t ) darga = ( argd * derivation ( Poly ( arga , self . t ) , self ) - arga * derivation ( Poly ( argd , self . t ) , self ) ) dargd = argd ** 2 darga , dargd = darga . cancel ( dargd , include = True ) darg = darga . as_expr ( ) / dargd . as_expr ( ) self . t = next ( self . ts ) self . T . append ( self . t ) self . E_args . append ( arg ) self . E_K . append ( len ( self . T ) - 1 ) self . D . append ( darg . as_poly ( self . t , expand = False ) * Poly ( self . t , self . t , expand = False ) ) if dummy : i = Dummy ( "i" ) else : i = Symbol ( 'i' ) self . Tfuncs = self . Tfuncs + [ Lambda ( i , exp ( arg . subs ( self . x , i ) ) ) ] self . newf = self . newf . xreplace ( dict ( ( exp ( exparg ) , self . t ** p ) for exparg , p in others ) ) new_extension = True if restart : return None return new_extension