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
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)
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
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)
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)
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
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)