Exemplo n.º 1
0
    def parse_term(expr):
        rat_expo, sym_expo = Rational(1), None
        sexpr, deriv = expr, None

        if isinstance(expr, Pow):
            if isinstance(expr.base, Derivative):
                sexpr, deriv = parse_derivative(expr.base)
            else:
                sexpr = expr.base

            if isinstance(expr.exp, Rational):
                rat_expo = expr.exp
            elif isinstance(expr.exp, Mul):
                coeff, tail = term.exp.as_coeff_terms()

                if isinstance(coeff, Rational):
                    rat_expo, sym_expo = coeff, Basic.Mul(*tail)
                else:
                    sym_expo = expr.exp
            else:
                sym_expo = expr.exp
        elif isinstance(expr, Basic.exp):
            if isinstance(expr[0], Rational):
                sexpr, rat_expo = Basic.exp(Rational(1)), expr[0]
            elif isinstance(expr[0], Mul):
                coeff, tail = expr[0].as_coeff_terms()

                if isinstance(coeff, Rational):
                    sexpr, rat_expo = Basic.exp(Basic.Mul(*tail)), coeff
        elif isinstance(expr, Derivative):
            sexpr, deriv = parse_derivative(expr)

        return sexpr, rat_expo, sym_expo, deriv
Exemplo n.º 2
0
    def _eval_apply(cls, a, x):
        if isinstance(a, Basic.Number):
            if isinstance(a, Basic.One):
                return S.One - Basic.exp(-x)
            elif isinstance(a, Basic.Integer):
                b = a - 1

                if b.is_positive:
                    return b*cls(b, x) - x**b * Basic.exp(-x)
Exemplo n.º 3
0
def separate(expr, deep=False):
    """Rewrite or separate a power of product to a product of powers
       but without any expanding, ie. rewriting products to summations.

       >>> from sympy import *
       >>> x, y, z = symbols('x', 'y', 'z')

       >>> separate((x*y)**2)
       x**2*y**2

       >>> separate((x*(y*z)**3)**2)
       x**2*y**6*z**6

       >>> separate((x*sin(x))**y + (x*cos(x))**y)
       x**y*cos(x)**y + x**y*sin(x)**y

       #>>> separate((exp(x)*exp(y))**x)
       #exp(x*y)*exp(x**2)

       Notice that summations are left un touched. If this is not the
       requested behaviour, apply 'expand' to input expression before:

       >>> separate(((x+y)*z)**2)
       z**2*(x + y)**2

       >>> separate((x*y)**(1+z))
       x**(1 + z)*y**(1 + z)

    """
    expr = Basic.sympify(expr)

    if isinstance(expr, Basic.Pow):
        terms, expo = [], separate(expr.exp, deep)
        #print expr, terms, expo, expr.base

        if isinstance(expr.base, Mul):
            t = [ separate(Basic.Pow(t,expo), deep) for t in expr.base ]
            return Basic.Mul(*t)
        elif isinstance(expr.base, Basic.exp):
            if deep == True:
                return Basic.exp(separate(expr.base[0], deep)*expo)
            else:
                return Basic.exp(expr.base[0]*expo)
        else:
            return Basic.Pow(separate(expr.base, deep), expo)
    elif isinstance(expr, (Basic.Add, Basic.Mul)):
        return type(expr)(*[ separate(t, deep) for t in expr ])
    elif isinstance(expr, Basic.Function) and deep:
        return expr.func(*[ separate(t) for t in expr])
    else:
        return expr
Exemplo n.º 4
0
    def _eval_apply(cls, a, z):
        if isinstance(z, Basic.Number):
            if isinstance(z, Basic.NaN):
                return S.NaN
            elif isinstance(z, Basic.Infinity):
                return S.Zero
            elif isinstance(z, Basic.Zero):
                return gamma(a)

        if isinstance(a, Basic.Number):
            if isinstance(a, Basic.One):
                return Basic.exp(-z)
            elif isinstance(a, Basic.Integer):
                b = a - 1

                if b.is_positive:
                    return b*cls(b, z) + z**b * Basic.exp(-z)
