def generate_Sx_Sy_Sz_operators(atom_list, Sa, Sb, Sn): """Generates Sx, Sy and Sz operators""" Sx_list = []; Sy_list = []; Sz_list = [] N = len(atom_list) loc_vect = spm.Matrix([Sa,Sb,Sn]) loc_vect = loc_vect.reshape(3,1) for i in range(N): rotmat = sp.Matrix(atom_list[i].spinRmatrix) glo_vect = rotmat * loc_vect Sx = sp.powsimp(glo_vect[0].expand()) Sy = sp.powsimp(glo_vect[1].expand()) Sz = sp.powsimp(glo_vect[2].expand()) Sx_list.append(Sx) Sy_list.append(Sy) Sz_list.append(Sz) Sx_list.append(KAPXHAT_SYM) Sy_list.append(KAPYHAT_SYM) Sz_list.append(KAPZHAT_SYM) print "Operators Generated: Sx, Sy, Sz" return (Sx_list,Sy_list,Sz_list)
def test_roots_binomial(): assert roots_binomial(Poly(5*x, x)) == [0] assert roots_binomial(Poly(5*x**4, x)) == [0, 0, 0, 0] assert roots_binomial(Poly(5*x + 2, x)) == [-Rational(2, 5)] A = 10**Rational(3, 4)/10 assert roots_binomial(Poly(5*x**4 + 2, x)) == \ [-A - A*I, -A + A*I, A - A*I, A + A*I] a1 = Symbol('a1', nonnegative=True) b1 = Symbol('b1', nonnegative=True) r0 = roots_quadratic(Poly(a1*x**2 + b1, x)) r1 = roots_binomial(Poly(a1*x**2 + b1, x)) assert powsimp(r0[0]) == powsimp(r1[0]) assert powsimp(r0[1]) == powsimp(r1[1]) for a, b, s, n in cartes((1, 2), (1, 2), (-1, 1), (2, 3, 4, 5)): if a == b and a != 1: # a == b == 1 is sufficient continue p = Poly(a*x**n + s*b) ans = roots_binomial(p) assert ans == _nsort(ans) # issue 8813 assert roots(Poly(2*x**3 - 16*y**3, x)) == { 2*y*(-S(1)/2 - sqrt(3)*I/2): 1, 2*y: 1, 2*y*(-S(1)/2 + sqrt(3)*I/2): 1}
def test_issue_3268(): z = -5*sqrt(2)/(2*sqrt(2*sqrt(29) + 29)) + sqrt(-sqrt(29)/29 + S(1)/2) assert Mul(*[powsimp(a) for a in Mul.make_args(z.normal())]) == 0 assert powsimp(z.normal()) == 0 assert simplify(z) == 0 assert powsimp(sqrt(2 + sqrt(3))*sqrt(2 - sqrt(3)) + 1) == 2 assert powsimp(z) != 0
def generate_Sx_Sy_Sz_operators(atom_list, Sa, Sb, Sn): """Generates Sx, Sy and Sz operators""" Sx_list = []; Sy_list = []; Sz_list = [] N = len(atom_list) S = sp.Symbol('S', commutative = True) loc_vect = spm.Matrix([Sa,Sb,Sn]) loc_vect = loc_vect.reshape(3,1) for i in range(N): rotmat = sp.Matrix(atom_list[i].spinRmatrix) glo_vect = rotmat * loc_vect Sx = sp.powsimp(glo_vect[0].expand()) Sy = sp.powsimp(glo_vect[1].expand()) Sz = sp.powsimp(glo_vect[2].expand()) Sx_list.append(Sx) Sy_list.append(Sy) Sz_list.append(Sz) #Unit vector markers kapxhat = sp.Symbol('kapxhat',real = True)#spm.Matrix([1,0,0])# kapyhat = sp.Symbol('kapyhat',real = True)#spm.Matrix([0,1,0])# kapzhat = sp.Symbol('kapzhat',real = True)#spm.Matrix([0,0,1])# Sx_list.append(kapxhat) Sy_list.append(kapyhat) Sz_list.append(kapzhat) print "Operators Generated: Sx, Sy, Sz" return (Sx_list,Sy_list,Sz_list)
def test_issue_from_PR1599(): n1, n2, n3, n4 = symbols('n1 n2 n3 n4', negative=True) assert (powsimp(sqrt(n1)*sqrt(n2)*sqrt(n3)) == -I*sqrt(-n1)*sqrt(-n2)*sqrt(-n3)) assert (powsimp(root(n1, 3)*root(n2, 3)*root(n3, 3)*root(n4, 3)) == -(-1)**(S(1)/3)* (-n1)**(S(1)/3)*(-n2)**(S(1)/3)*(-n3)**(S(1)/3)*(-n4)**(S(1)/3))
def test_powsimp_negated_base(): assert powsimp((-x + y)/sqrt(x - y)) == -sqrt(x - y) assert powsimp((-x + y)*(-z + y)/sqrt(x - y)/sqrt(z - y)) == sqrt(x - y)*sqrt(z - y) p = symbols('p', positive=True) assert powsimp((-p)**a/p**a) == (-1)**a n = symbols('n', negative=True) assert powsimp((-n)**a/n**a) == (-1)**a # if x is 0 then the lhs is 0**a*oo**a which is not (-1)**a assert powsimp((-x)**a/x**a) != (-1)**a
def test_issue_10195(): a = Symbol('a', integer=True) l = Symbol('l', even=True, nonzero=True) n = Symbol('n', odd=True) e_x = (-1)**(n/2 - Rational(1, 2)) - (-1)**(3*n/2 - Rational(1, 2)) assert powsimp((-1)**(l/2)) == I**l assert powsimp((-1)**(n/2)) == I**n assert powsimp((-1)**(3*n/2)) == -I**n assert powsimp(e_x) == (-1)**(n/2 - Rational(1, 2)) + (-1)**(3*n/2 + Rational(1,2)) assert powsimp((-1)**(3*a/2)) == (-I)**a
def test_powsimp(): x,y,n = symbols('xyn') f = Function('f') assert powsimp( 4**x * 2**(-x) * 2**(-x) ) == 1 assert powsimp( (-4)**x * (-2)**(-x) * 2**(-x) ) == 1 assert powsimp( f(4**x * 2**(-x) * 2**(-x)) ) == f(4**x * 2**(-x) * 2**(-x)) assert powsimp( f(4**x * 2**(-x) * 2**(-x)), deep = True ) == f(1) x,y = symbols('xy', nonnegative=True) n = Symbol('n', real=True) assert powsimp( y**n * (y/x)**(-n) ) == x**n
def list_mult(lista, listb): "Defines a way to multiply two lists of the same length" if len(lista) != len(listb): print "lists not same length" return [] else: temp = [] for i in range(len(lista)): if isinstance(lista[i], int): temp.append(sp.powsimp((lista[i] * listb[i]).expand(deep=False))) elif isinstance(listb[i], int): temp.append(sp.powsimp((lista[i] * listb[i]).expand(deep=False))) else: temp.append(sp.powsimp((lista[i] * listb[i]).expand(deep=False))) return temp
def _contains(self, expr): from sympy import powsimp, limit if expr is S.Zero: return True if expr is S.NaN: return False if expr.is_Order: if self.variables and expr.variables: common_symbols = tuple([s for s in self.variables if s in expr.variables]) elif self.variables: common_symbols = self.variables else: common_symbols = expr.variables if not common_symbols: if not (self.variables or expr.variables): # O(1),O(1) return True return None r = None for s in common_symbols: l = limit(powsimp(self.expr/expr.expr, deep=True,\ combine='exp'), s, 0) != 0 if r is None: r = l else: if r != l: return return r obj = Order(expr, *self.variables) return self.contains(obj)
def test_TR2i(): # just a reminder that ratios of powers only simplify if both # numerator and denominator satisfy the condition that each # has a positive base or an integer exponent; e.g. the following, # at y=-1, x=1/2 gives sqrt(2)*I != -sqrt(2)*I assert powsimp(2**x/y**x) != (2/y)**x assert TR2i(sin(x)/cos(x)) == tan(x) assert TR2i(sin(x)*sin(y)/cos(x)) == tan(x)*sin(y) assert TR2i(1/(sin(x)/cos(x))) == 1/tan(x) assert TR2i(1/(sin(x)*sin(y)/cos(x))) == 1/tan(x)/sin(y) assert TR2i(sin(x)/2/(cos(x) + 1)) == sin(x)/(cos(x) + 1)/2 assert TR2i(sin(x)/2/(cos(x) + 1), half=True) == tan(x/2)/2 assert TR2i(sin(1)/(cos(1) + 1), half=True) == tan(S.Half) assert TR2i(sin(2)/(cos(2) + 1), half=True) == tan(1) assert TR2i(sin(4)/(cos(4) + 1), half=True) == tan(2) assert TR2i(sin(5)/(cos(5) + 1), half=True) == tan(5*S.Half) assert TR2i((cos(1) + 1)/sin(1), half=True) == 1/tan(S.Half) assert TR2i((cos(2) + 1)/sin(2), half=True) == 1/tan(1) assert TR2i((cos(4) + 1)/sin(4), half=True) == 1/tan(2) assert TR2i((cos(5) + 1)/sin(5), half=True) == 1/tan(5*S.Half) assert TR2i((cos(1) + 1)**(-a)*sin(1)**a, half=True) == tan(S.Half)**a assert TR2i((cos(2) + 1)**(-a)*sin(2)**a, half=True) == tan(1)**a assert TR2i((cos(4) + 1)**(-a)*sin(4)**a, half=True) == (cos(4) + 1)**(-a)*sin(4)**a assert TR2i((cos(5) + 1)**(-a)*sin(5)**a, half=True) == (cos(5) + 1)**(-a)*sin(5)**a assert TR2i((cos(1) + 1)**a*sin(1)**(-a), half=True) == tan(S.Half)**(-a) assert TR2i((cos(2) + 1)**a*sin(2)**(-a), half=True) == tan(1)**(-a) assert TR2i((cos(4) + 1)**a*sin(4)**(-a), half=True) == (cos(4) + 1)**a*sin(4)**(-a) assert TR2i((cos(5) + 1)**a*sin(5)**(-a), half=True) == (cos(5) + 1)**a*sin(5)**(-a) i = symbols('i', integer=True) assert TR2i(((cos(5) + 1)**i*sin(5)**(-i)), half=True) == tan(5*S.Half)**(-i) assert TR2i(1/((cos(5) + 1)**i*sin(5)**(-i)), half=True) == tan(5*S.Half)**i
def contains(self, expr): """ Return True if expr belongs to Order(self.expr, *self.variables). Return False if self belongs to expr. Return None if the inclusion relation cannot be determined (e.g. when self and expr have different symbols). """ from sympy import powsimp, limit if expr is S.Zero: return True if expr is S.NaN: return False if expr.is_Order: if self.variables and expr.variables: common_symbols = tuple([s for s in self.variables if s in expr.variables]) elif self.variables: common_symbols = self.variables else: common_symbols = expr.variables if not common_symbols: if not (self.variables or expr.variables): # O(1),O(1) return True return None r = None for s in common_symbols: l = limit(powsimp(self.expr/expr.expr, deep=True,\ combine='exp'), s, 0) != 0 if r is None: r = l else: if r != l: return return r obj = Order(expr, *self.variables) return self.contains(obj)
def contains(self, expr): """ Return True if expr belongs to Order(self.expr, \*self.variables). Return False if self belongs to expr. Return None if the inclusion relation cannot be determined (e.g. when self and expr have different symbols). """ from sympy import powsimp, PoleError if expr is S.Zero: return True if expr is S.NaN: return False if expr.is_Order: if not all(p == expr.point[0] for p in expr.point) and \ not all(p == self.point[0] for p in self.point): raise NotImplementedError('Order at points other than 0 ' 'or oo not supported, got %s as a point.' % point) else: # self and/or expr is O(1): if any(not p for p in [expr.point, self.point]): point = self.point + expr.point if point: point = point[0] else: point = S.Zero else: point = self.point[0] if expr.expr == self.expr: # O(1) + O(1), O(1) + O(1, x), etc. return all([x in self.args[1:] for x in expr.args[1:]]) if expr.expr.is_Add: return all([self.contains(x) for x in expr.expr.args]) if self.expr.is_Add: return any([self.func(x, *self.args[1:]).contains(expr) for x in self.expr.args]) if self.variables and expr.variables: common_symbols = tuple( [s for s in self.variables if s in expr.variables]) elif self.variables: common_symbols = self.variables else: common_symbols = expr.variables if not common_symbols: return None r = None ratio = self.expr/expr.expr ratio = powsimp(ratio, deep=True, combine='exp') for s in common_symbols: try: l = ratio.limit(s, point) != 0 except PoleError: l = None if r is None: r = l else: if r != l: return return r obj = self.func(expr, *self.args[1:]) return self.contains(obj)
def as_leading_term(self, *symbols): """ Returns the leading term. Example: >>> from sympy.abc import x >>> (1+x+x**2).as_leading_term(x) 1 >>> (1/x**2+x+x**2).as_leading_term(x) x**(-2) Note: self is assumed to be the result returned by Basic.series(). """ from sympy import powsimp if len(symbols)>1: c = self for x in symbols: c = c.as_leading_term(x) return c elif not symbols: return self x = sympify(symbols[0]) assert x.is_Symbol, `x` if not self.has(x): return self obj = self._eval_as_leading_term(x) if obj is not None: return powsimp(obj, deep=True, combine='exp') raise NotImplementedError('as_leading_term(%s, %s)' % (self, x))
def _simplify(expr): u"""Simplifie une expression. Alias de simplify (sympy 0.6.4). Mais simplify n'est pas garanti d'être stable dans le temps. (Cf. simplify.__doc__).""" return together(expand(Poly.cancel(powsimp(expr))))
def test_roots_binomial(): assert roots_binomial(Poly(5 * x, x)) == [0] assert roots_binomial(Poly(5 * x ** 4, x)) == [0, 0, 0, 0] assert roots_binomial(Poly(5 * x + 2, x)) == [-Rational(2, 5)] A = 10 ** Rational(3, 4) / 10 assert roots_binomial(Poly(5 * x ** 4 + 2, x)) == [-A - A * I, -A + A * I, A - A * I, A + A * I] a1 = Symbol("a1", nonnegative=True) b1 = Symbol("b1", nonnegative=True) r0 = roots_quadratic(Poly(a1 * x ** 2 + b1, x)) r1 = roots_binomial(Poly(a1 * x ** 2 + b1, x)) assert powsimp(r0[0]) == powsimp(r1[0]) assert powsimp(r0[1]) == powsimp(r1[1])
def eqdiff(leq,lvars): '''Calculate the Jacobian of the system of equations with respect to a set of variables.''' from sympy import powsimp resp = [] for eq in leq: el = [ powsimp(eq.diff(v)) for v in lvars] resp += [el] return resp
def taylor_term(n, x, *previous_terms): # of log(1+x) from sympy import powsimp if n<0: return S.Zero x = sympify(x) if n==0: return x if previous_terms: p = previous_terms[-1] if p is not None: return powsimp((-n) * p * x / (n+1), deep=True, combine='exp') return (1-2*(n%2)) * x**(n+1)/(n+1)
def taylor_term(n, x, *previous_terms): # of log(1+x) """ Returns the next term in the Taylor series expansion of log(1+x). """ from sympy import powsimp if n<0: return S.Zero x = sympify(x) if n==0: return x if previous_terms: p = previous_terms[-1] if p is not None: return powsimp((-n) * p * x / (n+1), deep=True, combine='exp') return (1-2*(n%2)) * x**(n+1)/(n+1)
def _eval_nseries(self, x, x0, n): from sympy import limit, Symbol, oo, powsimp arg = self.args[0] arg_series = arg.nseries(x, x0, n) if arg_series.is_Order: return 1+arg_series arg0 = limit(arg_series, x, x0) if arg0 in [-oo, oo]: return self s = Symbol("s", dummy=True) exp_series = exp(s)._taylor(s, x0, n) r = exp(arg0)*exp_series.subs(s, arg_series-arg0) r = r.expand() return powsimp(r, deep=True, combine='exp')
def test_roots_binomial(): assert roots_binomial(Poly(5 * x, x)) == [0] assert roots_binomial(Poly(5 * x ** 4, x)) == [0, 0, 0, 0] assert roots_binomial(Poly(5 * x + 2, x)) == [-Rational(2, 5)] A = 10 ** Rational(3, 4) / 10 assert roots_binomial(Poly(5 * x ** 4 + 2, x)) == [-A - A * I, -A + A * I, A - A * I, A + A * I] a1 = Symbol("a1", nonnegative=True) b1 = Symbol("b1", nonnegative=True) r0 = roots_quadratic(Poly(a1 * x ** 2 + b1, x)) r1 = roots_binomial(Poly(a1 * x ** 2 + b1, x)) assert powsimp(r0[0]) == powsimp(r1[0]) assert powsimp(r0[1]) == powsimp(r1[1]) for a, b, s, n in cartes((1, 2), (1, 2), (-1, 1), (2, 3, 4, 5)): if a == b and a != 1: # a == b == 1 is sufficient continue p = Poly(a * x ** n + s * b) roots = roots_binomial(p) assert roots == _nsort(roots)
def _eval_nseries(self, x, n): from sympy import limit, oo, powsimp arg = self.args[0] arg_series = arg._eval_nseries(x, n=n) if arg_series.is_Order: return 1 + arg_series arg0 = limit(arg_series.removeO(), x, 0) if arg0 in [-oo, oo]: return self t = Dummy("t") exp_series = exp(t)._taylor(t, n) r = exp(arg0)*exp_series.subs(t, arg_series - arg0) r = r.expand() return powsimp(r, deep=True, combine='exp')
def test_action_verbs(): assert nsimplify((1/(exp(3*pi*x/5)+1))) == (1/(exp(3*pi*x/5)+1)).nsimplify() assert ratsimp(1/x + 1/y) == (1/x + 1/y).ratsimp() assert trigsimp(log(x), deep=True) == (log(x)).trigsimp(deep = True) assert radsimp(1/(2+sqrt(2))) == (1/(2+sqrt(2))).radsimp() assert powsimp(x**y*x**z*y**z, combine='all') == (x**y*x**z*y**z).powsimp(combine='all') assert simplify(x**y*x**z*y**z) == (x**y*x**z*y**z).simplify() assert together(1/x + 1/y) == (1/x + 1/y).together() assert separate((x*(y*z)**3)**2) == ((x*(y*z)**3)**2).separate() assert collect(a*x**2 + b*x**2 + a*x - b*x + c, x) == (a*x**2 + b*x**2 + a*x - b*x + c).collect(x) assert apart(y/(y+2)/(y+1), y) == (y/(y+2)/(y+1)).apart(y) assert combsimp(y/(x+2)/(x+1)) == (y/(x+2)/(x+1)).combsimp() assert factor(x**2+5*x+6) == (x**2+5*x+6).factor() assert refine(sqrt(x**2)) == sqrt(x**2).refine() assert cancel((x**2+5*x+6)/(x+2)) == ((x**2+5*x+6)/(x+2)).cancel()
def contains(self, expr): """ Return True if expr belongs to Order(self.expr, \*self.variables). Return False if self belongs to expr. Return None if the inclusion relation cannot be determined (e.g. when self and expr have different symbols). """ from sympy import powsimp, limit if expr is S.Zero: return True if expr is S.NaN: return False if expr.is_Order: if expr.point != self.point: return False if expr.expr == self.expr: # O(1) + O(1), O(1) + O(1, x), etc. return all([x in self.variables for x in expr.variables]) if expr.expr.is_Add: return all([self.contains(x) for x in expr.expr.args]) if self.expr.is_Add: return any([self.func(x, *self.args[1:]).contains(expr) for x in self.expr.args]) if self.variables and expr.variables: common_symbols = tuple( [s for s in self.variables if s in expr.variables]) elif self.variables: common_symbols = self.variables else: common_symbols = expr.variables if not common_symbols: return None r = None ratio = self.expr/expr.expr ratio = powsimp(ratio, deep=True, combine='exp') for s in common_symbols: l = limit(ratio, s, self.point) != 0 if r is None: r = l else: if r != l: return return r newargs = self.args[1:] obj = Order(expr, *newargs) return self.contains(obj)
def sphericalHarmonic(l,n) : """Returns an evaluator for the seminormalized real spherical harmonic of order l, degree n as defined in: http://ambisonics.iem.at/xchange/format/ambisonics-xchange-format-appendix """ import sympy sign = -1 if n<0 else +1 n = abs(n) x,y=sympy.var("x y") f= sympy.powsimp(sympy.trigsimp( sympy.assoc_legendre(l,n,sympy.sin(x)) * (-1)**n * sympy.sqrt((2*l+1) * (1 if n==0 else 2) * sympy.factorial(l-n)/sympy.factorial(l+n)) * (sympy.cos(n*y) if sign>=0 else sympy.sin(n*y)) )) return SympyEvaluator(f,x,y)
def test_action_verbs(): assert nsimplify((1/(exp(3*pi*x/5) + 1))) == \ (1/(exp(3*pi*x/5) + 1)).nsimplify() assert ratsimp(1/x + 1/y) == (1/x + 1/y).ratsimp() assert trigsimp(log(x), deep=True) == (log(x)).trigsimp(deep=True) assert radsimp(1/(2 + sqrt(2))) == (1/(2 + sqrt(2))).radsimp() assert powsimp(x**y*x**z*y**z, combine='all') == \ (x**y*x**z*y**z).powsimp(combine='all') assert simplify(x**y*x**z*y**z) == (x**y*x**z*y**z).simplify() assert together(1/x + 1/y) == (1/x + 1/y).together() # Not tested because it's deprecated #assert separate((x*(y*z)**3)**2) == ((x*(y*z)**3)**2).separate() assert collect(a*x**2 + b*x**2 + a*x - b*x + c, x) == \ (a*x**2 + b*x**2 + a*x - b*x + c).collect(x) assert apart(y/(y + 2)/(y + 1), y) == (y/(y + 2)/(y + 1)).apart(y) assert combsimp(y/(x + 2)/(x + 1)) == (y/(x + 2)/(x + 1)).combsimp() assert factor(x**2 + 5*x + 6) == (x**2 + 5*x + 6).factor() assert refine(sqrt(x**2)) == sqrt(x**2).refine() assert cancel((x**2 + 5*x + 6)/(x + 2)) == ((x**2 + 5*x + 6)/(x + 2)).cancel()
def test_hill_function_dwdx(): """Kinetic laws with Hill functions, may lead to NaNs in the Jacobian if involved states are zero if not properly arranged symbolically. Test that what we are applying the right sympy simplification.""" w = sp.Matrix([[sp.sympify('Pow(x1, p1) / (Pow(x1, p1) + a)')]]) dwdx = w.diff(sp.Symbol('x1')) # Verify that without simplification we fail with pytest.raises(ZeroDivisionError): with sp.evaluate(False): res = dwdx.subs({'x1': 0.0}) _ = str(res) # Test that powsimp does the job dwdx = dwdx.applyfunc(lambda x: sp.powsimp(x, deep=True)) with sp.evaluate(False): res = dwdx.subs({'x1': 0.0}) _ = str(res)
def _eval_nseries(self, x, n, logx): # NOTE Please see the comment at the beginning of this file, labelled # IMPORTANT. from sympy import limit, oo, powsimp arg = self.args[0] arg_series = arg._eval_nseries(x, n=n, logx=logx) if arg_series.is_Order: return 1 + arg_series arg0 = limit(arg_series.removeO(), x, 0) if arg0 in [-oo, oo]: return self t = Dummy("t") exp_series = exp(t)._taylor(t, n) o = exp_series.getO() exp_series = exp_series.removeO() r = exp(arg0)*exp_series.subs(t, arg_series - arg0) r += C.Order(o.expr.subs(t, (arg_series - arg0)), x) r = r.expand() return powsimp(r, deep=True, combine='exp')
def _contains(self, expr): from sympy import powsimp, limit if expr is S.Zero: return True if expr is S.NaN: return False if expr.is_Order: if expr.point != self.point: return False if expr.expr == self.expr: # O(1) + O(1), O(1) + O(1, x), etc. return all([x in self.variables for x in expr.variables]) if expr.expr.is_Add: return all([self.contains(x) for x in expr.expr.args]) if self.expr.is_Add: return any([self.func(x, *self.args[1:]).contains(expr) for x in self.expr.args]) if self.variables and expr.variables: common_symbols = tuple( [s for s in self.variables if s in expr.variables]) elif self.variables: common_symbols = self.variables else: common_symbols = expr.variables if not common_symbols: return None r = None for s in common_symbols: l = limit(powsimp(self.expr/expr.expr, deep=True, combine='exp'), s, self.point) != 0 if r is None: r = l else: if r != l: return return r newargs = self.variables + (S.Zero,) obj1 = Order(expr, *newargs) newargs = self.variables + (S.Infinity,) obj2 = Order(expr, *newargs) return self.contains(obj1) or self.contains(obj2)
def test_powsimp_polar(): from sympy import polar_lift, exp_polar x, y, z = symbols('x y z') p, q, r = symbols('p q r', polar=True) assert (polar_lift(-1))**(2*x) == exp_polar(2*pi*I*x) assert powsimp(p**x * q**x) == (p*q)**x assert p**x * (1/p)**x == 1 assert (1/p)**x == p**(-x) assert exp_polar(x)*exp_polar(y) == exp_polar(x)*exp_polar(y) assert powsimp(exp_polar(x)*exp_polar(y)) == exp_polar(x+y) assert powsimp(exp_polar(x)*exp_polar(y)*p**x*p**y) == (p*exp_polar(1))**(x + y) assert powsimp(exp_polar(x)*exp_polar(y)*p**x*p**y, combine='exp') \ == exp_polar(x+y)*p**(x+y) assert powsimp(exp_polar(x)*exp_polar(y)*exp_polar(2)*sin(x)+sin(y)+p**x*p**y) \ == p**(x+y) + sin(x)*exp_polar(2+x+y) + sin(y) assert powsimp(sin(exp_polar(x)*exp_polar(y))) == sin(exp_polar(x)*exp_polar(y)) assert powsimp(sin(exp_polar(x)*exp_polar(y)), deep=True) == sin(exp_polar(x+y))
def _simpsol(soleq): lhs = soleq.lhs sol = soleq.rhs sol = powsimp(sol) gens = list(sol.atoms(exp)) p = Poly(sol, *gens, expand=False) gens = [factor_terms(g) for g in gens] if not gens: gens = p.gens syms = [Symbol('C1'), Symbol('C2')] terms = [] for coeff, monom in zip(p.coeffs(), p.monoms()): coeff = piecewise_fold(coeff) if type(coeff) is Piecewise: coeff = Piecewise(*((ratsimp(coef).collect(syms), cond) for coef, cond in coeff.args)) else: coeff = ratsimp(coeff).collect(syms) monom = Mul(*(g**i for g, i in zip(gens, monom))) terms.append(coeff * monom) return Eq(lhs, Add(*terms))
def test_TR2i(): # just a reminder that ratios of powers only simplify if both # numerator and denominator satisfy the condition that each # has a positive base or an integer exponent; e.g. the following, # at y=-1, x=1/2 gives sqrt(2)*I != -sqrt(2)*I assert powsimp(2**x / y**x) != (2 / y)**x assert TR2i(sin(x) / cos(x)) == tan(x) assert TR2i(sin(x) * sin(y) / cos(x)) == tan(x) * sin(y) assert TR2i(1 / (sin(x) / cos(x))) == 1 / tan(x) assert TR2i(1 / (sin(x) * sin(y) / cos(x))) == 1 / tan(x) / sin(y) assert TR2i(sin(x) / 2 / (cos(x) + 1)) == sin(x) / (cos(x) + 1) / 2 assert TR2i(sin(x) / 2 / (cos(x) + 1), half=True) == tan(x / 2) / 2 assert TR2i(sin(1) / (cos(1) + 1), half=True) == tan(S.Half) assert TR2i(sin(2) / (cos(2) + 1), half=True) == tan(1) assert TR2i(sin(4) / (cos(4) + 1), half=True) == tan(2) assert TR2i(sin(5) / (cos(5) + 1), half=True) == tan(5 * S.Half) assert TR2i((cos(1) + 1) / sin(1), half=True) == 1 / tan(S.Half) assert TR2i((cos(2) + 1) / sin(2), half=True) == 1 / tan(1) assert TR2i((cos(4) + 1) / sin(4), half=True) == 1 / tan(2) assert TR2i((cos(5) + 1) / sin(5), half=True) == 1 / tan(5 * S.Half) assert TR2i((cos(1) + 1)**(-a) * sin(1)**a, half=True) == tan(S.Half)**a assert TR2i((cos(2) + 1)**(-a) * sin(2)**a, half=True) == tan(1)**a assert TR2i((cos(4) + 1)**(-a) * sin(4)**a, half=True) == (cos(4) + 1)**(-a) * sin(4)**a assert TR2i((cos(5) + 1)**(-a) * sin(5)**a, half=True) == (cos(5) + 1)**(-a) * sin(5)**a assert TR2i((cos(1) + 1)**a * sin(1)**(-a), half=True) == tan(S.Half)**(-a) assert TR2i((cos(2) + 1)**a * sin(2)**(-a), half=True) == tan(1)**(-a) assert TR2i((cos(4) + 1)**a * sin(4)**(-a), half=True) == (cos(4) + 1)**a * sin(4)**(-a) assert TR2i((cos(5) + 1)**a * sin(5)**(-a), half=True) == (cos(5) + 1)**a * sin(5)**(-a) i = symbols('i', integer=True) assert TR2i(((cos(5) + 1)**i * sin(5)**(-i)), half=True) == tan(5 * S.Half)**(-i) assert TR2i(1 / ((cos(5) + 1)**i * sin(5)**(-i)), half=True) == tan(5 * S.Half)**i
def leadterm(self, x): """ Returns the leading term a*x**b as a tuple (a, b). Example: >>> from sympy.abc import x >>> (1+x+x**2).leadterm(x) (1, 0) >>> (1/x**2+x+x**2).leadterm(x) (1, -2) Note: self is assumed to be the result returned by Basic.series(). """ from sympy import powsimp x = sympify(x) c,e = self.as_leading_term(x).as_coeff_exponent(x) c = powsimp(c, deep=True, combine='exp') if not c.has(x): return c,e raise ValueError("cannot compute leadterm(%s, %s), got c=%s" % (self, x, c))
def leadterm(self, x): """ Returns the leading term a*x**b as a tuple (a, b). Example: >>> from sympy.abc import x >>> (1+x+x**2).leadterm(x) (1, 0) >>> (1/x**2+x+x**2).leadterm(x) (1, -2) Note: self is assumed to be the result returned by Basic.series(). """ from sympy import powsimp x = sympify(x) c, e = self.as_leading_term(x).as_coeff_exponent(x) c = powsimp(c, deep=True, combine='exp') if not c.has(x): return c, e raise ValueError("cannot compute leadterm(%s, %s), got c=%s" % (self, x, c))
def rubi_powsimp(expr): """ This function is needed to preprocess an expression as done in matchpy `x^a*x^b` in matchpy auotmatically transforms to `x^(a+b)` Examples ======== >>> from sympy.integrals.rubi.rubimain import rubi_powsimp >>> from sympy.abc import a, b, x >>> rubi_powsimp(x**a*x**b) x**(a + b) """ lst_pow = [] lst_non_pow = [] if isinstance(expr, Mul): for i in expr.args: if isinstance(i, (Pow, rubi_exp, sym_exp)): lst_pow.append(i) else: lst_non_pow.append(i) return powsimp(Mul(*lst_pow)) * Mul(*lst_non_pow) return expr
def contains(self, expr): """ Return True if expr belongs to Order(self.expr, *self.variables). Return False if self belongs to expr. Return None if the inclusion relation cannot be determined (e.g. when self and expr have different symbols). """ from sympy import powsimp, limit if expr is S.Zero: return True if expr is S.NaN: return False if expr.is_Order: if self.variables and expr.variables: common_symbols = tuple( [s for s in self.variables if s in expr.variables]) elif self.variables: common_symbols = self.variables else: common_symbols = expr.variables if not common_symbols: if not (self.variables or expr.variables): # O(1),O(1) return True return None r = None for s in common_symbols: l = limit(powsimp(self.expr/expr.expr, deep=True,\ combine='exp'), s, 0) != 0 if r is None: r = l else: if r != l: return return r obj = Order(expr, *self.variables) return self.contains(obj)
def _eval_nseries(self, x, n, logx): # NOTE Please see the comment at the beginning of this file, labelled # IMPORTANT. from sympy import limit, oo, Order, powsimp, Wild, expand_complex arg = self.args[0] arg_series = arg._eval_nseries(x, n=n, logx=logx) if arg_series.is_Order: return 1 + arg_series arg0 = limit(arg_series.removeO(), x, 0) if arg0 in [-oo, oo]: return self t = Dummy("t") exp_series = exp(t)._taylor(t, n) o = exp_series.getO() exp_series = exp_series.removeO() r = exp(arg0) * exp_series.subs(t, arg_series - arg0) r += Order(o.expr.subs(t, (arg_series - arg0)), x) r = r.expand() r = powsimp(r, deep=True, combine='exp') # powsimp may introduce unexpanded (-1)**Rational; see PR #17201 simplerat = lambda x: x.is_Rational and x.q in [3, 4, 6] w = Wild('w', properties=[simplerat]) r = r.replace((-1)**w, expand_complex((-1)**w)) return r
def rubi_powsimp(expr): ''' This function is needed to preprocess an expression as done in matchpy `x^a*x^b` in matchpy auotmatically transforms to `x^(a+b)` Examples ======== >>> from sympy.integrals.rubi.rubi import rubi_powsimp >>> from sympy.abc import a, b, x >>> rubi_powsimp(x**a*x**b) x**(a+b) ''' lst_pow =[] lst_non_pow = [] if isinstance(expr, Mul): for i in expr.args: if isinstance(i, (Pow, exp, sym_exp)): lst_pow.append(i) else: lst_non_pow.append(i) return powsimp(Mul(*lst_pow))*Mul(*lst_non_pow) return expr
def mysimp(expr): from sympy import expand, logcombine, powsimp return expand(powsimp(logcombine(expr, force=True), force=True, deep=True), force=True).replace(exp_polar, exp)
def simp_pows(expr): return simplify(powsimp(expand_mul(expr, deep=False), force=True)).replace(exp_polar, exp)
def test_issue_15709(): assert powsimp(3**x * Rational(2, 3)) == 2 * 3**(x - 1) assert powsimp(2 * 3**x / 3) == 2 * 3**(x - 1)
def test_probability(): # various integrals from probability theory from sympy.abc import x, y from sympy import symbols, Symbol, Abs, expand_mul, combsimp, powsimp, sin mu1, mu2 = symbols('mu1 mu2', real=True, nonzero=True, finite=True) sigma1, sigma2 = symbols('sigma1 sigma2', real=True, nonzero=True, finite=True, positive=True) rate = Symbol('lambda', real=True, positive=True, finite=True) def normal(x, mu, sigma): return 1 / sqrt(2 * pi * sigma**2) * exp(-(x - mu)**2 / 2 / sigma**2) def exponential(x, rate): return rate * exp(-rate * x) assert integrate(normal(x, mu1, sigma1), (x, -oo, oo), meijerg=True) == 1 assert integrate(x*normal(x, mu1, sigma1), (x, -oo, oo), meijerg=True) == \ mu1 assert integrate(x**2*normal(x, mu1, sigma1), (x, -oo, oo), meijerg=True) \ == mu1**2 + sigma1**2 assert integrate(x**3*normal(x, mu1, sigma1), (x, -oo, oo), meijerg=True) \ == mu1**3 + 3*mu1*sigma1**2 assert integrate(normal(x, mu1, sigma1) * normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == 1 assert integrate(x * normal(x, mu1, sigma1) * normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == mu1 assert integrate(y * normal(x, mu1, sigma1) * normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == mu2 assert integrate(x * y * normal(x, mu1, sigma1) * normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == mu1 * mu2 assert integrate( (x + y + 1) * normal(x, mu1, sigma1) * normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == 1 + mu1 + mu2 assert integrate((x + y - 1)*normal(x, mu1, sigma1)*normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == \ -1 + mu1 + mu2 i = integrate(x**2 * normal(x, mu1, sigma1) * normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) assert not i.has(Abs) assert simplify(i) == mu1**2 + sigma1**2 assert integrate(y**2*normal(x, mu1, sigma1)*normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == \ sigma2**2 + mu2**2 assert integrate(exponential(x, rate), (x, 0, oo), meijerg=True) == 1 assert integrate(x*exponential(x, rate), (x, 0, oo), meijerg=True) == \ 1/rate assert integrate(x**2*exponential(x, rate), (x, 0, oo), meijerg=True) == \ 2/rate**2 def E(expr): res1 = integrate(expr * exponential(x, rate) * normal(y, mu1, sigma1), (x, 0, oo), (y, -oo, oo), meijerg=True) res2 = integrate(expr * exponential(x, rate) * normal(y, mu1, sigma1), (y, -oo, oo), (x, 0, oo), meijerg=True) assert expand_mul(res1) == expand_mul(res2) return res1 assert E(1) == 1 assert E(x * y) == mu1 / rate assert E(x * y**2) == mu1**2 / rate + sigma1**2 / rate ans = sigma1**2 + 1 / rate**2 assert simplify(E((x + y + 1)**2) - E(x + y + 1)**2) == ans assert simplify(E((x + y - 1)**2) - E(x + y - 1)**2) == ans assert simplify(E((x + y)**2) - E(x + y)**2) == ans # Beta' distribution alpha, beta = symbols('alpha beta', positive=True) betadist = x**(alpha - 1)*(1 + x)**(-alpha - beta)*gamma(alpha + beta) \ /gamma(alpha)/gamma(beta) assert integrate(betadist, (x, 0, oo), meijerg=True) == 1 i = integrate(x * betadist, (x, 0, oo), meijerg=True, conds='separate') assert (combsimp(i[0]), i[1]) == (alpha / (beta - 1), 1 < beta) j = integrate(x**2 * betadist, (x, 0, oo), meijerg=True, conds='separate') assert j[1] == (1 < beta - 1) assert combsimp(j[0] - i[0]**2) == (alpha + beta - 1)*alpha \ /(beta - 2)/(beta - 1)**2 # Beta distribution # NOTE: this is evaluated using antiderivatives. It also tests that # meijerint_indefinite returns the simplest possible answer. a, b = symbols('a b', positive=True) betadist = x**(a - 1) * (-x + 1)**(b - 1) * gamma(a + b) / (gamma(a) * gamma(b)) assert simplify(integrate(betadist, (x, 0, 1), meijerg=True)) == 1 assert simplify(integrate(x*betadist, (x, 0, 1), meijerg=True)) == \ a/(a + b) assert simplify(integrate(x**2*betadist, (x, 0, 1), meijerg=True)) == \ a*(a + 1)/(a + b)/(a + b + 1) assert simplify(integrate(x**y*betadist, (x, 0, 1), meijerg=True)) == \ gamma(a + b)*gamma(a + y)/gamma(a)/gamma(a + b + y) # Chi distribution k = Symbol('k', integer=True, positive=True) chi = 2**(1 - k / 2) * x**(k - 1) * exp(-x**2 / 2) / gamma(k / 2) assert powsimp(integrate(chi, (x, 0, oo), meijerg=True)) == 1 assert simplify(integrate(x*chi, (x, 0, oo), meijerg=True)) == \ sqrt(2)*gamma((k + 1)/2)/gamma(k/2) assert simplify(integrate(x**2 * chi, (x, 0, oo), meijerg=True)) == k # Chi^2 distribution chisquared = 2**(-k / 2) / gamma(k / 2) * x**(k / 2 - 1) * exp(-x / 2) assert powsimp(integrate(chisquared, (x, 0, oo), meijerg=True)) == 1 assert simplify(integrate(x * chisquared, (x, 0, oo), meijerg=True)) == k assert simplify(integrate(x**2*chisquared, (x, 0, oo), meijerg=True)) == \ k*(k + 2) assert combsimp( integrate(((x - k) / sqrt(2 * k))**3 * chisquared, (x, 0, oo), meijerg=True)) == 2 * sqrt(2) / sqrt(k) # Dagum distribution a, b, p = symbols('a b p', positive=True) # XXX (x/b)**a does not work dagum = a * p / x * (x / b)**(a * p) / (1 + x**a / b**a)**(p + 1) assert simplify(integrate(dagum, (x, 0, oo), meijerg=True)) == 1 # XXX conditions are a mess arg = x * dagum assert simplify(integrate( arg, (x, 0, oo), meijerg=True, conds='none')) == a * b * gamma(1 - 1 / a) * gamma(p + 1 + 1 / a) / ( (a * p + 1) * gamma(p)) assert simplify(integrate( x * arg, (x, 0, oo), meijerg=True, conds='none')) == a * b**2 * gamma(1 - 2 / a) * gamma(p + 1 + 2 / a) / ( (a * p + 2) * gamma(p)) # F-distribution d1, d2 = symbols('d1 d2', positive=True) f = sqrt(((d1*x)**d1 * d2**d2)/(d1*x + d2)**(d1 + d2))/x \ /gamma(d1/2)/gamma(d2/2)*gamma((d1 + d2)/2) assert simplify(integrate(f, (x, 0, oo), meijerg=True)) == 1 # TODO conditions are a mess assert simplify(integrate(x * f, (x, 0, oo), meijerg=True, conds='none')) == d2 / (d2 - 2) assert simplify( integrate(x**2 * f, (x, 0, oo), meijerg=True, conds='none')) == d2**2 * (d1 + 2) / d1 / (d2 - 4) / (d2 - 2) # TODO gamma, rayleigh # inverse gaussian lamda, mu = symbols('lamda mu', positive=True) dist = sqrt(lamda / 2 / pi) * x**(-S(3) / 2) * exp( -lamda * (x - mu)**2 / x / 2 / mu**2) mysimp = lambda expr: simplify(expr.rewrite(exp)) assert mysimp(integrate(dist, (x, 0, oo))) == 1 assert mysimp(integrate(x * dist, (x, 0, oo))) == mu assert mysimp(integrate((x - mu)**2 * dist, (x, 0, oo))) == mu**3 / lamda assert mysimp(integrate((x - mu)**3 * dist, (x, 0, oo))) == 3 * mu**5 / lamda**2 # Levi c = Symbol('c', positive=True) assert integrate( sqrt(c / 2 / pi) * exp(-c / 2 / (x - mu)) / (x - mu)**S('3/2'), (x, mu, oo)) == 1 # higher moments oo # log-logistic distn = (beta/alpha)*x**(beta - 1)/alpha**(beta - 1)/ \ (1 + x**beta/alpha**beta)**2 assert simplify(integrate(distn, (x, 0, oo))) == 1 # NOTE the conditions are a mess, but correctly state beta > 1 assert simplify(integrate(x*distn, (x, 0, oo), conds='none')) == \ pi*alpha/beta/sin(pi/beta) # (similar comment for conditions applies) assert simplify(integrate(x**y*distn, (x, 0, oo), conds='none')) == \ pi*alpha**y*y/beta/sin(pi*y/beta) # weibull k = Symbol('k', positive=True) n = Symbol('n', positive=True) distn = k / lamda * (x / lamda)**(k - 1) * exp(-(x / lamda)**k) assert simplify(integrate(distn, (x, 0, oo))) == 1 assert simplify(integrate(x**n*distn, (x, 0, oo))) == \ lamda**n*gamma(1 + n/k) # rice distribution from sympy import besseli nu, sigma = symbols('nu sigma', positive=True) rice = x / sigma**2 * exp(-(x**2 + nu**2) / 2 / sigma**2) * besseli( 0, x * nu / sigma**2) assert integrate(rice, (x, 0, oo), meijerg=True) == 1 # can someone verify higher moments? # Laplace distribution mu = Symbol('mu', real=True) b = Symbol('b', positive=True) laplace = exp(-abs(x - mu) / b) / 2 / b assert integrate(laplace, (x, -oo, oo), meijerg=True) == 1 assert integrate(x * laplace, (x, -oo, oo), meijerg=True) == mu assert integrate(x**2*laplace, (x, -oo, oo), meijerg=True) == \ 2*b**2 + mu**2 # TODO are there other distributions supported on (-oo, oo) that we can do? # misc tests k = Symbol('k', positive=True) assert combsimp( expand_mul( integrate(log(x) * x**(k - 1) * exp(-x) / gamma(k), (x, 0, oo)))) == polygamma(0, k)
def diop_simplify(eq): return _mexpand(powsimp(_mexpand(eq)))
def _eval_nseries(self, x, n, logx): # NOTE! This function is an important part of the gruntz algorithm # for computing limits. It has to return a generalized power # series with coefficients in C(log, log(x)). In more detail: # It has to return an expression # c_0*x**e_0 + c_1*x**e_1 + ... (finitely many terms) # where e_i are numbers (not necessarily integers) and c_i are # expressions involving only numbers, the log function, and log(x). from sympy import powsimp, collect, exp, log, O, ceiling b, e = self.args if e.is_Integer: if e > 0: # positive integer powers are easy to expand, e.g.: # sin(x)**4 = (x-x**3/3+...)**4 = ... return expand_multinomial(self.func( b._eval_nseries(x, n=n, logx=logx), e), deep=False) elif e is S.NegativeOne: # this is also easy to expand using the formula: # 1/(1 + x) = 1 - x + x**2 - x**3 ... # so we need to rewrite base to the form "1+x" nuse = n cf = 1 try: ord = b.as_leading_term(x) cf = C.Order(ord, x).getn() if cf and cf.is_Number: nuse = n + 2 * ceiling(cf) else: cf = 1 except NotImplementedError: pass b_orig, prefactor = b, O(1, x) while prefactor.is_Order: nuse += 1 b = b_orig._eval_nseries(x, n=nuse, logx=logx) prefactor = b.as_leading_term(x) # express "rest" as: rest = 1 + k*x**l + ... + O(x**n) rest = expand_mul((b - prefactor) / prefactor) if rest.is_Order: return 1 / prefactor + rest / prefactor + O(x**n, x) k, l = rest.leadterm(x) if l.is_Rational and l > 0: pass elif l.is_number and l > 0: l = l.evalf() elif l == 0: k = k.simplify() if k == 0: # if prefactor == w**4 + x**2*w**4 + 2*x*w**4, we need to # factor the w**4 out using collect: return 1 / collect(prefactor, x) else: raise NotImplementedError() else: raise NotImplementedError() if cf < 0: cf = S.One / abs(cf) try: dn = C.Order(1 / prefactor, x).getn() if dn and dn < 0: pass else: dn = 0 except NotImplementedError: dn = 0 terms = [1 / prefactor] for m in xrange(1, ceiling((n - dn) / l * cf)): new_term = terms[-1] * (-rest) if new_term.is_Pow: new_term = new_term._eval_expand_multinomial( deep=False) else: new_term = expand_mul(new_term, deep=False) terms.append(new_term) terms.append(O(x**n, x)) return powsimp(Add(*terms), deep=True, combine='exp') else: # negative powers are rewritten to the cases above, for # example: # sin(x)**(-4) = 1/( sin(x)**4) = ... # and expand the denominator: nuse, denominator = n, O(1, x) while denominator.is_Order: denominator = (b**(-e))._eval_nseries(x, n=nuse, logx=logx) nuse += 1 if 1 / denominator == self: return self # now we have a type 1/f(x), that we know how to expand return (1 / denominator)._eval_nseries(x, n=n, logx=logx) if e.has(Symbol): return exp(e * log(b))._eval_nseries(x, n=n, logx=logx) # see if the base is as simple as possible bx = b while bx.is_Pow and bx.exp.is_Rational: bx = bx.base if bx == x: return self # work for b(x)**e where e is not an Integer and does not contain x # and hopefully has no other symbols def e2int(e): """return the integer value (if possible) of e and a flag indicating whether it is bounded or not.""" n = e.limit(x, 0) unbounded = n.is_unbounded if not unbounded: # XXX was int or floor intended? int used to behave like floor # so int(-Rational(1, 2)) returned -1 rather than int's 0 try: n = int(n) except TypeError: #well, the n is something more complicated (like 1+log(2)) try: n = int(n.evalf()) + 1 # XXX why is 1 being added? except TypeError: pass # hope that base allows this to be resolved n = _sympify(n) return n, unbounded order = O(x**n, x) ei, unbounded = e2int(e) b0 = b.limit(x, 0) if unbounded and (b0 is S.One or b0.has(Symbol)): # XXX what order if b0 is S.One: resid = (b - 1) if resid.is_positive: return S.Infinity elif resid.is_negative: return S.Zero raise ValueError('cannot determine sign of %s' % resid) return b0**ei if (b0 is S.Zero or b0.is_unbounded): if unbounded is not False: return b0**e # XXX what order if not ei.is_number: # if not, how will we proceed? raise ValueError('expecting numerical exponent but got %s' % ei) nuse = n - ei if e.is_real and e.is_positive: lt = b.as_leading_term(x) # Try to correct nuse (= m) guess from: # (lt + rest + O(x**m))**e = # lt**e*(1 + rest/lt + O(x**m)/lt)**e = # lt**e + ... + O(x**m)*lt**(e - 1) = ... + O(x**n) try: cf = C.Order(lt, x).getn() nuse = ceiling(n - cf * (e - 1)) except NotImplementedError: pass bs = b._eval_nseries(x, n=nuse, logx=logx) terms = bs.removeO() if terms.is_Add: bs = terms lt = terms.as_leading_term(x) # bs -> lt + rest -> lt*(1 + (bs/lt - 1)) return ((self.func(lt, e) * self.func( (bs / lt).expand(), e).nseries( x, n=nuse, logx=logx)).expand() + order) if bs.is_Add: from sympy import O # So, bs + O() == terms c = Dummy('c') res = [] for arg in bs.args: if arg.is_Order: arg = c * arg.expr res.append(arg) bs = Add(*res) rv = (bs**e).series(x).subs(c, O(1, x)) rv += order return rv rv = bs**e if terms != bs: rv += order return rv # either b0 is bounded but neither 1 nor 0 or e is unbounded # b -> b0 + (b-b0) -> b0 * (1 + (b/b0-1)) o2 = order * (b0**-e) z = (b / b0 - 1) o = O(z, x) #r = self._compute_oseries3(z, o2, self.taylor_term) if o is S.Zero or o2 is S.Zero: unbounded = True else: if o.expr.is_number: e2 = log(o2.expr * x) / log(x) else: e2 = log(o2.expr) / log(o.expr) n, unbounded = e2int(e2) if unbounded: # requested accuracy gives infinite series, # order is probably non-polynomial e.g. O(exp(-1/x), x). r = 1 + z else: l = [] g = None for i in xrange(n + 2): g = self._taylor_term(i, z, g) g = g.nseries(x, n=n, logx=logx) l.append(g) r = Add(*l) return expand_mul(r * b0**e) + order
def test_issue_6440(): assert powsimp(16 * 2**a * 8**b) == 2**(a + 3 * b + 4)
def transport_terms(self): """ This function determines the RHS in the moments equation for given internal dynamics """ if self.num_coords == 1: x = smp.symbols("x") l = smp.symbols("l", real=True) xdot = parse_expr(self.internal_dynamics) integrand = xdot * (x**(l - 1)) self.symbolic_indices = l elif self.num_coords == 2: # if self.poly: # r0 = smp.symbols( self.poly_symbol ) x, xdot = smp.symbols("x xdot") l, m = smp.symbols("l m", real=True) xddot = parse_expr(self.internal_dynamics) integrand = xddot * (x**l) * (xdot**(m - 1)) self.symbolic_indices = [l, m] terms = smp.powsimp(smp.expand(integrand)).args num_terms = len(terms) # Add constant term for 2+D problems total_num_terms = num_terms if self.num_coords == 2: total_num_terms += 1 # Initialize exponents and coefficients (weird, but works) self.exponents = [[smp.symbols("a") for i in range(total_num_terms)] for j in range(self.num_coords)] self.coefficients = [smp.symbols("a") for i in range(total_num_terms)] # Everything is simpler if now transferred into numpy arrays self.exponents = np.array(self.exponents).T self.coefficients = np.array(self.coefficients).T # Loop over terms for i in range(num_terms): self.exponents[i, 0] = terms[i].as_coeff_exponent(x)[1] if self.num_coords == 1: self.coefficients[i] = l * smp.poly(terms[i]).coeffs()[0] else: self.exponents[i, 1] = terms[i].as_coeff_exponent(xdot)[1] self.coefficients[i] = m * smp.poly(terms[i]).coeffs()[0] # Add extra constant term if in 2D if self.num_coords == 2: self.exponents[num_terms, 0] = l - 1 self.exponents[num_terms, 1] = m + 1 self.coefficients[num_terms] = l self.num_coefficients = len(self.coefficients) self.num_exponents = len(self.exponents) # message = 'qbmm_mgr: transport_terms: ' # for i in range( total_num_terms ): # sym_array_pretty_print( message, 'exponents', self.exponents[i,:] ) # message = 'qbmm_mgr: transport_terms: ' # sym_array_pretty_print( message, 'coefficients', self.coefficients ) for i in range(self.num_coefficients): if self.num_coords == 1: self.coefficients[i] = smp.lambdify([l], self.coefficients[i]) for j in range(self.num_coords): self.exponents[i, j] = smp.lambdify([l], self.exponents[i, j]) elif self.num_coords == 2: self.coefficients[i] = smp.lambdify([l, m], self.coefficients[i]) for j in range(self.num_coords): self.exponents[i, j] = smp.lambdify([l, m], self.exponents[i, j]) return
def test_powsimp(): x, y, z, n = symbols('x,y,z,n') f = Function('f') assert powsimp(4**x * 2**(-x) * 2**(-x)) == 1 assert powsimp((-4)**x * (-2)**(-x) * 2**(-x)) == 1 assert powsimp(f(4**x * 2**(-x) * 2**(-x))) == f(4**x * 2**(-x) * 2**(-x)) assert powsimp(f(4**x * 2**(-x) * 2**(-x)), deep=True) == f(1) assert exp(x) * exp(y) == exp(x) * exp(y) assert powsimp(exp(x) * exp(y)) == exp(x + y) assert powsimp(exp(x) * exp(y) * 2**x * 2**y) == (2 * E)**(x + y) assert powsimp(exp(x)*exp(y)*2**x*2**y, combine='exp') == \ exp(x + y)*2**(x + y) assert powsimp(exp(x)*exp(y)*exp(2)*sin(x) + sin(y) + 2**x*2**y) == \ exp(2 + x + y)*sin(x) + sin(y) + 2**(x + y) assert powsimp(sin(exp(x) * exp(y))) == sin(exp(x) * exp(y)) assert powsimp(sin(exp(x) * exp(y)), deep=True) == sin(exp(x + y)) assert powsimp(x**2 * x**y) == x**(2 + y) # This should remain factored, because 'exp' with deep=True is supposed # to act like old automatic exponent combining. assert powsimp((1 + E*exp(E))*exp(-E), combine='exp', deep=True) == \ (1 + exp(1 + E))*exp(-E) assert powsimp((1 + E*exp(E))*exp(-E), deep=True) == \ (1 + exp(1 + E))*exp(-E) assert powsimp((1 + E * exp(E)) * exp(-E)) == (1 + exp(1 + E)) * exp(-E) assert powsimp((1 + E*exp(E))*exp(-E), combine='exp') == \ (1 + exp(1 + E))*exp(-E) assert powsimp((1 + E*exp(E))*exp(-E), combine='base') == \ (1 + E*exp(E))*exp(-E) x, y = symbols('x,y', nonnegative=True) n = Symbol('n', real=True) assert powsimp(y**n * (y / x)**(-n)) == x**n assert powsimp(x**(x**(x*y)*y**(x*y))*y**(x**(x*y)*y**(x*y)), deep=True) \ == (x*y)**(x*y)**(x*y) assert powsimp(2**(2**(2 * x) * x), deep=False) == 2**(2**(2 * x) * x) assert powsimp(2**(2**(2 * x) * x), deep=True) == 2**(x * 4**x) assert powsimp( exp(-x + exp(-x)*exp(-x*log(x))), deep=False, combine='exp') == \ exp(-x + exp(-x)*exp(-x*log(x))) assert powsimp( exp(-x + exp(-x)*exp(-x*log(x))), deep=False, combine='exp') == \ exp(-x + exp(-x)*exp(-x*log(x))) assert powsimp((x + y) / (3 * z), deep=False, combine='exp') == (x + y) / (3 * z) assert powsimp((x / 3 + y / 3) / z, deep=True, combine='exp') == (x / 3 + y / 3) / z assert powsimp(exp(x)/(1 + exp(x)*exp(y)), deep=True) == \ exp(x)/(1 + exp(x + y)) assert powsimp(x * y**(z**x * z**y), deep=True) == x * y**(z**(x + y)) assert powsimp((z**x * z**y)**x, deep=True) == (z**(x + y))**x assert powsimp(x * (z**x * z**y)**x, deep=True) == x * (z**(x + y))**x p = symbols('p', positive=True) assert powsimp((1 / x)**log(2) / x) == (1 / x)**(1 + log(2)) assert powsimp((1 / p)**log(2) / p) == p**(-1 - log(2)) # coefficient of exponent can only be simplified for positive bases assert powsimp(2**(2 * x)) == 4**x assert powsimp((-1)**(2 * x)) == (-1)**(2 * x) i = symbols('i', integer=True) assert powsimp((-1)**(2 * i)) == 1 assert powsimp((-1)**(-x)) != (-1)**x # could be 1/((-1)**x), but is not # force=True overrides assumptions assert powsimp((-1)**(2 * x), force=True) == 1 # rational exponents allow combining of negative terms w, n, m = symbols('w n m', negative=True) e = i / a # not a rational exponent if `a` is unknown ex = w**e * n**e * m**e assert powsimp(ex) == m**(i / a) * n**(i / a) * w**(i / a) e = i / 3 ex = w**e * n**e * m**e assert powsimp(ex) == (-1)**i * (-m * n * w)**(i / 3) e = (3 + i) / i ex = w**e * n**e * m**e assert powsimp(ex) == (-1)**(3 * e) * (-m * n * w)**e eq = x**(a * Rational(2, 3)) # eq != (x**a)**(2/3) (try x = -1 and a = 3 to see) assert powsimp(eq).exp == eq.exp == a * Rational(2, 3) # powdenest goes the other direction assert powsimp(2**(2 * x)) == 4**x assert powsimp(exp(p / 2)) == exp(p / 2) # issue 6368 eq = Mul(*[sqrt(Dummy(imaginary=True)) for i in range(3)]) assert powsimp(eq) == eq and eq.is_Mul assert all(powsimp(e) == e for e in (sqrt(x**a), sqrt(x**2))) # issue 8836 assert str(powsimp(exp(I * pi / 3) * root(-1, 3))) == '(-1)**(2/3)' # issue 9183 assert powsimp(-0.1**x) == -0.1**x # issue 10095 assert powsimp((1 / (2 * E))**oo) == (exp(-1) / 2)**oo # PR 13131 eq = sin(2 * x)**2 * sin(2.0 * x)**2 assert powsimp(eq) == eq # issue 14615 assert powsimp( x**2 * y**3 * (x * y**2)**Rational(3, 2)) == x * y * (x * y**2)**Rational(5, 2)
def test_issue_17524(): a = symbols("a", real=True) e = (-1 - a**2) * sqrt(1 + a**2) assert signsimp(powsimp(e)) == signsimp(e) == -(a**2 + 1)**(S(3) / 2)
def test_issue_11981(): x, y = symbols('x y', commutative=False) assert powsimp((x * y)**2 * (y * x)**2) == (x * y)**2 * (y * x)**2
def add_bf_on_numbers_on_pareto(pathdir, filename, PA, math_expr): def unsnap_recur(expr, param_dict, unsnapped_param_dict): """Recursively transform each numerical value into a learnable parameter.""" import sympy from sympy import Symbol if isinstance(expr, sympy.numbers.Float) or isinstance( expr, sympy.numbers.Integer) or isinstance( expr, sympy.numbers.Rational) or isinstance( expr, sympy.numbers.Pi): used_param_names = list( param_dict.keys()) + list(unsnapped_param_dict) unsnapped_param_name = get_next_available_key(used_param_names, "p", is_underscore=False) unsnapped_param_dict[unsnapped_param_name] = float(expr) unsnapped_expr = Symbol(unsnapped_param_name) return unsnapped_expr elif isinstance(expr, sympy.symbol.Symbol): return expr else: unsnapped_sub_expr_list = [] for sub_expr in expr.args: unsnapped_sub_expr = unsnap_recur(sub_expr, param_dict, unsnapped_param_dict) unsnapped_sub_expr_list.append(unsnapped_sub_expr) return expr.func(*unsnapped_sub_expr_list) def get_next_available_key(iterable, key, midfix="", suffix="", is_underscore=True): """Get the next available key that does not collide with the keys in the dictionary.""" if key + suffix not in iterable: return key + suffix else: i = 0 underscore = "_" if is_underscore else "" while "{}{}{}{}{}".format(key, underscore, midfix, i, suffix) in iterable: i += 1 new_key = "{}{}{}{}{}".format(key, underscore, midfix, i, suffix) return new_key eq = parse_expr(str(math_expr)) expr = eq # Get the numbers appearing in the expression is_atomic_number = lambda expr: expr.is_Atom and expr.is_number eq_numbers = [ subexpression for subexpression in preorder_traversal(expr) if is_atomic_number(subexpression) ] # Do bf on one parameter at a time bf_on_numbers_expr = [] for w in range(len(eq_numbers)): try: param_dict = {} unsnapped_param_dict = {'p': 1} eq_ = unsnap_recur(expr, param_dict, unsnapped_param_dict) eq = eq_ np.savetxt(pathdir + "number_for_bf_%s.txt" % w, [eq_numbers[w]]) brute_force_number(pathdir, "number_for_bf_%s.txt" % w) # Load the predictions made by the bf code bf_numbers = np.loadtxt("results.dat", usecols=(1, ), dtype="str") new_numbers = copy.deepcopy(eq_numbers) # replace the number under consideration by all the proposed bf numbers for kk in range(len(bf_numbers)): eq = eq_ new_numbers[w] = parse_expr(RPN_to_eq(bf_numbers[kk])) jj = 0 for parm in unsnapped_param_dict: if parm != "p": eq = eq.subs(parm, new_numbers[jj]) jj = jj + 1 bf_on_numbers_expr = bf_on_numbers_expr + [eq] except: continue for i in range(len(bf_on_numbers_expr)): try: # Calculate the error of the new, snapped expression snapped_error = get_symbolic_expr_error(pathdir, filename, str(bf_on_numbers_expr[i])) # Calculate the complexity of the new, snapped expression expr = simplify(powsimp(bf_on_numbers_expr[i])) is_atomic_number = lambda expr: expr.is_Atom and expr.is_number numbers_expr = [ subexpression for subexpression in preorder_traversal(expr) if is_atomic_number(subexpression) ] snapped_complexity = 0 for j in numbers_expr: snapped_complexity = snapped_complexity + get_number_DL_snapped( float(j)) # Add the complexity due to symbols n_variables = len(expr.free_symbols) n_operations = len(count_ops(expr, visual=True).free_symbols) if n_operations != 0 or n_variables != 0: snapped_complexity = snapped_complexity + ( n_variables + n_operations) * np.log2( (n_variables + n_operations)) PA.add(Point(x=snapped_complexity, y=snapped_error, data=str(expr))) except: continue return (PA)
def test_powsimp(): x, y, z, n = symbols('x,y,z,n') f = Function('f') assert powsimp(4**x * 2**(-x) * 2**(-x)) == 1 assert powsimp((-4)**x * (-2)**(-x) * 2**(-x)) == 1 assert powsimp(f(4**x * 2**(-x) * 2**(-x))) == f(4**x * 2**(-x) * 2**(-x)) assert powsimp(f(4**x * 2**(-x) * 2**(-x)), deep=True) == f(1) assert exp(x) * exp(y) == exp(x) * exp(y) assert powsimp(exp(x) * exp(y)) == exp(x + y) assert powsimp(exp(x) * exp(y) * 2**x * 2**y) == (2 * E)**(x + y) assert powsimp(exp(x) * exp(y) * 2**x * 2**y, combine='exp') == exp(x + y) * 2**(x + y) assert powsimp(exp(x) * exp(y) * exp(2) * sin(x) + sin(y) + 2**x * 2**y) == exp(2 + x + y) * sin(x) + sin(y) + 2**(x + y) assert powsimp(sin(exp(x) * exp(y))) == sin(exp(x) * exp(y)) assert powsimp(sin(exp(x) * exp(y)), deep=True) == sin(exp(x + y)) assert powsimp(x**2 * x**y) == x**(2 + y) # This should remain factored, because 'exp' with deep=True is supposed # to act like old automatic exponent combining. assert powsimp((1 + E * exp(E)) * exp(-E), combine='exp', deep=True) == (1 + exp(1 + E)) * exp(-E) assert powsimp((1 + E * exp(E)) * exp(-E), deep=True) == exp(1) + exp(-E) # This should not change without deep. Otherwise, simplify() will fail. assert powsimp((1 + E * exp(E)) * exp(-E)) == (1 + E * exp(E)) * exp(-E) assert powsimp((1 + E * exp(E)) * exp(-E), combine='exp') == (1 + E * exp(E)) * exp(-E) assert powsimp((1 + E * exp(E)) * exp(-E), combine='base') == (1 + E * exp(E)) * exp(-E) x, y = symbols('x,y', nonnegative=True) n = Symbol('n', real=True) assert powsimp(y**n * (y / x)**(-n)) == x**n assert powsimp(x**(x**(x * y) * y**(x * y)) * y**(x**(x * y) * y**(x * y)), deep=True) == (x * y)**(x * y)**(x * y) assert powsimp(2**(2**(2 * x) * x), deep=False) == 2**(2**(2 * x) * x) assert powsimp(2**(2**(2 * x) * x), deep=True) == 2**(x * 4**x) assert powsimp(exp(-x + exp(-x) * exp(-x * log(x))), deep=False, combine='exp') == exp(-x + exp(-x) * exp(-x * log(x))) assert powsimp(exp(-x + exp(-x) * exp(-x * log(x))), deep=False, combine='exp') == exp(-x + exp(-x) * exp(-x * log(x))) assert powsimp((x + y) / (3 * z), deep=False, combine='exp') == (x + y) / (3 * z) assert powsimp((x / 3 + y / 3) / z, deep=True, combine='exp') == (x / 3 + y / 3) / z assert powsimp(exp(x) / (1 + exp(x) * exp(y)), deep=True) == exp(x) / (1 + exp(x + y)) assert powsimp(x * y**(z**x * z**y), deep=True) == x * y**(z**(x + y)) assert powsimp((z**x * z**y)**x, deep=True) == (z**(x + y))**x assert powsimp(x * (z**x * z**y)**x, deep=True) == x * (z**(x + y))**x p = symbols('p', positive=True) assert powsimp((1 / x)**log(2) / x) == (1 / x)**(1 + log(2)) assert powsimp((1 / p)**log(2) / p) == p**(-1 - log(2)) # coefficient of exponent can only be simplified for positive bases assert powsimp(2**(2 * x)) == 4**x assert powsimp((-1)**(2 * x)) == (-1)**(2 * x) i = symbols('i', integer=True) assert powsimp((-1)**(2 * i)) == 1 assert powsimp((-1)**(-x)) != (-1)**x # could be 1/((-1)**x), but is not # force=True overrides assumptions assert powsimp((-1)**(2 * x), force=True) == 1
def test_powsimp_nc(): x, y, z = symbols('x,y,z') A, B, C = symbols('A B C', commutative=False) assert powsimp(A**x * A**y, combine='all') == A**(x + y) assert powsimp(A**x * A**y, combine='base') == A**x * A**y assert powsimp(A**x * A**y, combine='exp') == A**(x + y) assert powsimp(A**x * B**x, combine='all') == (A * B)**x assert powsimp(A**x * B**x, combine='base') == (A * B)**x assert powsimp(A**x * B**x, combine='exp') == A**x * B**x assert powsimp(B**x * A**x, combine='all') == (B * A)**x assert powsimp(B**x * A**x, combine='base') == (B * A)**x assert powsimp(B**x * A**x, combine='exp') == B**x * A**x assert powsimp(A**x * A**y * A**z, combine='all') == A**(x + y + z) assert powsimp(A**x * A**y * A**z, combine='base') == A**x * A**y * A**z assert powsimp(A**x * A**y * A**z, combine='exp') == A**(x + y + z) assert powsimp(A**x * B**x * C**x, combine='all') == (A * B * C)**x assert powsimp(A**x * B**x * C**x, combine='base') == (A * B * C)**x assert powsimp(A**x * B**x * C**x, combine='exp') == A**x * B**x * C**x assert powsimp(B**x * A**x * C**x, combine='all') == (B * A * C)**x assert powsimp(B**x * A**x * C**x, combine='base') == (B * A * C)**x assert powsimp(B**x * A**x * C**x, combine='exp') == B**x * A**x * C**x
def _eval_nseries(self, x, n, logx): # NOTE! This function is an important part of the gruntz algorithm # for computing limits. It has to return a generalized power series # with coefficients in C(log, log(x)). In more detail: # It has to return an expression # c_0*x**e_0 + c_1*x**e_1 + ... (finitely many terms) # where e_i are numbers (not necessarily integers) and c_i are expression # involving only numbers, the log function, and log(x). from sympy import powsimp, collect, exp, log, O, ceiling b, e = self.args if e.is_Integer: if e > 0: # positive integer powers are easy to expand, e.g.: # sin(x)**4 = (x-x**3/3+...)**4 = ... return Pow(b._eval_nseries(x, n=n, logx=logx), e)._eval_expand_multinomial(deep=False) elif e is S.NegativeOne: # this is also easy to expand using the formula: # 1/(1 + x) = 1 - x + x**2 - x**3 ... # so we need to rewrite base to the form "1+x" b = b._eval_nseries(x, n=n, logx=logx) prefactor = b.as_leading_term(x) # express "rest" as: rest = 1 + k*x**l + ... + O(x**n) rest = ((b - prefactor) / prefactor)._eval_expand_mul() if rest == 0: # if prefactor == w**4 + x**2*w**4 + 2*x*w**4, we need to # factor the w**4 out using collect: return 1 / collect(prefactor, x) if rest.is_Order: return 1 / prefactor + rest / prefactor n2 = rest.getn() if n2 is not None: n = n2 # remove the O - powering this is slow if logx is not None: rest = rest.removeO() k, l = rest.leadterm(x) if l.is_Rational and l > 0: pass elif l.is_number and l > 0: l = l.evalf() else: raise NotImplementedError() terms = [1 / prefactor] for m in xrange(1, ceiling(n / l)): new_term = terms[-1] * (-rest) if new_term.is_Pow: new_term = new_term._eval_expand_multinomial( deep=False) else: new_term = new_term._eval_expand_mul(deep=False) terms.append(new_term) # Append O(...), we know the order. if n2 is None or logx is not None: terms.append(O(x**n)) return powsimp(Add(*terms), deep=True, combine='exp') else: # negative powers are rewritten to the cases above, for example: # sin(x)**(-4) = 1/( sin(x)**4) = ... # and expand the denominator: denominator = (b**(-e))._eval_nseries(x, n=n, logx=logx) if 1 / denominator == self: return self # now we have a type 1/f(x), that we know how to expand return (1 / denominator)._eval_nseries(x, n=n, logx=logx) if e.has(Symbol): return exp(e * log(b))._eval_nseries(x, n=n, logx=logx) if b == x: return powsimp(self, deep=True, combine='exp') # work for b(x)**e where e is not an Integer and does not contain x # and hopefully has no other symbols def e2int(e): """return the integer value (if possible) of e and a flag indicating whether it is bounded or not.""" n = e.limit(x, 0) unbounded = n.is_unbounded if not unbounded: # XXX was int or floor intended? int used to behave like floor # so int(-Rational(1, 2)) returned -1 rather than int's 0 try: n = int(n) except TypeError: #well, the n is something more complicated (like 1+log(2)) try: n = int(n.evalf()) + 1 # XXX why is 1 being added? except TypeError: pass # hope that base allows this to be resolved n = _sympify(n) return n, unbounded order = O(x**n, x) ei, unbounded = e2int(e) b0 = b.limit(x, 0) if unbounded and (b0 is S.One or b0.has(Symbol)): # XXX what order if b0 is S.One: resid = (b - 1) if resid.is_positive: return S.Infinity elif resid.is_negative: return S.Zero raise ValueError('cannot determine sign of %s' % resid) return b0**ei if (b0 is S.Zero or b0.is_unbounded): if unbounded is not False: return b0**e # XXX what order if not ei.is_number: # if not, how will we proceed? raise ValueError('expecting numerical exponent but got %s' % ei) nuse = n - ei lt = b.compute_leading_term(x, logx=logx) # arg = sin(x); lt = x # XXX o is not used -- was this to be used as o and o2 below to compute a new e? o = order * lt**(1 - e) bs = b._eval_nseries(x, n=nuse, logx=logx) if bs.is_Add: bs = bs.removeO() if bs.is_Add: # bs -> lt + rest -> lt*(1 + (bs/lt - 1)) return ((Pow(lt, e) * Pow((bs / lt).expand(), e).nseries( x, n=nuse, logx=logx)).expand() + order) return bs**e + order # either b0 is bounded but neither 1 nor 0 or e is unbounded # b -> b0 + (b-b0) -> b0 * (1 + (b/b0-1)) o2 = order * (b0**-e) z = (b / b0 - 1) o = O(z, x) #r = self._compute_oseries3(z, o2, self.taylor_term) if o is S.Zero or o2 is S.Zero: unbounded = True else: if o.expr.is_number: e2 = log(o2.expr * x) / log(x) else: e2 = log(o2.expr) / log(o.expr) n, unbounded = e2int(e2) if unbounded: # requested accuracy gives infinite series, # order is probably non-polynomial e.g. O(exp(-1/x), x). r = 1 + z else: l = [] g = None for i in xrange(n + 2): g = self.taylor_term(i, z, g) g = g.nseries(x, n=n, logx=logx) l.append(g) r = Add(*l) return r * b0**e + order
def test_issue_2629(): b = x * sqrt(y) a = sqrt(b) c = sqrt(sqrt(x) * y) assert powsimp(a * b) == sqrt(b)**3 assert powsimp(a * b**2 * sqrt(y)) == sqrt(y) * a**5 assert powsimp(a * x**2 * c**3 * y) == c**3 * a**5 assert powsimp(a * x * c**3 * y**2) == c**7 * a assert powsimp(x * c**3 * y**2) == c**7 assert powsimp(x * c**3 * y) == x * y * c**3 assert powsimp(sqrt(x) * c**3 * y) == c**5 assert powsimp(sqrt(x) * a**3 * sqrt(y)) == sqrt(x) * sqrt(y) * a**3 assert powsimp(Mul(sqrt(x) * c**3 * sqrt(y), y, evaluate=False)) == sqrt(x) * sqrt(y)**3 * c**3 assert powsimp(a**2 * a * x**2 * y) == a**7 # symbolic powers work, too b = x**y * y a = b * sqrt(b) assert a.is_Mul is True assert powsimp(a) == sqrt(b)**3 # as does exp a = x * exp(2 * y / 3) assert powsimp(a * sqrt(a)) == sqrt(a)**3 assert powsimp(a**2 * sqrt(a)) == sqrt(a)**5 assert powsimp(a**2 * sqrt(sqrt(a))) == sqrt(sqrt(a))**9
def _eval_nseries(self, x, n): from sympy import powsimp, collect, exp, log, O, ceiling b, e = self.args if e.is_Integer: if e > 0: # positive integer powers are easy to expand, e.g.: # sin(x)**4 = (x-x**3/3+...)**4 = ... return Pow(b._eval_nseries(x, n=n), e)._eval_expand_multinomial(deep=False) elif e is S.NegativeOne: # this is also easy to expand using the formula: # 1/(1 + x) = 1 + x + x**2 + x**3 ... # so we need to rewrite base to the form "1+x" if b.has(log(x)): # we need to handle the log(x) singularity: y = Dummy("y") p = self.subs(log(x), -1 / y) if not p.has(x): p = p._eval_nseries(y, n=n) p = p.subs(y, -1 / log(x)) return p b = b._eval_nseries(x, n=n) if b.has(log(x)): # we need to handle the log(x) singularity: y = Dummy("y") self0 = 1 / b p = self0.subs(log(x), -1 / y) if not p.has(x): p = p._eval_nseries(y, n=n) p = p.subs(y, -1 / log(x)) return p prefactor = b.as_leading_term(x) # express "rest" as: rest = 1 + k*x**l + ... + O(x**n) rest = ((b - prefactor) / prefactor)._eval_expand_mul() if rest == 0: # if prefactor == w**4 + x**2*w**4 + 2*x*w**4, we need to # factor the w**4 out using collect: return 1 / collect(prefactor, x) if rest.is_Order: return (1 + rest) / prefactor n2 = rest.getn() if n2 is not None: n = n2 term2 = collect(rest.as_leading_term(x), x) k, l = C.Wild("k"), C.Wild("l") r = term2.match(k * x**l) # if term2 is NaN then r will not contain l k = r.get(k, S.One) l = r.get(l, S.Zero) if l.is_Rational and l > 0: pass elif l.is_number and l > 0: l = l.evalf() else: raise NotImplementedError() terms = [1 / prefactor] for m in xrange(1, ceiling(n / l)): new_term = terms[-1] * (-rest) if new_term.is_Pow: new_term = new_term._eval_expand_multinomial( deep=False) else: new_term = new_term._eval_expand_mul(deep=False) terms.append(new_term) if n2 is None: # Append O(...) because it is not included in "r" terms.append(O(x**n)) return powsimp(Add(*terms), deep=True, combine='exp') else: # negative powers are rewritten to the cases above, for example: # sin(x)**(-4) = 1/( sin(x)**4) = ... # and expand the denominator: denominator = (b**(-e))._eval_nseries(x, n=n) if 1 / denominator == self: return self # now we have a type 1/f(x), that we know how to expand return (1 / denominator)._eval_nseries(x, n=n) if e.has(x): return exp(e * log(b))._eval_nseries(x, n=n) if b == x: return powsimp(self, deep=True, combine='exp') # work for b(x)**e where e is not an Integer and does not contain x # and hopefully has no other symbols def e2int(e): """return the integer value (if possible) of e and a flag indicating whether it is bounded or not.""" n = e.limit(x, 0) unbounded = n.is_unbounded if not unbounded: # XXX was int or floor intended? int used to behave like floor # so int(-Rational(1, 2)) returned -1 rather than int's 0 try: n = int(n) except TypeError: #well, the n is something more complicated (like 1+log(2)) try: n = int(n.evalf()) + 1 # XXX why is 1 being added? except TypeError: pass # hope that base allows this to be resolved n = _sympify(n) if n.is_Integer: assert n.is_nonnegative return n, unbounded order = O(x**n, x) ei, unbounded = e2int(e) b0 = b.limit(x, 0) if unbounded and (b0 is S.One or b0.has(Symbol)): # XXX what order if b0 is S.One: resid = (b - 1) if resid.is_positive: return S.Infinity elif resid.is_negative: return S.Zero raise ValueError('cannot determine sign of %s' % resid) return b0**ei if (b0 is S.Zero or b0.is_unbounded): if unbounded is not False: return b0**e # XXX what order if not ei.is_number: # if not, how will we proceed? raise ValueError('expecting numerical exponent but got %s' % ei) nuse = n - ei lt = b.as_leading_term(x) # XXX o is not used -- was this to be used as o and o2 below to compute a new e? o = order * lt**(1 - e) bs = b._eval_nseries(x, n=nuse) if bs.is_Add: bs = bs.removeO() if bs.is_Add: # bs -> lt + rest -> lt*(1 + (bs/lt - 1)) return ((Pow(lt, e) * Pow( (bs / lt).expand(), e).nseries(x, n=nuse)).expand() + order) return bs**e + order # either b0 is bounded but neither 1 nor 0 or e is unbounded # b -> b0 + (b-b0) -> b0 * (1 + (b/b0-1)) o2 = order * (b0**-e) z = (b / b0 - 1) o = O(z, x) #r = self._compute_oseries3(z, o2, self.taylor_term) if o is S.Zero or o2 is S.Zero: unbounded = True else: if o.expr.is_number: e2 = log(o2.expr * x) / log(x) else: e2 = log(o2.expr) / log(o.expr) n, unbounded = e2int(e2) if unbounded: # requested accuracy gives infinite series, # order is probably nonpolynomial e.g. O(exp(-1/x), x). r = 1 + z else: l = [] g = None for i in xrange(n + 2): g = self.taylor_term(i, z, g) g = g.nseries(x, n=n) l.append(g) r = Add(*l) return r * b0**e + order
def test_issue_9324_powsimp_on_matrix_symbol(): M = MatrixSymbol('M', 10, 10) expr = powsimp(M, deep=True) assert expr == M assert expr.args[0] == Symbol('M')
def contains(self, expr): r""" Return True if expr belongs to Order(self.expr, \*self.variables). Return False if self belongs to expr. Return None if the inclusion relation cannot be determined (e.g. when self and expr have different symbols). """ from sympy import powsimp if expr is S.Zero: return True if expr is S.NaN: return False point = self.point[0] if self.point else S.Zero if expr.is_Order: if (any(p != point for p in expr.point) or any(p != point for p in self.point)): return None if expr.expr == self.expr: # O(1) + O(1), O(1) + O(1, x), etc. return all([x in self.args[1:] for x in expr.args[1:]]) if expr.expr.is_Add: return all([self.contains(x) for x in expr.expr.args]) if self.expr.is_Add and point == S.Zero: return any([ self.func(x, *self.args[1:]).contains(expr) for x in self.expr.args ]) if self.variables and expr.variables: common_symbols = tuple( [s for s in self.variables if s in expr.variables]) elif self.variables: common_symbols = self.variables else: common_symbols = expr.variables if not common_symbols: return None if (self.expr.is_Power and len(self.variables) == 1 and self.variables == expr.variables): symbol = self.variables[0] other = expr.expr.as_independent(symbol, as_Add=False)[1] if (other.is_Power and other.base == symbol and self.expr.base == symbol): if point == S.Zero: rv = (self.expr.exp - other.exp).is_nonpositive if point.is_infinite: rv = (self.expr.exp - other.exp).is_nonnegative if rv is not None: return rv r = None ratio = self.expr / expr.expr ratio = powsimp(ratio, deep=True, combine='exp') for s in common_symbols: from sympy.series.limits import Limit l = Limit(ratio, s, point).doit(heuristics=False) if not isinstance(l, Limit): l = l != 0 else: l = None if r is None: r = l else: if r != l: return return r if self.expr.is_Power and len(self.variables) == 1: symbol = self.variables[0] other = expr.as_independent(symbol, as_Add=False)[1] if (other.is_Power and other.base == symbol and self.expr.base == symbol): if point == S.Zero: rv = (self.expr.exp - other.exp).is_nonpositive if point.is_infinite: rv = (self.expr.exp - other.exp).is_nonnegative if rv is not None: return rv obj = self.func(expr, *self.args[1:]) return self.contains(obj)
def _eval_nseries(self, x, n): from sympy import powsimp terms = [t.nseries(x, n=n) for t in self.args] return powsimp(Mul(*terms).expand(), combine='exp', deep=True)