Exemplo n.º 5
0
def fraction(expr, exact=False):
    """Returns a pair with expression's numerator and denominator.
       If the given expression is not a fraction then this function
       will assume that the denominator is equal to one.

       This function will not make any attempt to simplify nested
       fractions or to do any term rewriting at all.

       If only one of the numerator/denominator pair is needed then
       use numer(expr) or denom(expr) functions respectively.

       >>> from sympy import *
       >>> x, y = symbols('x', 'y')

       >>> fraction(x/y)
       (x, y)
       >>> fraction(x)
       (x, 1)

       >>> fraction(1/y**2)
       (1, y**2)

       >>> fraction(x*y/2)
       (x*y, 2)
       >>> fraction(Rational(1, 2))
       (1, 2)

       This function will also work fine with assumptions:

       >>> k = Symbol('k', negative=True)
       >>> fraction(x * y**k)
       (x, y**(-k))

       If we know nothing about sign of some exponent and 'exact'
       flag is unset, then structure this exponent's structure will
       be analyzed and pretty fraction will be returned:

       >>> fraction(2*x**(-y))
       (2, x**y)

       #>>> fraction(exp(-x))
       #(1, exp(x))

       >>> fraction(exp(-x), exact=True)
       (exp(-x), 1)

    """
    expr = Basic.sympify(expr)

    #XXX this only works sometimes (caching bug?)
    if expr == exp(-Symbol("x")) and exact:
        return (expr, 1)

    numer, denom = [], []

    for term in make_list(expr, Mul):
        if isinstance(term, Pow):
            if term.exp.is_negative:
                if term.exp == Integer(-1):
                    denom.append(term.base)
                else:
                    denom.append(Pow(term.base, -term.exp))
            elif not exact and isinstance(term.exp, Mul):
                coeff, tail = term.exp[0], Mul(*term.exp[1:])#term.exp.getab()

                if isinstance(coeff, Rational) and coeff.is_negative:
                    denom.append(Pow(term.base, -term.exp))
                else:
                    numer.append(term)
            else:
                numer.append(term)
        elif isinstance(term, Basic.exp):
            if term[0].is_negative:
                denom.append(Basic.exp(-term[0]))
            elif not exact and isinstance(term[0], Mul):
                coeff, tail = term[0], Mul(*term[1:])#term.args.getab()

                if isinstance(coeff, Rational) and coeff.is_negative:
                    denom.append(Basic.exp(-term[0]))
                else:
                    numer.append(term)
            else:
                numer.append(term)
        elif isinstance(term, Rational):
            if term.is_integer:
                numer.append(term)
            else:
                numer.append(Rational(term.p))
                denom.append(Rational(term.q))
        else:
            numer.append(term)

    return Mul(*numer), Mul(*denom)
Exemplo n.º 6
0
    def _together(expr):

        from sympy.core.function import Function

        if isinstance(expr, Add):
            items, coeffs, basis = [], [], {}

            for elem in expr:
                numer, q = fraction(_together(elem))

                denom = {}

                for term in make_list(q.expand(), Mul):
                    expo = Integer(1)
                    coeff = Integer(1)


                    if isinstance(term, Pow):
                        if isinstance(term.exp, Rational):
                            term, expo = term.base, term.exp
                        elif isinstance(term.exp, Mul):
                            coeff, tail = term.exp.as_coeff_terms()
                            if isinstance(coeff, Rational):
                                tail = Basic.Mul(*tail)
                                term, expo = Pow(term.base, tail), coeff
                        coeff = Integer(1)
                    elif isinstance(term, Basic.exp):
                        if isinstance(term[0], Rational):
                            term, expo = Basic.E, term[0]
                        elif isinstance(term[0], Mul):
                            coeff, tail = term[0].as_coeff_terms()
                            if isinstance(coeff, Rational):
                                tail = Basic.Mul(*tail)
                                term, expo = Basic.exp(tail), coeff
                        coeff = Integer(1)
                    elif isinstance(term, Rational):
                        coeff = Integer(term.q)
                        term = Integer(term.p)

                    if term in denom:
                        denom[term] += expo
                    else:
                        denom[term] = expo

                    if term in basis:
                        total, maxi = basis[term]

                        n_total = total + expo
                        n_maxi = max(maxi, expo)

                        basis[term] = (n_total, n_maxi)
                    else:
                        basis[term] = (expo, expo)

                    coeffs.append(coeff)
                items.append((numer, denom))

            numerator, denominator = [], []

            for (term, (total, maxi)) in basis.iteritems():
                basis[term] = (total, total-maxi)

                if isinstance(term, Basic.exp):
                    denominator.append(Basic.exp(maxi*term[:]))
                else:
                    if isinstance(maxi, Basic.One):
                        denominator.append(term)
                    else:
                        denominator.append(Pow(term, maxi))

            from sympy.core.numbers import gcd as int_gcd

            if all([ c.is_integer for c in coeffs ]):
                gcds = lambda x, y: int_gcd(int(x), int(y))
                common = Rational(reduce(gcds, coeffs))
            else:
                common = Rational(1)

            product = reduce(lambda x, y: x*y, coeffs) / common

            for ((numer, denom), coeff) in zip(items, coeffs):

                expr, coeff = [], product / (coeff*common)

                for term in basis.iterkeys():
                    total, sub = basis[term]

                    if term in denom:
                        expo = total-denom[term]-sub
                    else:
                        expo = total-sub

                    if isinstance(term, Basic.exp):
                        expr.append(Basic.exp(expo*term[:]))
                    else:
                        if isinstance(expo, Basic.One):
                            expr.append(term)
                        else:
                            expr.append(Pow(term, expo))

                numerator.append(coeff*Mul(*([numer] + expr)))

            return Add(*numerator)/(product*Mul(*denominator))
        elif isinstance(expr, (Mul, Pow)):
            return type(expr)(*[ _together(t) for t in expr ])
        elif isinstance(expr, Function) and deep:
            return expr.func(*[ _together(t) for t in expr ])
        else:
            return expr
Exemplo n.º 7
0
 def fdiff(self, argindex=2):
     if argindex == 2:
         a, z = self[0:2]
         return -Basic.exp(-z)*z**(a-1)
     else:
         raise ArgumentIndexError(self, argindex)